Annotation of 43BSD/usr.lib/sendmail/src/collect.c, revision 1.1.1.1

1.1       root        1: /*
                      2: **  Sendmail
                      3: **  Copyright (c) 1983  Eric P. Allman
                      4: **  Berkeley, California
                      5: **
                      6: **  Copyright (c) 1983 Regents of the University of California.
                      7: **  All rights reserved.  The Berkeley software License Agreement
                      8: **  specifies the terms and conditions for redistribution.
                      9: */
                     10: 
                     11: #ifndef lint
                     12: static char    SccsId[] = "@(#)collect.c       5.2 (Berkeley) 6/8/85";
                     13: #endif not lint
                     14: 
                     15: # include <errno.h>
                     16: # include "sendmail.h"
                     17: 
                     18: /*
                     19: **  COLLECT -- read & parse message header & make temp file.
                     20: **
                     21: **     Creates a temporary file name and copies the standard
                     22: **     input to that file.  Leading UNIX-style "From" lines are
                     23: **     stripped off (after important information is extracted).
                     24: **
                     25: **     Parameters:
                     26: **             sayok -- if set, give an ARPANET style message
                     27: **                     to say we are ready to collect input.
                     28: **
                     29: **     Returns:
                     30: **             none.
                     31: **
                     32: **     Side Effects:
                     33: **             Temp file is created and filled.
                     34: **             The from person may be set.
                     35: */
                     36: 
                     37: collect(sayok)
                     38:        bool sayok;
                     39: {
                     40:        register FILE *tf;
                     41:        char buf[MAXFIELD+2];
                     42:        register char *p;
                     43:        extern char *hvalue();
                     44: 
                     45:        /*
                     46:        **  Create the temp file name and create the file.
                     47:        */
                     48: 
                     49:        CurEnv->e_df = newstr(queuename(CurEnv, 'd'));
                     50:        if ((tf = dfopen(CurEnv->e_df, "w")) == NULL)
                     51:        {
                     52:                syserr("Cannot create %s", CurEnv->e_df);
                     53:                NoReturn = TRUE;
                     54:                finis();
                     55:        }
                     56:        (void) chmod(CurEnv->e_df, FileMode);
                     57: 
                     58:        /*
                     59:        **  Tell ARPANET to go ahead.
                     60:        */
                     61: 
                     62:        if (sayok)
                     63:                message("354", "Enter mail, end with \".\" on a line by itself");
                     64: 
                     65:        /*
                     66:        **  Try to read a UNIX-style From line
                     67:        */
                     68: 
                     69:        (void) sfgets(buf, sizeof buf, InChannel);
                     70:        fixcrlf(buf, FALSE);
                     71: # ifndef NOTUNIX
                     72:        if (!SaveFrom && strncmp(buf, "From ", 5) == 0)
                     73:        {
                     74:                eatfrom(buf);
                     75:                (void) sfgets(buf, sizeof buf, InChannel);
                     76:                fixcrlf(buf, FALSE);
                     77:        }
                     78: # endif NOTUNIX
                     79: 
                     80:        /*
                     81:        **  Copy InChannel to temp file & do message editing.
                     82:        **      To keep certain mailers from getting confused,
                     83:        **      and to keep the output clean, lines that look
                     84:        **      like UNIX "From" lines are deleted in the header.
                     85:        */
                     86: 
                     87:        do
                     88:        {
                     89:                int c;
                     90:                extern bool isheader();
                     91: 
                     92:                /* drop out on error */
                     93:                if (ferror(InChannel))
                     94:                        break;
                     95: 
                     96:                /* if the line is too long, throw the rest away */
                     97:                if (index(buf, '\n') == NULL)
                     98:                {
                     99:                        while ((c = getc(InChannel)) != '\n' && c != EOF)
                    100:                                continue;
                    101:                        /* give an error? */
                    102:                }
                    103: 
                    104:                fixcrlf(buf, TRUE);
                    105: 
                    106:                /* see if the header is over */
                    107:                if (!isheader(buf))
                    108:                        break;
                    109: 
                    110:                /* get the rest of this field */
                    111:                while ((c = getc(InChannel)) == ' ' || c == '\t')
                    112:                {
                    113:                        p = &buf[strlen(buf)];
                    114:                        *p++ = '\n';
                    115:                        *p++ = c;
                    116:                        if (sfgets(p, MAXFIELD - (p - buf), InChannel) == NULL)
                    117:                                break;
                    118:                        fixcrlf(p, TRUE);
                    119:                }
                    120:                if (!feof(InChannel) && !ferror(InChannel))
                    121:                        (void) ungetc(c, InChannel);
                    122: 
                    123:                CurEnv->e_msgsize += strlen(buf);
                    124: 
                    125:                /*
                    126:                **  Snarf header away.
                    127:                */
                    128: 
                    129:                if (bitset(H_EOH, chompheader(buf, FALSE)))
                    130:                        break;
                    131:        } while (sfgets(buf, MAXFIELD, InChannel) != NULL);
                    132: 
                    133: # ifdef DEBUG
                    134:        if (tTd(30, 1))
                    135:                printf("EOH\n");
                    136: # endif DEBUG
                    137: 
                    138:        /* throw away a blank line */
                    139:        if (buf[0] == '\0')
                    140:                (void) sfgets(buf, MAXFIELD, InChannel);
                    141: 
                    142:        /*
                    143:        **  Collect the body of the message.
                    144:        */
                    145: 
                    146:        do
                    147:        {
                    148:                register char *bp = buf;
                    149: 
                    150:                fixcrlf(buf, TRUE);
                    151: 
                    152:                /* check for end-of-message */
                    153:                if (!IgnrDot && buf[0] == '.' && (buf[1] == '\n' || buf[1] == '\0'))
                    154:                        break;
                    155: 
                    156:                /* check for transparent dot */
                    157:                if (OpMode == MD_SMTP && !IgnrDot && bp[0] == '.' && bp[1] == '.')
                    158:                        bp++;
                    159: 
                    160:                /*
                    161:                **  Figure message length, output the line to the temp
                    162:                **  file, and insert a newline if missing.
                    163:                */
                    164: 
                    165:                CurEnv->e_msgsize += strlen(bp) + 1;
                    166:                fputs(bp, tf);
                    167:                fputs("\n", tf);
                    168:                if (ferror(tf))
                    169:                        tferror(tf);
                    170:        } while (sfgets(buf, MAXFIELD, InChannel) != NULL);
                    171:        if (fflush(tf) != 0)
                    172:                tferror(tf);
                    173:        (void) fclose(tf);
                    174: 
                    175:        /* An EOF when running SMTP is an error */
                    176:        if ((feof(InChannel) || ferror(InChannel)) && OpMode == MD_SMTP)
                    177:        {
                    178:                syserr("collect: unexpected close, from=%s", CurEnv->e_from.q_paddr);
                    179: 
                    180:                /* don't return an error indication */
                    181:                CurEnv->e_to = NULL;
                    182:                CurEnv->e_flags &= ~EF_FATALERRS;
                    183: 
                    184:                /* and don't try to deliver the partial message either */
                    185:                finis();
                    186:        }
                    187: 
                    188:        /*
                    189:        **  Find out some information from the headers.
                    190:        **      Examples are who is the from person & the date.
                    191:        */
                    192: 
                    193:        eatheader(CurEnv);
                    194: 
                    195:        /*
                    196:        **  Add an Apparently-To: line if we have no recipient lines.
                    197:        */
                    198: 
                    199:        if (hvalue("to") == NULL && hvalue("cc") == NULL &&
                    200:            hvalue("bcc") == NULL && hvalue("apparently-to") == NULL)
                    201:        {
                    202:                register ADDRESS *q;
                    203: 
                    204:                /* create an Apparently-To: field */
                    205:                /*    that or reject the message.... */
                    206:                for (q = CurEnv->e_sendqueue; q != NULL; q = q->q_next)
                    207:                {
                    208:                        if (q->q_alias != NULL)
                    209:                                continue;
                    210: # ifdef DEBUG
                    211:                        if (tTd(30, 3))
                    212:                                printf("Adding Apparently-To: %s\n", q->q_paddr);
                    213: # endif DEBUG
                    214:                        addheader("apparently-to", q->q_paddr, CurEnv);
                    215:                }
                    216:        }
                    217: 
                    218:        if ((CurEnv->e_dfp = fopen(CurEnv->e_df, "r")) == NULL)
                    219:                syserr("Cannot reopen %s", CurEnv->e_df);
                    220: }
                    221: /*
                    222: **  TFERROR -- signal error on writing the temporary file.
                    223: **
                    224: **     Parameters:
                    225: **             tf -- the file pointer for the temporary file.
                    226: **
                    227: **     Returns:
                    228: **             none.
                    229: **
                    230: **     Side Effects:
                    231: **             Gives an error message.
                    232: **             Arranges for following output to go elsewhere.
                    233: */
                    234: 
                    235: tferror(tf)
                    236:        FILE *tf;
                    237: {
                    238:        if (errno == ENOSPC)
                    239:        {
                    240:                (void) freopen(CurEnv->e_df, "w", tf);
                    241:                fputs("\nMAIL DELETED BECAUSE OF LACK OF DISK SPACE\n\n", tf);
                    242:                usrerr("452 Out of disk space for temp file");
                    243:        }
                    244:        else
                    245:                syserr("collect: Cannot write %s", CurEnv->e_df);
                    246:        (void) freopen("/dev/null", "w", tf);
                    247: }
                    248: /*
                    249: **  EATFROM -- chew up a UNIX style from line and process
                    250: **
                    251: **     This does indeed make some assumptions about the format
                    252: **     of UNIX messages.
                    253: **
                    254: **     Parameters:
                    255: **             fm -- the from line.
                    256: **
                    257: **     Returns:
                    258: **             none.
                    259: **
                    260: **     Side Effects:
                    261: **             extracts what information it can from the header,
                    262: **             such as the date.
                    263: */
                    264: 
                    265: # ifndef NOTUNIX
                    266: 
                    267: char   *DowList[] =
                    268: {
                    269:        "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL
                    270: };
                    271: 
                    272: char   *MonthList[] =
                    273: {
                    274:        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
                    275:        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
                    276:        NULL
                    277: };
                    278: 
                    279: eatfrom(fm)
                    280:        char *fm;
                    281: {
                    282:        register char *p;
                    283:        register char **dt;
                    284: 
                    285: # ifdef DEBUG
                    286:        if (tTd(30, 2))
                    287:                printf("eatfrom(%s)\n", fm);
                    288: # endif DEBUG
                    289: 
                    290:        /* find the date part */
                    291:        p = fm;
                    292:        while (*p != '\0')
                    293:        {
                    294:                /* skip a word */
                    295:                while (*p != '\0' && *p != ' ')
                    296:                        p++;
                    297:                while (*p == ' ')
                    298:                        p++;
                    299:                if (!isupper(*p) || p[3] != ' ' || p[13] != ':' || p[16] != ':')
                    300:                        continue;
                    301: 
                    302:                /* we have a possible date */
                    303:                for (dt = DowList; *dt != NULL; dt++)
                    304:                        if (strncmp(*dt, p, 3) == 0)
                    305:                                break;
                    306:                if (*dt == NULL)
                    307:                        continue;
                    308: 
                    309:                for (dt = MonthList; *dt != NULL; dt++)
                    310:                        if (strncmp(*dt, &p[4], 3) == 0)
                    311:                                break;
                    312:                if (*dt != NULL)
                    313:                        break;
                    314:        }
                    315: 
                    316:        if (*p != NULL)
                    317:        {
                    318:                char *q;
                    319:                extern char *arpadate();
                    320: 
                    321:                /* we have found a date */
                    322:                q = xalloc(25);
                    323:                (void) strncpy(q, p, 25);
                    324:                q[24] = '\0';
                    325:                define('d', q, CurEnv);
                    326:                q = arpadate(q);
                    327:                define('a', newstr(q), CurEnv);
                    328:        }
                    329: }
                    330: 
                    331: # endif NOTUNIX

unix.superglobalmegacorp.com

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