|
|
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.