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

Defined functions

eatfrom defined in line 285; used 1 times
  • in line 80
tferror defined in line 241; used 2 times

Defined variables

DowList defined in line 273; used 1 times
MonthList defined in line 278; used 1 times
sccsid defined in line 18; never used
Last modified: 1988-09-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3525
Valid CSS Valid XHTML 1.0 Strict