Annotation of 43BSD/usr.lib/sendmail/src/collect.c, revision 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.