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