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