1: /* post.c - enter messages into the transport system */
   2: 
   3: #include "../h/mh.h"
   4: #include "../h/addrsbr.h"
   5: #include "../h/aliasbr.h"
   6: #include "../h/dropsbr.h"
   7: #include "../zotnet/tws.h"
   8: #ifndef MMDFMTS
   9: #include <ctype.h>
  10: #include <errno.h>
  11: #include <setjmp.h>
  12: #include <stdio.h>
  13: #include <sys/types.h>
  14: #else   MMDFMTS
  15: #include "../mts/mmdf/util.h"
  16: #include "../mts/mmdf/mmdf.h"
  17: #endif	MMDFMTS
  18: #include "../zotnet/mts.h"
  19: #ifdef  MHMTS
  20: #ifndef V7
  21: #include <sys/ioctl.h>
  22: #endif	not V7
  23: #include <sys/stat.h>
  24: #endif	MHMTS
  25: #ifdef  SENDMTS
  26: #include "../mts/sendmail/smail.h"
  27: #undef  MF
  28: #endif	SENDMTS
  29: #include <signal.h>
  30: 
  31: 
  32: #ifndef MMDFMTS
  33: #define uptolow(c)  (isupper (c) ? tolower (c) : (c))
  34: #endif	not MMDFMTS
  35: 
  36: #define FCCS        10  /* max number of fccs allowed */
  37: 
  38: /*  */
  39: 
  40: static struct swit switches[] = {
  41: #define ALIASW  0
  42:     "alias aliasfile", 0,
  43: 
  44: #define CHKSW   1
  45:     "check", -5,        /* interface from whom */
  46: #define NCHKSW  2
  47:     "nocheck", -7,      /* interface from whom */
  48: 
  49: #define DEBUGSW 3
  50:     "debug", -5,
  51: 
  52: #define DISTSW  4
  53:     "dist", -4,         /* interface from dist */
  54: 
  55: #define ENCRSW  5
  56:     "encrypt",
  57: #ifndef TMA
  58:     -7,
  59: #else   TMA
  60:     0,
  61: #endif	TMA
  62: #define NENCRSW 6
  63:     "noencrypt",
  64: #ifndef TMA
  65:     -9,
  66: #else   TMA
  67:     0,
  68: #endif	TMA
  69: 
  70: #define FILTSW  7
  71:     "filter filterfile", 0,
  72: #define NFILTSW 8
  73:     "nofilter", 0,
  74: 
  75: #define FRMTSW  9
  76:     "format", 0,
  77: #define NFRMTSW 10
  78:     "noformat", 0,
  79: 
  80: #define LIBSW   11      /* interface from send, whom */
  81:     "library directory", -7,
  82: 
  83: #define MSGDSW  12
  84:     "msgid", 0,
  85: #define NMSGDSW 13
  86:     "nomsgid", 0,
  87: 
  88: #define VERBSW  14
  89:     "verbose", 0,
  90: #define NVERBSW 15
  91:     "noverbose", 0,
  92: 
  93: #define WATCSW  16
  94:     "watch", 0,
  95: #define NWATCSW 17
  96:     "nowatch", 0,
  97: 
  98: #define WHOMSW  18  /* interface from whom */
  99:     "whom", -4,
 100: 
 101: #define WIDTHSW 19
 102:     "width columns", 0,
 103: 
 104: #define HELPSW  20
 105:     "help", 4,
 106: 
 107: #define MAILSW  21
 108:     "mail", -4,
 109: #define SAMLSW  22
 110:     "saml", -4,
 111: #define SENDSW  23
 112:     "send", -4,
 113: #define SOMLSW  24
 114:     "soml", -4,
 115: 
 116: #define ANNOSW  25      /* interface from send */
 117:     "idanno number", -6,
 118: 
 119: #define DLVRSW  26
 120:     "deliver address-list", -7,
 121: 
 122: #define CLIESW  27
 123:     "client host", -6,
 124: #define SERVSW  28
 125:     "server host", -6,
 126: #define SNOOPSW 29
 127:     "snoop", -5,
 128: 
 129:     NULL, NULL
 130: };
 131: 
 132: /*  */
 133: 
 134: struct headers {
 135:     char   *value;
 136: 
 137:     unsigned int    flags;
 138: #define HNOP    0x0000      /* just used to keep .set around */
 139: #define HBAD    0x0001      /* bad header - don't let it through */
 140: #define HADR    0x0002      /* header has an address field */
 141: #define HSUB    0x0004      /* Subject: header */
 142: #define HTRY    0x0008      /* try to send to addrs on header */
 143: #define HBCC    0x0010      /* don't output this header */
 144: #define HMNG    0x0020      /* munge this header */
 145: #define HNGR    0x0040      /* no groups allowed in this header */
 146: #define HFCC    0x0080      /* FCC: type header */
 147: #define HNIL    0x0100      /* okay for this header not to have addrs */
 148: #define HIGN    0x0200      /* ignore this header */
 149: 
 150:     unsigned int    set;
 151: #define MFRM    0x0001      /* we've seen a From: */
 152: #define MDAT    0x0002      /* we've seen a Date: */
 153: #define MRFM    0x0004      /* we've seen a Resent-From: */
 154: #define MVIS    0x0008      /* we've seen sighted addrs */
 155: #define MINV    0x0010      /* we've seen blind addrs */
 156: };
 157: 
 158: /*  */
 159: 
 160: static struct headers  NHeaders[] = {
 161:     "Return-Path", HBAD, NULL,
 162:     "Received", HBAD, NULL,
 163:     "Reply-To", HADR | HNGR, NULL,
 164:     "From", HADR | HNGR, MFRM,
 165:     "Sender", HADR | HBAD, NULL,
 166:     "Date", HBAD, NULL,
 167:     "Subject", HSUB, NULL,
 168:     "To", HADR | HTRY, MVIS,
 169:     "cc", HADR | HTRY, MVIS,
 170:     "Bcc", HADR | HTRY | HBCC | HNIL, MINV,
 171:     "Message-ID", HBAD, NULL,
 172:     "Fcc", HFCC, NULL,
 173: 
 174:     NULL
 175: };
 176: 
 177: static struct headers  RHeaders[] = {
 178:     "Resent-Reply-To", HADR | HNGR, NULL,
 179:     "Resent-From", HADR | HNGR, MRFM,
 180:     "Resent-Sender", HADR | HBAD, NULL,
 181:     "Resent-Date", HBAD, NULL,
 182:     "Resent-Subject", HSUB, NULL,
 183:     "Resent-To", HADR | HTRY, MVIS,
 184:     "Resent-cc", HADR | HTRY, MVIS,
 185:     "Resent-Bcc", HADR | HTRY | HBCC, MINV,
 186:     "Resent-Message-ID", HBAD, NULL,
 187:     "Resent-Fcc", HFCC, NULL,
 188:     "Reply-To", HADR, NULL,
 189:     "From", HADR | HNGR, MFRM,
 190: #ifdef  MMDFI
 191:     "Sender", HADR | HMNG | HNGR, NULL,
 192: #else   not MMFDI
 193:     "Sender", HADR | HNGR, NULL,
 194: #endif	not MMDFI
 195:     "Date", HNOP, MDAT,
 196:     "To", HADR | HNIL, NULL,
 197:     "cc", HADR | HNIL, NULL,
 198:     "Bcc", HADR | HTRY | HBCC | HNIL, NULL,
 199:     "Fcc", HIGN, NULL,
 200: 
 201:     NULL
 202: };
 203: 
 204: /*  */
 205: 
 206: 
 207: static short    fccind = 0; /* index into fccfold[] */
 208: static short    outputlinelen = OUTPUTLINELEN;
 209: 
 210: static int  pfd = NOTOK;    /* fd to write annotation list to */
 211: static int  myuid;      /* my user id */
 212: static int  mygid;      /* my group id */
 213: static int  recipients = 0; /* how many people will get a copy */
 214: static int  unkadr = 0;     /* how many of those were unknown */
 215: static int  badadr = 0;     /* number of bad addrs */
 216: static int  badmsg = 0;     /* message has bad semantics */
 217: static int  verbose = 0;    /* spell it out */
 218: static int  format = 1;     /* format addresses */
 219: static int  msgid = 0;      /* add msgid */
 220: static int  debug = 0;      /* debugging post */
 221: static int  watch = 0;      /* watch the delivery process */
 222: static int  whomsw = 0;     /* we are whom not post */
 223: static int  checksw = 0;    /* whom -check */
 224: static int  linepos;        /* putadr()'s position on the line */
 225: static int  nameoutput;     /* putadr() has output header name */
 226: 
 227: static unsigned msgflags = 0;   /* what we've seen */
 228: 
 229: #define NORMAL 0
 230: #define RESENT 1
 231: static int msgstate = NORMAL;
 232: 
 233: static long clock = 0L;     /* the time we started (more or less) */
 234: 
 235: static int  (*hstat) (), (*istat) (), (*qstat) (), (*tstat) ();
 236: 
 237: static char tmpfil[BUFSIZ];
 238: static char bccfil[BUFSIZ];
 239: 
 240: static char from[BUFSIZ];   /* my network address */
 241: static char signature[BUFSIZ];  /* my signature */
 242: static char *filter = NULL; /* the filter for BCC'ing */
 243: static char *subject = NULL;    /* the subject field for BCC'ing */
 244: static char *fccfold[FCCS]; /* foldernames for FCC'ing */
 245: 
 246: static struct headers  *hdrtab; /* table for the message we're doing */
 247: 
 248: static struct mailname localaddrs;  /* local addrs */
 249: static struct mailname netaddrs;    /* network addrs */
 250: static struct mailname uuaddrs;     /* uucp addrs */
 251: static struct mailname tmpaddrs;    /* temporary queue */
 252: 
 253: /*  */
 254: 
 255: #ifdef  MMDFMTS
 256: static char *submitmode = "m";  /* deliver to mailbox only */
 257: #ifndef RP_DOK
 258: static char submitopts[6] = "vl";/* initial options for submit */
 259: #else   RP_DOK
 260: static char submitopts[7] = "vlk";/* initial options for submit */
 261: #endif	RP_DOK
 262: #endif	MMDFMTS
 263: 
 264: #ifdef  MHMTS
 265: static char *deliver = NULL;
 266: 
 267: extern char **environ;
 268: 
 269: int sigser ();
 270: #endif	MHMTS
 271: 
 272: #ifdef  SENDMTS
 273: static int smtpmode = S_MAIL;
 274: static int snoop = 0;
 275: static char *clientsw = NULL;
 276: static char *serversw = NULL;
 277: 
 278: extern struct smtp  sm_reply;
 279: #endif	SENDMTS
 280: 
 281: #ifdef  TMA
 282: #define post(a,b,c) \
 283:     if (encryptsw) postcipher ((a), (b), (c)); else postplain ((a), (b), (c))
 284: #endif	TMA
 285: 
 286: static int  encryptsw = 0;  /* encrypt it */
 287: 
 288: 
 289: long    lseek ();
 290: 
 291: /*    MAIN */
 292: 
 293: /* ARGSUSED */
 294: 
 295: main (argc, argv)
 296: int     argc;
 297: char   *argv[];
 298: {
 299:     int     state,
 300:             compnum;
 301:     char   *cp,
 302:            *msg = NULL,
 303:           **argp = argv + 1,
 304:             buf[BUFSIZ],
 305:             name[NAMESZ];
 306:     FILE   *in,
 307:        *out;
 308: 
 309:     invo_name = r1bindex (argv[0], '/');
 310:     m_foil (NULLCP);
 311:     mts_init (invo_name);
 312: #ifdef  MMDFMTS
 313: #ifdef  MMDFII
 314:     mmdf_init (invo_name);
 315: #endif	MMDFII
 316: #endif	MMDFMTS
 317: 
 318: /*  */
 319: 
 320:     while (cp = *argp++) {
 321:     if (*cp == '-')
 322:         switch (smatch (++cp, switches)) {
 323:         case AMBIGSW:
 324:             ambigsw (cp, switches);
 325:             done (1);
 326:         case UNKWNSW:
 327:             adios (NULLCP, "-%s unknown", cp);
 328:         case HELPSW:
 329:             (void) sprintf (buf, "%s [switches] file", invo_name);
 330:             help (buf, switches);
 331:             done (1);
 332: 
 333:         case LIBSW:
 334:             if (!(cp = *argp++) || *cp == '-')
 335:             adios (NULLCP, "missing argument to %s", argp[-2]);
 336:             m_foil (cp);
 337:             continue;
 338: 
 339:         case ALIASW:
 340:             if (!(cp = *argp++) || *cp == '-')
 341:             adios (NULLCP, "missing argument to %s", argp[-2]);
 342: #ifdef  MHMTS
 343:             if (access (libpath (cp), 04) == NOTOK)
 344:             adios (cp, "unable to read");
 345: #endif	MHMTS
 346:             if ((state = alias (cp)) != AK_OK)
 347:             adios (NULLCP, "aliasing error in %s - %s",
 348:                 cp, akerror (state));
 349:             continue;
 350: 
 351:         case CHKSW:
 352:             checksw++;
 353:             continue;
 354:         case NCHKSW:
 355:             checksw = 0;
 356:             continue;
 357: 
 358:         case DEBUGSW:
 359:             debug++;
 360:             continue;
 361: 
 362:         case DISTSW:
 363:             msgstate = RESENT;
 364:             continue;
 365: 
 366:         case FILTSW:
 367:             if (!(filter = *argp++) || *filter == '-')
 368:             adios (NULLCP, "missing argument to %s", argp[-2]);
 369:             continue;
 370:         case NFILTSW:
 371:             filter = NULL;
 372:             continue;
 373: 
 374:         case FRMTSW:
 375:             format++;
 376:             continue;
 377:         case NFRMTSW:
 378:             format = 0;
 379:             continue;
 380: 
 381:         case MSGDSW:
 382:             msgid++;
 383:             continue;
 384:         case NMSGDSW:
 385:             msgid = 0;
 386:             continue;
 387: 
 388:         case VERBSW:
 389:             verbose++;
 390:             continue;
 391:         case NVERBSW:
 392:             verbose = 0;
 393:             continue;
 394: 
 395:         case WATCSW:
 396:             watch++;
 397:             continue;
 398:         case NWATCSW:
 399:             watch = 0;
 400:             continue;
 401: 
 402:         case WHOMSW:
 403:             whomsw++;
 404:             continue;
 405: 
 406:         case WIDTHSW:
 407:             if (!(cp = *argp++) || *cp == '-')
 408:             adios (NULLCP, "missing argument to %s", argp[-2]);
 409:             if ((outputlinelen = atoi (cp)) < 10)
 410:             adios (NULLCP, "impossible width %d", outputlinelen);
 411:             continue;
 412: 
 413:         case ENCRSW:
 414:             encryptsw++;
 415:             continue;
 416:         case NENCRSW:
 417:             encryptsw = 0;
 418:             continue;
 419: 
 420:         case ANNOSW:
 421:             if (!(cp = *argp++) || *cp == '-')
 422:             adios (NULLCP, "missing argument to %s", argp[-2]);
 423:             if ((pfd = atoi (cp)) <= 2)
 424:             adios (NULLCP, "bad argument %s %s", argp[-2], cp);
 425:             continue;
 426: 
 427: #ifdef  MMDFMTS
 428:         case MAILSW:
 429:             submitmode = "m";
 430:             continue;
 431:         case SOMLSW:    /* for right now, sigh... */
 432:         case SAMLSW:
 433:             submitmode = "b";
 434:             continue;
 435:         case SENDSW:
 436:             submitmode = "y";
 437:             continue;
 438: #endif	MMDFMTS
 439: 
 440: #ifndef MHMTS
 441:         case DLVRSW:
 442:             if (!(cp = *argp++) || *cp == '-')
 443:             adios (NULLCP, "missing argument to %s", argp[-2]);
 444:             continue;
 445: #else   MHMTS
 446:         case MAILSW:
 447:         case SAMLSW:
 448:         case SOMLSW:
 449:         case SENDSW:
 450:             continue;
 451:         case DLVRSW:
 452:             if (!(deliver = *argp++) || *deliver == '-')
 453:             adios (NULLCP, "missing argument to %s", argp[-2]);
 454:             continue;
 455: #endif	MHMTS
 456: 
 457: #ifndef SENDMTS
 458:         case CLIESW:
 459:         case SERVSW:
 460:             if (!(cp = *argp++) || *cp == '-')
 461:             adios (NULLCP, "missing argument to %s", argp[-2]);
 462:             continue;
 463: 
 464:         case SNOOPSW:
 465:             continue;
 466: #else   SENDMTS
 467:         case MAILSW:
 468:             smtpmode = S_MAIL;
 469:             continue;
 470:         case SAMLSW:
 471:             smtpmode = S_SAML;
 472:             continue;
 473:         case SOMLSW:
 474:             smtpmode = S_SOML;
 475:             continue;
 476:         case SENDSW:
 477:             smtpmode = S_SEND;
 478:             continue;
 479:         case CLIESW:
 480:             if (!(clientsw = *argp++) || *clientsw == '-')
 481:             adios (NULLCP, "missing argument to %s", argp[-2]);
 482:             continue;
 483:         case SERVSW:
 484:             if (!(serversw = *argp++) || *serversw == '-')
 485:             adios (NULLCP, "missing argument to %s", argp[-2]);
 486:             continue;
 487:         case SNOOPSW:
 488:             snoop++;
 489:             continue;
 490: #endif	SENDMTS
 491:         }
 492:     if (msg)
 493:         adios (NULLCP, "only one message at a time!");
 494:     else
 495:         msg = cp;
 496:     }
 497: 
 498:     (void) alias (AliasFile);
 499: 
 500: /*  */
 501: 
 502:     if (!msg)
 503:     adios (NULLCP, "usage: %s [switches] file", invo_name);
 504: 
 505:     if (outputlinelen < 10)
 506:     adios (NULLCP, "impossible width %d", outputlinelen);
 507: 
 508: #ifdef  MHMTS
 509:     if (access (msg, 04) == NOTOK)
 510:     adios (msg, "unable to read");
 511: #endif	MHMTS
 512:     if ((in = fopen (msg, "r")) == NULL)
 513:     adios (msg, "unable to open");
 514: 
 515:     start_headers ();
 516:     if (debug) {
 517:     verbose++;
 518:     out = stdout;
 519: #ifdef  MHMTS
 520:     if (deliver) {
 521:         (void) strcpy (tmpfil, msg);
 522:         putfmt ("To", deliver, out);
 523:         goto daemon;
 524:     }
 525: #endif	MHMTS
 526:     }
 527:     else
 528: #ifdef  MHMTS
 529:     if (deliver) {
 530:     if ((out = fopen ("/dev/null", "r")) == NULL)
 531:         adios ("/dev/null", "unable to write");
 532:     (void) strcpy (tmpfil, msg);
 533:     putfmt ("To", deliver, out);
 534:     goto daemon;
 535:     }
 536:     else
 537: #endif	MHMTS
 538:     if (whomsw) {
 539:         if ((out = fopen ("/dev/null", "w")) == NULL)
 540:         adios ("/dev/null", "unable to open");
 541:     }
 542:     else {
 543:         (void) strcpy (tmpfil, m_tmpfil (invo_name));
 544:         if ((out = fopen (tmpfil, "w")) == NULL)
 545:         adios (tmpfil, "unable to create");
 546: #ifdef  MHMTS
 547:         (void) chown (tmpfil, myuid, mygid);
 548: #endif	MHMTS
 549:         (void) chmod (tmpfil, 0600);
 550:     }
 551: 
 552: /*  */
 553: 
 554:     hdrtab = msgstate == NORMAL ? NHeaders : RHeaders;
 555: 
 556:     for (compnum = 1, state = FLD;;) {
 557:     switch (state = m_getfld (state, name, buf, sizeof buf, in)) {
 558:         case FLD:
 559:         case FLDEOF:
 560:         case FLDPLUS:
 561:         compnum++;
 562:         cp = add (buf, NULLCP);
 563:         while (state == FLDPLUS) {
 564:             state = m_getfld (state, name, buf, sizeof buf, in);
 565:             cp = add (buf, cp);
 566:         }
 567:         putfmt (name, cp, out);
 568:         free (cp);
 569:         if (state != FLDEOF)
 570:             continue;
 571:         finish_headers (out);
 572:         break;
 573: 
 574:         case BODY:
 575:         case BODYEOF:
 576:         finish_headers (out);
 577:         if (whomsw)
 578:             break;
 579:         fprintf (out, "\n%s", buf);
 580:         while (state == BODY) {
 581:             state = m_getfld (state, name, buf, sizeof buf, in);
 582:             fputs (buf, out);
 583:         }
 584:         break;
 585: 
 586:         case FILEEOF:
 587:         finish_headers (out);
 588:         break;
 589: 
 590:         case LENERR:
 591:         case FMTERR:
 592:         adios (NULLCP, "message format error in component #%d",
 593:             compnum);
 594: 
 595:         default:
 596:         adios (NULLCP, "getfld() returned %d", state);
 597:     }
 598:     break;
 599:     }
 600: 
 601: /*  */
 602: 
 603: #ifdef  MHMTS
 604: daemon: ;
 605: #endif	MHMTS
 606:     if (pfd != NOTOK)
 607:     anno ();
 608:     (void) fclose (in);
 609:     if (debug) {
 610:     pl ();
 611:     done (0);
 612:     }
 613:     else
 614:     (void) fclose (out);
 615: 
 616: #ifdef  TMA
 617:     if (encryptsw)
 618:     tmastart ();
 619: #endif	TMA
 620:     if (whomsw) {
 621:     verify_all_addresses (1);
 622:     done (0);
 623:     }
 624: 
 625: #ifdef  MMDFMTS
 626:     (void) strcat (submitopts, submitmode);
 627:     if (watch)
 628:     (void) strcat (submitopts, "nw");
 629: #endif	MMDFMTS
 630: #ifdef  MHMTS
 631:     verify_all_addresses (0);
 632: #endif	MHMTS
 633:     if (encryptsw)
 634:     verify_all_addresses (verbose);
 635:     if (msgflags & MINV) {
 636:     make_bcc_file ();
 637:     if (msgflags & MVIS) {
 638: #ifndef MHMTS
 639:         if (!encryptsw)
 640:         verify_all_addresses (verbose);
 641: #endif	not MHMTS
 642:         post (tmpfil, 0, verbose);
 643:     }
 644:     post (bccfil, 1, verbose);
 645:     (void) unlink (bccfil);
 646:     }
 647:     else
 648:     post (tmpfil, 0, isatty (1));
 649: #ifdef  TMA
 650:     if (encryptsw)
 651:     tmastop ();
 652: #endif	TMA
 653: 
 654:     refile (tmpfil);
 655: 
 656: #ifdef  MHMTS
 657:     if (!deliver)
 658: #endif	MHMTS
 659:     (void) unlink (tmpfil);
 660: 
 661:     if (verbose)
 662:     printf ("Message Processed\n");
 663: 
 664:     done (0);
 665: }
 666: 
 667: /*    DRAFT GENERATION */
 668: 
 669: static putfmt (name, str, out)
 670: register char   *name,
 671:         *str;
 672: register FILE *out;
 673: {
 674:     int     count,
 675:             grp,
 676:             i,
 677:             keep;
 678:     register char  *cp,
 679:                    *pp,
 680:                    *qp;
 681:     char    namep[BUFSIZ];
 682:     register struct mailname   *mp,
 683:                                *np;
 684:     register struct headers *hdr;
 685: 
 686:     while (*str == ' ' || *str == '\t')
 687:     str++;
 688: 
 689:     if (msgstate == NORMAL && uprf (name, "resent")) {
 690:     advise (NULLCP, "illegal header line -- %s:", name);
 691:     badmsg++;
 692:     return;
 693:     }
 694: 
 695:     if ((i = get_header (name, hdrtab)) == NOTOK) {
 696:     fprintf (out, "%s: %s", name, str);
 697:     return;
 698:     }
 699: 
 700:     hdr = &hdrtab[i];
 701:     if (hdr -> flags & HIGN)
 702:     return;
 703:     if (hdr -> flags & HBAD) {
 704:     advise (NULLCP, "illegal header line -- %s:", name);
 705:     badmsg++;
 706:     return;
 707:     }
 708:     msgflags |= (hdr -> set & ~(MVIS | MINV));
 709: 
 710:     if (hdr -> flags & HSUB)
 711:     subject = subject ? add (str, add ("\t", subject)) : getcpy (str);
 712:     if (hdr -> flags & HFCC) {
 713:     if (cp = rindex (str, '\n'))
 714:         *cp = NULL;
 715:     for (cp = pp = str; cp = index (pp, ','); pp = cp) {
 716:         *cp++ = NULL;
 717:         insert_fcc (hdr, pp);
 718:     }
 719:     insert_fcc (hdr, pp);
 720:     return;
 721:     }
 722: 
 723: /*  */
 724: 
 725:     if (!(hdr -> flags & HADR)) {
 726:     fprintf (out, "%s: %s", name, str);
 727:     return;
 728:     }
 729: 
 730:     tmpaddrs.m_next = NULL;
 731:     for (count = 0; cp = getname (str); count++)
 732:     if (mp = getm (cp, NULLCP, 0, AD_HOST, NULLCP)) {
 733:         if (tmpaddrs.m_next)
 734:         np -> m_next = mp;
 735:         else
 736:         tmpaddrs.m_next = mp;
 737:         np = mp;
 738:     }
 739:     else
 740:         if (hdr -> flags & HTRY)
 741:         badadr++;
 742:         else
 743:         badmsg++;
 744: 
 745:     if (count < 1) {
 746:     if (hdr -> flags & HNIL)
 747:         fprintf (out, "%s: %s", name, str);
 748:     else {
 749: #ifdef  notdef
 750:         advise (NULLCP, "%s: field requires at least one address", name);
 751:         badmsg++;
 752: #endif	notdef
 753:     }
 754:     return;
 755:     }
 756: 
 757: /*  */
 758: 
 759:     nameoutput = linepos = 0;
 760:     (void) sprintf (namep, "%s%s",
 761:         (hdr -> flags & HMNG) ? "Original-" : "", name);
 762: 
 763:     for (grp = 0, mp = tmpaddrs.m_next; mp; mp = np)
 764:     if (mp -> m_nohost) {   /* also used to test (hdr -> flags & HTRY) */
 765:         pp = akvalue (mp -> m_mbox);
 766:         qp = akvisible () ? mp -> m_mbox : "";
 767:         np = mp;
 768:         if (np -> m_gname)
 769:         putgrp (namep, np -> m_gname, out, hdr -> flags);
 770:         while (cp = getname (pp)) {
 771:         if (!(mp = getm (cp, NULLCP, 0, AD_HOST, NULLCP))) {
 772:             badadr++;
 773:             continue;
 774:         }
 775:         if (hdr -> flags & HBCC)
 776:             mp -> m_bcc++;
 777:         if (mp -> m_ingrp = np -> m_ingrp)
 778:             grp++;
 779: #ifdef  MHMTS
 780:         mp -> m_aka = getcpy (np -> m_mbox);
 781: #endif	MHMTS
 782:         if (putadr (namep, qp, mp, out, hdr -> flags))
 783:             msgflags |= (hdr -> set & (MVIS | MINV));
 784:         else
 785:             mnfree (mp);
 786:         }
 787:         mp = np;
 788:         np = np -> m_next;
 789:         mnfree (mp);
 790:     }
 791:     else {
 792:         if (hdr -> flags & HBCC)
 793:         mp -> m_bcc++;
 794:         if (mp -> m_gname)
 795:         putgrp (namep, mp -> m_gname, out, hdr -> flags);
 796:         if (mp -> m_ingrp)
 797:         grp++;
 798:         keep = putadr (namep, "", mp, out, hdr -> flags);
 799:         np = mp -> m_next;
 800:         if (keep) {
 801:         mp -> m_next = NULL;
 802:         msgflags |= (hdr -> set & (MVIS | MINV));
 803:         }
 804:         else
 805:         mnfree (mp);
 806:     }
 807: 
 808:     if (grp > 0 && (hdr -> flags & HNGR)) {
 809:     advise (NULLCP, "%s: field does not allow groups", name);
 810:     badmsg++;
 811:     }
 812:     if (linepos)
 813:     (void) putc ('\n', out);
 814: }
 815: 
 816: /*  */
 817: 
 818: static  start_headers () {
 819:     register char  *cp;
 820:     char    myhost[BUFSIZ],
 821:             sigbuf[BUFSIZ];
 822:     register struct mailname   *mp;
 823: 
 824:     myuid = getuid ();
 825:     mygid = getgid ();
 826:     (void) time (&clock);
 827: 
 828:     (void) strcpy (from, adrsprintf (NULLCP, NULLCP));
 829: 
 830:     (void) strcpy (myhost, LocalName ());
 831:     for (cp = myhost; *cp; cp++)
 832:     *cp = uptolow (*cp);
 833: 
 834: #ifdef  MHMTS
 835:     if (deliver) {
 836:     if (geteuid () == 0 && myuid != 0 && myuid != 1 && mygid != 1)
 837:         adios (NULLCP, "-deliver unknown");
 838:     (void) strcpy (signature, from);
 839:     }
 840: #endif	MHMTS
 841: 
 842:     if ((cp = getfullname ()) && *cp) {
 843:     (void) strcpy (sigbuf, cp);
 844:     (void) sprintf (signature, "%s <%s>", sigbuf, adrsprintf (NULLCP, NULLCP));
 845:     if ((cp = getname (signature)) == NULL)
 846:         adios (NULLCP, "getname () failed -- you lose extraordinarily big");
 847:     if ((mp = getm (cp, NULLCP, 0, AD_HOST, NULLCP)) == NULL)
 848:         adios (NULLCP, "bad signature '%s'", sigbuf);
 849:     mnfree (mp);
 850:     while (getname (""))
 851:         continue;
 852:     }
 853:     else
 854:     (void) strcpy (signature, adrsprintf (NULLCP, NULLCP));
 855: }
 856: 
 857: /*  */
 858: 
 859: static finish_headers (out)
 860: register FILE *out;
 861: {
 862:     switch (msgstate) {
 863:     case NORMAL:
 864:         if (whomsw)
 865:         break;
 866: 
 867:         fprintf (out, "Date: %s\n", dtime (&clock));
 868:         if (msgid)
 869:         fprintf (out, "Message-ID: <%d.%ld@%s>\n",
 870:             getpid (), clock, LocalName ());
 871:         if (msgflags & MFRM)
 872:         fprintf (out, "Sender: %s\n", from);
 873:         else
 874:         fprintf (out, "From: %s\n", signature);
 875:         if (!(msgflags & MVIS))
 876:         fprintf (out, "Bcc: Blind Distribution List: ;\n");
 877:         break;
 878: 
 879:     case RESENT:
 880:         if (!(msgflags & MDAT)) {
 881:         advise (NULLCP, "message has no Date: header");
 882:         badmsg++;
 883:         }
 884:         if (!(msgflags & MFRM)) {
 885:         advise (NULLCP, "message has no From: header");
 886:         badmsg++;
 887:         }
 888:         if (whomsw)
 889:         break;
 890: 
 891: #ifdef  MMDFI           /* sigh */
 892:         fprintf (out, "Sender: %s\n", from);
 893: #endif	MMDFI
 894: 
 895:         fprintf (out, "Resent-Date: %s\n", dtime (&clock));
 896:         if (msgid)
 897:         fprintf (out, "Resent-Message-ID: <%d.%ld@%s>\n",
 898:             getpid (), clock, LocalName ());
 899:         if (msgflags & MRFM)
 900:         fprintf (out, "Resent-Sender: %s\n", from);
 901:         else
 902:         fprintf (out, "Resent-From: %s\n", signature);
 903:         if (!(msgflags & MVIS))
 904:         fprintf (out, "Resent-Bcc: Blind Re-Distribution List: ;\n");
 905:         break;
 906:     }
 907: 
 908:     if (badmsg)
 909:     adios (NULLCP, "re-format message and try again");
 910:     if (!recipients)
 911:     adios (NULLCP, "no addressees");
 912: }
 913: 
 914: /*  */
 915: 
 916: static int     get_header (header, table)
 917: register char   *header;
 918: register struct headers *table;
 919: {
 920:     register struct headers *h;
 921: 
 922:     for (h = table; h -> value; h++)
 923:     if (uleq (header, h -> value))
 924:         return (h - table);
 925: 
 926:     return NOTOK;
 927: }
 928: 
 929: /*  */
 930: 
 931: static int     putadr (name, aka, mp, out, flags)
 932: register char   *name,
 933:         *aka;
 934: register struct mailname *mp;
 935: register FILE *out;
 936: unsigned int    flags;
 937: {
 938:     int     len;
 939:     register char   *cp;
 940:     char    buffer[BUFSIZ];
 941: 
 942:     if (mp -> m_mbox == NULL || ((flags & HTRY) && !insert (mp)))
 943:     return 0;
 944:     if ((flags & HBCC) || mp -> m_ingrp)
 945:     return 1;
 946: 
 947:     if (!nameoutput) {
 948:     fprintf (out, "%s: ", name);
 949:     linepos += (nameoutput = strlen (name) + 2);
 950:     }
 951: 
 952:     if (*aka && mp -> m_type != UUCPHOST && !mp -> m_pers)
 953:     mp -> m_pers = getcpy (aka);
 954:     if (format) {
 955:     if (mp -> m_gname)
 956:         (void) sprintf (cp = buffer, "%s;", mp -> m_gname);
 957:     else
 958:         cp = adrformat (mp);
 959:     }
 960:     else
 961:     cp = mp -> m_text;
 962:     len = strlen (cp);
 963: 
 964:     if (linepos != nameoutput)
 965:     if (len + linepos + 2 > outputlinelen)
 966:         fprintf (out, ",\n%*s", linepos = nameoutput, "");
 967:     else {
 968:         fputs (", ", out);
 969:         linepos += 2;
 970:     }
 971: 
 972:     fputs (cp, out);
 973:     linepos += len;
 974: 
 975:     return (flags & HTRY);
 976: }
 977: 
 978: /*  */
 979: 
 980: static putgrp (name, group, out, flags)
 981: register char   *name,
 982:         *group;
 983: register FILE *out;
 984: unsigned int    flags;
 985: {
 986:     int     len;
 987:     char   *cp;
 988: 
 989:     if (flags & HBCC)
 990:     return;
 991: 
 992:     if (!nameoutput) {
 993:     fprintf (out, "%s: ", name);
 994:     linepos += (nameoutput = strlen (name) + 2);
 995:     }
 996: 
 997:     cp = concat (group, ";", NULLCP);
 998:     len = strlen (cp);
 999: 
1000:     if (linepos != nameoutput)
1001:     if (len + linepos + 2 > outputlinelen) {
1002:         fprintf (out, ",\n%*s", nameoutput, "");
1003:         linepos = nameoutput;
1004:     }
1005:     else {
1006:         fputs (", ", out);
1007:         linepos += 2;
1008:     }
1009: 
1010:     fputs (cp, out);
1011:     linepos += len;
1012: }
1013: 
1014: /*  */
1015: 
1016: static int     insert (np)
1017: register struct mailname   *np;
1018: {
1019:     register struct mailname   *mp;
1020: 
1021:     if (np -> m_mbox == NULL)
1022:     return 0;
1023: 
1024:     for (mp = np -> m_type == LOCALHOST ? &localaddrs
1025:         : np -> m_type == UUCPHOST ? &uuaddrs
1026:         : &netaddrs;
1027:         mp -> m_next;
1028:         mp = mp -> m_next)
1029:     if (uleq (np -> m_host, mp -> m_next -> m_host)
1030:         && uleq (np -> m_mbox, mp -> m_next -> m_mbox)
1031:         && np -> m_bcc == mp -> m_next -> m_bcc)
1032:         return 0;
1033: 
1034:     mp -> m_next = np;
1035:     recipients++;
1036:     return 1;
1037: }
1038: 
1039: 
1040: static  pl () {
1041:     register int     i;
1042:     register struct mailname *mp;
1043: 
1044:     printf ("-------\n\t-- Addresses --\nlocal:\t");
1045:     for (mp = localaddrs.m_next; mp; mp = mp -> m_next)
1046:     printf ("%s%s%s", mp -> m_mbox,
1047:         mp -> m_bcc ? "[BCC]" : "",
1048:         mp -> m_next ? ",\n\t" : "");
1049: 
1050:     printf ("\nnet:\t");
1051:     for (mp = netaddrs.m_next; mp; mp = mp -> m_next)
1052:     printf ("%s%s@%s%s%s", mp -> m_path ? mp -> m_path : "",
1053:         mp -> m_mbox, mp -> m_host,
1054:         mp -> m_bcc ? "[BCC]" : "",
1055:         mp -> m_next ? ",\n\t" : "");
1056: 
1057:     printf ("\nuucp:\t");
1058:     for (mp = uuaddrs.m_next; mp; mp = mp -> m_next)
1059:     printf ("%s!%s%s", mp -> m_host, mp -> m_mbox,
1060:         mp -> m_bcc ? "[BCC]" : "",
1061:         mp -> m_next ? ",\n\t" : "");
1062: 
1063:     printf ("\n\t-- Folder Copies --\nfcc:\t");
1064:     for (i = 0; i < fccind; i++)
1065:     printf ("%s%s", fccfold[i], i + 1 < fccind ? ",\n\t" : "");
1066:     printf ("\n");
1067: }
1068: 
1069: /*  */
1070: 
1071: static  anno () {
1072:     register struct mailname *mp;
1073: 
1074:     for (mp = localaddrs.m_next; mp; mp = mp -> m_next)
1075:     if (annoaux (mp) == NOTOK)
1076:         goto oops;
1077: 
1078:     for (mp = netaddrs.m_next; mp; mp = mp -> m_next)
1079:     if (annoaux (mp) == NOTOK)
1080:         goto oops;
1081: 
1082:     for (mp = uuaddrs.m_next; mp; mp = mp -> m_next)
1083:     if (annoaux (mp) == NOTOK)
1084:         break;
1085: 
1086: oops: ;
1087:     (void) close (pfd);
1088:     pfd = NOTOK;
1089: }
1090: 
1091: 
1092: static int  annoaux (mp)
1093: register struct mailname *mp;
1094: {
1095:     int     i;
1096:     char    buffer[BUFSIZ];
1097: 
1098:     (void) sprintf (buffer, "%s\n", adrformat (mp));
1099:     i = strlen (buffer);
1100: 
1101:     return (write (pfd, buffer, i) == i ? OK : NOTOK);
1102: }
1103: 
1104: /*  */
1105: 
1106: static  insert_fcc (hdr, pp)
1107: register struct headers *hdr;
1108: register char   *pp;
1109: {
1110:     register char   *cp;
1111: 
1112:     for (cp = pp; isspace (*cp); cp++)
1113:     continue;
1114:     for (pp += strlen (pp) - 1; pp > cp && isspace (*pp); pp--)
1115:     continue;
1116:     if (pp >= cp)
1117:     *++pp = NULL;
1118:     if (*cp == NULL)
1119:     return;
1120: 
1121:     if (fccind >= FCCS)
1122:     adios (NULLCP, "too many %ss", hdr -> value);
1123:     fccfold[fccind++] = getcpy (cp);
1124: }
1125: 
1126: /*    BCC GENERATION */
1127: 
1128: static  make_bcc_file () {
1129:     int     fd,
1130:         i,
1131:             child_id;
1132:     char   *vec[6];
1133:     register FILE   *out;
1134: 
1135:     (void) strcpy (bccfil, m_tmpfil ("bccs"));
1136:     if ((out = fopen (bccfil, "w")) == NULL)
1137:     adios (bccfil, "unable to create");
1138:     (void) chmod (bccfil, 0600);
1139: 
1140:     fprintf (out, "Date: %s\n", dtime (&clock));
1141:     if (msgid)
1142:     fprintf (out, "Message-ID: <%d.%ld@%s>\n",
1143:         getpid (), clock, LocalName ());
1144:     fprintf (out, "From: %s\n", signature);
1145:     if (subject)
1146:     fprintf (out, "Subject: %s", subject);
1147:     fprintf (out, "BCC:\n\n------- Blind-Carbon-Copy\n\n");
1148:     (void) fflush (out);
1149: 
1150:     if (filter == NULL) {
1151:     if ((fd = open (tmpfil, 0)) == NOTOK)
1152:         adios (NULLCP, "unable to re-open");
1153:     cpydgst (fd, fileno (out), tmpfil, bccfil);
1154:     (void) close (fd);
1155:     }
1156:     else {
1157:     vec[0] = r1bindex (mhlproc, '/');
1158: 
1159:     for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
1160:         sleep (5);
1161:     switch (child_id) {
1162:         case NOTOK:
1163:         adios ("fork", "unable to");
1164: 
1165:         case OK:
1166:         (void) dup2 (fileno (out), 1);
1167: 
1168:         i = 1;
1169:         vec[i++] = "-forward";
1170:         vec[i++] = "-form";
1171:         vec[i++] = filter;
1172:         vec[i++] = tmpfil;
1173:         vec[i] = NULL;
1174: 
1175:         execvp (mhlproc, vec);
1176:         fprintf (stderr, "unable to exec ");
1177:         perror (mhlproc);
1178:         _exit (-1);
1179: 
1180:         default:
1181:         (void) pidXwait (child_id, mhlproc);
1182:         break;
1183:     }
1184:     }
1185: 
1186:     (void) fseek (out, 0L, 2);
1187:     fprintf (out, "\n------- End of Blind-Carbon-Copy\n");
1188:     (void) fclose (out);
1189: }
1190: 
1191: /*    ADDRESS VERIFICATION */
1192: 
1193: static  verify_all_addresses (talk)
1194: int     talk;
1195: {
1196: #ifndef MHMTS
1197:     int     retval;
1198: #endif	not MHMTS
1199: #ifdef  MMDFMTS
1200: #ifdef  RP_NS
1201:     int     len;
1202:     struct rp_bufstruct reply;
1203: #endif	RP_NS
1204: #endif	MMDFMTS
1205:     register struct mailname *lp;
1206: 
1207: #ifndef MHMTS
1208:     sigon ();
1209: #endif	not MHMTS
1210: 
1211: #ifdef  MMDFMTS
1212:     if (!whomsw || checksw) {
1213:     if (rp_isbad (retval = mm_init ())
1214:         || rp_isbad (retval = mm_sbinit ())
1215:         || rp_isbad (retval = mm_winit (NULLCP, submitopts, from)))
1216:         die (NULLCP, "problem initializing MMDF system [%s]",
1217:             rp_valstr (retval));
1218: #ifdef  RP_NS
1219:     if (rp_isbad (retval = mm_rrply (&reply, &len)))
1220:         die (NULLCP, "problem with sender address [%s]",
1221:             rp_valstr (retval));
1222: #endif	RP_NS
1223:     }
1224: #endif	MMDFMTS
1225: #ifdef  SENDMTS
1226:     if (!whomsw || checksw)
1227:     if (rp_isbad (retval = sm_init (clientsw, serversw, 0, 0, snoop))
1228:         || rp_isbad (retval = sm_winit (smtpmode, from)))
1229:         die (NULLCP, "problem initializing server; %s",
1230:             rp_string (retval));
1231: #endif	SENDMTS
1232: 
1233:     if (talk && !whomsw)
1234:     printf (" -- Address Verification --\n");
1235: #ifndef BERK
1236:     if (talk && localaddrs.m_next)
1237:     printf ("  -- Local Recipients --\n");
1238: #endif	BERK
1239:     for (lp = localaddrs.m_next; lp; lp = lp -> m_next)
1240:     do_an_address (lp, talk, encryptsw);
1241: 
1242: #ifndef BERK
1243:     if (talk && uuaddrs.m_next)
1244:     printf ("  -- UUCP Recipients --\n");
1245: #endif	BERK
1246:     for (lp = uuaddrs.m_next; lp; lp = lp -> m_next)
1247:     do_an_address (lp, talk, encryptsw);
1248: 
1249: #ifndef BERK
1250:     if (talk && netaddrs.m_next)
1251:     printf ("  -- Network Recipients --\n");
1252: #endif	BERK
1253:     for (lp = netaddrs.m_next; lp; lp = lp -> m_next)
1254:     do_an_address (lp, talk, encryptsw);
1255: 
1256:     chkadr ();
1257:     if (talk && !whomsw)
1258:     printf (" -- Address Verification Successful --\n");
1259: 
1260: #ifdef  MMDFMTS
1261:     if (!whomsw || checksw)
1262:     (void) mm_end (NOTOK);
1263: #endif	MMDFMTS
1264: #ifdef  SENDMTS
1265:     if (!whomsw || checksw)
1266:     (void) sm_end (DONE);
1267: #endif	SENDMTS
1268:     (void) fflush (stdout);
1269: 
1270: #ifndef MHMTS
1271:     sigoff ();
1272: #endif	not MHMTS
1273: }
1274: 
1275: /*  */
1276: 
1277: static  chkadr () {
1278: #define plural(x) (x == 1 ? "" : "s")
1279: 
1280:     if (badadr && unkadr)
1281:     die (NULLCP, "%d address%s unparsable, %d addressee%s undeliverable",
1282:         badadr, plural (badadr), unkadr, plural (badadr));
1283:     if (badadr)
1284:     die (NULLCP, "%d address%s unparsable", badadr, plural (badadr));
1285:     if (unkadr)
1286:     die (NULLCP, "%d addressee%s undeliverable", unkadr, plural (unkadr));
1287: }
1288: 
1289: /*    MTS INTERACTION */
1290: 
1291: #ifdef  TMA
1292: static postplain (file, bccque, talk)
1293: #else   TMA
1294: static post (file, bccque, talk)
1295: #endif	TMA
1296: register char   *file;
1297: int     bccque,
1298:         talk;
1299: {
1300:     int     fd;
1301: #ifndef MHMTS
1302:     int     retval;
1303: #ifdef  MMDFMTS
1304: #ifdef  RP_NS
1305:     int     len;
1306:     struct rp_bufstruct reply;
1307: #endif	RP_NS
1308: #endif	MMDFMTS
1309: #else   MHMTS
1310:     int     ud;
1311: #endif	MHMTS
1312: 
1313:     if (verbose)
1314:     if (msgflags & MINV)
1315:         printf (" -- Posting for %s Recipients --\n",
1316:             bccque ? "Blind" : "Sighted");
1317:     else
1318:         printf (" -- Posting for All Recipients --\n");
1319: 
1320:     sigon ();
1321: 
1322: #ifdef  MMDFMTS
1323:     if (rp_isbad (retval = mm_init ())
1324:         || rp_isbad (retval = mm_sbinit ())
1325:         || rp_isbad (retval = mm_winit (NULLCP, submitopts, from)))
1326:     die (NULLCP, "problem initializing MMDF system [%s]",
1327:         rp_valstr (retval));
1328: #ifdef  RP_NS
1329:     if (rp_isbad (retval = mm_rrply (&reply, &len)))
1330:         die (NULLCP, "problem with sender address [%s]",
1331:             rp_valstr (retval));
1332: #endif	RP_NS
1333: #endif	MMDFMTS
1334: #ifdef  SENDMTS
1335:     if (rp_isbad (retval = sm_init (clientsw, serversw, watch, verbose, snoop))
1336:         || rp_isbad (retval = sm_winit (smtpmode, from)))
1337:     die (NULLCP, "problem initializing server; %s", rp_string (retval));
1338: #endif	SENDMTS
1339: 
1340: #ifndef MHMTS
1341:     do_addresses (bccque, talk && verbose);
1342:     if ((fd = open (file, 0)) == NOTOK)
1343:     die (file, "unable to re-open");
1344:     do_text (file, fd);
1345: #else   MHMTS
1346:     if ((fd = open (file, 0)) == NULL)
1347:     adios (file, "unable to re-open");
1348: #ifdef  MF
1349:     ud = UucpChan () && uuaddrs.m_next ? make_uucp_file (fd) : NOTOK;
1350: #else   not MF
1351:     ud = NOTOK;
1352: #endif	not MF
1353:     do_addresses (file, fd, ud, bccque, talk && verbose);
1354:     if (ud != NOTOK)
1355:     (void) close (ud);
1356: #endif	MHMTS
1357:     (void) close (fd);
1358:     (void) fflush (stdout);
1359: 
1360: #ifdef  MMDFMTS
1361:     (void) mm_sbend ();
1362:     (void) mm_end (OK);
1363: #endif	MMDFMTS
1364: #ifdef  SENDMTS
1365:     (void) sm_end (!(msgflags & MINV) || bccque ? OK : DONE);
1366: #endif	SENDMTS
1367: 
1368:     sigoff ();
1369: 
1370:     if (verbose)
1371:     if (msgflags & MINV)
1372:         printf (" -- %s Recipient Copies Posted --\n",
1373:             bccque ? "Blind" : "Sighted");
1374:     else
1375:         printf (" -- Recipient Copies Posted --\n");
1376:     (void) fflush (stdout);
1377: }
1378: 
1379: /*  */
1380: 
1381: #ifdef  TMA
1382: static postcipher (file, bccque, talk)
1383: register char   *file;
1384: int     bccque,
1385:         talk;
1386: {
1387:     int     fdP,
1388:             state;
1389:     char    reason[BUFSIZ];
1390:     struct mailname *lp;
1391: 
1392:     if (verbose)
1393:     if (msgflags & MINV)
1394:         printf (" -- Posting for %s Recipients --\n",
1395:             bccque ? "Blind" : "Sighted");
1396:     else
1397:         printf (" -- Posting for All Recipients --\n");
1398: 
1399:     if ((fdP = open (file, 0)) == NOTOK)
1400:     adios (file, "unable to re-open");
1401:     if (ciphinit (fdP, reason) == NOTOK)
1402:     adios (NULLCP, "%s", reason);
1403:     (void) close (fdP);
1404: 
1405:     for (state = 0, lp = localaddrs.m_next; lp; lp = lp -> m_next)
1406:     if (lp -> m_bcc ? bccque : !bccque) {
1407: #ifndef BERK
1408:         if (talk && !state)
1409:         printf ("  -- Local Recipients --\n");
1410: #endif	BERK
1411:         do_a_cipher (lp, talk);
1412: #ifndef BERK
1413:         state++;
1414: #endif	BERK
1415:     }
1416: 
1417:     for (state = 0, lp = uuaddrs.m_next; lp; lp = lp -> m_next)
1418:     if (lp -> m_bcc ? bccque : !bccque) {
1419: #ifndef BERK
1420:         if (talk && !state)
1421:         printf ("  -- UUCP Recipients --\n");
1422: #endif	BERK
1423:         do_a_cipher (lp, talk);
1424: #ifndef BERK
1425:         state++;
1426: #endif	BERK
1427:     }
1428: 
1429:     for (state = 0, lp = netaddrs.m_next; lp; lp = lp -> m_next)
1430:     if (lp -> m_bcc ? bccque : !bccque) {
1431: #ifndef BERK
1432:         if (talk && !state)
1433:         printf ("  -- Network Recipients --\n");
1434: #endif	BERK
1435:         do_a_cipher (lp, talk);
1436: #ifndef BERK
1437:         state++;
1438: #endif	BERK
1439:     }
1440: 
1441:     if (ciphdone (reason) == NOTOK)
1442:     admonish (NULLCP, "%s", reason);
1443: #ifdef  SENDMTS
1444:     if (!(msgflags & MINV) || bccque)
1445:     (void) sm_end (OK);
1446: #endif	SENDMTS
1447: 
1448:     if (verbose)
1449:     if (msgflags & MINV)
1450:         printf (" -- %s Recipient Copies Posted --\n",
1451:             bccque ? "Blind" : "Sighted");
1452:     else
1453:         printf (" -- Recipient Copies Posted --\n");
1454:     (void) fflush (stdout);
1455: }
1456: 
1457: /*  */
1458: 
1459: static do_a_cipher (lp, talk)
1460: register struct mailname *lp;
1461: int talk;
1462: {
1463:     int     fd,
1464:             retval;
1465:     register char  *mbox,
1466:                    *host;
1467:     char    addr[BUFSIZ],
1468:             reason[BUFSIZ];
1469: #ifdef  MMDFMTS
1470: #ifdef  RP_NS
1471:     int     len;
1472:     struct rp_bufstruct reply;
1473: #endif	RP_NS
1474: #endif	MMDFMTS
1475: 
1476:     sigon ();
1477: 
1478: #ifdef  MMDFMTS
1479:     if (rp_isbad (retval = mm_init ())
1480:         || rp_isbad (retval = mm_sbinit ())
1481:         || rp_isbad (retval = mm_winit (NULL, submitopts, from)))
1482:     die (NULLCP, "problem initializing MMDF system [%s]",
1483:         rp_valstr (retval));
1484: #ifdef  RP_NS
1485:     if (rp_isbad (retval = mm_rrply (&reply, &len)))
1486:         die (NULLCP, "problem with sender address [%s]",
1487:             rp_valstr (retval));
1488: #endif	RP_NS
1489: #endif	MMDFMTS
1490: #ifdef  SENDMTS
1491:     if (rp_isbad (retval = sm_init (clientsw, serversw, watch, verbose, snoop))
1492:         || rp_isbad (retval = sm_winit (smtpmode, from)))
1493:     die (NULLCP, "problem initializing server; %s", rp_string (retval));
1494: #endif	SENDMTS
1495: 
1496:     do_an_address (lp, talk, 0);
1497: 
1498:     switch (lp -> m_type) {
1499:     case LOCALHOST:
1500:         mbox = lp -> m_mbox;
1501:         host = LocalName ();
1502:         (void) strcpy (addr, mbox);
1503:         break;
1504: 
1505:     case UUCPHOST:
1506: #ifdef  MMDFMTS
1507:         mbox = concat (lp -> m_host, "!", lp -> m_mbox, NULLCP);
1508:         host = UucpChan ();
1509: #endif	MMDFMTS
1510: #ifdef  SENDMTS
1511:         mbox = auxformat (lp, 0);
1512:         host = NULL;
1513: #endif	SENDMTS
1514:         (void) sprintf (addr, "%s!%s", lp -> m_host, lp -> m_mbox);
1515:         break;
1516: 
1517:     default:
1518:         mbox = lp -> m_mbox;
1519:         host = lp -> m_host;
1520:         (void) sprintf (addr, "%s at %s", lp -> m_mbox, lp -> m_host);
1521:         break;
1522:     }
1523:     chkadr ();          /* XXX */
1524: 
1525: #ifdef  MMDFMTS
1526:     if (rp_isbad (retval = mm_waend ()))
1527:     die (NULLCP, "problem ending addresses [%s]\n",
1528:         rp_valstr (retval));
1529: #endif	MMDFMTS
1530: #ifdef  SENDMTS
1531:     if (rp_isbad (retval = sm_waend ()))
1532:     die (NULLCP, "problem ending addresses; %s", rp_string (retval));
1533: #endif	SENDMTS
1534: 
1535:     if ((fd = encipher (mbox, host, reason)) == NOTOK)
1536:     die (NULLCP, "%s: %s", addr, reason);
1537:     do_text ("temporary file", fd);
1538:     (void) close (fd);
1539:     (void) fflush (stdout);
1540: 
1541: #ifdef  MMDFMTS
1542:     (void) mm_sbend ();
1543:     (void) mm_end (OK);
1544: #endif	MMDFMTS
1545: #ifdef  SENDMTS
1546:     (void) sm_end (DONE);
1547: #endif	SENDMTS
1548: 
1549:     sigoff ();
1550: }
1551: #endif	TMA
1552: 
1553: /*  */
1554: 
1555: #ifndef MHMTS
1556: static do_addresses (bccque, talk)
1557: #else   MHMTS
1558: static do_addresses (file, fd, ud, bccque, talk)
1559: register char   *file;
1560: int fd,
1561:     ud;
1562: #endif	MHMTS
1563: int bccque,
1564:     talk;
1565: {
1566:     int     retval;
1567: #ifndef BERK
1568:     int     state;
1569: #endif	not BERK
1570:     register struct mailname *lp;
1571: 
1572: #ifndef BERK
1573:     state = 0;
1574: #endif	not BERK
1575:     for (lp = localaddrs.m_next; lp; lp = lp -> m_next)
1576:     if (lp -> m_bcc ? bccque : !bccque) {
1577: #ifndef BERK
1578:         if (talk && !state)
1579:         printf ("  -- Local Recipients --\n");
1580: #endif	not BERK
1581: #ifndef MHMTS
1582:         do_an_address (lp, talk, 0);
1583: #else   MHMTS
1584:         localmail (lp, talk, fd);
1585: #endif	MHMTS
1586: #ifndef BERK
1587:         state++;
1588: #endif	not BERK
1589:     }
1590: 
1591: #ifndef BERK
1592:     state = 0;
1593: #endif	not BERK
1594:     for (lp = uuaddrs.m_next; lp; lp = lp -> m_next)
1595:     if (lp -> m_bcc ? bccque : !bccque) {
1596: #ifndef BERK
1597:         if (talk && !state)
1598:         printf ("  -- UUCP Recipients --\n");
1599: #endif	not BERK
1600: #ifndef MHMTS
1601:         do_an_address (lp, talk, 0);
1602: #else   MHMTS
1603:         uucpmail (lp, talk, ud != NOTOK ? ud : fd, ud == NOTOK);
1604: #endif	MHMTS
1605: #ifndef BERK
1606:         state++;
1607: #endif	not BERK
1608:     }
1609: 
1610: #ifndef BERK
1611:     state = 0;
1612: #endif	not BERK
1613:     for (lp = netaddrs.m_next; lp; lp = lp -> m_next)
1614:     if (lp -> m_bcc ? bccque : !bccque) {
1615: #ifndef BERK
1616:         if (talk && !state)
1617:         printf ("  -- Network Recipients --\n");
1618: #endif	not BERK
1619: #ifndef MHMTS
1620:         do_an_address (lp, talk, 0);
1621: #else   MHMTS
1622:         netmail (talk, fd, bccque);
1623: #endif	MHMTS
1624: #ifndef BERK
1625:         state++;
1626: #endif	not BERK
1627:     }
1628: 
1629: /*  */
1630: 
1631:     chkadr ();
1632: 
1633: #ifdef  MMDFMTS
1634:     if (rp_isbad (retval = mm_waend ()))
1635:     die (NULLCP, "problem ending addresses [%s]\n",
1636:         rp_valstr (retval));
1637: #endif	MMDFMTS
1638: #ifdef  SENDMTS
1639:     if (rp_isbad (retval = sm_waend ()))
1640:     die (NULLCP, "problem ending addresses; %s", rp_string (retval));
1641: #endif	SENDMTS
1642: }
1643: 
1644: /*  */
1645: 
1646: #ifndef MHMTS
1647: static  do_text (file, fd)
1648: register char   *file;
1649: int     fd;
1650: {
1651:     int     retval,
1652:             state;
1653:     char    buf[BUFSIZ];
1654: #ifdef  MMDFMTS
1655:     struct rp_bufstruct reply;
1656: #endif	MMDFMTS
1657: 
1658:     (void) lseek (fd, 0L, 0);
1659:     while ((state = read (fd, buf, sizeof buf)) > 0)
1660: #ifdef  MMDFMTS
1661:     if (rp_isbad (mm_wtxt (buf, state)))
1662:         die (NULLCP, "problem writing text [%s]\n", rp_valstr (retval));
1663: #endif	MMDFMTS
1664: #ifdef  SENDMTS
1665:     if (rp_isbad (retval = sm_wtxt (buf, state)))
1666:         die (NULLCP, "problem writing text; %s\n", rp_string (retval));
1667: #endif	SENDMTS
1668: 
1669:     if (state == NOTOK)
1670:     die (file, "problem reading from");
1671: 
1672: #ifdef  MMDFMTS
1673:     if (rp_isbad (retval = mm_wtend ()))
1674:     die (NULLCP, "problem ending text [%s]\n", rp_valstr (retval));
1675: 
1676:     if (rp_isbad (retval = mm_rrply (&reply, &state)))
1677:     die (NULLCP, "problem getting submission status [%s]\n",
1678:         rp_valstr (retval));
1679: 
1680:     switch (rp_gval (reply.rp_val)) {
1681:     case RP_OK:
1682:     case RP_MOK:
1683:         break;
1684: 
1685:     case RP_NO:
1686:         die (NULLCP, "you lose; %s", reply.rp_line);
1687: 
1688:     case RP_NDEL:
1689:         die (NULLCP, "no delivery occurred; %s", reply.rp_line);
1690: 
1691:     case RP_AGN:
1692:         die (NULLCP, "try again later; %s", reply.rp_line);
1693: 
1694:     case RP_NOOP:
1695:         die (NULLCP, "nothing done; %s", reply.rp_line);
1696: 
1697:     default:
1698:         die (NULLCP, "unexpected response;\n\t[%s] -- %s",
1699:             rp_valstr (reply.rp_val), reply.rp_line);
1700:     }
1701: #endif	MMDFMTS
1702: #ifdef  SENDMTS
1703:     switch (retval = sm_wtend ()) {
1704:     case RP_OK:
1705:         break;
1706: 
1707:     case RP_NO:
1708:     case RP_NDEL:
1709:         die (NULLCP, "posting failed; %s", rp_string (retval));
1710: 
1711:     default:
1712:         die (NULLCP, "unexpected response; %s", rp_string (retval));
1713:     }
1714: #endif	SENDMTS
1715: }
1716: #endif	not MHMTS
1717: 
1718: /*    MTS-SPECIFIC INTERACTION */
1719: 
1720: #ifdef  MMDFMTS
1721: 
1722: #ifndef TMA
1723: /* ARGSUSED */
1724: #endif	TMA
1725: 
1726: static do_an_address (lp, talk, tma)
1727: register struct mailname *lp;
1728: int     talk,
1729:     tma;
1730: {
1731:     int     len,
1732:             retval;
1733:     register char  *mbox,
1734:                    *host,
1735:                    *text,
1736:                    *path;
1737:     char    addr[BUFSIZ];
1738: #ifdef  TMA
1739:     char    reason[BUFSIZ];
1740: #endif	TMA
1741:     struct rp_bufstruct reply;
1742: 
1743:     switch (lp -> m_type) {
1744:     case LOCALHOST:
1745:         mbox = lp -> m_mbox;
1746:         host = LocalName ();
1747:         (void) strcpy (addr, mbox);
1748:         break;
1749: 
1750:     case UUCPHOST:
1751: #ifdef  MF
1752:         mbox = concat (lp -> m_host, "!", lp -> m_mbox, NULLCP);
1753:         host = UucpChan ();
1754:         (void) strcpy (addr, mbox);
1755:         break;
1756: #else   MF
1757:         fprintf (talk ? stdout : stderr, "  %s!%s: %s\n",
1758:         lp -> m_host, lp -> m_mbox, "not supported; UUCP address");
1759:         unkadr++;
1760:         (void) fflush (stdout);
1761:         return;
1762: #endif	MF
1763: 
1764:     default:        /* let MMDF decide if the host is bad */
1765:         mbox = lp -> m_mbox;
1766:         host = lp -> m_host;
1767:         (void) sprintf (addr, "%s at %s", mbox, host);
1768:         break;
1769:     }
1770: #ifdef  TMA
1771:     if ((!whomsw || checksw)
1772:         && tma
1773:         && seekaddr (mbox, host, reason) == NOTOK) {
1774:     fprintf (talk ? stdout : stderr, "  %s%s: %s\n",
1775:         addr, "[TMA]", reason);
1776:     unkadr++;
1777:     }
1778: #endif	TMA
1779: 
1780:     if (talk)
1781:     printf ("  %s%s", addr, whomsw && lp -> m_bcc ? "[BCC]" : "");
1782: 
1783:     if (whomsw && !checksw) {
1784:     (void) putchar ('\n');
1785:     return;
1786:     }
1787:     if (talk)
1788:     printf (": ");
1789:     (void) fflush (stdout);
1790: 
1791: /*  */
1792: 
1793: #ifdef  MMDFII
1794:     if (lp -> m_path)
1795:     path = concat (lp -> m_path, mbox, "@", host, NULLCP);
1796:     else
1797: #endif	MMDFII
1798:     path = NULLCP;
1799:     if (rp_isbad (retval = mm_wadr (path ? NULLCP : host, path ? path : mbox))
1800:         || rp_isbad (retval = mm_rrply (&reply, &len)))
1801:     die (NULLCP, "problem submitting address [%s]", rp_valstr (retval));
1802: 
1803:     switch (rp_gval (reply.rp_val)) {
1804:     case RP_AOK:
1805:         if (talk)
1806:         printf ("address ok\n");
1807:         (void) fflush (stdout);
1808:         return;
1809: 
1810: #ifdef  RP_DOK
1811:     case RP_DOK:
1812:         if (talk)
1813:         printf ("nameserver timeout - queued for checking\n");
1814:         (void) fflush (stdout);
1815:         return;
1816: #endif	RP_DOK
1817: 
1818:     case RP_NO:
1819:         text = "you lose";
1820:         break;
1821: 
1822: #ifdef  RP_NS
1823:     case RP_NS:
1824:         text = "temporary nameserver failure";
1825:         break;
1826: 
1827: #endif	RP_NS
1828: 
1829:     case RP_USER:
1830:     case RP_NDEL:
1831:         text = "not deliverable";
1832:         break;
1833: 
1834:     case RP_AGN:
1835:         text = "try again later";
1836:         break;
1837: 
1838:     case RP_NOOP:
1839:         text = "nothing done";
1840:         break;
1841: 
1842:     default:
1843:         if (!talk)
1844:         fprintf (stderr, "  %s: ", addr);
1845:         text = "unexpected response";
1846:         die (NULLCP, "%s;\n    [%s] -- %s", text,
1847:             rp_valstr (reply.rp_val), reply.rp_line);
1848:     }
1849: 
1850:     if (!talk)
1851:     fprintf (stderr, "  %s: ", addr);
1852:     fprintf (talk ? stdout : stderr, "%s;\n    %s\n", text, reply.rp_line);
1853:     unkadr++;
1854: 
1855:     (void) fflush (stdout);
1856: }
1857: #endif	MMDFMTS
1858: 
1859: /*  */
1860: 
1861: #ifdef  MHMTS
1862: /* ARGSUSED */
1863: 
1864: static do_an_address (lp, talk, tma)
1865: register struct mailname *lp;
1866: int     talk,
1867:     tma;
1868: {
1869:     register char  *mbox;
1870:     char    addr[BUFSIZ];
1871: 
1872:     switch (lp -> m_type) {
1873:     case LOCALHOST:
1874:         (void) strcpy (addr, lp -> m_mbox);
1875:         break;
1876: 
1877:     case UUCPHOST:
1878:         (void) sprintf (addr, "%s!%s", lp -> m_host, lp -> m_mbox);
1879:         break;
1880: 
1881:     default:
1882:         (void) sprintf (addr, "%s at %s", lp -> m_mbox, lp -> m_host);
1883:         break;
1884:     }
1885:     if (talk)
1886:     printf ("  %s%s", addr, whomsw && lp -> m_bcc ? "[BCC]" : "");
1887: 
1888:     if (whomsw && !checksw) {
1889:     (void) putchar ('\n');
1890:     return;
1891:     }
1892:     if (talk)
1893:     printf (": ");
1894:     (void) fflush (stdout);
1895: 
1896: /*  */
1897: 
1898:     switch (lp -> m_type) {
1899:     case LOCALHOST:
1900:         mbox = lp -> m_mbox;
1901:         if (*mbox == '~')
1902:         mbox++;
1903:         if (seek_home (mbox)) {
1904:         lp -> m_mbox = mbox;
1905:         if (talk)
1906:             printf ("address ok\n");
1907:         }
1908:         else {
1909:         if (!talk)
1910:             fprintf (stderr, "  %s: ", addr);
1911:         fprintf (talk ? stdout : stderr,
1912:             "not deliverable; unknown user\n");
1913:         unkadr++;
1914:         }
1915:         break;
1916: 
1917:     case UUCPHOST:
1918:         if (uucpsite (lp -> m_host) == OK) {
1919:         if (talk)
1920:             printf ("address ok\n");
1921:         }
1922:         else {
1923:         if (!talk)
1924:             fprintf (stderr, "  %s: ", addr);
1925:         fprintf (talk ? stdout : stderr,
1926:             "not deliverable; unknown system\n");
1927:         unkadr++;
1928:         }
1929:         break;
1930: 
1931:     case NETHOST:
1932:         if (talk)
1933:         printf ("address ok\n");
1934:         break;
1935: 
1936:     default:
1937:         if (!talk)
1938:         fprintf (stderr, "  %s: ", addr);
1939:         fprintf (talk ? stdout : stderr,
1940:             "not deliverable; unknown host\n");
1941:         unkadr++;
1942:         break;
1943:     }
1944: 
1945:     (void) fflush (stdout);
1946: }
1947: #endif	MHMTS
1948: 
1949: /*  */
1950: 
1951: #ifdef  SENDMTS
1952: 
1953: #ifndef TMA
1954: /* ARGSUSED */
1955: #endif	TMA
1956: 
1957: static do_an_address (lp, talk, tma)
1958: register struct mailname *lp;
1959: int     talk,
1960:     tma;
1961: {
1962:     int     retval;
1963:     register char  *mbox,
1964:                    *host;
1965:     char    addr[BUFSIZ];
1966: #ifdef  TMA
1967:     char    reason[BUFSIZ];
1968: #endif	TMA
1969: 
1970:     switch (lp -> m_type) {
1971:     case LOCALHOST:
1972:         mbox = lp -> m_mbox;
1973:         host = lp -> m_host;
1974:         (void) strcpy (addr, mbox);
1975:         break;
1976: 
1977:     case UUCPHOST:
1978:         mbox = auxformat (lp, 0);
1979:         host = NULL;
1980:         (void) sprintf (addr, "%s!%s", lp -> m_host, lp -> m_mbox);
1981:         break;
1982: 
1983:     default:        /* let SendMail decide if the host is bad  */
1984:         mbox = lp -> m_mbox;
1985:         host = lp -> m_host;
1986:         (void) sprintf (addr, "%s at %s", mbox, host);
1987:         break;
1988:     }
1989: 
1990: #ifdef  TMA
1991:     if ((!whomsw || checksw)
1992:         && tma
1993:         && seekaddr (mbox, host, reason) == NOTOK) {
1994:     fprintf (talk ? stdout : stderr, "  %s%s: %s\n",
1995:         addr, "[TMA]", reason);
1996:     unkadr++;
1997:     }
1998: #endif	TMA
1999: 
2000:     if (talk)
2001:     printf ("  %s%s", addr, whomsw && lp -> m_bcc ? "[BCC]" : "");
2002: 
2003:     if (whomsw && !checksw) {
2004:     (void) putchar ('\n');
2005:     return;
2006:     }
2007:     if (talk)
2008:     printf (": ");
2009:     (void) fflush (stdout);
2010: 
2011: /*  */
2012: 
2013:     switch (retval = sm_wadr (mbox, host,
2014:              lp -> m_type != UUCPHOST ? lp -> m_path : NULLCP)) {
2015:     case RP_OK:
2016:         if (talk)
2017:         printf ("address ok\n");
2018:         break;
2019: 
2020:     case RP_NO:
2021:     case RP_USER:
2022:         if (!talk)
2023:         fprintf (stderr, "  %s: ", addr);
2024:         fprintf (talk ? stdout : stderr, "loses; %s\n",
2025:             rp_string (retval));
2026:         unkadr++;
2027:         break;
2028: 
2029:     default:
2030:         if (!talk)
2031:         fprintf (stderr, "  %s: ", addr);
2032:         die (NULLCP, "unexpected response; %s", rp_string (retval));
2033:     }
2034: 
2035:     (void) fflush (stdout);
2036: }
2037: #endif	SENDMTS
2038: 
2039: /*    SIGNAL HANDLING */
2040: 
2041: #ifndef MHMTS
2042: 
2043: /* ARGSUSED */
2044: 
2045: static  int sigser (i)
2046: int     i;
2047: {
2048: #ifndef BSD42
2049:     (void) signal (i, SIG_IGN);
2050: #endif	not BSD42
2051:     (void) unlink (tmpfil);
2052:     if (msgflags & MINV)
2053:     (void) unlink (bccfil);
2054: #ifdef  MMDFMTS
2055:     if (!whomsw || checksw)
2056:     (void) mm_end (NOTOK);
2057: #endif	MMDFMTS
2058: #ifdef  SENDMTS
2059:     if (!whomsw || checksw)
2060:     (void) sm_end (NOTOK);
2061: #endif	SENDMTS
2062:     done (1);
2063: }
2064: #endif	not MHMTS
2065: 
2066: 
2067: static  sigon () {
2068:     if (debug)
2069:     return;
2070: 
2071: #ifndef MHMTS
2072:     setsigx (hstat, SIGHUP, sigser);
2073:     setsigx (istat, SIGINT, sigser);
2074:     setsigx (qstat, SIGQUIT, sigser);
2075:     setsigx (tstat, SIGTERM, sigser);
2076: #else   MHMTS
2077:     setsigx (hstat, SIGHUP, SIG_IGN);
2078:     setsigx (istat, SIGINT, SIG_IGN);
2079:     setsigx (qstat, SIGQUIT, SIG_IGN);
2080:     setsigx (tstat, SIGTERM, SIG_IGN);
2081: #endif	MHMTS
2082: }
2083: 
2084: 
2085: static sigoff () {
2086:     if (debug)
2087:     return;
2088: 
2089:     (void) signal (SIGHUP, hstat);
2090:     (void) signal (SIGINT, istat);
2091:     (void) signal (SIGQUIT, qstat);
2092:     (void) signal (SIGTERM, tstat);
2093: }
2094: 
2095: /*    FCC INTERACTION */
2096: 
2097: static  refile (file)
2098: register char   *file;
2099: {
2100:     register int     i;
2101: 
2102:     if (fccind == 0)
2103:     return;
2104: 
2105: #ifdef  MHMTS
2106:     (void) setuid (myuid);
2107: #endif	MHMTS
2108:     if (verbose)
2109:     printf (" -- Filing Folder Copies --\n");
2110:     for (i = 0; i < fccind; i++)
2111:     fcc (file, fccfold[i]);
2112:     if (verbose)
2113:     printf (" -- Folder Copies Filed --\n");
2114: }
2115: 
2116: 
2117: static fcc (file, folder)
2118: register char   *file,
2119:         *folder;
2120: {
2121:     int     i,
2122:             child_id,
2123:         status;
2124:     char    fold[BUFSIZ];
2125: 
2126:     if (verbose)
2127:     printf ("  %sFcc %s: ", msgstate == RESENT ? "Resent-" : "", folder);
2128:     (void) fflush (stdout);
2129: 
2130:     for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
2131:     sleep (5);
2132:     switch (child_id) {
2133:     case NOTOK:
2134:         if (!verbose)
2135:         fprintf (stderr, "  %sFcc %s: ",
2136:             msgstate == RESENT ? "Resent-" : "", folder);
2137:         fprintf (verbose ? stdout : stderr, "no forks, so not ok\n");
2138:         break;
2139: 
2140:     case OK:
2141:         (void) sprintf (fold, "%s%s",
2142:             *folder == '+' || *folder == '@' ? "" : "+", folder);
2143:         execlp (fileproc, r1bindex (fileproc, '/'),
2144:             "-link", "-file", file, fold, NULLCP);
2145:         _exit (-1);
2146: 
2147:     default:
2148:         if (status = pidwait (child_id, OK)) {
2149:         if (!verbose)
2150:             fprintf (stderr, "  %sFcc %s: ",
2151:                 msgstate == RESENT ? "Resent-" : "", folder);
2152:         (void) pidstatus (status, verbose ? stdout : stderr, NULLCP);
2153:         }
2154:         else
2155:         if (verbose)
2156:             printf ("folder ok\n");
2157:     }
2158: 
2159:     (void) fflush (stdout);
2160: }
2161: 
2162: /*    TERMINATION */
2163: 
2164: /* VARARGS2 */
2165: 
2166: static die (what, fmt, a, b, c, d)
2167: char   *what,
2168:        *fmt,
2169:        *a,
2170:        *b,
2171:        *c,
2172:        *d;
2173: {
2174: #ifndef MHMTS
2175:     (void) unlink (tmpfil);
2176:     if (msgflags & MINV)
2177:     (void) unlink (bccfil);
2178: #endif	MHMTS
2179: #ifdef  MMDFMTS
2180:     if (!whomsw || checksw)
2181:     (void) mm_end (NOTOK);
2182: #endif	MMDFMTS
2183: #ifdef  SENDMTS
2184:     if (!whomsw || checksw)
2185:     (void) sm_end (NOTOK);
2186: #endif	SENDMTS
2187: 
2188:     adios (what, fmt, a, b, c, d);
2189: }
2190: 
2191: 
2192: #ifdef  MMDFMTS
2193: /*
2194:  *    err_abrt() is used by the mm_ routines
2195:  *    		 do not, under *ANY* circumstances, remove it from post,
2196:  *		 or you will lose *BIG*
2197:  */
2198: 
2199: err_abrt (code, fmt, a, b, c)
2200: int     code;
2201: char   *fmt,
2202:        *a,
2203:        *b,
2204:        *c;
2205: {
2206:     char    buffer[BUFSIZ];
2207: 
2208:     (void) sprintf (buffer, "[%s]", rp_valstr (code));
2209: 
2210:     adios (buffer, fmt, a, b, c);
2211: }
2212: #endif	MMDFMTS
2213: 
2214: /*    STAND-ALONE DELIVERY */
2215: 
2216: #ifdef  MHMTS
2217: 
2218: /* BUG: MHMTS ignores 822-style route addresses... */
2219: 
2220: static  localmail (lp, talk, fd)
2221: register struct mailname *lp;
2222: int     talk,
2223:         fd;
2224: {
2225:     int     md;
2226:     char    mailbox[BUFSIZ],
2227:         ddate[BUFSIZ];
2228:     register struct home *hp;
2229: 
2230:     if (talk)
2231:     printf ("  %s: ", lp -> m_mbox);
2232:     (void) fflush (stdout);
2233: 
2234:     if ((hp = seek_home (lp -> m_mbox)) == NULL) {
2235:     if (!talk)
2236:         fprintf (stderr, "  %s: ", lp -> m_mbox);
2237:     fprintf (talk ? stdout : stderr,
2238:         "not deliverable; unknown address\n");
2239:     unkadr++;
2240:     return;
2241:     }
2242: 
2243:     (void) sprintf (mailbox, "%s/%s",
2244:         mmdfldir[0] ? mmdfldir : hp -> h_home,
2245:         mmdflfil[0] ? mmdflfil : hp -> h_name);
2246: 
2247: /*  */
2248: 
2249:     switch (access (slocalproc, 01)) {
2250:     default:
2251:         if (talk)
2252:         printf ("(invoking hook)\n\t");
2253:         (void) fflush (stdout);
2254: 
2255:         if (usr_hook (lp, talk, fd, hp, mailbox) != NOTOK)
2256:         return;
2257:         if (talk)
2258:         printf ("  %s: ", lp -> m_mbox);
2259:         (void) fflush (stdout);
2260: 
2261:     case NOTOK:
2262:         (void) lseek (fd, 0L, 0);
2263:         if ((md = mbx_open (mailbox, hp -> h_uid, hp -> h_gid, m_gmprot ()))
2264:             == NOTOK) {
2265:         if (!talk)
2266:             fprintf (stderr, "  %s: ", lp -> m_mbox);
2267:         fprintf (talk ? stdout : stderr,
2268:             "error in transmission; unable to open maildrop\n");
2269:         unkadr++;
2270:         return;
2271:         }
2272:         (void) sprintf (ddate, "Delivery-Date: %s\n", dtimenow ());
2273:         if (mbx_copy (mailbox, md, fd, 0, ddate, 0) == NOTOK) {
2274:         if (!talk)
2275:             fprintf (stderr, "  %s: ", lp -> m_mbox);
2276:         fprintf (talk ? stdout : stderr,
2277:             "error in transmission; write to maildrop failed\n");
2278:         unkadr++;
2279:         (void) close (md);
2280:         return;
2281:         }
2282:         mbx_close (mailbox, md);
2283: 
2284:         if (talk)
2285:         printf ("sent\n");
2286:         break;
2287:     }
2288: 
2289:     (void) fflush (stdout);
2290: }
2291: 
2292: /*  */
2293: 
2294: static int  usr_hook (lp, talk, fd, hp, mailbox)
2295: register struct mailname *lp;
2296: int     talk,
2297:         fd;
2298: register struct home *hp;
2299: register char   *mailbox;
2300: {
2301:     int     i,
2302:             child_id,
2303:             status;
2304:     char    tmpfil[BUFSIZ];
2305: 
2306:     if ((fd = copyfile (fd, tmpfil)) == NOTOK) {
2307:     if (!talk)
2308:         fprintf (stderr, "  %s: ", lp -> m_mbox);
2309:     fprintf (talk ? stdout : stderr,
2310:         "unable to copy message; skipping hook\n");
2311:     return NOTOK;
2312:     }
2313:     (void) chown (tmpfil, hp -> h_uid, hp -> h_gid);
2314: 
2315:     (void) fflush (stdout);
2316: 
2317:     for (i = 0; (child_id = fork ()) == NOTOK && i < 5; i++)
2318:     sleep (5);
2319:     switch (child_id) {
2320:     case NOTOK:
2321:         if (!talk)
2322:         fprintf (stderr, "  %s: ", lp -> m_mbox);
2323:         fprintf (talk ? stdout : stderr,
2324:             "unable to invoke hook; fork() failed\n");
2325:         return NOTOK;
2326: 
2327:     case OK:
2328:         if (fd != 0)
2329:         (void) dup2 (fd, 0);
2330:         (void) freopen ("/dev/null", "w", stdout);
2331:         (void) freopen ("/dev/null", "w", stderr);
2332:         if (fd != 3)    /* backwards compatible... */
2333:         (void) dup2 (fd, 3);
2334:         closefds (4);
2335: #ifdef  TIOCNOTTY
2336:         if ((fd = open ("/dev/tty", 2)) != NOTOK) {
2337:         (void) ioctl (fd, TIOCNOTTY, NULLCP);
2338:         (void) close (fd);
2339:         }
2340: #endif	TIOCNOTTY
2341: #ifdef  BSD42
2342:         (void) setpgrp (0, getpid ());
2343: #endif	BSD42
2344: 
2345:         *environ = NULL;
2346:         (void) putenv ("USER", hp -> h_name);
2347:         (void) putenv ("HOME", hp -> h_home);
2348:         (void) putenv ("SHELL", hp -> h_shell);
2349:         if (chdir (hp -> h_home) == NOTOK)
2350:         (void) chdir ("/");
2351:         (void) umask (0077);
2352: #ifdef  BSD41A
2353:         (void) inigrp (hp -> h_name, hp -> h_gid);
2354: #endif	BSD41A
2355:         (void) setgid (hp -> h_gid);
2356: #ifdef  BSD42
2357:         (void) initgroups (hp -> h_name, hp -> h_gid);
2358: #endif	BSD42
2359:         (void) setuid (hp -> h_uid);
2360: 
2361:         execlp (slocalproc, r1bindex (slocalproc, '/'),
2362:             "-file", tmpfil, "-mailbox", mailbox,
2363:             "-home", hp -> h_home, "-addr", lp -> m_aka,
2364:             "-user", hp -> h_name, "-sender", from,
2365:             talk ? "-verbose" : NULLCP, NULLCP);
2366:         _exit (-1);
2367: 
2368: /*  */
2369: 
2370:     default:
2371:         (void) close (fd);
2372: 
2373:         status = pidwait (child_id, OK);
2374: 
2375:         (void) unlink (tmpfil);
2376:         if (status == 0) {
2377:         if (talk)
2378:             printf ("accepted\n");
2379:         return OK;
2380:         }
2381:         if (!talk)
2382:         fprintf (stderr, "  %s: ", lp -> m_mbox);
2383:         fprintf (talk ? stdout : stderr,
2384:             "%s error on hook; status=0%o\n",
2385:             status & 0x00ff ? "system" : "user",
2386:             status & 0x00ff ? status & 0xff
2387:             : (status & 0xff00) >> 8);
2388:         return NOTOK;
2389:     }
2390: }
2391: 
2392: /*  */
2393: 
2394: static int  copyfile (qd, tmpfil)
2395: int     qd;
2396: register char   *tmpfil;
2397: {
2398:     int     i,
2399:             fd;
2400:     char    buffer[BUFSIZ];
2401: 
2402:     (void) strcpy (tmpfil, m_tmpfil ("hook"));
2403:     if ((fd = creat (tmpfil, 0600)) == NOTOK)
2404:     return NOTOK;
2405:     (void) close (fd);
2406:     if ((fd = open (tmpfil, 2)) == NOTOK)
2407:     return NOTOK;
2408: 
2409:     (void) lseek (qd, 0L, 0);
2410:     while ((i = read (qd, buffer, sizeof buffer)) > 0)
2411:     if (write (fd, buffer, i) != i) {
2412:         (void) close (fd);
2413:         return NOTOK;
2414:     }
2415:     if (i == NOTOK) {
2416:     (void) close (fd);
2417:     return NOTOK;
2418:     }
2419: 
2420:     (void) lseek (fd, 0L, 0);
2421: 
2422:     return fd;
2423: }
2424: 
2425: /*  */
2426: 
2427: static  uucpmail (lp, talk, fd, from)
2428: register struct mailname *lp;
2429: int     talk,
2430:         fd,
2431:     from;
2432: {
2433:     int     i;
2434:     int     (*pstat) ();
2435:     char    addr[BUFSIZ],
2436:             buffer[BUFSIZ];
2437:     register FILE *fp;
2438: 
2439:     (void) sprintf (addr, "%s!%s", lp -> m_host, lp -> m_mbox);
2440:     if (talk)
2441:     printf ("  %s: ", addr);
2442:     (void) fflush (stdout);
2443: 
2444: #ifndef UCI
2445:     (void) sprintf (buffer, "uux -r -p %s!rmail \\(%s\\)",
2446:         lp -> m_host, lp -> m_mbox);
2447: #else   UCI
2448:     (void) sprintf (buffer, "uux -p %s!rmail \\(%s\\)", lp -> m_host,
2449:         lp -> m_mbox);
2450: #endif	UCI
2451:     if ((fp = popen (buffer, "w")) == NULL) {
2452:     if (!talk)
2453:         fprintf (stderr, "  %s: ", addr);
2454:     fprintf (talk ? stdout : stderr,
2455:         "unable to start uux; popen() failed\n");
2456:     unkadr++;
2457:     return;
2458:     }
2459: 
2460:     pstat = signal (SIGPIPE, SIG_IGN);
2461:     if (from) {         /* no mail filtering, so... */
2462:     (void) sprintf (buffer, "From %s %.24s remote from %s\n",
2463:         getusr (), ctime (&clock), SystemName ());
2464:     i = strlen (buffer);
2465:     if (fwrite (buffer, sizeof *buffer, i, fp) != i)
2466:         goto oops;
2467:     }
2468: 
2469:     (void) lseek (fd, 0L, 0);
2470:     while ((i = read (fd, buffer, sizeof buffer)) > 0)
2471:     if (fwrite (buffer, sizeof *buffer, i, fp) != i) {
2472:     oops:   ;
2473:         if (!talk)
2474:         fprintf (stderr, "  %s: ", addr);
2475:         fprintf (talk ? stdout : stderr,
2476:             "error in transmission; write to uux failed\n");
2477:         unkadr++;
2478:         (void) pclose (fp);
2479:         return;
2480:     }
2481:     if (pclose (fp))
2482:     goto oops;
2483:     (void) signal (SIGPIPE, pstat);
2484: 
2485:     if (i < 0) {
2486:     if (!talk)
2487:         fprintf (stderr, "  %s: ", addr);
2488:     fprintf (talk ? stdout : stderr,
2489:         "error in transmission; read failed\n");
2490:     unkadr++;
2491:     return;
2492:     }
2493: 
2494:     if (talk)
2495:     printf ("queued (via uux)\n");
2496:     (void) fflush (stdout);
2497: }
2498: 
2499: /*  */
2500: 
2501: #ifdef  MF
2502: static int  make_uucp_file (td)
2503: int     td;
2504: {
2505:     int     i,
2506:             qd,
2507:             fd;
2508:     char    tmpfil[BUFSIZ];
2509: 
2510:     (void) lseek (td, 0L, 0);
2511:     if ((qd = dup (td)) == NOTOK)
2512:     adios ("fd", "unable to dup");
2513: 
2514:     (void) strcpy (tmpfil, m_tmpfil ("uumf"));
2515:     if ((fd = creat (tmpfil, 0600)) == NOTOK)
2516:     adios (tmpfil, "unable to create");
2517:     (void) close (fd);
2518:     if ((fd = open (tmpfil, 2)) == NOTOK)
2519:     adios (tmpfil, "unable to re-open");
2520: 
2521:     switch (i = mmdf2uucp (qd, fd, 1)) {
2522:     case OK:
2523:         if (!debug)
2524:         (void) unlink (tmpfil);
2525:         break;
2526: 
2527:     default:
2528:         adios (NULLCP, "unable to filter mail(%d), examine %s", i, tmpfil);
2529:     }
2530:     (void) close (qd);
2531: 
2532:     return fd;
2533: }
2534: #endif	MF
2535: 
2536: /*  */
2537: 
2538: static  netmail (talk, fd, bccque)
2539: int     talk,
2540:         fd,
2541:         bccque;
2542: {
2543:     int     i,
2544:             naddrs;
2545:     char    buffer[BUFSIZ];
2546:     register struct mailname *lp;
2547: 
2548:     naddrs = 0;
2549:     if (nm_init (getusr (), &clock) == NOTOK) {
2550:     for (lp = netaddrs.m_next; lp; lp = lp -> m_next)
2551:         if (lp -> m_bcc ? bccque : !bccque)
2552:         fprintf (stderr, "  %s at %s: unable to get queue file\n",
2553:             lp -> m_mbox, lp -> m_host);
2554:     return;
2555:     }
2556: 
2557:     for (lp = netaddrs.m_next; lp; lp = lp -> m_next)
2558:     if (lp -> m_bcc ? bccque : !bccque) {
2559:         (void) nm_wadr (lp -> m_mbox, lp -> m_host);
2560:         naddrs++;
2561:         if (talk)
2562:         printf ("  %s at %s: queued\n", lp -> m_mbox, lp -> m_host);
2563:         (void) fflush (stdout);
2564:     }
2565:     nm_waend ();
2566: 
2567:     (void) lseek (fd, 0L, 0);
2568:     while ((i = read (fd, buffer, sizeof buffer)) > 0)
2569:     if (nm_wtxt (buffer, i) == NOTOK) {
2570:         fprintf (stderr,
2571:             "error in transmission; write to temporary failed");
2572:         unkadr += naddrs;
2573:         return;
2574:     }
2575: 
2576:     if (i < 0) {
2577:     fprintf (stderr, "error in transmission; read failed\n");
2578:     unkadr += naddrs;
2579:     return;
2580:     }
2581: 
2582:     if (nm_wtend () == NOTOK) {
2583:     fprintf (stderr, "error in transmission; unable to queue message\n");
2584:     unkadr += naddrs;
2585:     return;
2586:     }
2587: }
2588: #endif	MHMTS

Defined functions

anno defined in line 1071; used 1 times
annoaux defined in line 1092; used 3 times
chkadr defined in line 1277; used 3 times
copyfile defined in line 2394; used 1 times
die defined in line 2166; used 33 times
do_a_cipher defined in line 1459; used 3 times
do_addresses defined in line 1556; used 2 times
do_an_address defined in line 1957; used 7 times
do_text defined in line 1647; used 2 times
err_abrt defined in line 2199; never used
fcc defined in line 2117; used 1 times
finish_headers defined in line 859; used 3 times
get_header defined in line 916; used 1 times
insert defined in line 1016; used 1 times
insert_fcc defined in line 1106; used 2 times
localmail defined in line 2220; used 1 times
main defined in line 295; never used
make_bcc_file defined in line 1128; used 1 times
make_uucp_file defined in line 2502; used 1 times
netmail defined in line 2538; used 1 times
pl defined in line 1040; used 1 times
post defined in line 1292; never used
postcipher defined in line 1382; used 1 times
postplain defined in line 1292; used 1 times
putadr defined in line 931; used 2 times
putfmt defined in line 669; used 3 times
putgrp defined in line 980; used 2 times
refile defined in line 2097; used 1 times
sigoff defined in line 2085; used 3 times
sigon defined in line 2067; used 3 times
sigser defined in line 2045; used 5 times
start_headers defined in line 818; used 1 times
usr_hook defined in line 2294; used 1 times
uucpmail defined in line 2427; used 1 times
verify_all_addresses defined in line 1193; used 4 times

Defined variables

NHeaders defined in line 160; used 1 times
RHeaders defined in line 177; used 1 times
badadr defined in line 215; used 9 times
badmsg defined in line 216; used 8 times
bccfil defined in line 238; used 9 times
checksw defined in line 223; used 15 times
clientsw defined in line 275; used 5 times
clock defined in line 233; used 9 times
debug defined in line 220; used 6 times
deliver defined in line 265; used 8 times
encryptsw defined in line 286; used 10 times
fccfold defined in line 244; used 3 times
fccind defined in line 207; used 6 times
filter defined in line 242; used 5 times
format defined in line 218; used 3 times
from defined in line 240; used 15 times
hdrtab defined in line 246; used 3 times
linepos defined in line 224; used 14 times
localaddrs defined in line 248; used 7 times
msgflags defined in line 227; used 19 times
msgid defined in line 219; used 5 times
msgstate defined in line 231; used 7 times
mygid defined in line 212; used 3 times
myuid defined in line 211; used 5 times
nameoutput defined in line 225; used 10 times
netaddrs defined in line 249; used 9 times
outputlinelen defined in line 208; used 6 times
pfd defined in line 210; used 5 times
recipients defined in line 213; used 2 times
serversw defined in line 276; used 5 times
signature defined in line 241; used 7 times
smtpmode defined in line 273; used 7 times
snoop defined in line 274; used 4 times
subject defined in line 243; used 5 times
submitmode defined in line 256; used 4 times
submitopts defined in line 260; used 5 times
switches defined in line 40; used 3 times
tmpaddrs defined in line 251; used 4 times
tmpfil defined in line 237; used 34 times
unkadr defined in line 214; used 22 times
uuaddrs defined in line 250; used 8 times
verbose defined in line 217; used 24 times
watch defined in line 221; used 5 times
whomsw defined in line 222; used 24 times

Defined struct's

headers defined in line 134; used 14 times

Defined macros

ALIASW defined in line 41; never used
ANNOSW defined in line 116; never used
CHKSW defined in line 44; never used
CLIESW defined in line 122; never used
DEBUGSW defined in line 49; never used
DISTSW defined in line 52; never used
DLVRSW defined in line 119; never used
ENCRSW defined in line 55; never used
FCCS defined in line 36; used 2 times
FILTSW defined in line 70; never used
FRMTSW defined in line 75; never used
HADR defined in line 140; used 20 times
HBAD defined in line 139; used 9 times
HBCC defined in line 143; used 7 times
HELPSW defined in line 104; never used
HFCC defined in line 146; used 3 times
HIGN defined in line 148; used 2 times
HMNG defined in line 144; used 2 times
HNGR defined in line 145; used 8 times
HNIL defined in line 147; used 5 times
HNOP defined in line 138; used 1 times
HSUB defined in line 141; used 3 times
HTRY defined in line 142; used 10 times
LIBSW defined in line 80; never used
MAILSW defined in line 107; never used
MDAT defined in line 152; used 2 times
MFRM defined in line 151; used 4 times
MINV defined in line 155; used 14 times
MRFM defined in line 153; used 2 times
MSGDSW defined in line 83; never used
MVIS defined in line 154; used 10 times
NCHKSW defined in line 46; never used
NENCRSW defined in line 62; never used
NFILTSW defined in line 72; never used
NFRMTSW defined in line 77; never used
NMSGDSW defined in line 85; never used
NORMAL defined in line 229; used 3 times
NVERBSW defined in line 90; never used
NWATCSW defined in line 95; never used
RESENT defined in line 230; used 4 times
SAMLSW defined in line 109; never used
SENDSW defined in line 111; never used
SERVSW defined in line 124; never used
SNOOPSW defined in line 126; never used
SOMLSW defined in line 113; never used
VERBSW defined in line 88; never used
WATCSW defined in line 93; never used
WHOMSW defined in line 98; never used
WIDTHSW defined in line 101; never used
plural defined in line 1278; used 4 times
post defined in line 282; used 3 times
uptolow defined in line 33; used 1 times
Last modified: 1986-04-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 8224
Valid CSS Valid XHTML 1.0 Strict