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: #if !defined(lint) && !defined(NOSCCS)
  12: static char SccsId[] = "@(#)collect.c	5.2 (Berkeley) 6/8/85";
  13: #endif
  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

Defined functions

eatfrom defined in line 279; used 1 times
  • in line 74
tferror defined in line 235; used 2 times

Defined variables

DowList defined in line 267; used 1 times
MonthList defined in line 272; used 1 times
SccsId defined in line 12; never used
Last modified: 1989-01-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3380
Valid CSS Valid XHTML 1.0 Strict