|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.