]> diplodocus.org Git - nmh/blob - sbr/folder_read.c
Fix invalid pointer arithmetic.
[nmh] / sbr / folder_read.c
1 /* folder_read.c -- initialize folder structure and read folder
2 *
3 * This code is Copyright (c) 2002, by the authors of nmh. See the
4 * COPYRIGHT file in the root directory of the nmh distribution for
5 * complete copyright information.
6 */
7
8 #include <h/mh.h>
9 #include <h/utils.h>
10 #include "m_maildir.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, int lockflag)
26 {
27 int msgnum, len, *mi;
28 struct msgs *mp;
29 struct dirent *dp;
30 DIR *dd;
31 struct bvector *v;
32 size_t i;
33
34 name = m_mailpath (name);
35 if (!(dd = opendir (name))) {
36 free (name);
37 return NULL;
38 }
39
40 /* Allocate the main structure for folder information */
41 NEW(mp);
42 clear_folder_flags (mp);
43 mp->foldpath = name;
44 mp->lowmsg = 0;
45 mp->hghmsg = 0;
46 mp->curmsg = 0;
47 mp->lowsel = 0;
48 mp->hghsel = 0;
49 mp->numsel = 0;
50 mp->nummsg = 0;
51 mp->seqhandle = NULL;
52 mp->seqname = NULL;
53
54 if (access (name, W_OK) == -1)
55 set_readonly (mp);
56
57 /*
58 * Allocate a temporary place to record the
59 * name of the messages in this folder.
60 */
61 len = NUMMSGS;
62 mi = mh_xmalloc ((size_t) (len * sizeof(*mi)));
63
64 while ((dp = readdir (dd))) {
65 if ((msgnum = m_atoi (dp->d_name)) && msgnum > 0) {
66 /*
67 * Check if we need to allocate more
68 * temporary elements for message names.
69 */
70 if (mp->nummsg >= len) {
71 len += NUMMSGS;
72 mi = mh_xrealloc (mi, (size_t) (len * sizeof(*mi)));
73 }
74
75 /* Check if this is the first message we've seen */
76 if (mp->nummsg == 0) {
77 mp->lowmsg = msgnum;
78 mp->hghmsg = msgnum;
79 } else {
80 /* Check if this is it the highest or lowest we've seen? */
81 if (msgnum < mp->lowmsg)
82 mp->lowmsg = msgnum;
83 if (msgnum > mp->hghmsg)
84 mp->hghmsg = msgnum;
85 }
86
87 /*
88 * Now increment count, and record message
89 * number in a temporary place for now.
90 */
91 mi[mp->nummsg++] = msgnum;
92
93 } else {
94 switch (dp->d_name[0]) {
95 case '.':
96 case ',':
97 continue;
98
99 default:
100 /* skip any files beginning with backup prefix */
101 if (has_prefix(dp->d_name, BACKUP_PREFIX))
102 continue;
103
104 /* skip the LINK file */
105 if (!strcmp (dp->d_name, LINK))
106 continue;
107
108 /* indicate that there are other files in folder */
109 set_other_files (mp);
110 continue;
111 }
112 }
113 }
114
115 closedir (dd);
116 mp->lowoff = max (mp->lowmsg, 1);
117
118 /* Go ahead and allocate space for 100 additional messages. */
119 mp->hghoff = mp->hghmsg + 100;
120
121 /* for testing, allocate minimal necessary space */
122 /* mp->hghoff = max (mp->hghmsg, 1); */
123
124 /*
125 * If for some reason hghoff < lowoff (like we got an integer overflow)
126 * the complain about this now.
127 */
128
129 if (mp->hghoff < mp->lowoff) {
130 adios(NULL, "Internal failure: high message limit < low message "
131 "limit; possible overflow?");
132 }
133
134 /*
135 * Allocate space for status of each message.
136 */
137 mp->num_msgstats = MSGSTATNUM (mp->lowoff, mp->hghoff);
138 mp->msgstats = mh_xmalloc (MSGSTATSIZE(mp));
139 for (i = 0, v = mp->msgstats; i < mp->num_msgstats; ++i, ++v) {
140 bvector_init(v);
141 }
142
143 mp->msgattrs = svector_create (0);
144
145 /*
146 * Scan through the array of messages we've seen and
147 * setup the initial flags for those messages in the
148 * newly allocated mp->msgstats area.
149 */
150 for (msgnum = 0; msgnum < mp->nummsg; msgnum++)
151 set_exists (mp, mi[msgnum]);
152
153 free (mi); /* We don't need this anymore */
154
155 /*
156 * Read and initialize the sequence information.
157 */
158 if (seq_read (mp, lockflag) == NOTOK) {
159 char seqfile[PATH_MAX];
160
161 /* Failed to lock sequence file. */
162 snprintf (seqfile, sizeof(seqfile), "%s/%s", mp->foldpath, mh_seq);
163 advise (seqfile, "failed to lock");
164
165 return NULL;
166 }
167
168 return mp;
169 }