Annotation of 43BSDReno/contrib/mh/uip/spost.c, revision 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.