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