|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.