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