1: #ifndef lint
   2: static char sccsid[] = "@(#)spost.c	1.6 (Berkeley) 11/2/85";
   3: #endif
   4: 
   5: /* spost.c - feed messages to sendmail */
   6: /*
   7:  * (This is a simpler, faster, replacement for "post" for use when "sendmail"
   8:  * is the transport system)
   9:  */
  10: 
  11: #include <ctype.h>
  12: #include <stdio.h>
  13: #include <signal.h>
  14: #include "../h/mh.h"
  15: #include "../h/addrsbr.h"
  16: #include "../h/aliasbr.h"
  17: #include "../h/dropsbr.h"
  18: #include "../zotnet/tws.h"
  19: 
  20: extern char *getfullname (), *getusr ();
  21: 
  22: 
  23: #define uptolow(c)  (isupper (c) ? tolower (c) : c)
  24: 
  25: #define SENDMAIL    "/usr/lib/sendmail"
  26: #define FCCS        10  /* max number of fccs allowed */
  27: 
  28: /*  */
  29: 
  30: struct swit switches[] = {
  31: #define FILTSW  0
  32:     "filter filterfile", 0,
  33: #define NFILTSW 1
  34:     "nofilter", 0,
  35: 
  36: #define FRMTSW  2
  37:     "format", 0,
  38: #define NFRMTSW 3
  39:     "noformat", 0,
  40: 
  41: #define REMVSW  4
  42:     "remove", 0,
  43: #define NREMVSW 5
  44:     "noremove", 0,
  45: 
  46: #define VERBSW  6
  47:     "verbose", 0,
  48: #define NVERBSW 7
  49:     "noverbose", 0,
  50: 
  51: #define WATCSW  8
  52:     "watch", 0,
  53: #define NWATCSW 9
  54:     "nowatch", 0,
  55: 
  56: #define HELPSW  10
  57:     "help", 4,
  58: 
  59: #define DEBUGSW 11
  60:     "debug", -5,
  61: 
  62: #define DISTSW  12
  63:     "dist", -4,         /* interface from dist */
  64: 
  65: #define BACKSW 13
  66:     "backup", 0,
  67: #define NBACKSW 14
  68:     "nobackup", 0,
  69: 
  70: #define CHKSW 15
  71:     "check", -5,        /* interface from whom */
  72: #define NCHKSW 16
  73:     "nocheck", -7,      /* interface from whom */
  74: #define WHOMSW 17
  75:     "whom", -4,         /* interface from whom */
  76: 
  77: #define PUSHSW 18       /* fork to sendmail then exit */
  78:     "push", -4,
  79: #define NPUSHSW 19      /* exec sendmail */
  80:     "nopush", -6,
  81: 
  82: #define ALIASW 20
  83:     "alias aliasfile", 0,
  84: #define NALIASW 21
  85:     "noalias", 0,
  86: 
  87: #define WIDTHSW 22
  88:     "width columns", 0,
  89: 
  90: #define LIBSW 23
  91:     "library directory", -7,
  92: 
  93: #define ANNOSW  24
  94:     "idanno number", -6,
  95: 
  96:     NULL, NULL
  97: };
  98: 
  99: /*  */
 100: 
 101: struct headers {
 102:     char   *value;
 103: 
 104:     unsigned int    flags;
 105: #define HNOP    0x0000      /* just used to keep .set around */
 106: #define HBAD    0x0001      /* bad header - don't let it through */
 107: #define HADR    0x0002      /* header has an address field */
 108: #define HSUB    0x0004      /* Subject: header */
 109: #define HTRY    0x0008      /* try to send to addrs on header */
 110: #define HBCC    0x0010      /* don't output this header */
 111: #define HMNG    0x0020      /* mung this header */
 112: #define HNGR    0x0040      /* no groups allowed in this header */
 113: #define HFCC    0x0080      /* FCC: type header */
 114: #define HNIL    0x0100      /* okay for this header not to have addrs */
 115: #define HIGN    0x0200      /* ignore this header */
 116: 
 117:     unsigned int    set;
 118: #define MFRM    0x0001      /* we've seen a From: */
 119: #define MDAT    0x0002      /* we've seen a Date: */
 120: #define MRFM    0x0004      /* we've seen a Resent-From: */
 121: #define MVIS    0x0008      /* we've seen sighted addrs */
 122: #define MINV    0x0010      /* we've seen blind addrs */
 123: #define MRDT    0x0020      /* we've seen a Resent-Date: */
 124: };
 125: 
 126: /*  */
 127: 
 128: static struct headers  NHeaders[] = {
 129:     "Return-Path", HBAD, NULL,
 130:     "Received", HBAD, NULL,
 131:     "Reply-To", HADR | HNGR, NULL,
 132:     "From", HADR | HNGR, MFRM,
 133:     "Sender", HADR | HBAD, NULL,
 134:     "Date", HNOP, MDAT,
 135:     "Subject", HSUB, NULL,
 136:     "To", HADR | HTRY, MVIS,
 137:     "cc", HADR | HTRY, MVIS,
 138:     "Bcc", HADR | HTRY | HBCC | HNIL, MINV,
 139:     "Message-Id", HBAD, NULL,
 140:     "Fcc", HFCC, NULL,
 141: 
 142:     NULL
 143: };
 144: 
 145: static struct headers  RHeaders[] = {
 146:     "Resent-Reply-To", HADR | HNGR, NULL,
 147:     "Resent-From", HADR | HNGR, MRFM,
 148:     "Resent-Sender", HADR | HBAD, NULL,
 149:     "Resent-Date", HNOP, MRDT,
 150:     "Resent-Subject", HSUB, NULL,
 151:     "Resent-To", HADR | HTRY, MVIS,
 152:     "Resent-cc", HADR | HTRY, MVIS,
 153:     "Resent-Bcc", HADR | HTRY | HBCC, MINV,
 154:     "Resent-Message-Id", HBAD, NULL,
 155:     "Resent-Fcc", HFCC, NULL,
 156:     "Reply-To", HADR, NULL,
 157:     "Fcc", HIGN, NULL,
 158: 
 159:     NULL
 160: };
 161: 
 162: /*  */
 163: 
 164: 
 165: static short    fccind = 0; /* index into fccfold[] */
 166: 
 167: static int  badmsg = 0;     /* message has bad semantics */
 168: static int  verbose = 0;    /* spell it out */
 169: static int  debug = 0;      /* debugging post */
 170: static int  rmflg = 1;      /* remove temporary file when done */
 171: static int  watch = 0;      /* watch the delivery process */
 172: static int  backflg = 0;    /* rename input file as *.bak when done */
 173: static int  whomflg = 0;    /* if just checking addresses */
 174: static int  pushflg = 0;    /* if going to fork to sendmail */
 175: static int  aliasflg = -1;  /* if going to process aliases */
 176: static int  outputlinelen=72;
 177: 
 178: static unsigned msgflags = 0;   /* what we've seen */
 179: 
 180: static enum {
 181:     normal, resent
 182: } msgstate = normal;
 183: 
 184: static char tmpfil[] = "/tmp/pstXXXXXX";
 185: 
 186: static char from[BUFSIZ];   /* my network address */
 187: static char signature[BUFSIZ];  /* my signature */
 188: static char *filter = NULL; /* the filter for BCC'ing */
 189: static char *subject = NULL;    /* the subject field for BCC'ing */
 190: static char *fccfold[FCCS]; /* foldernames for FCC'ing */
 191: 
 192: static struct headers  *hdrtab; /* table for the message we're doing */
 193: static FILE *out;       /* output (temp) file */
 194: 
 195: /*    MAIN */
 196: 
 197: /* ARGSUSED */
 198: 
 199: main (argc, argv)
 200: int     argc;
 201: char   *argv[];
 202: {
 203:     int     state,
 204:         i,
 205:         pid,
 206:             compnum;
 207:     char   *cp,
 208:            *msg = NULL,
 209:           **argp = argv + 1,
 210:         *sargv[16],
 211:             buf[BUFSIZ],
 212:             name[NAMESZ],
 213:         *arguments[MAXARGS];
 214:     FILE * in;
 215: 
 216:     invo_name = r1bindex (argv[0], '/');
 217:     mts_init (invo_name);
 218:     if ((cp = m_find (invo_name)) != NULL) {
 219:     argp = copyip (brkstring (cp, " ", "\n"), arguments);
 220:     (void) copyip (argv+1, argp);
 221:     argp = arguments;
 222:     }
 223: 
 224: /*  */
 225: 
 226:     while (cp = *argp++) {
 227:     if (*cp == '-')
 228:         switch (smatch (++cp, switches)) {
 229:         case AMBIGSW:
 230:             ambigsw (cp, switches);
 231:             done (1);
 232:         case UNKWNSW:
 233:             adios (NULLCP, "-%s unknown", cp);
 234:         case HELPSW:
 235:             (void)sprintf (buf, "%s [switches] file", invo_name);
 236:             help (buf, switches);
 237:             done (1);
 238: 
 239:         case DEBUGSW:
 240:             debug++;
 241:             continue;
 242: 
 243:         case DISTSW:
 244:             msgstate = resent;
 245:             continue;
 246: 
 247:         case WHOMSW:
 248:             whomflg++;
 249:             continue;
 250: 
 251:         case FILTSW:
 252:             if (!(filter = *argp++) || *filter == '-')
 253:             adios (NULLCP, "missing argument to %s", argp[-2]);
 254:             continue;
 255:         case NFILTSW:
 256:             filter = NULL;
 257:             continue;
 258: 
 259:         case REMVSW:
 260:             rmflg++;
 261:             continue;
 262:         case NREMVSW:
 263:             rmflg = 0;
 264:             continue;
 265: 
 266:         case BACKSW:
 267:             backflg++;
 268:             continue;
 269:         case NBACKSW:
 270:             backflg = 0;
 271:             continue;
 272: 
 273:         case VERBSW:
 274:             verbose++;
 275:             continue;
 276:         case NVERBSW:
 277:             verbose = 0;
 278:             continue;
 279: 
 280:         case WATCSW:
 281:             watch++;
 282:             continue;
 283:         case NWATCSW:
 284:             watch = 0;
 285:             continue;
 286: 
 287:         case PUSHSW:
 288:             pushflg++;
 289:             continue;
 290:         case NPUSHSW:
 291:             pushflg = 0;
 292:             continue;
 293: 
 294:         case ALIASW:
 295:             if (!(cp = *argp++) || *cp == '-')
 296:             adios (NULLCP, "missing argument to %s", argp[-2]);
 297:             if (aliasflg < 0)
 298:             (void)alias (AliasFile);/* load default aka's */
 299:             aliasflg = 1;
 300:             if ((state = alias(cp)) != AK_OK)
 301:             adios (NULLCP, "aliasing error in file %s - %s",
 302:                    cp, akerror(state) );
 303:             continue;
 304:         case NALIASW:
 305:             aliasflg = 0;
 306:             continue;
 307: 
 308:         case WIDTHSW:
 309:             if (!(cp = *argp++) || *cp == '-')
 310:             adios (NULLCP, "missing argument to %s", argp[-2]);
 311:             outputlinelen = atoi (cp);
 312:             if (outputlinelen <= 10)
 313:             outputlinelen = 72;
 314:             continue;
 315: 
 316:         case LIBSW:
 317:         case ANNOSW:
 318:             /* -library & -idanno switch ignored */
 319:             if (!(cp = *argp++) || *cp == '-')
 320:             adios (NULLCP, "missing argument to %s", argp[-2]);
 321:             continue;
 322:         }
 323:     if (msg)
 324:         adios (NULLCP, "only one message at a time!");
 325:     else
 326:         msg = cp;
 327:     }
 328: 
 329: /*  */
 330: 
 331:     if (aliasflg < 0)
 332:     alias (AliasFile);  /* load default aka's */
 333: 
 334:     if (!msg)
 335:     adios (NULLCP, "usage: %s [switches] file", invo_name);
 336: 
 337:     if ((in = fopen (msg, "r")) == NULL)
 338:     adios (msg, "unable to open");
 339: 
 340:     start_headers ();
 341:     if (debug) {
 342:     verbose++;
 343:     out = stdout;
 344:     }
 345:     else {
 346:         (void)mktemp (tmpfil);
 347:         if ((out = fopen (tmpfil, "w")) == NULL)
 348:         adios (tmpfil, "unable to create");
 349:         (void)chmod (tmpfil, 0600);
 350:     }
 351: 
 352:     hdrtab = (msgstate == normal) ? NHeaders : RHeaders;
 353: 
 354:     for (compnum = 1, state = FLD;;) {
 355:     switch (state = m_getfld (state, name, buf, sizeof buf, in)) {
 356:         case FLD:
 357:         compnum++;
 358:         putfmt (name, buf, out);
 359:         continue;
 360: 
 361:         case FLDPLUS:
 362:         compnum++;
 363:         cp = add (buf, cp);
 364:         while (state == FLDPLUS) {
 365:             state = m_getfld (state, name, buf, sizeof buf, in);
 366:             cp = add (buf, cp);
 367:         }
 368:         putfmt (name, cp, out);
 369:         free (cp);
 370:         continue;
 371: 
 372:         case BODY:
 373:         finish_headers (out);
 374:         fprintf (out, "\n%s", buf);
 375:         if(whomflg == 0)
 376:             while (state == BODY) {
 377:             state = m_getfld (state, name, buf, sizeof buf, in);
 378:             fputs (buf, out);
 379:             }
 380:         break;
 381: 
 382:         case FILEEOF:
 383:         finish_headers (out);
 384:         break;
 385: 
 386:         case LENERR:
 387:         case FMTERR:
 388:         adios (NULLCP, "message format error in component #%d",
 389:             compnum);
 390: 
 391:         default:
 392:         adios (NULLCP, "getfld() returned %d", state);
 393:     }
 394:     break;
 395:     }
 396: 
 397: /*  */
 398: 
 399:     (void)fclose (in);
 400:     if (backflg && !whomflg) {
 401:     (void) strcpy (buf, m_backup (msg));
 402:     if (rename (msg, buf) == NOTOK)
 403:         advise (buf, "unable to rename %s to", msg);
 404:     }
 405: 
 406:     if (debug) {
 407:     done (0);
 408:     }
 409:     else
 410:     (void)fclose (out);
 411: 
 412:     file (tmpfil);
 413: 
 414:     /*
 415:      * re-open the temp file, unlink it and exec sendmail, giving it
 416:      * the msg temp file as std in.
 417:      */
 418:     if ( freopen( tmpfil, "r", stdin) == NULL)
 419:     adios (tmpfil, "can't reopen for sendmail");
 420:     if (rmflg)
 421:     (void)unlink (tmpfil);
 422: 
 423:     argp = sargv;
 424:     *argp++ = "send-mail";
 425:     *argp++ = "-m"; /* send to me too */
 426:     *argp++ = "-t"; /* read msg for recipients */
 427:     *argp++ = "-i"; /* don't stop on "." */
 428:     if (whomflg)
 429:     *argp++ = "-bv";
 430:     if (watch || verbose)
 431:     *argp++ = "-v";
 432:     *argp = NULL;
 433: 
 434:     if (pushflg && !(watch || verbose)) {
 435:     /* fork to a child to run sendmail */
 436:     for (i=0; (pid = vfork()) == NOTOK && i < 5; i++)
 437:         sleep(5);
 438:     switch (pid) {
 439:         case NOTOK:
 440:         fprintf (verbose ? stdout : stderr, "%s: can't fork to %s\n",
 441:              invo_name, SENDMAIL);
 442:         exit(-1);
 443:         case OK:
 444:         /* we're the child .. */
 445:         break;
 446:         default:
 447:         exit(0);
 448:     }
 449:     }
 450:     execv ( SENDMAIL, sargv);
 451:     adios ( SENDMAIL, "can't exec");
 452: }
 453: 
 454: /*    DRAFT GENERATION */
 455: 
 456: static putfmt (name, str, out)
 457: char   *name,
 458:        *str;
 459: FILE * out;
 460: {
 461:     int     count,
 462:             grp,
 463:             i,
 464:             keep;
 465:     char   *cp,
 466:            *pp,
 467:            *qp,
 468:             namep[BUFSIZ];
 469:     struct mailname *mp,
 470:                    *np;
 471:     struct headers *hdr;
 472: 
 473:     while (*str == ' ' || *str == '\t')
 474:     str++;
 475: 
 476:     if ((i = get_header (name, hdrtab)) == NOTOK) {
 477:     fprintf (out, "%s: %s", name, str);
 478:     return;
 479:     }
 480: 
 481:     hdr = &hdrtab[i];
 482:     if (hdr -> flags & HIGN)
 483:     return;
 484:     if (hdr -> flags & HBAD) {
 485:     advise (NULLCP, "illegal header line -- %s:", name);
 486:     badmsg++;
 487:     return;
 488:     }
 489:     msgflags |= hdr -> set;
 490: 
 491:     if (hdr -> flags & HSUB)
 492:     subject = subject ? add (str, add ("\t", subject)) : getcpy (str);
 493: 
 494:     if (hdr -> flags & HFCC) {
 495:     if (cp = rindex (str, '\n'))
 496:         *cp = NULL;
 497:     for (cp = pp = str; cp = index (pp, ','); pp = cp) {
 498:         *cp++ = NULL;
 499:         insert_fcc (hdr, pp);
 500:     }
 501:     insert_fcc (hdr, pp);
 502:     return;
 503:     }
 504: 
 505: #ifdef notdef
 506:     if (hdr -> flags & HBCC) {
 507:     insert_bcc(str);
 508:     return;
 509:     }
 510: #endif notdef
 511: 
 512:     if (*str != '\n' && *str != '\0')
 513:     if (aliasflg && hdr->flags & HTRY) {
 514:         /* this header contains address(es) that we have to do
 515: 	     * alias expansion on.  Because of the saved state in
 516: 	     * getname we have to put all the addresses into a list.
 517: 	     * We then let putadr munch on that list, possibly
 518: 	     * expanding aliases.
 519: 	     */
 520:         register struct mailname *f = 0;
 521:         register struct mailname *mp = 0;
 522: 
 523:         while (cp = getname( str ) ) {
 524:         mp = getm( cp, NULLCP, 0, AD_HOST, NULLCP);
 525:         if (f == 0) {
 526:             f = mp;
 527:             mp->m_next = mp;
 528:         } else {
 529:             mp->m_next = f->m_next;
 530:             f->m_next = mp;
 531:             f = mp;
 532:         }
 533:         }
 534:         f = mp->m_next; mp->m_next = 0;
 535:         putadr( name, f );
 536:     } else {
 537:         fprintf (out, "%s: %s", name, str );
 538:     }
 539: }
 540: 
 541: /*  */
 542: 
 543: static
 544: start_headers ()
 545: {
 546:     char   *cp;
 547:     char    sigbuf[BUFSIZ];
 548: 
 549:     (void)strcpy( from, getusr() );
 550: 
 551:     if ((cp = getfullname ()) && *cp) {
 552:     (void)strcpy (sigbuf, cp);
 553:     (void)sprintf (signature, "%s <%s>", sigbuf,  from);
 554:     }
 555:     else
 556:     (void)sprintf (signature, "%s",  from);
 557: }
 558: 
 559: /*  */
 560: 
 561: static
 562: finish_headers (out)
 563:     FILE * out;
 564: {
 565:     switch (msgstate) {
 566:     case normal:
 567:         if (!(msgflags & MDAT))
 568:         fprintf (out, "Date: %s\n", dtimenow ());
 569:         if (msgflags & MFRM)
 570:         fprintf (out, "Sender: %s\n", from);
 571:         else
 572:         fprintf (out, "From: %s\n", signature);
 573: #ifdef notdef
 574:         if (!(msgflags & MVIS))
 575:         fprintf (out, "Bcc: Blind Distribution List: ;\n");
 576: #endif notdef
 577:         break;
 578: 
 579:     case resent:
 580:         if (!(msgflags & MRDT))
 581:         fprintf (out, "Resent-Date: %s\n", dtimenow());
 582:         if (msgflags & MRFM)
 583:         fprintf (out, "Resent-Sender: %s\n", from);
 584:         else
 585:         fprintf (out, "Resent-From: %s\n", signature);
 586: #ifdef notdef
 587:         if (!(msgflags & MVIS))
 588:         fprintf (out, "Resent-Bcc: Blind Re-Distribution List: ;\n");
 589: #endif notdef
 590:         break;
 591:     }
 592: 
 593:     if (badmsg)
 594:     adios (NULLCP, "re-format message and try again");
 595: }
 596: 
 597: /*  */
 598: 
 599: static int
 600: get_header (header, table)
 601:     char   *header;
 602:     struct headers *table;
 603: {
 604:     struct headers *h;
 605: 
 606:     for (h = table; h -> value; h++)
 607:     if (uleq (header, h -> value))
 608:         return (h - table);
 609: 
 610:     return NOTOK;
 611: }
 612: 
 613: /*  */
 614: 
 615: /* output the address list for header "name".  The address list
 616:  * is a linked list of mailname structs.  "nl" points to the head
 617:  * of the list.  Alias substitution should be done on nl.
 618:  */
 619: static putadr (name, nl)
 620: char *name;
 621: struct mailname *nl;
 622: {
 623:     register struct mailname *mp, *mp2;
 624:     register int linepos;
 625:     register char *cp;
 626:     int namelen;
 627: 
 628:     fprintf (out, "%s: ", name);
 629:     namelen = strlen(name) + 2;
 630:     linepos = namelen;
 631: 
 632:     for (mp = nl; mp; ) {
 633:     if (mp->m_nohost) {
 634:         /* a local name - see if it's an alias */
 635:         cp = akvalue(mp->m_mbox);
 636:         if (cp == mp->m_mbox)
 637:         /* wasn't an alias - use what the user typed */
 638:         linepos = putone( mp->m_text, linepos, namelen );
 639:         else
 640:         /* an alias - expand it */
 641:         while (cp = getname(cp) ) {
 642:             mp2 = getm( cp, NULLCP, 0, AD_HOST, NULLCP);
 643:             if (akvisible()) {
 644:             mp2->m_pers = getcpy(mp->m_mbox);
 645:             linepos = putone( adrformat(mp2), linepos, namelen );
 646:             } else {
 647:             linepos = putone( mp2->m_text, linepos, namelen );
 648:             }
 649:             mnfree( mp2 );
 650:         }
 651:     } else {
 652:         /* not a local name - use what the user typed */
 653:         linepos = putone( mp->m_text, linepos, namelen );
 654:     }
 655:     mp2 = mp;
 656:     mp = mp->m_next;
 657:     mnfree( mp2 );
 658:     }
 659:     putc( '\n', out );
 660: }
 661: 
 662: static int putone ( adr, pos, indent )
 663: register char *adr;
 664: register int pos;
 665: int indent;
 666: {
 667:     register int len;
 668: 
 669:     len = strlen( adr );
 670:     if ( pos+len > outputlinelen ) {
 671:     fprintf ( out, ",\n%*s", indent, "");
 672:     pos = indent;
 673:     } else if ( pos > indent ) {
 674:     fputs( ", ", out );
 675:     pos += 2;
 676:     }
 677:     fputs( adr, out );
 678: 
 679:     return (pos+len);
 680: }
 681: 
 682: /*  */
 683: 
 684: static  insert_fcc (hdr, pp)
 685: struct  headers *hdr;
 686: char   *pp;
 687: {
 688:     char   *cp;
 689: 
 690:     for (cp = pp; isspace (*cp); cp++)
 691:     continue;
 692:     for (pp += strlen (pp) - 1; pp > cp && isspace (*pp); pp--)
 693:     continue;
 694:     if (pp >= cp)
 695:     *++pp = NULL;
 696:     if (*cp == NULL)
 697:     return;
 698: 
 699:     if (fccind >= FCCS)
 700:     adios (NULLCP, "too many %ss", hdr -> value);
 701:     fccfold[fccind++] = getcpy (cp);
 702: }
 703: 
 704: #ifdef notdef
 705: /*    BCC GENERATION */
 706: 
 707: static  make_bcc_file () {
 708:     int     fd,
 709:         i,
 710:             child_id,
 711:         status;
 712:     char   *vec[6];
 713:     FILE * in, *out;
 714: 
 715:     (void)mktemp (bccfil);
 716:     if ((out = fopen (bccfil, "w")) == NULL)
 717:     adios (bccfil, "unable to create");
 718:     (void)chmod (bccfil, 0600);
 719: 
 720:     fprintf (out, "Date: %s\n", dtimenow ());
 721:     fprintf (out, "From: %s\n", signature);
 722:     if (subject)
 723:     fprintf (out, "Subject: %s", subject);
 724:     fprintf (out, "BCC:\n\n------- Blind-Carbon-Copy\n\n");
 725:     (void)fflush (out);
 726: 
 727:     if (filter == NULL) {
 728:     if ((fd = open (tmpfil, 0)) == NOTOK)
 729:         adios (NULLCP, "unable to re-open");
 730:     cpydgst (fd, fileno (out), tmpfil, bccfil);
 731:     close (fd);
 732:     }
 733:     else {
 734:     vec[0] = r1bindex (mhlproc, '/');
 735: 
 736:     for (i = 0; (child_id = vfork ()) == NOTOK && i < 5; i++)
 737:         sleep (5);
 738:     switch (child_id) {
 739:         case NOTOK:
 740:         adios ("vfork", "unable to");
 741: 
 742:         case OK:
 743:         dup2 (fileno (out), 1);
 744: 
 745:         i = 1;
 746:         vec[i++] = "-forward";
 747:         vec[i++] = "-form";
 748:         vec[i++] = filter;
 749:         vec[i++] = tmpfil;
 750:         vec[i] = NULL;
 751: 
 752:         execvp (mhlproc, vec);
 753:         adios (mhlproc, "unable to exec");
 754: 
 755:         default:
 756:         if (status = pidwait (child_id, OK))
 757:             admonish (NULL, "%s lost (status=0%o)", vec[0], status);
 758:         break;
 759:     }
 760:     }
 761: 
 762:     fseek (out, 0L, 2);
 763:     fprintf (out, "\n------- End of Blind-Carbon-Copy\n");
 764:     (void)fclose (out);
 765: }
 766: #endif notdef
 767: 
 768: /*    FCC INTERACTION */
 769: 
 770: static  file (path)
 771: char   *path;
 772: {
 773:     int     i;
 774: 
 775:     if (fccind == 0)
 776:     return;
 777: 
 778:     for (i = 0; i < fccind; i++)
 779:     if (whomflg)
 780:         printf ("Fcc: %s\n", fccfold[i]);
 781:     else
 782:         fcc (path, fccfold[i]);
 783: }
 784: 
 785: 
 786: static fcc (file, folder)
 787: char   *file,
 788:        *folder;
 789: {
 790:     int     i,
 791:             child_id,
 792:             status;
 793:     char    fold[BUFSIZ];
 794: 
 795:     if (verbose)
 796:     printf ("%sFcc: %s\n", msgstate == resent ? "Resent-" : "", folder);
 797:     (void)fflush (stdout);
 798: 
 799:     for (i = 0; (child_id = vfork ()) == NOTOK && i < 5; i++)
 800:     sleep (5);
 801:     switch (child_id) {
 802:     case NOTOK:
 803:         if (!verbose)
 804:         fprintf (stderr, "  %sFcc %s: ",
 805:             msgstate == resent ? "Resent-" : "", folder);
 806:         fprintf (verbose ? stdout : stderr, "no forks, so not ok\n");
 807:         break;
 808: 
 809:     case OK:
 810:         (void)sprintf (fold, "%s%s",
 811:             *folder == '+' || *folder == '@' ? "" : "+", folder);
 812:         execlp (fileproc, r1bindex (fileproc, '/'),
 813:             "-link", "-file", file, fold, NULL);
 814:         _exit (-1);
 815: 
 816:     default:
 817:         if (status = pidwait (child_id)) {
 818:         if (!verbose)
 819:             fprintf (stderr, "  %sFcc %s: ",
 820:                 msgstate == resent ? "Resent-" : "", folder);
 821:         fprintf (verbose ? stdout : stderr,
 822:             " errored (0%o)\n", status);
 823:         }
 824:     }
 825: 
 826:     (void)fflush (stdout);
 827: }
 828: 
 829: /*    TERMINATION */
 830: 
 831: /* VARARGS2 */
 832: 
 833: static die (what, fmt, a, b, c, d)
 834: char   *what,
 835:        *fmt,
 836:        *a,
 837:        *b,
 838:        *c,
 839:        *d;
 840: {
 841:     adios (what, fmt, a, b, c, d);
 842: }

Defined functions

die defined in line 833; never used
fcc defined in line 786; used 1 times
file defined in line 770; used 4 times
finish_headers defined in line 561; used 2 times
get_header defined in line 599; used 1 times
insert_fcc defined in line 684; used 2 times
main defined in line 199; never used
make_bcc_file defined in line 707; never used
putadr defined in line 619; used 1 times
putfmt defined in line 456; used 2 times
putone defined in line 662; used 4 times
start_headers defined in line 543; used 1 times

Defined variables

NHeaders defined in line 128; used 1 times
RHeaders defined in line 145; used 1 times
aliasflg defined in line 175; used 5 times
backflg defined in line 172; used 3 times
badmsg defined in line 167; used 2 times
debug defined in line 169; used 3 times
fccfold defined in line 190; used 3 times
fccind defined in line 165; used 4 times
filter defined in line 188; used 5 times
from defined in line 186; used 5 times
hdrtab defined in line 192; used 3 times
msgflags defined in line 178; used 7 times
outputlinelen defined in line 176; used 4 times
pushflg defined in line 174; used 3 times
rmflg defined in line 170; used 3 times
sccsid defined in line 2; never used
signature defined in line 187; used 5 times
subject defined in line 189; used 5 times
switches defined in line 30; used 3 times
tmpfil defined in line 184; used 11 times
verbose defined in line 168; used 11 times
watch defined in line 171; used 4 times
whomflg defined in line 173; used 5 times

Defined struct's

headers defined in line 101; used 14 times

Defined macros

ALIASW defined in line 82; never used
ANNOSW defined in line 93; never used
BACKSW defined in line 65; never used
CHKSW defined in line 70; never used
DEBUGSW defined in line 59; never used
DISTSW defined in line 62; never used
FCCS defined in line 26; used 2 times
FILTSW defined in line 31; never used
FRMTSW defined in line 36; never used
HADR defined in line 107; used 13 times
HBAD defined in line 106; used 7 times
HBCC defined in line 110; used 3 times
HELPSW defined in line 56; never used
HFCC defined in line 113; used 3 times
HIGN defined in line 115; used 2 times
HMNG defined in line 111; never used
HNGR defined in line 112; used 4 times
HNIL defined in line 114; used 1 times
HNOP defined in line 105; used 2 times
HSUB defined in line 108; used 3 times
HTRY defined in line 109; used 7 times
LIBSW defined in line 90; never used
MDAT defined in line 119; used 2 times
MFRM defined in line 118; used 2 times
MINV defined in line 122; used 2 times
MRDT defined in line 123; used 2 times
MRFM defined in line 120; used 2 times
MVIS defined in line 121; used 6 times
NALIASW defined in line 84; never used
NBACKSW defined in line 67; never used
NCHKSW defined in line 72; never used
NFILTSW defined in line 33; never used
NFRMTSW defined in line 38; never used
NPUSHSW defined in line 79; never used
NREMVSW defined in line 43; never used
NVERBSW defined in line 48; never used
NWATCSW defined in line 53; never used
PUSHSW defined in line 77; never used
REMVSW defined in line 41; never used
SENDMAIL defined in line 25; used 3 times
VERBSW defined in line 46; never used
WATCSW defined in line 51; never used
WHOMSW defined in line 74; never used
WIDTHSW defined in line 87; never used
uptolow defined in line 23; never used
Last modified: 1986-02-26
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3516
Valid CSS Valid XHTML 1.0 Strict