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