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

Defined functions

eatfrom defined in line 260; used 1 times
  • in line 63
tferror defined in line 216; used 2 times

Defined variables

DowList defined in line 248; used 1 times
MonthList defined in line 253; used 1 times
Last modified: 1983-12-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1096
Valid CSS Valid XHTML 1.0 Strict