|
|
1.1 root 1: /* dropsbr.c - write to a mailbox */
2:
3: #include <stdio.h>
4: #ifndef MMDFONLY
5: #include "../h/mh.h"
6: #include "../h/dropsbr.h"
7: #include "../zotnet/mts.h"
8: #else MMDFONLY
9: #include "dropsbr.h"
10: #include "strings.h"
11: #include "mmdfonly.h"
12: #endif MMDFONLY
13: #include <errno.h>
14: #include <sys/types.h>
15: #include <sys/stat.h>
16:
17:
18: #define MMDF 1
19: #define UUCP 2
20:
21: /* */
22:
23: static int mbx_style = MMDF;
24:
25:
26: extern int errno;
27:
28:
29: long lseek ();
30:
31: /* */
32:
33: int mbx_mmdf () {
34: int style = mbx_style;
35:
36: mbx_style = MMDF;
37: return style;
38: }
39:
40:
41: int mbx_uucp () {
42: int style = mbx_style;
43:
44: mbx_style = UUCP;
45: return style;
46: }
47:
48: /* */
49:
50: int mbx_open (file, uid, gid, mode)
51: char *file;
52: int uid,
53: gid,
54: mode;
55: {
56: int clear,
57: fd;
58:
59: if ((fd = mbx_Xopen (file, uid, gid, mode, &clear)) == NOTOK)
60: return fd;
61:
62: if (!clear)
63: switch (mbx_style) {
64: case MMDF:
65: default:
66: if (mbx_chk (fd) == NOTOK) {
67: (void) close (fd);
68: return NOTOK;
69: }
70: break;
71:
72: case UUCP:
73: if (lseek (fd, 0L, 2) == (long) NOTOK) {
74: (void) close (fd);
75: return NOTOK;
76: }
77: break;
78: }
79:
80: return fd;
81: }
82:
83: /* */
84:
85: int mbx_Xopen (file, uid, gid, mode, clear)
86: char *file;
87: int uid,
88: gid,
89: mode,
90: *clear;
91: {
92: register int j;
93: int count,
94: fd;
95: struct stat st;
96:
97: for (*clear = 0, count = 4, j = 0; count > 0; count--)
98: if ((fd = lkopen (file, 6)) == NOTOK)
99: switch (errno) {
100: case ENOENT:
101: if (mbx_create (file, uid, gid, mode) == NOTOK)
102: return NOTOK;
103: (*clear)++;
104: break;
105:
106: #ifdef BSD42
107: case EWOULDBLOCK:
108: #endif BSD42
109: case ETXTBSY:
110: j = errno;
111: sleep (5);
112: break;
113:
114: default:
115: return NOTOK;
116: }
117: else {
118: *clear = fstat (fd, &st) != NOTOK && st.st_size == 0L;
119: break;
120: }
121:
122: errno = j;
123: return fd;
124: }
125:
126: /* */
127:
128: static int mbx_create (file, uid, gid, mode)
129: char *file;
130: int uid,
131: gid,
132: mode;
133: {
134: int fd;
135:
136: if ((fd = creat (file, 0600)) == NOTOK)
137: return NOTOK;
138:
139: (void) close (fd);
140: (void) chown (file, uid, gid);
141: (void) chmod (file, mode);
142:
143: return OK;
144: }
145:
146:
147: static int mbx_chk (fd)
148: int fd;
149: {
150: int count;
151: char ldelim[BUFSIZ];
152:
153: count = strlen (mmdlm2);
154:
155: if (lseek (fd, (long) (-count), 2) == (long) NOTOK
156: || read (fd, ldelim, count) != count)
157: return NOTOK;
158: ldelim[count] = NULL;
159:
160: if (strcmp (ldelim, mmdlm2)
161: && write (fd, "\n", 1) != 1
162: && write (fd, mmdlm2, count) != count)
163: return NOTOK;
164:
165: return OK;
166: }
167:
168: /* */
169:
170: int mbx_read (fp, pos, drops, noisy)
171: register FILE *fp;
172: register long pos;
173: struct drop **drops;
174: int noisy;
175: {
176: register int len,
177: size;
178: long ld1,
179: ld2;
180: register char *bp;
181: char buffer[BUFSIZ];
182: register struct drop *cp,
183: *dp,
184: *ep,
185: *pp;
186:
187: pp = (struct drop *) calloc ((unsigned) (len = MAXFOLDER), sizeof *dp);
188: if (pp == NULL) {
189: if (noisy)
190: admonish (NULLCP, "unable to allocate drop storage");
191: return NOTOK;
192: }
193:
194: ld1 = (long) strlen (mmdlm1);
195: ld2 = (long) strlen (mmdlm2);
196:
197: (void) fseek (fp, pos, 0);
198: for (ep = (dp = pp) + len - 1; fgets (buffer, sizeof buffer, fp);) {
199: size = 0;
200: if (strcmp (buffer, mmdlm1) == 0)
201: pos += ld1, dp -> d_start = pos;
202: else {
203: dp -> d_start = pos, pos += (long) strlen (buffer);
204: for (bp = buffer; *bp; bp++, size++)
205: if (*bp == '\n')
206: size++;
207: }
208:
209: while (fgets (buffer, sizeof buffer, fp) != NULL)
210: if (strcmp (buffer, mmdlm2) == 0)
211: break;
212: else {
213: pos += (long) strlen (buffer);
214: for (bp = buffer; *bp; bp++, size++)
215: if (*bp == '\n')
216: size++;
217: }
218:
219: if (dp -> d_start != pos) {
220: dp -> d_id = 0;
221: dp -> d_size = size;
222: dp -> d_stop = pos;
223: dp++;
224: }
225: pos += ld2;
226:
227: if (dp >= ep) {
228: register int curlen = dp - pp;
229:
230: cp = (struct drop *) realloc ((char *) pp,
231: (unsigned) (len += MAXFOLDER) * sizeof *pp);
232: if (cp == NULL) {
233: if (noisy)
234: admonish (NULLCP, "unable to allocate drop storage");
235: free ((char *) pp);
236: return 0;
237: }
238: dp = cp + curlen, ep = (pp = cp) + len - 1;
239: }
240: }
241:
242: if (dp == pp)
243: free ((char *) pp);
244: else
245: *drops = pp;
246: return (dp - pp);
247: }
248:
249: /* */
250:
251: int mbx_write (mailbox, md, fp, id, pos, stop, mapping, noisy)
252: char *mailbox;
253: register FILE *fp;
254: int md,
255: id,
256: mapping,
257: noisy;
258: register long pos,
259: stop;
260: {
261: register int i,
262: j,
263: size;
264: register long start,
265: off;
266: register char *cp;
267: char buffer[BUFSIZ];
268:
269: off = lseek (md, 0L, 1);
270: j = strlen (mmdlm1);
271: if (write (md, mmdlm1, j) != j)
272: return NOTOK;
273: start = lseek (md, 0L, 1);
274: size = 0;
275:
276: (void) fseek (fp, pos, 0);
277: while (fgets (buffer, sizeof buffer, fp) != NULL && pos < stop) {
278: i = strlen (buffer);
279: for (j = 0; (j = stringdex (mmdlm1, buffer)) >= 0; buffer[j]++)
280: continue;
281: for (j = 0; (j = stringdex (mmdlm2, buffer)) >= 0; buffer[j]++)
282: continue;
283: if (write (md, buffer, i) != i)
284: return NOTOK;
285: pos += (long) i;
286: if (mapping)
287: for (cp = buffer; i-- > 0; size++)
288: if (*cp++ == '\n')
289: size++;
290: }
291:
292: stop = lseek (md, 0L, 1);
293: j = strlen (mmdlm2);
294: if (write (md, mmdlm2, j) != j)
295: return NOTOK;
296: if (mapping)
297: (void) map_write (mailbox, md, id, start, stop, off, size, noisy);
298:
299: return OK;
300: }
301:
302: /* */
303:
304: int mbx_copy (mailbox, md, fd, mapping, text, noisy)
305: char *mailbox;
306: int md,
307: fd,
308: mapping,
309: noisy;
310: char *text;
311: {
312: register int i,
313: j,
314: size;
315: register long start,
316: stop,
317: pos;
318: register char *cp;
319: char buffer[BUFSIZ];
320: register FILE *fp;
321:
322: pos = lseek (md, 0L, 1);
323: size = 0;
324:
325: switch (mbx_style) {
326: case MMDF:
327: default:
328: j = strlen (mmdlm1);
329: if (write (md, mmdlm1, j) != j)
330: return NOTOK;
331: start = lseek (md, 0L, 1);
332:
333: if (text) {
334: i = strlen (text);
335: if (write (md, text, i) != i)
336: return NOTOK;
337: for (cp = buffer; *cp++; size++)
338: if (*cp == '\n')
339: size++;
340: }
341:
342: while ((i = read (fd, buffer, sizeof buffer)) > 0) {
343: for (j = 0;
344: (j = stringdex (mmdlm1, buffer)) >= 0;
345: buffer[j]++)
346: continue;
347: for (j = 0;
348: (j = stringdex (mmdlm2, buffer)) >= 0;
349: buffer[j]++)
350: continue;
351: if (write (md, buffer, i) != i)
352: return NOTOK;
353: if (mapping)
354: for (cp = buffer; i-- > 0; size++)
355: if (*cp++ == '\n')
356: size++;
357: }
358:
359: stop = lseek (md, 0L, 1);
360: j = strlen (mmdlm2);
361: if (write (md, mmdlm2, j) != j)
362: return NOTOK;
363: if (mapping)
364: (void) map_write (mailbox, md, 0, start, stop, pos, size, noisy);
365:
366: return (i != NOTOK ? OK : NOTOK);
367:
368: case UUCP: /* I hate this... */
369: if ((j = dup (fd)) == NOTOK)
370: return NOTOK;
371: if ((fp = fdopen (j, "r")) == NULL) {
372: (void) close (j);
373: return NOTOK;
374: }
375: start = lseek (md, 0L, 1);
376:
377: if (text) {
378: i = strlen (text);
379: if (write (md, text, i) != i)
380: return NOTOK;
381: for (cp = buffer; *cp++; size++)
382: if (*cp == '\n')
383: size++;
384: }
385:
386: for (j = 0; fgets (buffer, sizeof buffer, fp) != NULL; j++) {
387: if (j != 0 && strncmp (buffer, "From ", 5) == 0) {
388: (void) write (fd, ">", 1);
389: size++;
390: }
391: i = strlen (buffer);
392: if (write (md, buffer, i) != i) {
393: (void) fclose (fp);
394: return NOTOK;
395: }
396: if (mapping)
397: for (cp = buffer; i-- > 0; size++)
398: if (*cp++ == '\n')
399: size++;
400: }
401:
402: (void) fclose (fp);
403: (void) lseek (fd, 0L, 2);
404: stop = lseek (md, 0L, 1);
405: if (mapping)
406: (void) map_write (mailbox, md, 0, start, stop, pos, size,
407: noisy);
408:
409: return OK;
410: }
411: }
412:
413: /* */
414:
415: int mbx_size (md, start, stop)
416: int md;
417: long start,
418: stop;
419: {
420: register int i,
421: fd;
422: register long pos;
423: register FILE *fp;
424:
425: if ((fd = dup (md)) == NOTOK || (fp = fdopen (fd, "r")) == NULL) {
426: if (fd != NOTOK)
427: (void) close (fd);
428: return NOTOK;
429: }
430:
431: (void) fseek (fp, start, 0);
432: for (i = 0, pos = stop - start; pos-- > 0; i++)
433: if (fgetc (fp) == '\n')
434: i++;
435:
436: (void) fclose (fp);
437:
438: return i;
439: }
440:
441: /* */
442:
443: int mbx_close (mailbox, md)
444: char *mailbox;
445: int md;
446: {
447: (void) lkclose (md, mailbox);
448:
449: return OK;
450: }
451:
452: /* */
453:
454: /* This function is performed implicitly by getbbent.c:
455:
456: bb -> bb_map = map_name (bb -> bb_file);
457: */
458:
459: char *map_name (file)
460: register char *file;
461: {
462: register char *cp,
463: *dp;
464: static char buffer[BUFSIZ];
465:
466: if ((dp = index (cp = r1bindex (file, '/'), '.')) == NULL)
467: dp = cp + strlen (cp);
468: if (cp == file)
469: (void) sprintf (buffer, ".%.*s%s", dp - cp, cp, ".map");
470: else
471: (void) sprintf (buffer, "%.*s.%.*s%s", cp - file, file, dp - cp,
472: cp, ".map");
473:
474: return buffer;
475: }
476:
477: /* */
478:
479: int map_read (file, pos, drops, noisy)
480: char *file;
481: long pos;
482: struct drop **drops;
483: int noisy;
484: {
485: register int i,
486: md,
487: msgp;
488: register char *cp;
489: struct drop d;
490: register struct drop *mp,
491: *dp;
492:
493: if ((md = open (cp = map_name (file), 0)) == NOTOK
494: || map_chk (cp, md, mp = &d, pos, noisy)) {
495: if (md != NOTOK)
496: (void) close (md);
497: return 0;
498: }
499:
500: msgp = mp -> d_id;
501: dp = (struct drop *) calloc ((unsigned) msgp, sizeof *dp);
502: if (dp == NULL) {
503: (void) close (md);
504: return 0;
505: }
506:
507: (void) lseek (md, (long) sizeof *mp, 0);
508: if ((i = read (md, (char *) dp, msgp * sizeof *dp)) < sizeof *dp) {
509: i = 0;
510: free ((char *) dp);
511: }
512: else
513: *drops = dp;
514:
515: (void) close (md);
516:
517: return (i / sizeof *dp);
518: }
519:
520: /* */
521:
522: int map_write (mailbox, md, id, start, stop, pos, size, noisy)
523: register char *mailbox;
524: int md,
525: id,
526: size,
527: noisy;
528: long start,
529: stop,
530: pos;
531: {
532: register int i;
533: int clear,
534: fd,
535: td;
536: char *file;
537: register struct drop *dp;
538: struct drop d1,
539: d2,
540: *rp;
541: register FILE *fp;
542:
543: if ((fd = map_open (file = map_name (mailbox), &clear, md)) == NOTOK)
544: return NOTOK;
545:
546: if (!clear && map_chk (file, fd, &d1, pos, noisy)) {
547: (void) unlink (file);
548: (void) mbx_close (file, fd);
549: if ((fd = map_open (file, &clear, md)) == NOTOK)
550: return NOTOK;
551: clear++;
552: }
553:
554: if (clear) {
555: if ((td = dup (md)) == NOTOK || (fp = fdopen (td, "r")) == NULL) {
556: if (noisy)
557: admonish (file, "unable to %s", td != NOTOK ? "fdopen" : "dup");
558: if (td != NOTOK)
559: (void) close (td);
560: (void) mbx_close (file, fd);
561: return NOTOK;
562: }
563:
564: switch (i = mbx_read (fp, 0L, &rp, noisy)) {
565: case NOTOK:
566: (void) fclose (fp);
567: (void) mbx_close (file, fd);
568: return NOTOK;
569:
570: case OK:
571: break;
572:
573: default:
574: d1.d_id = 0;
575: for (dp = rp; i-- >0; dp++) {
576: if (dp -> d_start == start)
577: dp -> d_id = id;
578: (void) lseek (fd, (long) (++d1.d_id * sizeof *dp), 0);
579: if (write (fd, (char *) dp, sizeof *dp) != sizeof *dp) {
580: if (noisy)
581: admonish (file, "write error");
582: (void) mbx_close (file, fd);
583: (void) fclose (fp);
584: return NOTOK;
585: }
586: }
587: free ((char *) rp);
588: break;
589: }
590: }
591: else {
592: dp = &d2;
593: dp -> d_id = id;
594: dp -> d_size = size ? size : mbx_size (fd, start, stop);
595: dp -> d_start = start;
596: dp -> d_stop = stop;
597: (void) lseek (fd, (long) (++d1.d_id * sizeof *dp), 0);
598: if (write (fd, (char *) dp, sizeof *dp) != sizeof *dp) {
599: if (noisy)
600: admonish (file, "write error");
601: (void) mbx_close (file, fd);
602: return NOTOK;
603: }
604: }
605:
606: dp = &d1;
607: dp -> d_size = DRVRSN;
608: dp -> d_start = DRMAGIC;
609: dp -> d_stop = lseek (md, 0L, 1);
610: (void) lseek (fd, 0L, 0);
611: if (write (fd, (char *) dp, sizeof *dp) != sizeof *dp) {
612: if (noisy)
613: admonish (file, "write error");
614: (void) mbx_close (file, fd);
615: return NOTOK;
616: }
617:
618: (void) mbx_close (file, fd);
619:
620: return OK;
621: }
622:
623: /* */
624:
625: static int map_open (file, clear, md)
626: char *file;
627: int *clear,
628: md;
629: {
630: int mode;
631: struct stat st;
632:
633: mode = fstat (md, &st) != NOTOK ? (int) (st.st_mode & 0777) : m_gmprot ();
634: return mbx_Xopen (file, st.st_uid, st.st_gid, mode, clear);
635: }
636:
637: /* */
638:
639: int map_chk (file, fd, dp, pos, noisy)
640: char *file;
641: int fd,
642: noisy;
643: register struct drop *dp;
644: long pos;
645: {
646: long count;
647: struct drop d;
648: register struct drop *dl;
649:
650: if (read (fd, (char *) dp, sizeof *dp) != sizeof *dp) {
651: #ifdef notdef
652: admonish (NULLCP, "%s: missing or partial index", file);
653: #endif notdef
654: return NOTOK;
655: }
656: if (dp -> d_size != DRVRSN) {
657: if (noisy)
658: admonish (NULLCP, "%s: version mismatch", file);
659: return NOTOK;
660: }
661: if (dp -> d_start != DRMAGIC) {
662: if (noisy)
663: admonish (NULLCP, "%s: bad magic number", file);
664: return NOTOK;
665: }
666: if (dp -> d_stop != pos) {
667: if (noisy && pos != 0L)
668: admonish (NULLCP,
669: "%s: pointer mismatch or incomplete index (%ld!=%ld)",
670: file, dp -> d_stop, pos);
671: return NOTOK;
672: }
673:
674: if ((long) ((dp -> d_id + 1) * sizeof *dp) != lseek (fd, 0L, 2)) {
675: if (noisy)
676: admonish (NULLCP, "%s: corrupt index(1)", file);
677: return NOTOK;
678: }
679:
680: dl = &d;
681: count = (long) strlen (mmdlm2);
682: (void) lseek (fd, (long) (dp -> d_id * sizeof *dp), 0);
683: if (read (fd, (char *) dl, sizeof *dl) != sizeof *dl
684: || (dl -> d_stop != dp -> d_stop
685: && dl -> d_stop + count != dp -> d_stop)) {
686: if (noisy)
687: admonish (NULLCP, "%s: corrupt index(2)", file);
688: return NOTOK;
689: }
690:
691: return OK;
692: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.