Annotation of coherent/a/tmp/smail/headers.c, revision 1.1.1.1

1.1       root        1: /*
                      2: **  message spooing, header and address parsing and completion
                      3: **  functions for smail/rmail
                      4: */
                      5: 
                      6: #ifndef lint
                      7: static char    *sccsid="@(#)headers.c  2.5 (smail) 9/15/87";
                      8: #endif
                      9: 
                     10: # include      <stdio.h>
                     11: # include      <sys/types.h>
                     12: # include      <time.h>
                     13: # include      <ctype.h>
                     14: # include      <pwd.h>
                     15: # include      "defs.h"
                     16: 
                     17: extern enum edebug debug;      /* how verbose we are           */ 
                     18: extern char hostname[];                /* */
                     19: extern char hostdomain[];      /* */
                     20: extern char *spoolfile;                /* file name of spooled message */
                     21: extern FILE *spoolfp;          /* file ptr  to spooled message */
                     22: extern int spoolmaster;                /* set if creator of spoolfile  */
                     23: extern time_t now;             /* time                         */
                     24: extern char nows[], arpanows[];        /* time strings                 */
                     25: extern struct tm *gmt, *loc;   /* time structs                 */
                     26: extern char *from_addr;                /* replacement fromaddr with -F */
                     27: 
                     28: static char toline[SMLBUF];
                     29: static char fromline[SMLBUF];
                     30: static char dateline[SMLBUF];
                     31: static char midline[SMLBUF];
                     32: static char *ieof = "NOTNULL";
                     33: 
                     34: struct reqheaders {
                     35:        char *name;
                     36:        char *field;
                     37:        char have;
                     38: };
                     39: 
                     40: static struct reqheaders reqtab[] = {
                     41:        "Message-Id:"   ,       midline         ,       'N'     ,
                     42:        "Date:"         ,       dateline        ,       'N'     ,
                     43:        "From:"         ,       fromline        ,       'N'     ,
                     44:        "To:"           ,       toline          ,       'N'     ,
                     45:        NULL            ,       NULL            ,       'N'
                     46: };
                     47: 
                     48: 
                     49: /*
                     50: **
                     51: ** parse(): parse <address> into <domain, user, form>.
                     52: **
                     53: **     input           form
                     54: **     -----           ----
                     55: **     user            LOCAL
                     56: **     domain!user     DOMAIN
                     57: **     user@domain     DOMAIN
                     58: **     @domain,address LOCAL   (just for sendmail)
                     59: **     host!address    UUCP
                     60: **
                     61: */
                     62: 
                     63: enum eform
                     64: parse(address, domain, user)
                     65: char *address;         /* input address        */
                     66: char *domain;          /* output domain        */
                     67: char *user;            /* output user          */
                     68: {
                     69:        int parts;
                     70:        char *partv[MAXPATH];                           /* to crack address */
                     71: 
                     72: /*
                     73: **  If this is route address form @domain_a,@domain_b:user@domain_c, ...
                     74: */
                     75:        if(*address == '@')
                     76: #ifdef SENDMAIL
                     77: /*
                     78: **  hand it to sendmail
                     79: */
                     80:        {
                     81:                goto local;
                     82:        }
                     83: #else
                     84: /*
                     85: **  no sendmail, convert it into a bang path: domain_a!domain_b!domain_c!user
                     86: */
                     87:        {
                     88:                char buf[SMLBUF], *p;
                     89:                char t_dom[SMLBUF], t_user[SMLBUF];
                     90: 
                     91:                (void) strcpy(buf, address+1);          /* elide leading '@' */
                     92: 
                     93:                for(p=buf; *p != '\0' ; p++) {  /* search for ',' or ':' */
                     94:                        if(*p == ':') {         /* reached end of route */
                     95:                                break;
                     96:                        }
                     97:                        if(*p == ',') {         /* elide ','s */
                     98:                                (void) strcpy(p, p+1);
                     99:                        }
                    100:                        if(*p == '@') {         /* convert '@' to '!' */
                    101:                                *p = '!';
                    102:                        }
                    103:                }
                    104: 
                    105:                if(*p != ':') { /* bad syntax - punt */
                    106:                        goto local;
                    107:                }
                    108:                *p = '\0';
                    109: 
                    110:                if(parse(p+1, t_dom, t_user) != LOCAL) {
                    111:                        (void) strcat(buf, "!");
                    112:                        (void) strcat(buf, t_dom);
                    113:                }
                    114:                (void) strcat(buf, "!");
                    115:                (void) strcat(buf, t_user);
                    116: 
                    117:                /* munge the address (yuk)
                    118:                ** it's OK to copy into 'address', because the machinations
                    119:                ** above don't increase the string length of the address.
                    120:                */
                    121: 
                    122:                (void) strcpy(address, buf);
                    123: 
                    124:                /* re-parse the address */
                    125:                return(parse(address, domain, user));
                    126:        }
                    127: #endif
                    128: /*
                    129: **  Try splitting at @.  If it works, this is user@domain, form DOMAIN.
                    130: **  Prefer the righthand @ in a@b@c.
                    131: */
                    132:        if ((parts = ssplit(address, '@', partv)) >= 2) {
                    133:                (void) strcpy(domain, partv[parts-1]);
                    134:                (void) strncpy(user, partv[0], partv[parts-1]-partv[0]-1);
                    135:                user[partv[parts-1]-partv[0]-1] = '\0';
                    136:                return (DOMAIN);
                    137:        } 
                    138: /*
                    139: **  Try splitting at !. If it works, see if the piece before the ! has
                    140: **  a . in it (domain!user, form DOMAIN) or not (host!user, form UUCP).
                    141: */
                    142:        if (ssplit(address, '!', partv) > 1) {
                    143:                (void) strcpy(user, partv[1]);
                    144:                (void) strncpy(domain, partv[0], partv[1]-partv[0]-1);
                    145:                domain[partv[1]-partv[0]-1] = '\0';
                    146: 
                    147:                if((parts = ssplit(domain, '.', partv)) < 2) {
                    148:                        return(UUCP);
                    149:                }
                    150: 
                    151:                if(partv[parts-1][0] == '\0') {
                    152:                        partv[parts-1][-1] = '\0'; /* strip trailing . */
                    153:                }
                    154:                return (DOMAIN);
                    155:        }
                    156: /* 
                    157: **  Done trying.  This must be just a user name, form LOCAL.
                    158: */
                    159: local:
                    160:        (void) strcpy(user, address);
                    161:        (void) strcpy(domain, "");
                    162:        return(LOCAL);                          /* user */
                    163: }
                    164: 
                    165: build(domain, user, form, result)
                    166: char *domain;
                    167: char *user;
                    168: enum eform form;
                    169: char *result;
                    170: {
                    171:        switch((int) form) {
                    172:        case LOCAL:
                    173:                (void) sprintf(result, "%s", user); 
                    174:                break;
                    175:        case UUCP:
                    176:                (void) sprintf(result, "%s!%s", domain, user);
                    177:                break;
                    178:        case DOMAIN:
                    179:                (void) sprintf(result, "%s@%s", user, domain);
                    180:                break;
                    181:        }
                    182: }
                    183: 
                    184: /*
                    185: **  ssplit(): split a line into array pointers.
                    186: **
                    187: **  Each pointer wordv[i] points to the first character after the i'th 
                    188: **  occurence of c in buf.  Note that each wordv[i] includes wordv[i+1].
                    189: **
                    190: */
                    191: 
                    192: ssplit(buf, c, ptr)
                    193: register char *buf;            /* line to split up             */
                    194: char c;                                /* character to split on        */
                    195: char **ptr;                    /* the resultant vector         */
                    196: {
                    197:         int count = 0;
                    198:         int wasword = 0;
                    199: 
                    200:         for(; *buf; buf++) {
                    201:                if (!wasword) {
                    202:                        count++;
                    203:                        *ptr++ = buf;
                    204:                }
                    205:                wasword = (c != *buf);
                    206:         }
                    207:        if (!wasword) {
                    208:                count++;
                    209:                *ptr++ = buf;
                    210:        }
                    211:         *ptr = NULL;
                    212:         return(count);
                    213: }
                    214: 
                    215: /*
                    216: ** Determine whether an address is a local address
                    217: */
                    218: 
                    219: islocal(addr, domain, user)
                    220: char *addr, *domain, *user;
                    221: {
                    222:                enum eform form, parse();
                    223:                extern char hostuucp[];
                    224: 
                    225:                /*
                    226:                ** parse the address
                    227:                */
                    228: 
                    229:                form = parse(addr, domain, user);
                    230: 
                    231:                if((form == LOCAL)                      /* user */
                    232:                ||(strcmpic(domain, hostdomain) == 0)   /* user@hostdomain */
                    233:                ||(strcmpic(domain, hostname)   == 0)   /* user@hostname */
                    234: #ifdef DOMGATE
                    235:                ||(strcmpic(domain, &MYDOM[0]) == 0)    /* user@MYDOM w/ dot */
                    236:                ||(strcmpic(domain, &MYDOM[1]) == 0)    /* user@MYDOM no dot */
                    237: #endif
                    238:                ||(strcmpic(domain, hostuucp)   == 0)) {/* user@hostuucp */
                    239:                        return(1);
                    240:                }
                    241:                return(0);
                    242: }
                    243: 
                    244: /*
                    245: ** spool - message spooling module
                    246: **
                    247: ** (1) get dates for headers, etc.
                    248: ** (2) if the message is on the standard input (no '-f')
                    249: **     (a) create a temp file for spooling the message.
                    250: **     (b) collapse the From_ headers into a path.
                    251: **     (c) if the mail originated locally, then
                    252: **          (i) establish default headers
                    253: **         (ii) scan the message headers for required header fields
                    254: **        (iii) add any required message headers that are absent
                    255: **     (d) copy rest of the message to the spool file
                    256: **     (e) close the spool file
                    257: ** (3) open the spool file for reading
                    258: */
                    259: 
                    260: void
                    261: spool(argc, argv)
                    262: int argc;
                    263: char **argv;
                    264: {
                    265:        static char *tmpf = "/tmp/rmXXXXXX";    /* temp file name */
                    266:        char *mktemp();
                    267:        char buf[SMLBUF];
                    268:        static char splbuf[SMLBUF];
                    269:        char from[SMLBUF], domain[SMLBUF], user[SMLBUF];
                    270:        void rline(), scanheaders(), compheaders();
                    271: 
                    272:        /*
                    273:        ** if the mail has already been spooled by
                    274:        ** a previous invocation of smail don't respool.
                    275:        ** check the file name to prevent things like
                    276:        ** rmail -f /etc/passwd badguy@dreadfuldomain
                    277:        */
                    278: 
                    279:        if((spoolfile != NULL)
                    280:        && (strncmp(spoolfile, tmpf, strlen(tmpf) - 6) != 0)) {
                    281:                error(EX_TEMPFAIL, "spool: bad file name '%s'\n", spoolfile);
                    282:        }
                    283: 
                    284:        /*
                    285:        ** set dates in local, arpa, and gmt forms
                    286:        */
                    287:        setdates();
                    288: 
                    289:        /*
                    290:        ** If necessary, copy stdin to a temp file.
                    291:        */
                    292: 
                    293:        if(spoolfile == NULL) {
                    294:                spoolfile = strcpy(splbuf, tmpf);
                    295:                (void) mktemp(spoolfile);
                    296: 
                    297:                if((spoolfp = fopen(spoolfile, "w")) == NULL) {
                    298:                        error(EX_CANTCREAT, "can't create %s.\n", spoolfile);
                    299:                }
                    300: 
                    301:                spoolmaster = 1;
                    302: 
                    303:                /*
                    304:                ** rline reads the standard input,
                    305:                ** collapsing the From_ and >From_
                    306:                ** lines into a single uucp path.
                    307:                ** first non-from_ line is in buf[];
                    308:                */
                    309: 
                    310:                rline(from, buf);
                    311: 
                    312:                /*
                    313:                ** if the mail originated here, we parse the header
                    314:                ** and add any required headers that are missing.
                    315:                */
                    316: 
                    317:                if(islocal(from, domain, user) || (from_addr != NULL)) {
                    318:                        /*
                    319:                        ** initialize default headers
                    320:                        */
                    321:                        def_headers(argc, argv, from);
                    322: 
                    323:                        /*
                    324:                        ** buf has first, non-from_  line
                    325:                        */
                    326:                        scanheaders(buf);
                    327:                        /*
                    328:                        ** buf has first, non-header line,
                    329:                        */
                    330: 
                    331:                        compheaders();
                    332: 
                    333:                        if(buf[0] != '\n') {
                    334:                                (void) fputs("\n", spoolfp);
                    335:                        }
                    336:                }
                    337: 
                    338:                /*
                    339:                ** now, copy the rest of the letter into the spool file
                    340:                ** terminate on either EOF or '^.$'
                    341:                */
                    342: 
                    343:                while(ieof != NULL) {
                    344:                        (void) fputs(buf, spoolfp);
                    345:                        if((fgets(buf, SMLBUF, stdin) == NULL)
                    346:                        || (buf[0] == '.' && buf[1] == '\n')) {
                    347:                                ieof = NULL;
                    348:                        }
                    349:                }
                    350: 
                    351:                /*
                    352:                ** close the spool file, and the standard input.
                    353:                */
                    354: 
                    355:                (void) fclose(spoolfp);
                    356:                (void) fclose(stdin);   /* you don't see this too often! */
                    357:        }
                    358: 
                    359:        if((spoolfp = fopen(spoolfile, "r")) == NULL) {
                    360:                error(EX_TEMPFAIL, "can't open %s.\n", spoolfile);
                    361:        }
                    362: }
                    363: 
                    364: /*
                    365: **
                    366: **  rline(): collapse From_ and >From_ lines.
                    367: **
                    368: **  Same idea as the old rmail, but also turns user@domain to domain!user. 
                    369: **
                    370: */
                    371: 
                    372: void
                    373: rline(from, retbuf)
                    374: char *from;
                    375: char *retbuf;
                    376: {
                    377:        int parts;                      /* for cracking From_ lines ... */
                    378:        char *partv[16];                /* ... apart using ssplit()     */
                    379:        char user[SMLBUF];              /* for rewriting user@host      */
                    380:        char domain[SMLBUF];            /* "   "         "              */
                    381:        char addr[SMLBUF];              /* "   "         "              */
                    382:        enum eform form, parse();       /* "   "         "              */
                    383:        extern build();                 /* "   "         "              */
                    384:        char *c;
                    385:        int nhops, i;
                    386:        char buf[SMLBUF], tmp[SMLBUF], *hop[128], *e, *b;
                    387:        char *pwuid();
                    388: 
                    389:        if(spoolmaster == 0) return;
                    390: 
                    391:        buf[0] = from[0] = addr[0] = '\0';
                    392: /*
                    393: **  Read each line until we hit EOF or a line not beginning with "From "
                    394: **  or ">From " (called From_ lines), accumulating the new path in from
                    395: **  and stuffing the actual sending user (the user name on the last From_ 
                    396: **  line) in addr.
                    397: */
                    398:        for(;;) {
                    399:                (void) strcpy(retbuf, buf);
                    400:                if(ieof == NULL) {
                    401:                        break;
                    402:                }
                    403:                if((fgets(buf, sizeof(buf), stdin) == NULL)
                    404:                || (buf[0] == '.' && buf[1] == '\n')) {
                    405:                        ieof = NULL;
                    406:                        break;
                    407:                }
                    408:                if (strncmp("From ", buf, 5) 
                    409:                    && strncmp(">From ", buf, 6)) {
                    410:                        break;
                    411:                }
                    412: /*
                    413: **  Crack the line apart using ssplit.
                    414: */
                    415:                if(c = index(buf, '\n')) {
                    416:                        *c = '\0';
                    417:                }
                    418:                parts = ssplit(buf, ' ', partv);
                    419: /*
                    420: **  Tack host! onto the from argument if "remote from host" is present.
                    421: */
                    422: 
                    423:                if((parts > 3)
                    424:                && (strncmp("remote from ", partv[parts-3], 12) == 0)) {
                    425:                        (void) strcat(from, partv[parts-1]);
                    426:                        (void) strcat(from, "!");
                    427:                }
                    428: /*
                    429: **  Stuff user name into addr, overwriting the user name from previous 
                    430: **  From_ lines, since only the last one counts.  Then rewrite user@host 
                    431: **  into host!user, since @'s don't belong in the From_ argument.
                    432: */
                    433:                if(parts < 2) {
                    434:                        break;
                    435:                } else {
                    436:                        char *x = partv[1];
                    437:                        char *q = index(x, ' ');
                    438:                        if(q != NULL) {
                    439:                                *q = '\0';
                    440:                        }
                    441:                        (void) strcpy(addr, x);
                    442:                }
                    443: 
                    444:                (void) parse(addr, domain, user);
                    445:                if(*domain == '\0') {
                    446:                        form = LOCAL;
                    447:                } else {
                    448:                        form = UUCP;
                    449:                }
                    450: 
                    451:                build(domain, user, form, addr);
                    452:        }
                    453: /*
                    454: **  Now tack the user name onto the from argument.
                    455: */
                    456:        (void) strcat(from, addr);
                    457: /*
                    458: **  If we still have no from argument, we have junk headers, but we try
                    459: **  to get the user's name using /etc/passwd.
                    460: */
                    461: 
                    462:        if (from[0] == '\0') {
                    463:                char *login;
                    464:                if ((login = pwuid(getuid())) == NULL) {
                    465:                        (void) strcpy(from, "nobody");  /* bad news */
                    466:                } else {
                    467:                        (void) strcpy(from, login);
                    468:                }
                    469:        }
                    470: 
                    471:        /* split the from line on '!'s */
                    472:        nhops = ssplit(from, '!', hop);
                    473: 
                    474:        for(i = 0; i < (nhops - 1); i++) {
                    475:                b = hop[i];
                    476:                if(*b == '\0') {
                    477:                        continue;
                    478:                }
                    479:                e = hop[i+1];
                    480:                e-- ;
                    481:                *e = '\0';      /* null terminate each path segment */
                    482:                e++;
                    483: 
                    484: #ifdef HIDDENHOSTS
                    485: /*
                    486: **  Strip hidden hosts:  anything.hostname.MYDOM -> hostname.MYDOM
                    487: */
                    488:                for(p = b;(p = index(p, '.')) != NULL; p++) {
                    489:                        if(strcmpic(hostdomain, p+1) == 0) {
                    490:                                (void) strcpy(b, hostdomain);
                    491:                                break;
                    492:                        }
                    493:                }
                    494: #endif
                    495: 
                    496: /*
                    497: **  Strip useless MYDOM: hostname.MYDOM -> hostname
                    498: */
                    499:                if(strcmpic(hop[i], hostdomain) == 0) {
                    500:                        (void) strcpy(hop[i], hostname);
                    501:                }
                    502:        }
                    503: 
                    504: /*
                    505: **  Now strip out any redundant information in the From_ line
                    506: **  a!b!c!c!d  => a!b!c!d
                    507: */
                    508: 
                    509:        for(i = 0; i < (nhops - 2); i++) {
                    510:                b = hop[i];
                    511:                e = hop[i+1];
                    512:                if(strcmpic(b, e) == 0) {
                    513:                        *b = '\0';
                    514:                }
                    515:        }
                    516: /*
                    517: **  Reconstruct the From_ line
                    518: */
                    519:        tmp[0] = '\0';                  /* empty the tmp buffer */
                    520: 
                    521:        for(i = 0; i < (nhops - 1); i++) {
                    522:                if((hop[i][0] == '\0')  /* deleted this hop */
                    523:                 ||((tmp[0] == '\0')    /* first hop == hostname */
                    524:                  &&(strcmpic(hop[i], hostname) == 0))) {
                    525:                        continue;
                    526:                }
                    527:                (void) strcat(tmp, hop[i]);
                    528:                (void) strcat(tmp, "!");
                    529:        }
                    530:        (void) strcat(tmp, hop[i]);
                    531:        (void) strcpy(from, tmp);
                    532:        (void) strcpy(retbuf, buf);
                    533:        (void) fprintf(spoolfp, "%s\n", from);
                    534: }
                    535: 
                    536: void
                    537: scanheaders(buf)
                    538: char *buf;
                    539: {
                    540:        int inheader = 0;
                    541: 
                    542:        while(ieof != NULL) {
                    543:                if(buf[0] == '\n') {
                    544:                        break; /* end of headers */
                    545:                }
                    546: 
                    547:                /*
                    548:                ** header lines which begin with whitespace
                    549:                ** are continuation lines
                    550:                */
                    551:                if((inheader == 0)
                    552:                || ((buf[0] != ' ' && buf[0] != '\t'))) {
                    553:                        /* not a continuation line
                    554:                        ** check for header
                    555:                        */
                    556:                        if(isheader(buf) == 0) {
                    557:                                /*
                    558:                                ** not a header
                    559:                                */
                    560:                                break;
                    561:                        }
                    562:                        inheader = 1;
                    563:                        haveheaders(buf);
                    564:                }
                    565:                (void) fputs(buf, spoolfp);
                    566:                if((fgets(buf, SMLBUF, stdin) == NULL)
                    567:                || (buf[0] == '.' && buf[1] == '\n')) {
                    568:                        ieof = NULL;
                    569:                }
                    570:        }
                    571: 
                    572:        if(isheader(buf)) {
                    573:                buf[0] = '\0';
                    574:        }
                    575: }
                    576: 
                    577: /*
                    578: ** complete headers - add any required headers that are not in the message
                    579: */
                    580: void
                    581: compheaders()
                    582: {
                    583:        struct reqheaders *i;
                    584: 
                    585:        /*
                    586:        ** look at the table of required headers and
                    587:        ** add those that are missing to the spooled message.
                    588:        */
                    589:        for(i = reqtab; i->name != NULL; i++) {
                    590:                if(i->have != 'Y') {
                    591:                        (void) fprintf(spoolfp, "%s\n", i->field);
                    592:                }
                    593:        }
                    594: }
                    595: 
                    596: /*
                    597: ** look at a string and determine
                    598: ** whether or not it is a valid header.
                    599: */
                    600: isheader(s)
                    601: char *s;
                    602: {
                    603:        char *p;
                    604: 
                    605:        /*
                    606:        ** header field names must terminate with a colon
                    607:        ** and may not be null.
                    608:        */
                    609:        if(((p = index(s, ':')) == NULL) || (s == p)) {
                    610:                return(0);
                    611: 
                    612:        }
                    613:        /*
                    614:        ** header field names must consist entirely of
                    615:        ** printable ascii characters.
                    616:        */
                    617:        while(s != p) {
                    618:                if((*s < '!') || (*s > '~')) {
                    619:                        return(0);
                    620:                }
                    621:                s++;
                    622:        }
                    623:        /*
                    624:        ** we hit the ':', so the field may be a header
                    625:        */
                    626:        return(1);
                    627: }
                    628: 
                    629: /*
                    630: ** compare the header field to those in the required header table.
                    631: ** if it matches, then mark the required header as being present
                    632: ** in the message.
                    633: */
                    634: haveheaders(s)
                    635: char *s;
                    636: {
                    637:        struct reqheaders *i;
                    638: 
                    639:        for(i = reqtab; i->name != NULL; i++) {
                    640:                if(strncmpic(i->name, s, strlen(i->name)) == 0) {
                    641:                        if((strncmpic("From:", s, 5) == 0)
                    642:                        && (from_addr != NULL)) {
                    643:                                (void) sprintf(s, "From: %s\n", from_addr);
                    644:                        }
                    645:                        i->have = 'Y';
                    646:                        break;
                    647:                }
                    648:        }
                    649: }
                    650: 
                    651: /*
                    652: ** create default headers for the message.
                    653: */
                    654: def_headers(argc, argv, from)
                    655: int argc;
                    656: char **argv;
                    657: char *from;
                    658: {
                    659:        def_to(argc, argv);     /* default To:          */
                    660:        def_date();             /* default Date:        */
                    661:        def_from(from);         /* default From:        */
                    662:        def_mid();              /* default Message-Id:  */
                    663: }
                    664: 
                    665: /*
                    666: ** default Date: in arpa format
                    667: */
                    668: def_date()
                    669: {
                    670:        (void) strcpy(dateline, "Date: ");
                    671:        (void) strcat(dateline, arpanows);
                    672: }
                    673: 
                    674: /*
                    675: ** default Message-Id
                    676: **  Message-Id: <yymmddhhmm.AAppppp@hostdomain>
                    677: **
                    678: **     yy       year
                    679: **     mm       month
                    680: **     dd       day
                    681: **     hh       hour
                    682: **     mm       minute
                    683: **     ppppp   process-id
                    684: **
                    685: ** date and time are set by GMT
                    686: */
                    687: def_mid()
                    688: {
                    689:        (void) sprintf(midline, "Message-Id: <%02d%02d%02d%02d%02d.AA%05d@%s>",
                    690:                gmt->tm_year,
                    691:                gmt->tm_mon+1,
                    692:                gmt->tm_mday,
                    693:                gmt->tm_hour,
                    694:                gmt->tm_min,
                    695:                getpid(),
                    696:                hostdomain);
                    697: }
                    698: 
                    699: /*
                    700: ** default From:
                    701: **  From: user@hostdomain (Full Name)
                    702: */
                    703: def_from(from)
                    704: char *from;
                    705: {
                    706: 
                    707:        char *nameptr;
                    708:        char name[SMLBUF];
                    709:        char *getenv(), *login;
                    710:        char *pwfnam(), *pwuid();
                    711: 
                    712:        if (from_addr != NULL) {
                    713:                (void) sprintf(fromline, "From: %s", from_addr);
                    714:                return;
                    715:        }
                    716: 
                    717:        name[0] = '\0';
                    718:        if((nameptr = getenv("NAME")) != NULL) {
                    719:                (void) strcpy(name, nameptr);
                    720:        } else if((login = pwuid(getuid())) != NULL) {
                    721:                if((nameptr = pwfnam(login)) != NULL) {
                    722:                        (void) strcpy(name, nameptr);
                    723:                }
                    724:        }
                    725:        if(name[0] != '\0') {
                    726:                (void) sprintf(fromline,
                    727:                        "From: %s@%s (%s)", from, hostdomain, name);
                    728:        } else {
                    729:                (void) sprintf(fromline,
                    730:                        "From: %s@%s", from, hostdomain);
                    731:        }
                    732: }
                    733: 
                    734: /*
                    735: ** default To:
                    736: **  To: recip1, recip2, ...
                    737: **
                    738: ** lines longer than 50 chars are continued on another line.
                    739: */
                    740: def_to(argc, argv)
                    741: int argc;
                    742: char **argv;
                    743: {
                    744:        int i, n;
                    745:        char *bol;
                    746: 
                    747:        bol = toline;
                    748:        (void) strcpy(bol, "To: ");
                    749:        for(n = i = 0; i < argc; i++) {
                    750:                (void) strcat(bol, argv[i]);
                    751: 
                    752:                if((index(argv[i], '!') == NULL)
                    753:                && (index(argv[i], '@') == NULL)) {
                    754:                        (void) strcat(bol, "@");
                    755:                        (void) strcat(bol, hostdomain);
                    756:                }
                    757:                if(i+1 < argc) {
                    758:                        n = strlen(bol);
                    759:                        if(n > 50) {
                    760:                                (void) strcat(bol, ",\n\t");
                    761:                                bol = bol + strlen(bol);
                    762:                                *bol = '\0';
                    763:                                n = 8;
                    764:                        } else {
                    765:                                (void) strcat(bol, ", ");
                    766:                        }
                    767:                }
                    768:        }
                    769: }

unix.superglobalmegacorp.com

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