|
|
1.1 ! root 1: /* mmuu.c - routines to filter MMDF to UUCP 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: ! 35: static char buffer[BUFSIZ], ! 36: tmpbuf[BUFSIZ]; ! 37: ! 38: long time (); ! 39: char *ctime (); ! 40: ! 41: /* */ ! 42: ! 43: /* ! 44: * mmdf2uucp() - given a file descriptor to a mmdf 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 mmdf2uucp (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 = mmuu (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: static int mmuu (in, out, nodelim) ! 87: FILE *in, ! 88: *out; ! 89: int nodelim; ! 90: { ! 91: int i, ! 92: tmp_fd; ! 93: FILE *tmp; ! 94: ! 95: for (tmp_fd = NOTOK;;) { ! 96: if ((i = mmdf_file (&tmp_fd, in, &tmp, nodelim)) == DONE) ! 97: break; ! 98: else ! 99: if (i != OK) ! 100: return i; ! 101: if ((i = mmdf_headers (tmp, out, nodelim)) != OK) ! 102: return mmdf_die (i, tmp, in, out, nodelim); ! 103: if ((i = mmdf_text (tmp, out, nodelim)) != OK) ! 104: return mmdf_die (i, tmp, in, out, nodelim); ! 105: } ! 106: ! 107: fflush (out); ! 108: ! 109: return (ferror (in) || ferror (out) ? MFERR : MFOK); ! 110: } ! 111: ! 112: /* */ ! 113: ! 114: static int mmdf_file (tmp_fd, in, tmp, nodelim) ! 115: int *tmp_fd, ! 116: nodelim; ! 117: FILE * in, **tmp; ! 118: { ! 119: int done, ! 120: fd; ! 121: char tmpfil[LINESIZ]; ! 122: FILE * out; ! 123: ! 124: if (nodelim) ! 125: if (*tmp_fd != NOTOK) ! 126: return DONE; ! 127: else ! 128: if ((*tmp_fd = dup (fileno (in))) == NOTOK) ! 129: return MFERR; ! 130: else ! 131: if ((*tmp = fdopen (*tmp_fd, "r")) == NULL) { ! 132: close (*tmp_fd); ! 133: return MFERR; ! 134: } ! 135: else ! 136: return OK; ! 137: ! 138: if (fgets (tmpbuf, sizeof tmpbuf, in) == NULL) ! 139: return DONE; ! 140: if (!isdlm1 (tmpbuf)) ! 141: return MFDLM; ! 142: ! 143: strcpy (tmpfil, "/tmp/mmuuXXXXXX"); ! 144: unlink (mktemp (tmpfil)); ! 145: if ((fd = creat (tmpfil, TMPMODE)) == NOTOK) ! 146: return MFERR; ! 147: close (fd); ! 148: ! 149: if ((fd = open (tmpfil, 2)) == NOTOK) ! 150: return MFERR; ! 151: if ((out = fdopen (fd, "w")) == NULL) { ! 152: close (fd); ! 153: return MFERR; ! 154: } ! 155: unlink (tmpfil); ! 156: ! 157: if ((*tmp_fd = dup (fd)) == NOTOK) { ! 158: close (fd); ! 159: return MFERR; ! 160: } ! 161: if ((*tmp = fdopen (*tmp_fd, "r")) == NULL) { ! 162: close (fd); ! 163: close (*tmp_fd); ! 164: return MFERR; ! 165: } ! 166: ! 167: /* */ ! 168: ! 169: for (done = FALSE;;) { ! 170: if (fgets (tmpbuf, sizeof tmpbuf, in) == NULL) ! 171: return MFDLM; ! 172: if (done && isdlm2 (tmpbuf)) ! 173: break; ! 174: done = tmpbuf[strlen (tmpbuf) - 1] == '\n'; ! 175: fputs (tmpbuf, out); ! 176: } ! 177: ! 178: fclose (out); ! 179: fseek (*tmp, 0L, 0); ! 180: return OK; ! 181: } ! 182: ! 183: /* */ ! 184: ! 185: static int mmdf_headers (in, out, nodelim) ! 186: FILE * in, *out; ! 187: int nodelim; ! 188: { ! 189: int fd, ! 190: i, ! 191: tmp_fd; ! 192: char *cp, ! 193: line[BUFSIZ], ! 194: from[LINESIZ], ! 195: date[LINESIZ], ! 196: tmpfil[LINESIZ]; ! 197: FILE * tmp; ! 198: ! 199: *from = *date = NULL; ! 200: ! 201: strcpy (tmpfil, "/tmp/mmuuXXXXXX"); ! 202: unlink (mktemp (tmpfil)); ! 203: if ((fd = creat (tmpfil, TMPMODE)) == NOTOK) ! 204: return MFERR; ! 205: close (fd); ! 206: if ((tmp_fd = open (tmpfil, 2)) == NOTOK) ! 207: return MFERR; ! 208: unlink (tmpfil); ! 209: ! 210: if ((fd = dup (tmp_fd)) == NOTOK) { ! 211: close (tmp_fd); ! 212: return MFERR; ! 213: } ! 214: if ((tmp = fdopen (fd, "w")) == NULL) { ! 215: close (tmp_fd); ! 216: close (fd); ! 217: return MFERR; ! 218: } ! 219: ! 220: for (;;) { ! 221: switch (do_header (from, date, in, tmp)) { ! 222: case NOTOK: ! 223: close (tmp_fd); ! 224: fclose (tmp); ! 225: return MFHDR; ! 226: ! 227: case OK: ! 228: continue; ! 229: ! 230: case DONE: ! 231: fclose (tmp); ! 232: break; ! 233: } ! 234: break; ! 235: } ! 236: ! 237: /* */ ! 238: ! 239: if (*date == NULL || *from == NULL) { ! 240: if (*date) ! 241: strcpy (buffer, "No (valid) From: field found in message\n"); ! 242: else ! 243: if (*from) ! 244: strcpy (buffer, "No (valid) Date: field found in message\n"); ! 245: else ! 246: strcpy (buffer, ! 247: "No (valid) From: or Date: fields found in message\n"); ! 248: if (nodelim) { ! 249: if (*date == NULL) { ! 250: long clock; ! 251: ! 252: time (&clock); ! 253: sprintf (date, "%.24s", ctime (&clock)); ! 254: } ! 255: if (*from == NULL) ! 256: sprintf (from, "%s!%s", SystemName (), getusr ()); ! 257: } ! 258: else ! 259: return MFHDR; ! 260: } ! 261: else ! 262: buffer[0] = NULL; ! 263: ! 264: if (nodelim && (cp = index (from, '!')) != NULL) { ! 265: *cp++ = NULL; ! 266: fprintf (out, "From %s %s remote from %s\n", cp, date, from); ! 267: } ! 268: else ! 269: fprintf (out, "From %s %s\n", from, date); ! 270: ! 271: fprintf (out, "Munged: from %s to %s; %s\n", ! 272: LocalName (), SystemName (), dtimenow ()); ! 273: if (buffer[0]) ! 274: fprintf (out, "Illegal-Field: %s", buffer); ! 275: ! 276: if ((tmp = fdopen (tmp_fd, "r")) == NULL) { ! 277: close (tmp_fd); ! 278: return MFERR; ! 279: } ! 280: fseek (tmp, 0L, 0); ! 281: ! 282: while ((i = fread (line, sizeof *line, sizeof line, tmp)) > 0) ! 283: fwrite (line, sizeof *line, i, out); ! 284: putc ('\n', out); /* separate headers from body */ ! 285: fclose (tmp); ! 286: ! 287: return OK; ! 288: } ! 289: ! 290: /* */ ! 291: ! 292: static int mmdf_text (in, out, nodelim) ! 293: int nodelim; ! 294: FILE * in, *out; ! 295: { ! 296: int i; ! 297: ! 298: if (feof (in)) /* probably no body */ ! 299: putc ('\n', out); ! 300: else ! 301: while ((i = fread (buffer, sizeof *buffer, sizeof buffer, in)) > 0) ! 302: fwrite (buffer, sizeof *buffer, i, out); ! 303: ! 304: if (!nodelim) ! 305: putc ('\n', out); ! 306: fclose (in); ! 307: ! 308: return OK; ! 309: } ! 310: ! 311: /* */ ! 312: ! 313: static int do_header (from, date, in, out) ! 314: char *from, ! 315: *date; ! 316: FILE * in, *out; ! 317: { ! 318: int i, ! 319: margin, ! 320: some, ! 321: spat, ! 322: pos; ! 323: char *bp, ! 324: *cp, ! 325: *pp, ! 326: line[BUFSIZ]; ! 327: struct adrx *adrxp; ! 328: struct header *hl; ! 329: ! 330: if ((i = mfgets (in, &bp)) != OK) ! 331: return i; ! 332: ! 333: if ((cp = index (bp, ':')) == NULL) { ! 334: fprintf (out, "Illegal-Field: %s\n", bp); ! 335: return OK; ! 336: } ! 337: ! 338: *cp = NULL; ! 339: for (hl = &headers[0]; hl -> h_name; hl++) ! 340: if (lequal (hl -> h_name, bp)) ! 341: break; ! 342: ! 343: /* */ ! 344: ! 345: switch (hl -> h_type) { ! 346: case HOTHR: ! 347: *cp = ':'; ! 348: fprintf (out, "%s\n", bp); ! 349: break; ! 350: ! 351: case HDATE: ! 352: pp = ++cp; ! 353: if (*date != NULL || !lequal (hl -> h_name, "Date")) ! 354: return OK; ! 355: date_convert (pp, date); ! 356: if (*date == NULL) ! 357: fprintf (out, ! 358: "Illegal-Object: %s: %s -- illegal date construct\n", ! 359: hl -> h_name, pp); ! 360: break; ! 361: ! 362: case HFROM: ! 363: pp = ++cp; ! 364: if (*from != NULL) ! 365: return OK; ! 366: if ((adrxp = getadrx (pp)) == NULL) { ! 367: fprintf (out, "Illegal-Object: %s: %s -- %s\n", ! 368: hl -> h_name, pp, "no address"); ! 369: return OK; /* catch errors later (possibly) */ ! 370: } ! 371: addr_convert (adrxp, from, TRUE); ! 372: if (*from == NULL) ! 373: fprintf (out, "Illegal-Object: %s: %s -- %s\n", ! 374: hl -> h_name, adrxp -> text, adrxp -> err); ! 375: while (getadrx (NULL)) ! 376: continue; ! 377: break; ! 378: ! 379: case HADDR: ! 380: case HSNDR: ! 381: spat = 0; ! 382: some = FALSE; ! 383: pp = ++cp; ! 384: margin = pos = strlen (hl -> h_name) + 2; ! 385: while (adrxp = getadrx (pp)) { ! 386: addr_convert (adrxp, line, FALSE); ! 387: if (line[0] != NULL) { ! 388: if (!spat++) ! 389: fprintf (out, "%s: ", hl -> h_name); ! 390: if (some++) ! 391: fputs (", ", out), pos += 2; ! 392: if (pos + strlen (line) >= OWIDTH) { ! 393: fprintf (out, "\n%*s", margin, " "); ! 394: pos = margin; ! 395: } ! 396: fputs (line, out); ! 397: pos += strlen (line); ! 398: } ! 399: else { ! 400: if (spat) ! 401: putc ('\n', out); ! 402: fprintf (out, "Illegal-Object: %s: %s -- %s\n", ! 403: hl -> h_name, adrxp -> text, adrxp -> err); ! 404: spat = 0; ! 405: some = FALSE; ! 406: pos = margin; ! 407: } ! 408: } ! 409: if (spat) ! 410: putc ('\n', out); ! 411: break; ! 412: ! 413: default: ! 414: return NOTOK; ! 415: } ! 416: ! 417: return OK; ! 418: } ! 419: ! 420: /* */ ! 421: ! 422: static addr_convert (adrxp, to, notice) ! 423: struct adrx *adrxp; ! 424: char *to; ! 425: int notice; ! 426: { ! 427: int mboxlen, ! 428: uucplen; ! 429: char *cp, ! 430: tmp[LINESIZ], ! 431: uucp[LINESIZ]; ! 432: static char path[LINESIZ] = ""; ! 433: ! 434: if (path[0] == NULL) ! 435: strcpy (path, LocalName ()); ! 436: ! 437: if (adrxp -> err || !adrxp -> mbox) { ! 438: *to = NULL; ! 439: return; ! 440: } ! 441: if (notice) ! 442: strcpy (path, adrxp -> host ? adrxp -> host : LocalName ()); ! 443: ! 444: if (adrxp -> host == NULL) ! 445: if (index (adrxp -> mbox, '!') != NULL) ! 446: strcpy (tmp, adrxp -> mbox); ! 447: else ! 448: if (lequal (path, LocalName ())) ! 449: sprintf (tmp, "%s!%s", SystemName (), adrxp -> mbox); ! 450: else ! 451: sprintf (tmp, "%s!%s@%s", SystemName (), adrxp -> mbox, path); ! 452: else ! 453: if (index (adrxp -> mbox, '!') == NULL) ! 454: sprintf (tmp, "%s!%s@%s", ! 455: SystemName (), adrxp -> mbox, adrxp -> host); ! 456: else { ! 457: sprintf (uucp, "%%%s", UucpChan ()); ! 458: uucplen = strlen (uucp); ! 459: cp = (lequal (LocalName (), adrxp -> host) ! 460: && (mboxlen = strlen (adrxp -> mbox) - uucplen) > 0) ! 461: ? (adrxp -> mbox) + mboxlen : NULL; ! 462: if (lequal (uucp, cp)) ! 463: sprintf (tmp, "%.*s", mboxlen, adrxp -> mbox); ! 464: else ! 465: if ((cp = index (adrxp -> host, '.')) ! 466: && lequal (UucpChan (), cp + 1)) ! 467: sprintf (tmp, "%.*s!%s", ! 468: cp - adrxp -> host, adrxp -> host, adrxp -> mbox); ! 469: else ! 470: if (lequal (adrxp -> host, UucpChan ())) ! 471: strcpy (tmp, adrxp -> mbox); ! 472: else { ! 473: sprintf (uucp, "%s!", SystemName ()); ! 474: uucplen = strlen (uucp); ! 475: if (strncmp (uucp, adrxp -> mbox, uucplen)) ! 476: sprintf (tmp, "%s!%s@%s", ! 477: SystemName (), adrxp -> mbox, adrxp -> host); ! 478: else ! 479: sprintf (tmp, "%s@%s", adrxp -> mbox, adrxp -> host); ! 480: } ! 481: } ! 482: ! 483: strcpy (to, tmp); ! 484: } ! 485: ! 486: /* */ ! 487: ! 488: static date_convert (from, to) ! 489: char *from, ! 490: *to; ! 491: { ! 492: char *cp; ! 493: ! 494: if ((cp = dctime (dparsetime (from))) != NULL) ! 495: sprintf (to, "%.24s", cp); ! 496: else ! 497: *to = NULL; ! 498: } ! 499: ! 500: /* */ ! 501: ! 502: static int mmdf_die (error, in1, in2, out, nodelim) ! 503: int error, ! 504: nodelim; ! 505: FILE * in1, *in2, *out; ! 506: { ! 507: int i; ! 508: long clock; ! 509: char date[LINESIZ]; ! 510: ! 511: if (nodelim) { ! 512: fclose (in1); ! 513: return error; ! 514: } ! 515: ! 516: switch (error) { ! 517: case MFTXT: ! 518: putc ('\n', out); ! 519: break; ! 520: } ! 521: ! 522: time (&clock); ! 523: sprintf (date, "%.24s", ctime (&clock)); ! 524: fprintf (out, "From %s %s\nSubject: %s %s\n\n", ! 525: getusr (), date, "Bad MMDF mailbox - error in", ! 526: error == MFHDR ? "Header" : error == MFTXT ? "Body" : "Mailbox"); ! 527: ! 528: fprintf (out, "%s: %s\n%s\n--------\n", ! 529: "Error detected at line", buffer, "Message being processed"); ! 530: fseek (in1, 0L, 0); ! 531: while ((i = fread (buffer, sizeof *buffer, sizeof buffer, in1)) > 0) ! 532: fwrite (buffer, sizeof *buffer, i, out); ! 533: fclose (in1); ! 534: ! 535: if (!feof (in2)) { ! 536: fprintf (out, "--------\n%s\n--------\n%s", ! 537: "Remainder of unfiltered mailbox follows", tmpbuf); ! 538: while ((i = fread (buffer, sizeof *buffer, sizeof buffer, in2)) > 0) ! 539: fwrite (buffer, sizeof *buffer, i, out); ! 540: } ! 541: ! 542: fprintf (out, "--------\n\n"); ! 543: fflush (out); ! 544: ! 545: return error; ! 546: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.