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