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

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

unix.superglobalmegacorp.com

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