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: }

Defined functions

adrcheck defined in line 297; used 2 times
deliver defined in line 216; used 1 times
filter defined in line 557; used 6 times
get_mmdf_addr defined in line 623; used 1 times
lookup defined in line 344; used 4 times
main defined in line 72; never used
okhost defined in line 335; used 1 times
pipeser defined in line 464; used 2 times
rcpy defined in line 476; used 1 times
rtnmesg defined in line 372; used 3 times
txtcpy defined in line 391; used 8 times
xpost defined in line 406; used 5 times
xuucp defined in line 433; used 2 times
zcpy defined in line 519; used 1 times

Defined variables

Mailsys defined in line 36; used 8 times
date defined in line 31; used 2 times
from defined in line 32; used 17 times
mmdf defined in line 39; used 8 times
oopsmessage defined in line 54; used 2 times
origpath defined in line 34; used 1 times
origsys defined in line 33; used 6 times
overseer defined in line 37; used 2 times
pbroke defined in line 28; used 3 times
rtnbegin defined in line 49; used 2 times
rtnend defined in line 51; used 2 times
rtnflag defined in line 29; used 3 times
rtnmessage defined in line 41; used 2 times
usrfrm defined in line 35; used 10 times

Defined macros

ADDROK defined in line 23; used 4 times
RETURN defined in line 25; used 4 times
UUCP defined in line 24; used 1 times
Last modified: 1986-01-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2220
Valid CSS Valid XHTML 1.0 Strict