Annotation of 43BSDReno/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 <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: }

unix.superglobalmegacorp.com

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