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