]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/sbr/m_gmsg.c
Always check that mktemp()/mktemp2() succeeds before trying to
[nmh] / docs / historical / mh-6.8.5 / sbr / m_gmsg.c
1 /* m_gmsg.c - read a folder */
2 #ifndef lint
3 static char ident[] = "@(#)$Id: m_gmsg.c,v 2.10 1992/10/20 22:46:29 jromine Exp $";
4 #endif /* lint */
5
6 #include "../h/mh.h"
7 #include "../h/local.h"
8 #include <stdio.h>
9
10
11 #define NINFO (MAXFOLDER / 5) /* PLEASE be non-trivial... */
12 struct info {
13 int msgno;
14 int stats;
15 };
16
17 static int len=0;
18 static struct info *head;
19
20 static m_getatr();
21 static int m_setatr();
22 /* \f */
23
24 struct msgs *m_gmsg (name)
25 register char *name;
26 {
27 #ifdef COMPAT
28 register int cur,
29 fd;
30 #endif /* COMPAT */
31 register int i,
32 j;
33 register struct info *rover,
34 *tail;
35 #ifdef COMPAT
36 register char *cp;
37 char buffer[BUFSIZ];
38 #endif /* COMPAT */
39 register struct msgs *mp;
40 #ifdef SYS5DIR
41 register struct dirent *dp;
42 DIR * dd;
43 #else /* SYS5DIR */
44 register struct direct *dp;
45 register DIR * dd;
46 #endif /* SYS5DIR */
47 struct stat st;
48
49 if ((dd = opendir (name = m_mailpath (name))) == NULL) {
50 free (name);
51 return NULL;
52 }
53 (void) fstat (dd -> dd_fd, &st);
54
55 mp = (struct msgs *) malloc (MHSIZE (mp, 0, 0));
56 if (mp == NULL)
57 adios (NULLCP, "unable to allocate folder storage");
58 mp -> lowmsg = mp -> hghmsg = mp -> nummsg = 0;
59 mp -> curmsg = 0;
60 mp -> lowsel = mp -> hghsel = mp -> numsel = 0;
61 mp -> foldpath = name;
62 mp -> msgflags = 0;
63 if (st.st_uid != getuid () || access (name, 02) == NOTOK)
64 mp -> msgflags |= READONLY;
65 #ifdef COMPAT
66 cur = 0;
67 #endif /* COMPAT */
68 j = strlen (SBACKUP);
69 if (head == NULL)
70 if ((head = (struct info *)
71 malloc ((unsigned) ((len = NINFO) * sizeof *head))) == NULL)
72 adios (NULLCP, "unable to allocate info storage");
73 tail = (rover = head) + len;
74
75 while (dp = readdir (dd))
76 if (i = m_atoi (dp -> d_name)) {
77 if (rover >= tail) {
78 register int curlen = tail - head;
79
80 if ((tail = (struct info *) realloc ((char *) head,
81 (unsigned) ((len += NINFO) * sizeof *head)))
82 == NULL)
83 adios (NULLCP, "unable to allocate info storage");
84 else
85 rover = tail + curlen, head = tail, tail += len;
86 }
87 if (i > mp -> hghmsg)
88 mp -> hghmsg = i;
89 mp -> nummsg++;
90 if (mp -> lowmsg == 0 || i < mp -> lowmsg)
91 mp -> lowmsg = i;
92 rover -> msgno = i;
93 rover -> stats = EXISTS;
94 #ifdef notdef
95 rover -> stats &= ~DELETED;
96 #endif /* notdef */
97 rover++;
98 }
99 else
100 switch (dp -> d_name[0]) {
101 case '.':
102 continue;
103
104 case ',':
105 #ifdef notdef
106 if ((i = m_atoi (dp -> d_name + 1)) {
107 register struct info *l;
108
109 for (l = head; l < rover; l++)
110 if (l -> msgno == i) {
111 if (!(l -> stats & EXISTS))
112 l -> stats |= DELETED;
113 break;
114 }
115 }
116 #endif /* notdef */
117 continue;
118
119 #ifdef MHE
120 case '+':
121 continue;
122 #endif /* MHE */
123
124 #ifdef UCI
125 case '_':
126 case '#':
127 continue;
128 #endif /* UCI */
129
130 default:
131 #ifdef COMPAT
132 if (strcmp (dp -> d_name, current) == 0) {
133 cur++;
134 continue;
135 }
136 #endif /* COMPAT */
137 if (strcmp (dp -> d_name, LINK) == 0
138 || strncmp (dp -> d_name, SBACKUP, j) == 0)
139 continue;
140 mp -> msgflags |= OTHERS;
141 continue;
142 }
143
144 closedir (dd);
145
146 /* \f */
147
148 #ifdef COMPAT
149 (void) sprintf (buffer, "%s-%s", current, name);
150 if (cp = m_find (buffer)) {
151 i = m_atoi (cp);
152 (void) m_delete(buffer);
153 if (i > 0)
154 mp -> curmsg = i;
155 }
156 if (mp -> curmsg == 0 && cur && (fd = open (current, 0)) != NOTOK) {
157 if ((i = read (fd, buffer, sizeof buffer)) > 0) {
158 if (cp = index (buffer, '\n'))
159 *cp = 0;
160 if ((i = m_atoi (buffer)) > 0)
161 mp -> curmsg = i;
162 }
163 (void) close (fd);
164 }
165 if (cur && !(mp -> msgflags & READONLY)){ /* sneaky... */
166 (void) sprintf (buffer, "%s/%s", name, current);
167 (void) unlink (buffer);
168 }
169 #endif /* COMPAT */
170
171 #ifndef MTR
172 mp -> lowoff = 1;
173 #else /* MTR */
174 mp -> lowoff = mp -> lowmsg;
175 #endif /* MTR */
176 mp -> hghoff = mp -> hghmsg + 1;/* for "new" in m_convert */
177
178 mp = (struct msgs *)
179 realloc ((char *) mp, MHSIZE (mp, mp -> lowoff, mp -> hghoff));
180 if (mp == NULL)
181 adios (NULLCP, "unable to allocate folder storage");
182 #ifndef MTR
183 for (i = mp -> lowmsg; i <= mp -> hghmsg; i++)
184 mp -> msgstats[i] = 0;
185 #else /* MTR */
186 mp -> msgstats = (int *)
187 calloc ((unsigned) 1, MHSIZEX (mp, mp -> lowmsg, mp -> hghmsg));
188 if (mp -> msgstats == NULL)
189 adios (NULLCP, "unable to allocate messages storage");
190 mp -> msgstats = (mp -> msgbase = mp -> msgstats) - mp -> lowoff;
191 if (mp -> msgstats < (int *)0) /* non portable */
192 adios (NULLCP, "m_gmsg() botch -- you lose big");
193 #endif /* MTR */
194 for (tail = head; tail < rover; tail++)
195 mp -> msgstats[tail -> msgno] = tail -> stats;
196 m_getatr (mp);
197
198 return mp;
199 }
200
201 /* \f */
202
203 static m_getatr (mp)
204 register struct msgs *mp;
205 {
206 int alen,
207 bits,
208 i,
209 j,
210 plen,
211 state;
212 register char *cp;
213 char name[NAMESZ],
214 field[BUFSIZ * 2];
215 register struct node *np;
216 register FILE * fp;
217
218 bits = FFATTRSLOT;
219
220 mp -> msgattrs[i = 0] = getcpy (current);
221 mp -> msgattrs[++i] = '\0';
222 mp -> attrstats = 0; /* initially, all public */
223
224 m_getdefs ();
225 if (mh_seq == '\0' || *mh_seq == '\0')
226 goto private_only;
227
228 (void) sprintf (field, "%s/%s", mp -> foldpath, mh_seq);
229 if (fp = fopen (field, "r")) {
230 for (state = FLD;;) {
231 switch (state = m_getfld (state, name, field, sizeof field, fp)) {
232 case FLD:
233 case FLDEOF:
234 (void) m_setatr (mp, getcpy (name), trimcpy (field));
235 if (state == FLDEOF)
236 break;
237 continue;
238
239 case BODY:
240 case BODYEOF:
241 adios (NULLCP,
242 "no blank lines are permitted in %s/%s",
243 mp -> foldpath, mh_seq);/* fall */
244
245 case FILEEOF:
246 break;
247
248 default:
249 adios (NULLCP, "%s/%s is poorly formatted",
250 mp -> foldpath, mh_seq);
251 }
252 break;
253 }
254 (void) fclose (fp);
255 }
256
257 private_only: ;
258 alen = strlen ("atr-");
259 plen = strlen (mp -> foldpath) + 1;
260
261 for (np = m_defs; np; np = np -> n_next)
262 if (ssequal ("atr-", np -> n_name)
263 && (j = strlen (np -> n_name) - plen) > alen
264 && *(np -> n_name + j) == '-'
265 && strcmp (mp -> foldpath, np -> n_name + j + 1) == 0) {
266 cp = getcpy (np -> n_name + alen);
267 *(cp + j - alen) = '\0';
268 if ((i = m_setatr (mp, cp, getcpy (np -> n_field))) != NOTOK)
269 mp -> attrstats |= 1 << (bits + i);/* private */
270 }
271 }
272
273 /* \f */
274
275 static int m_setatr (mp, name, field)
276 register struct msgs *mp;
277 register char *name,
278 *field;
279 {
280 int bits,
281 hack;
282 register int i,
283 j,
284 k;
285 register char *cp,
286 **ap;
287
288 bits = FFATTRSLOT;
289 hack = strcmp (current, name) == 0;/* hack... */
290 /* if we're going to use UNSEEN, it should be set here! */
291
292 for (i = 0; mp -> msgattrs[i]; i++)
293 if (strcmp (mp -> msgattrs[i], name) == 0) {
294 for (j = mp -> lowmsg; j <= mp -> hghmsg; j++)
295 mp -> msgstats[j] &= ~(1 << (bits + i));
296 break;
297 }
298 if (i >= NATTRS) {
299 free (name);
300 free (field);
301 return NOTOK;
302 }
303
304 if (mp -> msgattrs[i] == NULL) {
305 mp -> msgattrs[i] = name;
306 mp -> msgattrs[i + 1] = NULL;
307 }
308 else
309 free (name);
310
311 for (ap = brkstring (field, " ", "\n");
312 *ap;
313 ap++) {
314 if (cp = index (*ap, '-'))
315 *cp++ = '\0';
316 if ((j = m_atoi (*ap)) > 0) {
317 #ifdef notdef
318 if (hack && j >= mp -> lowmsg && j <= mp -> hghmsg
319 && (mp -> msgstats[j] & EXISTS))
320 mp -> curmsg = j;
321 #else /* not notdef */
322 if (hack)
323 mp -> curmsg = j;
324 #endif /* not notdef */
325 for (k = cp ? m_atoi (cp) : j; j <= k; j++)
326 if (j >= mp -> lowmsg && j <= mp -> hghmsg
327 && (mp -> msgstats[j] & EXISTS))
328 mp -> msgstats[j] |= 1 << (bits + i);
329 }
330 }
331 free (field);
332
333 return i;
334 }