|
|
1.1 ! root 1: /* uumm.c - routines to filter UUCP to MMDF mailboxes */ ! 2: ! 3: #include "mf.h" ! 4: #include "../tws/tws.h" ! 5: #include <stdio.h> ! 6: #include "../mts/mts.h" ! 7: #include <ctype.h> ! 8: #include <sys/types.h> ! 9: #include <sys/stat.h> ! 10: ! 11: /* */ ! 12: ! 13: static struct header { ! 14: char *h_name; ! 15: int h_type; ! 16: } headers[] = { ! 17: "From", HFROM, ! 18: "Sender", HSNDR, ! 19: "Reply-To", HADDR, ! 20: "To", HADDR, ! 21: "cc", HADDR, ! 22: "Bcc", HADDR, ! 23: "Resent-From", HADDR, ! 24: "Resent-Sender", HADDR, ! 25: "Resent-Reply-To", HADDR, ! 26: "Resent-To", HADDR, ! 27: "Resent-cc", HADDR, ! 28: "Resent-Bcc", HADDR, ! 29: "Date", HDATE, ! 30: "Resent-Date", HDATE, ! 31: NULL, HOTHR ! 32: }; ! 33: ! 34: static char buffer[BUFSIZ], ! 35: tmpbuf[BUFSIZ]; ! 36: ! 37: char *shrink (); ! 38: ! 39: long time (); ! 40: ! 41: /* */ ! 42: ! 43: /* ! 44: * uucp2mmdf() - given a file descriptor to a uucp mailbox, filter ! 45: * its contents to the file descriptor for a mmdf mailbox. Returns ! 46: * non-zero on error (see mf.h for values) ! 47: * ! 48: * It is assumed that the caller will have made sure that the necessary ! 49: * locking has been performed on the output fd. ! 50: */ ! 51: ! 52: int uucp2mmdf (infd, outfd, nodelim) ! 53: int infd, ! 54: outfd, ! 55: nodelim; ! 56: { ! 57: int fd, ! 58: result; ! 59: struct stat st; ! 60: FILE * in, *out; ! 61: ! 62: if (fstat (infd, &st) == NOTOK || fstat (outfd, &st) == NOTOK) ! 63: return MFPRM; ! 64: if ((in = fdopen (infd, "r")) == NULL ! 65: || (out = fdopen (outfd, "w")) == NULL) ! 66: return MFSIO; ! 67: ! 68: result = uumm (in, out, nodelim); ! 69: ! 70: /* for STDIO - free up some fp:s */ ! 71: fd = dup (fileno (in)); ! 72: fclose (in); ! 73: dup2 (fd, infd); ! 74: close (fd); ! 75: ! 76: fd = dup (fileno (out)); ! 77: fclose (out); ! 78: dup2 (fd, outfd); ! 79: close (fd); ! 80: ! 81: return result; ! 82: } ! 83: ! 84: /* */ ! 85: ! 86: int uumm (in, out, nodelim) ! 87: FILE *in, ! 88: *out; ! 89: int nodelim; ! 90: { ! 91: int i, ! 92: tmp_fd; ! 93: char from[LINESIZ], ! 94: date[LINESIZ]; ! 95: FILE *tmp; ! 96: ! 97: for (tmp_fd = NOTOK;;) { ! 98: if ((i = uucp_file (&tmp_fd, in, &tmp, nodelim)) == DONE) ! 99: break; ! 100: else ! 101: if (i != OK) ! 102: return i; ! 103: if ((i = uucp_from (from, date, tmp)) != OK) ! 104: return uucp_die (i, tmp, in, out, nodelim); ! 105: if ((i = uucp_headers (from, date, tmp, out, nodelim)) != OK) ! 106: return uucp_die (i, tmp, in, out, nodelim); ! 107: if ((i = uucp_text (tmp, out, nodelim)) != OK) ! 108: return uucp_die (i, tmp, in, out, nodelim); ! 109: } ! 110: ! 111: fflush (out); ! 112: ! 113: return (ferror (in) || ferror (out) ? MFERR : MFOK); ! 114: } ! 115: ! 116: /* */ ! 117: ! 118: static int uucp_file (tmp_fd, in, tmp, nodelim) ! 119: int *tmp_fd, ! 120: nodelim; ! 121: FILE * in, **tmp; ! 122: { ! 123: int done, ! 124: fd; ! 125: char tmpfil[LINESIZ]; ! 126: FILE * out; ! 127: ! 128: if (nodelim) ! 129: if (*tmp_fd != NOTOK) ! 130: return DONE; ! 131: else ! 132: if ((*tmp_fd = dup (fileno (in))) == NOTOK) ! 133: return MFERR; ! 134: else ! 135: if ((*tmp = fdopen (*tmp_fd, "r")) == NULL) { ! 136: close (*tmp_fd); ! 137: return MFERR; ! 138: } ! 139: else ! 140: return OK; ! 141: ! 142: if (*tmp_fd == NOTOK && fgets (tmpbuf, sizeof tmpbuf, in) == NULL) ! 143: return DONE; ! 144: else ! 145: if (feof (in)) ! 146: return DONE; ! 147: ! 148: strcpy (tmpfil, "/tmp/uummXXXXXX"); ! 149: unlink (mktemp (tmpfil)); ! 150: if ((fd = creat (tmpfil, TMPMODE)) == NOTOK) ! 151: return MFERR; ! 152: close (fd); ! 153: ! 154: if ((fd = open (tmpfil, 2)) == NOTOK) ! 155: return MFERR; ! 156: if ((out = fdopen (fd, "w")) == NULL) { ! 157: close (fd); ! 158: return MFERR; ! 159: } ! 160: unlink (tmpfil); ! 161: ! 162: if ((*tmp_fd = dup (fd)) == NOTOK) { ! 163: close (fd); ! 164: return MFERR; ! 165: } ! 166: if ((*tmp = fdopen (*tmp_fd, "r")) == NULL) { ! 167: close (fd); ! 168: close (*tmp_fd); ! 169: return MFERR; ! 170: } ! 171: ! 172: /* */ ! 173: ! 174: for (done = FALSE;;) { ! 175: if (done) ! 176: if (isfrom (tmpbuf)) ! 177: break; ! 178: else ! 179: putc ('\n', out); ! 180: done = tmpbuf[0] == '\n'; ! 181: if (!done) ! 182: fputs (tmpbuf, out); ! 183: if (fgets (tmpbuf, sizeof tmpbuf, in) == NULL) ! 184: break; ! 185: } ! 186: ! 187: fclose (out); ! 188: fseek (*tmp, 0L, 0); ! 189: return OK; ! 190: } ! 191: ! 192: /* */ ! 193: ! 194: /* We might want to attempt recovery here. Forget it. */ ! 195: ! 196: static int uucp_from (from, date, in) ! 197: char *from, ! 198: *date; ! 199: FILE * in; ! 200: { ! 201: char *cp, ! 202: *pp, ! 203: fromwhom[LINESIZ]; ! 204: struct adrx *adrxp; ! 205: ! 206: if (fgets (buffer, sizeof buffer, in) == NULL || !isfrom (buffer)) ! 207: return MFROM; ! 208: if (buffer[strlen (buffer) - 1] == '\n') ! 209: buffer[strlen (buffer) - 1] = NULL; ! 210: if ((cp = index (buffer, ' ')) == NULL) ! 211: return MFROM; ! 212: pp = ++cp; ! 213: if ((cp = index (cp, ' ')) == NULL) ! 214: return MFROM; ! 215: *cp++ = NULL; ! 216: strcpy (fromwhom, pp); ! 217: while (isspace (*cp)) ! 218: cp++; ! 219: sprintf (date, "%.24s", cp); ! 220: ! 221: for (;;) { ! 222: if ((cp = index (cp + 1, 'r')) == NULL) { ! 223: if (index (fromwhom, '!') || index (fromwhom, '@')) ! 224: strcpy (from, fromwhom); ! 225: else ! 226: sprintf (from, "%s!%s", SystemName (), fromwhom); ! 227: break; ! 228: } ! 229: if (strncmp (cp, "remote from ", 12) == 0) { ! 230: *cp = NULL; ! 231: sprintf (from, "%s!%s", cp + 12, fromwhom); ! 232: break; ! 233: } ! 234: } ! 235: ! 236: if ((adrxp = seekadrx (from)) == NULL) ! 237: return MFROM; ! 238: addr_convert (adrxp, from, TRUE); ! 239: while (seekadrx (NULL)) ! 240: continue; ! 241: if (from[0] == NULL) ! 242: return MFROM; ! 243: date_convert (date, date); ! 244: return (date[0] != NULL ? OK : MFROM); ! 245: } ! 246: ! 247: /* */ ! 248: ! 249: static int uucp_headers (from, date, in, out, nodelim) ! 250: int nodelim; ! 251: char *from, ! 252: *date; ! 253: FILE * in, *out; ! 254: { ! 255: int i, ! 256: seen_from, ! 257: seen_sender, ! 258: seen_date; ! 259: ! 260: seen_from = seen_sender = seen_date = 0; ! 261: if (!nodelim) ! 262: fputs (mmdlm1, out); ! 263: ! 264: fprintf (out, "Munged: from %s to %s; %s\n", ! 265: SystemName (), LocalName (), dtimenow ()); ! 266: ! 267: for (;;) { ! 268: switch (do_header (&seen_from, &seen_sender, &seen_date, in, out)) { ! 269: case NOTOK: ! 270: return MFHDR; ! 271: ! 272: case OK: ! 273: continue; ! 274: ! 275: case DONE: ! 276: break; ! 277: } ! 278: break; ! 279: } ! 280: /* extra newline separates headers and body */ ! 281: fprintf (out, "%sDate: %s\n%s: %s\n\n", ! 282: seen_date ? "UUCP-" : NULL, date, ! 283: seen_from ? (seen_sender ? "UUCP-Sender" : "Sender") : "From", ! 284: from); ! 285: ! 286: return OK; ! 287: } ! 288: ! 289: /* */ ! 290: ! 291: static int uucp_text (in, out, nodelim) ! 292: int nodelim; ! 293: FILE * in, *out; ! 294: { ! 295: if (feof (in)) /* probably no body */ ! 296: putc ('\n', out); ! 297: else ! 298: while (fgets (buffer, sizeof buffer, in) != NULL) { ! 299: if (!nodelim && isdlm2 (buffer)) ! 300: buffer[0]++; ! 301: fputs (buffer, out); ! 302: } ! 303: ! 304: if (!nodelim) ! 305: fputs (mmdlm2, out); ! 306: fclose (in); ! 307: ! 308: return OK; ! 309: } ! 310: ! 311: /* */ ! 312: ! 313: static int do_header (seen_from, seen_sender, seen_date, in, out) ! 314: int *seen_from, ! 315: *seen_sender, ! 316: *seen_date; ! 317: FILE * in, *out; ! 318: { ! 319: int i, ! 320: margin, ! 321: some, ! 322: spat, ! 323: pos; ! 324: char *bp, ! 325: *cp, ! 326: *pp, ! 327: line[BUFSIZ]; ! 328: struct adrx *adrxp; ! 329: struct header *hl; ! 330: ! 331: if ((i = mfgets (in, &bp)) != OK) ! 332: return i; ! 333: ! 334: if ((cp = index (bp, ':')) == NULL) { ! 335: fprintf (out, "Illegal-Field: %s\n", bp); ! 336: return OK; ! 337: } ! 338: ! 339: *cp = NULL; ! 340: for (hl = &headers[0]; hl -> h_name; hl++) ! 341: if (lequal (hl -> h_name, bp)) ! 342: break; ! 343: ! 344: /* */ ! 345: ! 346: switch (hl -> h_type) { ! 347: case HDATE: ! 348: if (lequal (hl -> h_name, "Date")) ! 349: (*seen_date)++; ! 350: for (pp = cp + 1; isspace (*pp); pp++) ! 351: continue; ! 352: date_convert (pp, line); ! 353: if (line[0] == NULL) ! 354: fprintf (out, "Illegal-Object: %s: %s -- %s\n", ! 355: hl -> h_name, pp, "illegal date construct"); ! 356: else ! 357: fprintf (out, "%s: %s\n", hl -> h_name, line); ! 358: break; ! 359: ! 360: case HOTHR: ! 361: *cp = ':'; ! 362: fprintf (out, "%s\n", bp); ! 363: break; ! 364: ! 365: case HFROM: ! 366: case HSNDR: ! 367: if (hl -> h_type == HFROM) ! 368: (*seen_from)++; ! 369: else ! 370: (*seen_sender)++; ! 371: case HADDR: ! 372: spat = 0; ! 373: some = FALSE; ! 374: pp = ++cp; ! 375: margin = pos = strlen (hl -> h_name) + 2; ! 376: while (adrxp = seekadrx (pp)) { ! 377: addr_convert (adrxp, line, FALSE); ! 378: if (line[0] != NULL) { ! 379: if (!spat++) ! 380: fprintf (out, "%s: ", hl -> h_name); ! 381: if (some++) ! 382: fputs (", ", out), pos += 2; ! 383: if (pos + strlen (line) >= OWIDTH) { ! 384: fprintf (out, "\n%*s", margin, " "); ! 385: pos = margin; ! 386: } ! 387: fputs (line, out); ! 388: pos += strlen (line); ! 389: } ! 390: else { ! 391: if (spat) ! 392: putc ('\n', out); ! 393: fprintf (out, "Illegal-Object: %s: %s -- %s\n", ! 394: hl -> h_name, adrxp -> text, adrxp -> err); ! 395: spat = 0; ! 396: some = FALSE; ! 397: pos = margin; ! 398: } ! 399: } ! 400: if (spat) ! 401: putc ('\n', out); ! 402: break; ! 403: ! 404: default: ! 405: return NOTOK; ! 406: } ! 407: ! 408: return OK; ! 409: } ! 410: ! 411: /* */ ! 412: ! 413: addr_convert (adrxp, to, notice) ! 414: struct adrx *adrxp; ! 415: char *to; ! 416: int notice; ! 417: { ! 418: int addrlen, ! 419: uucplen; ! 420: char *cp, ! 421: *wp, ! 422: addr[BUFSIZ], ! 423: tmp[LINESIZ], ! 424: uucp[LINESIZ]; ! 425: static char path[LINESIZ] = ""; ! 426: ! 427: if (adrxp -> err || !adrxp -> mbox) { ! 428: *to = NULL; ! 429: return; ! 430: } ! 431: if (notice) ! 432: if ((cp = rindex (adrxp -> mbox, '!')) != NULL) ! 433: sprintf (path, "%.*s!", cp - adrxp -> mbox, adrxp -> mbox); ! 434: else ! 435: path[0] = NULL; ! 436: ! 437: sprintf (addr, "%s%s", path, adrxp -> mbox); ! 438: sprintf (uucp, "%s!", SystemName ()); ! 439: uucplen = strlen (uucp); ! 440: if ((addrlen = strlen (addr) - uucplen - 1) >= 0) ! 441: for (cp = addr + addrlen; cp >= addr; cp--) ! 442: if (strncmp (cp, uucp, uucplen) == NULL) { ! 443: if (cp != addr && *(cp - 1) != '!') ! 444: continue; ! 445: strcpy (addr, cp + uucplen); ! 446: break; ! 447: } ! 448: ! 449: /* */ ! 450: ! 451: if (adrxp -> host == NULL) { ! 452: cp = shrink (addr); ! 453: #ifdef MMDFMTS ! 454: sprintf (uucp, "%s%%%s@%s", cp, UucpChan (), LocalName ()); ! 455: #else MMDFMTS ! 456: if (wp = index (adrxp -> mbox, '!')) ! 457: sprintf (uucp, "%s@%.*s.%s", ! 458: wp + 1, wp - adrxp -> mbox, adrxp -> mbox, UucpChan ()); ! 459: else ! 460: sprintf (uucp, "%s@%s.%s", ! 461: adrxp -> mbox, SystemName (), UucpChan ()); ! 462: #endif MMDFMTS ! 463: if (strcmp (adrxp -> mbox, cp)) ! 464: sprintf (tmp, "\"%s\" <%s>", adrxp -> mbox, uucp); ! 465: else ! 466: strcpy (tmp, uucp); ! 467: } ! 468: else ! 469: if ((wp = rindex (adrxp -> mbox, '!')) == NULL) ! 470: sprintf (tmp, "%s@%s", adrxp -> mbox, adrxp -> host); ! 471: else { ! 472: sprintf (uucp, "%%%s", UucpChan ()); ! 473: uucplen = strlen (uucp); ! 474: cp = (lequal (LocalName (), adrxp -> host) ! 475: && (addrlen = strlen (addr) - uucplen) > 0) ! 476: ? addr + addrlen : NULL; ! 477: if (lequal (uucp, cp)) ! 478: sprintf (tmp, "%s@%s", shrink (addr), adrxp -> host); ! 479: else { ! 480: if (lequal (adrxp -> mbox, ++wp)) ! 481: sprintf (tmp, "%s@%s", wp, adrxp -> host); ! 482: else ! 483: sprintf (tmp, "\"%s\" <%s@%s>", adrxp -> mbox, ! 484: wp, adrxp -> host); ! 485: } ! 486: } ! 487: ! 488: strcpy (to, tmp); ! 489: } ! 490: ! 491: /* */ ! 492: ! 493: static char *shrink (addr) ! 494: char *addr; ! 495: { ! 496: int i, ! 497: j; ! 498: char *cp, ! 499: *pp, ! 500: *wp, ! 501: *xp; ! 502: static char r1[BUFSIZ], ! 503: r2[BUFSIZ]; ! 504: ! 505: sprintf (r2, "%s!", SystemName ()); ! 506: i = strlen (r2); ! 507: if ((j = strlen (addr) - i - 1) >= 0) ! 508: for (cp = &addr[j]; cp >= addr; cp--) ! 509: if (strncmp (cp, r2, i) == NULL) { ! 510: if (cp != addr && *(cp - 1) != '!') ! 511: continue; ! 512: strcpy (addr, cp + i); ! 513: break; ! 514: } ! 515: ! 516: if ((cp = rindex (addr, '!')) == NULL) { ! 517: sprintf (r1, "%s%s", r2, addr); ! 518: return r1; ! 519: } ! 520: *cp++ = NULL; ! 521: ! 522: if ((pp = rindex (addr, '!')) == NULL) { ! 523: *--cp = '!'; ! 524: strcpy (r1, addr); ! 525: return r1; ! 526: } ! 527: strcpy (r1, cp); ! 528: ! 529: while ((pp = rindex (addr, '!')) != NULL) { ! 530: for (pp++, xp = addr; (wp = index (xp, '!')) != NULL;) { ! 531: *wp = NULL; ! 532: if (strcmp (pp, xp)) { ! 533: *wp++ = '!'; ! 534: xp = wp; ! 535: } ! 536: else { ! 537: pp = xp; ! 538: break; ! 539: } ! 540: } ! 541: sprintf (r2, "%s!%s", pp, r1); ! 542: strcpy (r1, r2); ! 543: if (--pp > addr) ! 544: *pp = NULL; ! 545: } ! 546: ! 547: /* */ ! 548: ! 549: if ((wp = index (r1, '!')) != NULL) { ! 550: *wp = NULL; ! 551: strcpy (r2, r1); ! 552: *wp = '!'; ! 553: if (strcmp (addr, r2)) { ! 554: sprintf (r2, "%s!%s", addr, r1); ! 555: strcpy (r1, r2); ! 556: } ! 557: } ! 558: ! 559: return r1; ! 560: } ! 561: ! 562: /* */ ! 563: ! 564: date_convert (from, to) ! 565: char from[], ! 566: *to; ! 567: { ! 568: static int zone = -1, ! 569: flags = TW_NULL; ! 570: char date[LINESIZ]; ! 571: struct tws *tw; ! 572: ! 573: if (dparsetime (from)) /* might be OK as is */ ! 574: strcpy (date, from); ! 575: else ! 576: if (isdigit (from[20])) { ! 577: if (zone == -1) { ! 578: if (tw = dtwstime ()) { ! 579: zone = tw -> tw_zone; ! 580: flags = tw -> tw_flags; ! 581: } ! 582: else ! 583: zone = 0, flags = TW_NULL; ! 584: } ! 585: sprintf (date, "%.3s, %.2s %.3s %.2s %.2s:%.2s:%.2s %s", ! 586: from + 0, from + 8, from + 4, from + 22, from + 11, ! 587: from + 14, from + 17, dtimezone (zone, flags)); ! 588: } ! 589: else ! 590: sprintf (date, "%.3s, %.2s %.3s %.2s %.2s:%.2s:%.2s %s", ! 591: from + 0, from + 8, from + 4, from + 26, from + 11, ! 592: from + 14, from + 17, from + 20); ! 593: ! 594: strcpy (to, date); ! 595: } ! 596: ! 597: /* */ ! 598: ! 599: static int uucp_die (error, in1, in2, out, nodelim) ! 600: int error, ! 601: nodelim; ! 602: FILE * in1, *in2, *out; ! 603: { ! 604: long clock; ! 605: char date[LINESIZ]; ! 606: ! 607: if (nodelim) { ! 608: fclose (in1); ! 609: return error; ! 610: } ! 611: ! 612: switch (error) { ! 613: case MFHDR: ! 614: putc ('\n', out); ! 615: case MFTXT: ! 616: fprintf (out, "\n%s", mmdlm2); ! 617: break; ! 618: } ! 619: ! 620: time (&clock); ! 621: sprintf (date, "%.*s", sizeof date - 1, dtime (&clock)); ! 622: fprintf (out, "%sFrom: %s <%s@%s>\nDate: %s\nSubject: %s %s\n\n", ! 623: mmdlm1, "UUCP to MMDF filter", getusr (), LocalName (), date, ! 624: "Bad UUCP mailbox - error in", ! 625: error == MFHDR ? "Header" : error == MFTXT ? "Body" : "Mailbox"); ! 626: ! 627: fprintf (out, "%s: %s\n%s\n--------\n", ! 628: "Error detected at line", buffer, "Message being processed"); ! 629: fseek (in1, 0L, 0); ! 630: while (fgets (buffer, sizeof buffer, in1) != NULL) { ! 631: if (isdlm2 (buffer)) ! 632: buffer[0]++; ! 633: fputs (buffer, out); ! 634: } ! 635: fclose (in1); ! 636: ! 637: if (!feof (in2)) { ! 638: fprintf (out, "--------\n%s\n--------\n%s", ! 639: "Remainder of unfiltered mailbox follows", tmpbuf); ! 640: while (fgets (buffer, sizeof buffer, in2) != NULL) { ! 641: if (isdlm2 (buffer)) ! 642: buffer[0]++; ! 643: fputs (buffer, out); ! 644: } ! 645: } ! 646: ! 647: fprintf (out, "--------\n%s", mmdlm2); ! 648: fflush (out); ! 649: ! 650: return error; ! 651: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.