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