|
|
1.1 ! root 1: /* rmail.c - replacement for /bin/rmail */ ! 2: ! 3: /* This program has a long, long history. It started as UCB's rmail, and ! 4: was then modified by OBrien@Rand-Unix to run with MMDF. Then DpK@Brl ! 5: re-wrote it, and SmB@Unc hacked it up a bit. After that ! 6: MRose.UCI@Rand-Relay upgraded it to use the nifty MF (mail filtering) ! 7: system. Finally, the latter stripped it down to work with MH. ! 8: ! 9: This program should be used ONLY if you have both "mts mh" and "uucp on" ! 10: set in your MH configuration. ! 11: */ ! 12: ! 13: ! 14: #include "../h/mh.h" ! 15: #include "../h/addrsbr.h" ! 16: #include "../zotnet/mf.h" ! 17: #include "../zotnet/tws.h" ! 18: #include <stdio.h> ! 19: #include "../zotnet/mts.h" ! 20: #include <signal.h> ! 21: ! 22: ! 23: #define ADDROK 0 /* okay to use post to deliver message */ ! 24: #define UUCP 1 /* okay to use uux to deliver message */ ! 25: #define RETURN 2 /* message loses */ ! 26: ! 27: /* */ ! 28: int pbroke; /* broken-pipe flag */ ! 29: int rtnflag; /* note was sent back */ ! 30: ! 31: char date[BUFSIZ]; /* date of origination from uucp header */ ! 32: char from[BUFSIZ]; /* accumulated path of sender */ ! 33: char origsys[BUFSIZ]; /* originating system */ ! 34: char origpath[BUFSIZ]; /* path from us to originating system */ ! 35: char usrfrm[BUFSIZ]; /* the 822 version of from[] */ ! 36: char Mailsys[BUFSIZ]; /* address of the mail agent */ ! 37: char overseer[BUFSIZ]; /* address of the watchdog */ ! 38: ! 39: char mmdf[BUFSIZ]; /* filtered mail file */ ! 40: ! 41: char *rtnmessage[] = { ! 42: " Your message has been intercepted trying to access\n", ! 43: "a restricted access host (e.g. an ARPANET host). A copy\n", ! 44: "of your message has been sent to the system administrators.\n", ! 45: "The text of your message follows.\n\n", ! 46: NULL ! 47: }; ! 48: ! 49: char rtnbegin[] = ! 50: " ---------------- Returned Mail Follows --------------\n"; ! 51: char rtnend[] = ! 52: " --------------- End of Returned Mail ---------------\n"; ! 53: ! 54: char *oopsmessage[] = { ! 55: "\n\n\tThe system administrators (%s) have been informed of\n", ! 56: "the problem, but have not been given a copy of your message.\n\n", ! 57: NULL ! 58: }; ! 59: ! 60: FILE * fromf; /* UUCP "From lines */ ! 61: FILE * msgf; /* message text */ ! 62: FILE * pipef; /* output for "post" or "uux" */ ! 63: ! 64: ! 65: int pipeser (); ! 66: ! 67: ! 68: long lseek (); ! 69: ! 70: /* */ ! 71: ! 72: main (argc, argv) ! 73: int argc; ! 74: char **argv; ! 75: { ! 76: int cpyback; ! 77: char *cp, ! 78: *fromptr, ! 79: fromwhom[BUFSIZ], ! 80: linebuf[BUFSIZ], ! 81: sys[BUFSIZ]; ! 82: ! 83: invo_name = r1bindex (*argv, '/'); ! 84: m_foil (NULLCP); ! 85: mts_init (invo_name); ! 86: ! 87: if (argc < 2) ! 88: adios (NULLCP, "usage: %s user [user ...]", invo_name); ! 89: (void) umask (0); ! 90: (void) setgid (1); ! 91: (void) setuid (1); ! 92: ! 93: (void) sprintf (Mailsys, "%s@%s", Mailer, LocalName ()); ! 94: if (Overseer == NULL) ! 95: Overseer = Mailsys; ! 96: if (index (Overseer, '@') == NULL) { ! 97: (void) sprintf (overseer, "%s@%s", Overseer, LocalName ()); ! 98: Overseer = overseer; ! 99: } ! 100: ! 101: (void) mktemp (Errtmp); ! 102: if (freopen (Errtmp, "w", stderr) == NULL) ! 103: adios (Errtmp, "unable to create"); ! 104: (void) dup2 (fileno (stderr), fileno (stdout)); ! 105: ! 106: (void) mktemp (Msgtmp); ! 107: if ((msgf = fdopen (creat (Msgtmp, Tmpmode), "w")) == NULL) ! 108: adios (Msgtmp, "unable to create"); ! 109: ! 110: (void) mktemp (Fromtmp); ! 111: if ((fromf = fdopen (creat (Fromtmp, Tmpmode), "w")) == NULL) ! 112: adios (Fromtmp, "unable to create"); ! 113: ! 114: /* */ ! 115: ! 116: for (;;) { ! 117: if (fgets (linebuf, sizeof linebuf, stdin) == NULL) ! 118: break; ! 119: if (strncmp (linebuf, "From ", 5) ! 120: && strncmp (linebuf, ">From ", 6)) ! 121: break; ! 122: ! 123: if (linebuf[0] != '>') ! 124: fputs (">", fromf); ! 125: fputs (linebuf, fromf); ! 126: cp = index (linebuf, ' '); ! 127: fromptr = ++cp; ! 128: cp = index (cp, ' '); ! 129: *cp++ = NULL; ! 130: (void) strcpy (fromwhom, fromptr); ! 131: (void) strncpy (date, cp, 24); ! 132: ! 133: for (;;) { ! 134: if ((cp = index (cp + 1, 'r')) == NULL) { ! 135: if ((cp = rindex (fromwhom, '!')) != NULL) { ! 136: char *p; ! 137: *cp = NULL; ! 138: if ((p = rindex (fromwhom, '!')) != NULL) ! 139: (void) strcpy (origsys, p + 1); ! 140: else ! 141: (void) strcpy (origsys, fromwhom); ! 142: (void) strcat (from, fromwhom); ! 143: (void) strcat (from, "!"); ! 144: (void) strcpy (fromwhom, cp + 1); ! 145: goto out; ! 146: } ! 147: (void) strcpy (sys, SystemName ()); ! 148: (void) strcat (from, sys); ! 149: (void) strcpy (origsys, sys); ! 150: (void) strcat (from, "!"); ! 151: goto out; ! 152: } ! 153: if (strncmp (cp, "remote from ", 12) == 0) ! 154: break; ! 155: } ! 156: ! 157: (void) sscanf (cp, "remote from %s", sys); ! 158: (void) strcat (from, sys); ! 159: (void) strcpy (origsys, sys); ! 160: (void) strcat (from, "!"); ! 161: out: ; ! 162: } ! 163: if (fromwhom[0] == NULL) ! 164: adios (NULLCP, "no from line"); ! 165: ! 166: /* */ ! 167: ! 168: (void) strcpy (origpath, from); ! 169: (void) strcat (from, fromwhom); ! 170: get_mmdf_addr (from, usrfrm); ! 171: if ((cp = rindex (usrfrm, '<')) != NULL) { ! 172: (void) strcpy (usrfrm, ++cp); /* sigh */ ! 173: if ((cp = rindex (usrfrm, '>')) != NULL) ! 174: *cp = NULL; ! 175: } ! 176: if (usrfrm[0] == NULL) ! 177: (void) sprintf (usrfrm, "%s!%s%%%s@%s%c", ! 178: SystemName (), from, UucpChan (), LocalName (), NULL); ! 179: ! 180: fputs (linebuf, msgf); ! 181: if (txtcpy (stdin, msgf) == NOTOK) ! 182: fputs ("\n *** Problem during receipt from UUCP ***\n", msgf); ! 183: ! 184: (void) freopen (Msgtmp, "r", msgf); ! 185: (void) freopen (Fromtmp, "r", fromf); ! 186: (void) unlink (Fromtmp); ! 187: mmdf[0] = NULL; ! 188: ! 189: cpyback = 0; ! 190: for (argv++; --argc > 0;) { ! 191: rewind (fromf); ! 192: rewind (msgf); ! 193: rtnflag = 0; ! 194: if (deliver (*argv++) == NOTOK && !rtnflag) ! 195: cpyback++; ! 196: } ! 197: ! 198: (void) fflush (stderr); ! 199: (void) fflush (stdout); ! 200: ! 201: if (cpyback) { ! 202: rcpy (); ! 203: zcpy (); ! 204: } ! 205: ! 206: (void) unlink (Msgtmp); ! 207: if (mmdf[0]) ! 208: (void) unlink (mmdf); ! 209: (void) unlink (Errtmp); ! 210: ! 211: exit (0); ! 212: } ! 213: ! 214: /* */ ! 215: ! 216: deliver (to) ! 217: char *to; ! 218: { ! 219: int i, ! 220: replyval; ! 221: char tmpfil[BUFSIZ]; ! 222: ! 223: switch (adrcheck (to)) { ! 224: case ADDROK: ! 225: if (mmdf[0] == NULL && filter () == NOTOK) ! 226: (void) strcpy (mmdf, Msgtmp); ! 227: replyval = xpost (to, mmdf); ! 228: break; ! 229: ! 230: case UUCP: ! 231: if ((replyval = xuucp (to)) == NOTOK) ! 232: break; ! 233: ! 234: if ((replyval = txtcpy (fromf, pipef)) != NOTOK) ! 235: replyval = txtcpy (msgf, pipef); ! 236: i = (pclose (pipef) >> 8) & 0xff; ! 237: if (replyval != NOTOK) ! 238: replyval = (i != 0 ? NOTOK : OK); ! 239: break; ! 240: ! 241: /* */ ! 242: ! 243: case RETURN: ! 244: rtnflag++; ! 245: switch (adrcheck (from)) { ! 246: case ADDROK: ! 247: case RETURN: ! 248: (void) strcpy (tmpfil, "/tmp/rmailXXXXXX"); ! 249: (void) unlink (mktemp (tmpfil)); ! 250: if ((pipef = fdopen (creat (tmpfil, Tmpmode), "w")) == NULL) ! 251: return NOTOK; ! 252: ! 253: fprintf (pipef, "Date: %s\nFrom: %s\n", ! 254: dtimenow (), Mailsys); ! 255: fprintf (pipef, "To: %s\ncc: %s\n", from, Overseer); ! 256: rtnmesg (to); ! 257: (void) fclose (pipef); ! 258: ! 259: replyval = xpost (from, tmpfil); ! 260: (void) unlink (tmpfil); ! 261: break; ! 262: ! 263: case UUCP: ! 264: if ((replyval = xuucp (from)) == NOTOK) ! 265: break; ! 266: ! 267: fprintf (pipef, "To: %s\ncc: %s\n", from, Overseer); ! 268: rtnmesg (to); ! 269: i = (pclose (pipef) >> 8) & 0xff; ! 270: if (replyval != NOTOK) ! 271: replyval = (i != 0 ? NOTOK : OK); ! 272: break; ! 273: } ! 274: if (Syscpy) { ! 275: (void) strcpy (tmpfil, "/tmp/rmailXXXXXX"); ! 276: (void) unlink (mktemp (tmpfil)); ! 277: if ((pipef = fdopen (creat (tmpfil, Tmpmode), "w")) == NULL) ! 278: return NOTOK; ! 279: ! 280: fprintf (pipef, "Date: %s\nFrom: %s\n", ! 281: dtimenow (), Mailsys); ! 282: fprintf (pipef, "To: %s\ncc: %s\n", usrfrm, Overseer); ! 283: rtnmesg (to); ! 284: (void) fclose (pipef); ! 285: ! 286: replyval = xpost (Overseer, tmpfil); ! 287: (void) unlink (tmpfil); ! 288: } ! 289: break; ! 290: } ! 291: ! 292: return replyval; ! 293: } ! 294: ! 295: /* */ ! 296: ! 297: adrcheck (adr) ! 298: char *adr; ! 299: { ! 300: int type; ! 301: char *cp, ! 302: host[BUFSIZ]; ! 303: struct mailname *mp; ! 304: ! 305: if ((cp = getname (adr)) == NULL) ! 306: return RETURN; ! 307: mp = getm (cp, NULLCP, 0, AD_HOST, NULLCP); ! 308: while (getname ("")) ! 309: continue; ! 310: if (mp == NULL) ! 311: return RETURN; ! 312: ! 313: type = mp -> m_type; ! 314: (void) strcpy (host, mp -> m_host); ! 315: mnfree (mp); ! 316: if (mp -> m_mbox == NULL) ! 317: return RETURN; ! 318: ! 319: switch (type) { ! 320: case LOCALHOST: ! 321: return ADDROK; ! 322: ! 323: case UUCPHOST: ! 324: return (strcmp (host, SystemName ()) ? UUCP : ADDROK); ! 325: ! 326: default: ! 327: if (lookup (origsys, Okhosts) == OK) ! 328: return ADDROK; ! 329: return (okhost (host) == NOTOK ? RETURN : ADDROK); ! 330: } ! 331: } ! 332: ! 333: /* */ ! 334: ! 335: okhost (host) ! 336: char *host; ! 337: { ! 338: return (lookup (origsys, Okhosts) == OK ! 339: || lookup (host, Okhosts) == OK ! 340: || lookup (host, Okdests) == OK ? OK : NOTOK); ! 341: } ! 342: ! 343: ! 344: lookup (what, where) ! 345: char *what, ! 346: *where; ! 347: { ! 348: char *cp, ! 349: entry[BUFSIZ]; ! 350: FILE * lookf; ! 351: ! 352: if ((lookf = fopen (where, "r")) == NULL) ! 353: return NOTOK; ! 354: while (fgets (entry, sizeof entry, lookf) != NULL) { ! 355: cp = entry; ! 356: while (*cp != '\n' && *cp != ' ' && *cp != '\t') ! 357: cp++; ! 358: *cp = NULL; ! 359: if (uleq (what, entry)) { ! 360: (void) fclose (lookf); ! 361: return OK; ! 362: } ! 363: } ! 364: (void) fclose (lookf); ! 365: ! 366: return NOTOK; ! 367: } ! 368: ! 369: ! 370: /* */ ! 371: ! 372: rtnmesg (badadr) ! 373: char *badadr; ! 374: { ! 375: int i; ! 376: ! 377: fprintf (pipef, "Subject: Illegal Address (%s)\n\n", badadr); ! 378: for (i = 0; rtnmessage[i]; i++) ! 379: fputs (rtnmessage[i], pipef); ! 380: fputs (rtnbegin, pipef); ! 381: ! 382: rewind (fromf); ! 383: (void) txtcpy (fromf, pipef); ! 384: rewind (msgf); ! 385: (void) txtcpy (msgf, pipef); ! 386: ! 387: fputs (rtnend, pipef); ! 388: } ! 389: ! 390: ! 391: txtcpy (frm, to) ! 392: FILE * frm, *to; ! 393: { ! 394: int nread; ! 395: char buffer[BUFSIZ]; ! 396: ! 397: while (!pbroke ! 398: && (nread = fread (buffer, sizeof (*buffer), BUFSIZ, frm)) > 0) ! 399: (void) fwrite (buffer, sizeof (*buffer), nread, to); ! 400: ! 401: return (ferror (frm) ? NOTOK : OK); ! 402: } ! 403: ! 404: /* */ ! 405: ! 406: xpost (addr, file) ! 407: char *addr, ! 408: *file; ! 409: { ! 410: int i, ! 411: child_id; ! 412: ! 413: for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++) ! 414: sleep (5); ! 415: switch (child_id) { ! 416: case NOTOK: ! 417: return NOTOK; ! 418: ! 419: case OK: ! 420: execlp (postproc, r1bindex (postproc, '/'), ! 421: "-deliver", addr, file, NULLCP); ! 422: fprintf (stderr, "unable to exec "); ! 423: perror (postproc); ! 424: _exit (1); ! 425: ! 426: default: ! 427: return (pidwait (child_id, OK) ? NOTOK : OK); ! 428: } ! 429: } ! 430: ! 431: /* */ ! 432: ! 433: xuucp (to) ! 434: char *to; ! 435: { ! 436: char *cp, ! 437: buffer[BUFSIZ], ! 438: cmdstr[BUFSIZ]; ! 439: ! 440: (void) strcpy (buffer, to); ! 441: if (cp = index (buffer, '!')) ! 442: *cp++ = NULL; ! 443: else { ! 444: fprintf (stderr, "internal error -- %s has no host\n", to); ! 445: return NOTOK; ! 446: } ! 447: (void) sprintf (cmdstr, "uux -p %s!rmail \\(%s\\)", buffer, cp); ! 448: ! 449: if ((pipef = popen (cmdstr, "w")) == NULL) ! 450: return NOTOK; ! 451: ! 452: (void) signal (SIGPIPE, pipeser); ! 453: pbroke = 0; ! 454: ! 455: return OK; ! 456: } ! 457: ! 458: /* */ ! 459: ! 460: #ifdef BSD42 ! 461: /* ARGSUSED */ ! 462: #endif BSD42 ! 463: ! 464: static int pipeser (i) ! 465: int i; ! 466: { ! 467: #ifndef BSD42 ! 468: (void) signal (i, SIG_IGN); ! 469: #endif BSD42 ! 470: ! 471: pbroke = 1; ! 472: } ! 473: ! 474: /* */ ! 475: ! 476: rcpy () { ! 477: int i; ! 478: char buffer[BUFSIZ], ! 479: tmpfil[BUFSIZ]; ! 480: FILE * fp; ! 481: ! 482: (void) strcpy (tmpfil, "/tmp/rmailXXXXXX"); ! 483: (void) unlink (mktemp (tmpfil)); ! 484: if ((pipef = fdopen (creat (tmpfil, Tmpmode), "w")) == NULL) ! 485: return; ! 486: ! 487: fprintf (pipef, "Date: %s\nFrom: %s\n", dtimenow (), Mailsys); ! 488: fprintf (pipef, "To: %s\n", usrfrm); ! 489: fprintf (pipef, "\nProblems sending mail:\n\n"); ! 490: i = 0; ! 491: if ((fp = fopen (Errtmp, "r")) != NULL) { ! 492: while (fgets (buffer, sizeof buffer, fp) != NULL) { ! 493: if (ferror (pipef)) ! 494: break; ! 495: fputs (buffer, pipef); ! 496: i++; ! 497: } ! 498: } ! 499: if (i == 0) ! 500: fprintf (pipef, "\tunknown problem\n"); ! 501: for (i = 0; oopsmessage[i]; i++) ! 502: fprintf (pipef, oopsmessage[i], Overseer); ! 503: fputs (rtnbegin, pipef); ! 504: ! 505: rewind (fromf); ! 506: (void) txtcpy (fromf, pipef); ! 507: rewind (msgf); ! 508: (void) txtcpy (msgf, pipef); ! 509: ! 510: fputs (rtnend, pipef); ! 511: (void) fclose (pipef); ! 512: ! 513: (void) xpost (usrfrm, tmpfil); ! 514: (void) unlink (tmpfil); ! 515: } ! 516: ! 517: /* */ ! 518: ! 519: zcpy () { ! 520: int i; ! 521: char buffer[BUFSIZ], ! 522: tmpfil[BUFSIZ]; ! 523: FILE * fp; ! 524: ! 525: (void) strcpy (tmpfil, "/tmp/rmailXXXXXX"); ! 526: (void) unlink (mktemp (tmpfil)); ! 527: if ((pipef = fdopen (creat (tmpfil, Tmpmode), "w")) == NULL) ! 528: return; ! 529: ! 530: fprintf (pipef, "Date: %s\nFrom: %s\n", dtimenow (), Mailsys); ! 531: fprintf (pipef, "To: %s\n", Mailsys); ! 532: fprintf (pipef, "\nProblems sending mail for %s (aka %s):\n\n", ! 533: from, usrfrm); ! 534: ! 535: i = 0; ! 536: if ((fp = fopen (Errtmp, "r")) != NULL) { ! 537: while (fgets (buffer, sizeof buffer, fp) != NULL) { ! 538: if (ferror (pipef)) ! 539: break; ! 540: fputs (buffer, pipef); ! 541: i = 1; ! 542: } ! 543: (void) fclose (fp); ! 544: if (i == 0) ! 545: fprintf (pipef, "\tunknown problem\n"); ! 546: } ! 547: else ! 548: fprintf (pipef, "\tunable to open %s\n", Errtmp); ! 549: (void) fclose (pipef); ! 550: ! 551: (void) xpost (Mailsys, tmpfil); ! 552: (void) unlink (tmpfil); ! 553: } ! 554: ! 555: /* */ ! 556: ! 557: filter () { ! 558: int i, ! 559: fd, ! 560: td; ! 561: char tmpfil[BUFSIZ], ! 562: mmdfil[BUFSIZ]; ! 563: FILE * out; ! 564: ! 565: (void) strcpy (tmpfil, "/tmp/rmailXXXXXX"); ! 566: (void) unlink (mktemp (tmpfil)); ! 567: if ((fd = creat (tmpfil, Tmpmode)) == NOTOK) ! 568: return NOTOK; ! 569: (void) close (fd); ! 570: if ((fd = open (tmpfil, 2)) == NOTOK) ! 571: return NOTOK; ! 572: if ((out = fdopen (fd, "w")) == NULL) { ! 573: (void) close (fd); ! 574: return NOTOK; ! 575: } ! 576: if ((td = dup (fd)) == NOTOK) { ! 577: (void) close (fd); ! 578: return NOTOK; ! 579: } ! 580: ! 581: fprintf (out, "From %s %s\n", from, date); ! 582: if (txtcpy (msgf, out) == NOTOK) { ! 583: (void) close (fd); ! 584: (void) close (td); ! 585: return NOTOK; ! 586: } ! 587: (void) fclose (out); ! 588: (void) lseek (td, 0L, 0); ! 589: ! 590: (void) strcpy (mmdfil, "/tmp/mmdfXXXXXX"); ! 591: (void) unlink (mktemp (mmdfil)); ! 592: if ((fd = creat (mmdfil, Tmpmode)) == NOTOK) { ! 593: (void) close (td); ! 594: (void) unlink (tmpfil); ! 595: return NOTOK; ! 596: } ! 597: if ((fd = open (mmdfil, 2)) == NOTOK) { ! 598: (void) close (td); ! 599: (void) unlink (tmpfil); ! 600: return NOTOK; ! 601: } ! 602: ! 603: /* */ ! 604: ! 605: switch (i = uucp2mmdf (td, fd, TRUE)) { ! 606: case OK: ! 607: (void) strcpy (mmdf, mmdfil); ! 608: break; ! 609: ! 610: default: ! 611: mmdf[0] = NULL; ! 612: break; ! 613: } ! 614: (void) close (td); ! 615: (void) unlink (tmpfil); ! 616: (void) close (fd); ! 617: ! 618: return (i != OK ? NOTOK : OK); ! 619: } ! 620: ! 621: /* */ ! 622: ! 623: get_mmdf_addr (addr, to) ! 624: char *addr, ! 625: *to; ! 626: { ! 627: struct adrx *adrxp; ! 628: ! 629: *to = NULL; ! 630: if ((adrxp = seekadrx (addr)) == NULL) ! 631: return; ! 632: ! 633: addr_convert (adrxp, to, TRUE); ! 634: while (seekadrx (NULLCP)) ! 635: continue; ! 636: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.