Fix spelling errors, including binaries ones
[mmh] / sbr / folder_read.c
1 /*
2 ** folder_read.c -- initialize folder structure and read folder
3 **
4 ** This code is Copyright (c) 2002, by the authors of nmh.  See the
5 ** COPYRIGHT file in the root directory of the nmh distribution for
6 ** complete copyright information.
7 */
8
9 #include <unistd.h>
10 #include <h/mh.h>
11 #include <h/utils.h>
12 #include <dirent.h>
13 #include <sys/stat.h>
14
15 /* We allocate the `mi' array 1024 elements at a time */
16 #define NUMMSGS  1024
17
18 /*
19 ** 1) Create the folder/message structure
20 ** 2) Read the directory (folder) and temporarily
21 **    record the numbers of the messages we have seen.
22 ** 3) Then allocate the array for message attributes and
23 **    set the initial flags for all messages we've seen.
24 ** 4) Read and initialize the sequence information.
25 */
26
27 struct msgs *
28 folder_read(char *name)
29 {
30         int msgnum, len, *mi;
31         struct msgs *mp;
32         struct stat st;
33         struct dirent *dp;
34         DIR *dd;
35
36         name = mh_xstrdup(toabsdir(name));
37         if (!(dd = opendir(name))) {
38                 mh_free0(&name);
39                 return NULL;
40         }
41
42         if (stat(name, &st) == -1) {
43                 mh_free0(&name);
44                 closedir(dd);
45                 return NULL;
46         }
47
48         /* Allocate the main structure for folder information */
49         mp = mh_xcalloc(1, sizeof(*mp));
50
51         clear_folder_flags(mp);
52         mp->foldpath = name;
53         mp->lowmsg = 0;
54         mp->hghmsg = 0;
55         mp->curmsg = 0;
56         mp->lowsel = 0;
57         mp->hghsel = 0;
58         mp->numsel = 0;
59         mp->nummsg = 0;
60
61         if (access(name, W_OK) == -1)
62                 set_readonly(mp);
63
64         /*
65         ** Allocate a temporary place to record the
66         ** name of the messages in this folder.
67         */
68         len = NUMMSGS;
69         mi = mh_xcalloc(len, sizeof(*mi));
70
71         while ((dp = readdir(dd))) {
72                 if ((msgnum = m_atoi(dp->d_name)) && msgnum > 0) {
73                         /*
74                         ** Check if we need to allocate more
75                         ** temporary elements for message names.
76                         */
77                         if (mp->nummsg >= len) {
78                                 len += NUMMSGS;
79                                 mi = mh_xrealloc(mi, len * sizeof(*mi));
80                         }
81
82                         /* Check if this is the first message we've seen */
83                         if (mp->nummsg == 0) {
84                                 mp->lowmsg = msgnum;
85                                 mp->hghmsg = msgnum;
86                         } else {
87                                 /*
88                                 ** Check if this is it the highest or
89                                 ** lowest we've seen?
90                                 */
91                                 if (msgnum < mp->lowmsg)
92                                         mp->lowmsg = msgnum;
93                                 if (msgnum > mp->hghmsg)
94                                         mp->hghmsg = msgnum;
95                         }
96
97                         /*
98                         ** Now increment count, and record message
99                         ** number in a temporary place for now.
100                         */
101                         mi[mp->nummsg++] = msgnum;
102
103                 } else {
104                         switch (dp->d_name[0]) {
105                         case '.':
106                         case ',':
107                                 continue;
108
109                         default:
110                                 /*
111                                 ** indicate that there are other
112                                 ** files in folder
113                                 */
114                                 set_other_files(mp);
115                                 continue;
116                         }
117                 }
118         }
119
120         closedir(dd);
121         mp->lowoff = max(mp->lowmsg, 1);
122
123         /* Go ahead and allocate space for 100 additional messages. */
124         mp->hghoff = mp->hghmsg + 100;
125
126         /* for testing, allocate minimal necessary space */
127         /* mp->hghoff = max(mp->hghmsg, 1); */
128
129         /* Allocate space for status of each message. */
130
131         mp->msgstats = mh_xcalloc(MSGSTATSIZE(mp, mp->lowoff, mp->hghoff), 1);
132
133         /*
134         ** Clear all the flag bits for all the message
135         ** status entries we just allocated.
136         ** TODO: use memset() ?
137         */
138         for (msgnum = mp->lowoff; msgnum <= mp->hghoff; msgnum++)
139                 clear_msg_flags(mp, msgnum);
140
141         /*
142         ** Scan through the array of messages we've seen and
143         ** setup the initial flags for those messages in the
144         ** newly allocated mp->msgstats area.
145         */
146         for (msgnum = 0; msgnum < mp->nummsg; msgnum++)
147                 set_exists(mp, mi[msgnum]);
148
149         mh_free0(&mi);  /* We don't need this anymore */
150
151         /*
152         ** Read and initialize the sequence information.
153         */
154         seq_read(mp);
155
156         return mp;
157 }