Annotation of 43BSD/contrib/mh/uip/spost.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.