1 /* 2 * Copyright (c) 1998-2006, 2008 Sendmail, Inc. and its suppliers. 3 * All rights reserved. 4 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. 5 * Copyright (c) 1988, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * By using this file, you agree to the terms and conditions set 9 * forth in the LICENSE file which can be found at the top level of 10 * the sendmail distribution. 11 * 12 */ 13 14 #include <sendmail.h> 15 16 SM_RCSID("@(#)$Id: collect.c,v 8.285 2012/06/14 23:54:02 ca Exp $") 17 18 static void eatfrom __P((char *volatile, ENVELOPE *)); 19 static void collect_doheader __P((ENVELOPE *)); 20 static SM_FILE_T *collect_dfopen __P((ENVELOPE *)); 21 static SM_FILE_T *collect_eoh __P((ENVELOPE *, int, int)); 22 23 /* 24 ** COLLECT_EOH -- end-of-header processing in collect() 25 ** 26 ** Called by collect() when it encounters the blank line 27 ** separating the header from the message body, or when it 28 ** encounters EOF in a message that contains only a header. 29 ** 30 ** Parameters: 31 ** e -- envelope 32 ** numhdrs -- number of headers 33 ** hdrslen -- length of headers 34 ** 35 ** Results: 36 ** NULL, or handle to open data file 37 ** 38 ** Side Effects: 39 ** end-of-header check ruleset is invoked. 40 ** envelope state is updated. 41 ** headers may be added and deleted. 42 ** selects the queue. 43 ** opens the data file. 44 */ 45 46 static SM_FILE_T * 47 collect_eoh(e, numhdrs, hdrslen) 48 ENVELOPE *e; 49 int numhdrs; 50 int hdrslen; 51 { 52 char hnum[16]; 53 char hsize[16]; 54 55 /* call the end-of-header check ruleset */ 56 (void) sm_snprintf(hnum, sizeof(hnum), "%d", numhdrs); 57 (void) sm_snprintf(hsize, sizeof(hsize), "%d", hdrslen); 58 if (tTd(30, 10)) 59 sm_dprintf("collect: rscheck(\"check_eoh\", \"%s $| %s\")\n", 60 hnum, hsize); 61 (void) rscheck("check_eoh", hnum, hsize, e, RSF_UNSTRUCTURED|RSF_COUNT, 62 3, NULL, e->e_id, NULL); 63 64 /* 65 ** Process the header, 66 ** select the queue, open the data file. 67 */ 68 69 collect_doheader(e); 70 return collect_dfopen(e); 71 } 72 73 /* 74 ** COLLECT_DOHEADER -- process header in collect() 75 ** 76 ** Called by collect() after it has finished parsing the header, 77 ** but before it selects the queue and creates the data file. 78 ** The results of processing the header will affect queue selection. 79 ** 80 ** Parameters: 81 ** e -- envelope 82 ** 83 ** Results: 84 ** none. 85 ** 86 ** Side Effects: 87 ** envelope state is updated. 88 ** headers may be added and deleted. 89 */ 90 91 static void 92 collect_doheader(e) 93 ENVELOPE *e; 94 { 95 /* 96 ** Find out some information from the headers. 97 ** Examples are who is the from person & the date. 98 */ 99 100 eatheader(e, true, false); 101 102 if (GrabTo && e->e_sendqueue == NULL) 103 usrerr("No recipient addresses found in header"); 104 105 /* 106 ** If we have a Return-Receipt-To:, turn it into a DSN. 107 */ 108 109 if (RrtImpliesDsn && hvalue("return-receipt-to", e->e_header) != NULL) 110 { 111 ADDRESS *q; 112 113 for (q = e->e_sendqueue; q != NULL; q = q->q_next) 114 if (!bitset(QHASNOTIFY, q->q_flags)) 115 q->q_flags |= QHASNOTIFY|QPINGONSUCCESS; 116 } 117 118 /* 119 ** Add an appropriate recipient line if we have none. 120 */ 121 122 if (hvalue("to", e->e_header) != NULL || 123 hvalue("cc", e->e_header) != NULL || 124 hvalue("apparently-to", e->e_header) != NULL) 125 { 126 /* have a valid recipient header -- delete Bcc: headers */ 127 e->e_flags |= EF_DELETE_BCC; 128 } 129 else if (hvalue("bcc", e->e_header) == NULL) 130 { 131 /* no valid recipient headers */ 132 register ADDRESS *q; 133 char *hdr = NULL; 134 135 /* create a recipient field */ 136 switch (NoRecipientAction) 137 { 138 case NRA_ADD_APPARENTLY_TO: 139 hdr = "Apparently-To"; 140 break; 141 142 case NRA_ADD_TO: 143 hdr = "To"; 144 break; 145 146 case NRA_ADD_BCC: 147 addheader("Bcc", " ", 0, e, true); 148 break; 149 150 case NRA_ADD_TO_UNDISCLOSED: 151 addheader("To", "undisclosed-recipients:;", 0, e, true); 152 break; 153 } 154 155 if (hdr != NULL) 156 { 157 for (q = e->e_sendqueue; q != NULL; q = q->q_next) 158 { 159 if (q->q_alias != NULL) 160 continue; 161 if (tTd(30, 3)) 162 sm_dprintf("Adding %s: %s\n", 163 hdr, q->q_paddr); 164 addheader(hdr, q->q_paddr, 0, e, true); 165 } 166 } 167 } 168 } 169 170 /* 171 ** COLLECT_DFOPEN -- open the message data file 172 ** 173 ** Called by collect() after it has finished processing the header. 174 ** Queue selection occurs at this point, possibly based on the 175 ** envelope's recipient list and on header information. 176 ** 177 ** Parameters: 178 ** e -- envelope 179 ** 180 ** Results: 181 ** NULL, or a pointer to an open data file, 182 ** into which the message body will be written by collect(). 183 ** 184 ** Side Effects: 185 ** Calls syserr, sets EF_FATALERRS and returns NULL 186 ** if there is insufficient disk space. 187 ** Aborts process if data file could not be opened. 188 ** Otherwise, the queue is selected, 189 ** e->e_{dfino,dfdev,msgsize,flags} are updated, 190 ** and a pointer to an open data file is returned. 191 */ 192 193 static SM_FILE_T * 194 collect_dfopen(e) 195 ENVELOPE *e; 196 { 197 MODE_T oldumask = 0; 198 int dfd; 199 struct stat stbuf; 200 SM_FILE_T *df; 201 char *dfname; 202 203 if (!setnewqueue(e)) 204 return NULL; 205 206 dfname = queuename(e, DATAFL_LETTER); 207 if (bitset(S_IWGRP, QueueFileMode)) 208 oldumask = umask(002); 209 df = bfopen(dfname, QueueFileMode, DataFileBufferSize, 210 SFF_OPENASROOT); 211 if (bitset(S_IWGRP, QueueFileMode)) 212 (void) umask(oldumask); 213 if (df == NULL) 214 { 215 syserr("@Cannot create %s", dfname); 216 e->e_flags |= EF_NO_BODY_RETN; 217 flush_errors(true); 218 finis(false, true, ExitStat); 219 /* NOTREACHED */ 220 } 221 dfd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL); 222 if (dfd < 0 || fstat(dfd, &stbuf) < 0) 223 e->e_dfino = -1; 224 else 225 { 226 e->e_dfdev = stbuf.st_dev; 227 e->e_dfino = stbuf.st_ino; 228 } 229 e->e_flags |= EF_HAS_DF; 230 return df; 231 } 232 233 /* 234 ** COLLECT -- read & parse message header & make temp file. 235 ** 236 ** Creates a temporary file name and copies the standard 237 ** input to that file. Leading UNIX-style "From" lines are 238 ** stripped off (after important information is extracted). 239 ** 240 ** Parameters: 241 ** fp -- file to read. 242 ** smtpmode -- if set, we are running SMTP: give an RFC821 243 ** style message to say we are ready to collect 244 ** input, and never ignore a single dot to mean 245 ** end of message. 246 ** hdrp -- the location to stash the header. 247 ** e -- the current envelope. 248 ** rsetsize -- reset e_msgsize? 249 ** 250 ** Returns: 251 ** none. 252 ** 253 ** Side Effects: 254 ** If successful, 255 ** - Data file is created and filled, and e->e_dfp is set. 256 ** - The from person may be set. 257 ** If the "enough disk space" check fails, 258 ** - syserr is called. 259 ** - e->e_dfp is NULL. 260 ** - e->e_flags & EF_FATALERRS is set. 261 ** - collect() returns. 262 ** If data file cannot be created, the process is terminated. 263 */ 264 265 /* values for input state machine */ 266 #define IS_NORM 0 /* middle of line */ 267 #define IS_BOL 1 /* beginning of line */ 268 #define IS_DOT 2 /* read a dot at beginning of line */ 269 #define IS_DOTCR 3 /* read ".\r" at beginning of line */ 270 #define IS_CR 4 /* read a carriage return */ 271 272 /* values for message state machine */ 273 #define MS_UFROM 0 /* reading Unix from line */ 274 #define MS_HEADER 1 /* reading message header */ 275 #define MS_BODY 2 /* reading message body */ 276 #define MS_DISCARD 3 /* discarding rest of message */ 277 278 void 279 collect(fp, smtpmode, hdrp, e, rsetsize) 280 SM_FILE_T *fp; 281 bool smtpmode; 282 HDR **hdrp; 283 register ENVELOPE *e; 284 bool rsetsize; 285 { 286 register SM_FILE_T *df; 287 bool ignrdot; 288 int dbto; 289 register char *bp; 290 int c; 291 bool inputerr; 292 bool headeronly; 293 char *buf; 294 int buflen; 295 int istate; 296 int mstate; 297 int hdrslen; 298 int numhdrs; 299 int afd; 300 unsigned char *pbp; 301 unsigned char peekbuf[8]; 302 char bufbuf[MAXLINE]; 303 304 df = NULL; 305 ignrdot = smtpmode ? false : IgnrDot; 306 307 /* timeout for I/O functions is in milliseconds */ 308 dbto = smtpmode ? ((int) TimeOuts.to_datablock * 1000) 309 : SM_TIME_FOREVER; 310 sm_io_setinfo(fp, SM_IO_WHAT_TIMEOUT, &dbto); 311 set_tls_rd_tmo(TimeOuts.to_datablock); 312 c = SM_IO_EOF; 313 inputerr = false; 314 headeronly = hdrp != NULL; 315 hdrslen = 0; 316 numhdrs = 0; 317 HasEightBits = false; 318 buf = bp = bufbuf; 319 buflen = sizeof(bufbuf); 320 pbp = peekbuf; 321 istate = IS_BOL; 322 mstate = SaveFrom ? MS_HEADER : MS_UFROM; 323 324 /* 325 ** Tell ARPANET to go ahead. 326 */ 327 328 if (smtpmode) 329 message("354 Enter mail, end with \".\" on a line by itself"); 330 331 /* simulate an I/O timeout when used as sink */ 332 if (tTd(83, 101)) 333 sleep(319); 334 335 if (tTd(30, 2)) 336 sm_dprintf("collect\n"); 337 338 /* 339 ** Read the message. 340 ** 341 ** This is done using two interleaved state machines. 342 ** The input state machine is looking for things like 343 ** hidden dots; the message state machine is handling 344 ** the larger picture (e.g., header versus body). 345 */ 346 347 if (rsetsize) 348 e->e_msgsize = 0; 349 for (;;) 350 { 351 if (tTd(30, 35)) 352 sm_dprintf("top, istate=%d, mstate=%d\n", istate, 353 mstate); 354 for (;;) 355 { 356 if (pbp > peekbuf) 357 c = *--pbp; 358 else 359 { 360 while (!sm_io_eof(fp) && !sm_io_error(fp)) 361 { 362 errno = 0; 363 c = sm_io_getc(fp, SM_TIME_DEFAULT); 364 if (c == SM_IO_EOF && errno == EINTR) 365 { 366 /* Interrupted, retry */ 367 sm_io_clearerr(fp); 368 continue; 369 } 370 371 /* timeout? */ 372 if (c == SM_IO_EOF && errno == EAGAIN 373 && smtpmode) 374 { 375 /* 376 ** Override e_message in 377 ** usrerr() as this is the 378 ** reason for failure that 379 ** should be logged for 380 ** undelivered recipients. 381 */ 382 383 e->e_message = NULL; 384 errno = 0; 385 inputerr = true; 386 goto readabort; 387 } 388 break; 389 } 390 if (TrafficLogFile != NULL && !headeronly) 391 { 392 if (istate == IS_BOL) 393 (void) sm_io_fprintf(TrafficLogFile, 394 SM_TIME_DEFAULT, 395 "%05d <<< ", 396 (int) CurrentPid); 397 if (c == SM_IO_EOF) 398 (void) sm_io_fprintf(TrafficLogFile, 399 SM_TIME_DEFAULT, 400 "[EOF]\n"); 401 else 402 (void) sm_io_putc(TrafficLogFile, 403 SM_TIME_DEFAULT, 404 c); 405 } 406 if (c == SM_IO_EOF) 407 goto readerr; 408 if (SevenBitInput) 409 c &= 0x7f; 410 else 411 HasEightBits |= bitset(0x80, c); 412 } 413 if (tTd(30, 94)) 414 sm_dprintf("istate=%d, c=%c (0x%x)\n", 415 istate, (char) c, c); 416 switch (istate) 417 { 418 case IS_BOL: 419 if (c == '.') 420 { 421 istate = IS_DOT; 422 continue; 423 } 424 break; 425 426 case IS_DOT: 427 if (c == '\n' && !ignrdot && 428 !bitset(EF_NL_NOT_EOL, e->e_flags)) 429 goto readerr; 430 else if (c == '\r' && 431 !bitset(EF_CRLF_NOT_EOL, e->e_flags)) 432 { 433 istate = IS_DOTCR; 434 continue; 435 } 436 else if (ignrdot || 437 (c != '.' && 438 OpMode != MD_SMTP && 439 OpMode != MD_DAEMON && 440 OpMode != MD_ARPAFTP)) 441 442 { 443 SM_ASSERT(pbp < peekbuf + 444 sizeof(peekbuf)); 445 *pbp++ = c; 446 c = '.'; 447 } 448 break; 449 450 case IS_DOTCR: 451 if (c == '\n' && !ignrdot) 452 goto readerr; 453 else 454 { 455 /* push back the ".\rx" */ 456 SM_ASSERT(pbp < peekbuf + 457 sizeof(peekbuf)); 458 *pbp++ = c; 459 if (OpMode != MD_SMTP && 460 OpMode != MD_DAEMON && 461 OpMode != MD_ARPAFTP) 462 { 463 SM_ASSERT(pbp < peekbuf + 464 sizeof(peekbuf)); 465 *pbp++ = '\r'; 466 c = '.'; 467 } 468 else 469 c = '\r'; 470 } 471 break; 472 473 case IS_CR: 474 if (c == '\n') 475 istate = IS_BOL; 476 else 477 { 478 (void) sm_io_ungetc(fp, SM_TIME_DEFAULT, 479 c); 480 c = '\r'; 481 istate = IS_NORM; 482 } 483 goto bufferchar; 484 } 485 486 if (c == '\r' && !bitset(EF_CRLF_NOT_EOL, e->e_flags)) 487 { 488 istate = IS_CR; 489 continue; 490 } 491 else if (c == '\n' && !bitset(EF_NL_NOT_EOL, 492 e->e_flags)) 493 istate = IS_BOL; 494 else 495 istate = IS_NORM; 496 497 bufferchar: 498 if (!headeronly) 499 { 500 /* no overflow? */ 501 if (e->e_msgsize >= 0) 502 { 503 e->e_msgsize++; 504 if (MaxMessageSize > 0 && 505 !bitset(EF_TOOBIG, e->e_flags) && 506 e->e_msgsize > MaxMessageSize) 507 e->e_flags |= EF_TOOBIG; 508 } 509 } 510 switch (mstate) 511 { 512 case MS_BODY: 513 /* just put the character out */ 514 if (!bitset(EF_TOOBIG, e->e_flags)) 515 (void) sm_io_putc(df, SM_TIME_DEFAULT, 516 c); 517 518 /* FALLTHROUGH */ 519 520 case MS_DISCARD: 521 continue; 522 } 523 524 SM_ASSERT(mstate == MS_UFROM || mstate == MS_HEADER); 525 526 /* header -- buffer up */ 527 if (bp >= &buf[buflen - 2]) 528 { 529 char *obuf; 530 531 /* out of space for header */ 532 obuf = buf; 533 if (buflen < MEMCHUNKSIZE) 534 buflen *= 2; 535 else 536 buflen += MEMCHUNKSIZE; 537 if (buflen <= 0) 538 { 539 sm_syslog(LOG_NOTICE, e->e_id, 540 "header overflow from %s during message collect", 541 CURHOSTNAME); 542 errno = 0; 543 e->e_flags |= EF_CLRQUEUE; 544 e->e_status = "5.6.0"; 545 usrerrenh(e->e_status, 546 "552 Headers too large"); 547 goto discard; 548 } 549 buf = xalloc(buflen); 550 memmove(buf, obuf, bp - obuf); 551 bp = &buf[bp - obuf]; 552 if (obuf != bufbuf) 553 sm_free(obuf); /* XXX */ 554 } 555 556 if (c != '\0') 557 { 558 *bp++ = c; 559 ++hdrslen; 560 if (!headeronly && 561 MaxHeadersLength > 0 && 562 hdrslen > MaxHeadersLength) 563 { 564 sm_syslog(LOG_NOTICE, e->e_id, 565 "headers too large (%d max) from %s during message collect", 566 MaxHeadersLength, 567 CURHOSTNAME); 568 errno = 0; 569 e->e_flags |= EF_CLRQUEUE; 570 e->e_status = "5.6.0"; 571 usrerrenh(e->e_status, 572 "552 Headers too large (%d max)", 573 MaxHeadersLength); 574 discard: 575 mstate = MS_DISCARD; 576 } 577 } 578 if (istate == IS_BOL) 579 break; 580 } 581 *bp = '\0'; 582 583 nextstate: 584 if (tTd(30, 35)) 585 sm_dprintf("nextstate, istate=%d, mstate=%d, line=\"%s\"\n", 586 istate, mstate, buf); 587 switch (mstate) 588 { 589 case MS_UFROM: 590 mstate = MS_HEADER; 591 #ifndef NOTUNIX 592 if (strncmp(buf, "From ", 5) == 0) 593 { 594 bp = buf; 595 eatfrom(buf, e); 596 continue; 597 } 598 #endif /* ! NOTUNIX */ 599 /* FALLTHROUGH */ 600 601 case MS_HEADER: 602 if (!isheader(buf)) 603 { 604 mstate = MS_BODY; 605 goto nextstate; 606 } 607 608 /* check for possible continuation line */ 609 do 610 { 611 sm_io_clearerr(fp); 612 errno = 0; 613 c = sm_io_getc(fp, SM_TIME_DEFAULT); 614 615 /* timeout? */ 616 if (c == SM_IO_EOF && errno == EAGAIN 617 && smtpmode) 618 { 619 /* 620 ** Override e_message in 621 ** usrerr() as this is the 622 ** reason for failure that 623 ** should be logged for 624 ** undelivered recipients. 625 */ 626 627 e->e_message = NULL; 628 errno = 0; 629 inputerr = true; 630 goto readabort; 631 } 632 } while (c == SM_IO_EOF && errno == EINTR); 633 if (c != SM_IO_EOF) 634 (void) sm_io_ungetc(fp, SM_TIME_DEFAULT, c); 635 if (c == ' ' || c == '\t') 636 { 637 /* yep -- defer this */ 638 continue; 639 } 640 641 SM_ASSERT(bp > buf); 642 643 /* guaranteed by isheader(buf) */ 644 SM_ASSERT(*(bp - 1) != '\n' || bp > buf + 1); 645 646 /* trim off trailing CRLF or NL */ 647 if (*--bp != '\n' || *--bp != '\r') 648 bp++; 649 *bp = '\0'; 650 651 if (bitset(H_EOH, chompheader(buf, 652 CHHDR_CHECK | CHHDR_USER, 653 hdrp, e))) 654 { 655 mstate = MS_BODY; 656 goto nextstate; 657 } 658 numhdrs++; 659 break; 660 661 case MS_BODY: 662 if (tTd(30, 1)) 663 sm_dprintf("EOH\n"); 664 665 if (headeronly) 666 goto readerr; 667 668 df = collect_eoh(e, numhdrs, hdrslen); 669 if (df == NULL) 670 e->e_flags |= EF_TOOBIG; 671 672 bp = buf; 673 674 /* toss blank line */ 675 if ((!bitset(EF_CRLF_NOT_EOL, e->e_flags) && 676 bp[0] == '\r' && bp[1] == '\n') || 677 (!bitset(EF_NL_NOT_EOL, e->e_flags) && 678 bp[0] == '\n')) 679 { 680 break; 681 } 682 683 /* if not a blank separator, write it out */ 684 if (!bitset(EF_TOOBIG, e->e_flags)) 685 { 686 while (*bp != '\0') 687 (void) sm_io_putc(df, SM_TIME_DEFAULT, 688 *bp++); 689 } 690 break; 691 } 692 bp = buf; 693 } 694 695 readerr: 696 if ((sm_io_eof(fp) && smtpmode) || sm_io_error(fp)) 697 { 698 const char *errmsg; 699 700 if (sm_io_eof(fp)) 701 errmsg = "unexpected close"; 702 else 703 errmsg = sm_errstring(errno); 704 if (tTd(30, 1)) 705 sm_dprintf("collect: premature EOM: %s\n", errmsg); 706 if (LogLevel > 1) 707 sm_syslog(LOG_WARNING, e->e_id, 708 "collect: premature EOM: %s", errmsg); 709 inputerr = true; 710 } 711 712 if (headeronly) 713 return; 714 715 if (mstate != MS_BODY) 716 { 717 /* no body or discard, so we never opened the data file */ 718 SM_ASSERT(df == NULL); 719 df = collect_eoh(e, numhdrs, hdrslen); 720 } 721 722 if (df == NULL) 723 { 724 /* skip next few clauses */ 725 /* EMPTY */ 726 } 727 else if (sm_io_flush(df, SM_TIME_DEFAULT) != 0 || sm_io_error(df)) 728 { 729 dferror(df, "sm_io_flush||sm_io_error", e); 730 flush_errors(true); 731 finis(true, true, ExitStat); 732 /* NOTREACHED */ 733 } 734 else if (SuperSafe == SAFE_NO || 735 SuperSafe == SAFE_INTERACTIVE || 736 (SuperSafe == SAFE_REALLY_POSTMILTER && smtpmode)) 737 { 738 /* skip next few clauses */ 739 /* EMPTY */ 740 /* Note: updfs() is not called in this case! */ 741 } 742 else if (sm_io_setinfo(df, SM_BF_COMMIT, NULL) < 0 && errno != EINVAL) 743 { 744 int save_errno = errno; 745 746 if (save_errno == EEXIST) 747 { 748 char *dfile; 749 struct stat st; 750 int dfd; 751 752 dfile = queuename(e, DATAFL_LETTER); 753 if (stat(dfile, &st) < 0) 754 st.st_size = -1; 755 errno = EEXIST; 756 syserr("@collect: bfcommit(%s): already on disk, size=%ld", 757 dfile, (long) st.st_size); 758 dfd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL); 759 if (dfd >= 0) 760 dumpfd(dfd, true, true); 761 } 762 errno = save_errno; 763 dferror(df, "bfcommit", e); 764 flush_errors(true); 765 finis(save_errno != EEXIST, true, ExitStat); 766 } 767 else if ((afd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL)) < 0) 768 { 769 dferror(df, "sm_io_getinfo", e); 770 flush_errors(true); 771 finis(true, true, ExitStat); 772 /* NOTREACHED */ 773 } 774 else if (fsync(afd) < 0) 775 { 776 dferror(df, "fsync", e); 777 flush_errors(true); 778 finis(true, true, ExitStat); 779 /* NOTREACHED */ 780 } 781 else if (sm_io_close(df, SM_TIME_DEFAULT) < 0) 782 { 783 dferror(df, "sm_io_close", e); 784 flush_errors(true); 785 finis(true, true, ExitStat); 786 /* NOTREACHED */ 787 } 788 else 789 { 790 /* everything is happily flushed to disk */ 791 df = NULL; 792 793 /* remove from available space in filesystem */ 794 updfs(e, 0, 1, "collect"); 795 } 796 797 /* An EOF when running SMTP is an error */ 798 readabort: 799 if (inputerr && (OpMode == MD_SMTP || OpMode == MD_DAEMON)) 800 { 801 char *host; 802 char *problem; 803 ADDRESS *q; 804 805 host = RealHostName; 806 if (host == NULL) 807 host = "localhost"; 808 809 if (sm_io_eof(fp)) 810 problem = "unexpected close"; 811 else if (sm_io_error(fp)) 812 problem = "I/O error"; 813 else 814 problem = "read timeout"; 815 if (LogLevel > 0 && sm_io_eof(fp)) 816 sm_syslog(LOG_NOTICE, e->e_id, 817 "collect: %s on connection from %.100s, sender=%s", 818 problem, host, 819 shortenstring(e->e_from.q_paddr, MAXSHORTSTR)); 820 if (sm_io_eof(fp)) 821 usrerr("421 4.4.1 collect: %s on connection from %s, from=%s", 822 problem, host, 823 shortenstring(e->e_from.q_paddr, MAXSHORTSTR)); 824 else 825 syserr("421 4.4.1 collect: %s on connection from %s, from=%s", 826 problem, host, 827 shortenstring(e->e_from.q_paddr, MAXSHORTSTR)); 828 flush_errors(true); 829 830 /* don't return an error indication */ 831 e->e_to = NULL; 832 e->e_flags &= ~EF_FATALERRS; 833 e->e_flags |= EF_CLRQUEUE; 834 835 /* Don't send any message notification to sender */ 836 for (q = e->e_sendqueue; q != NULL; q = q->q_next) 837 { 838 if (QS_IS_DEAD(q->q_state)) 839 continue; 840 q->q_state = QS_FATALERR; 841 } 842 843 (void) sm_io_close(df, SM_TIME_DEFAULT); 844 df = NULL; 845 finis(true, true, ExitStat); 846 /* NOTREACHED */ 847 } 848 849 /* Log collection information. */ 850 if (tTd(92, 2)) 851 sm_dprintf("collect: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n", 852 e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel); 853 if (bitset(EF_LOGSENDER, e->e_flags) && LogLevel > 4) 854 { 855 logsender(e, e->e_msgid); 856 e->e_flags &= ~EF_LOGSENDER; 857 } 858 859 /* check for message too large */ 860 if (bitset(EF_TOOBIG, e->e_flags)) 861 { 862 e->e_flags |= EF_NO_BODY_RETN|EF_CLRQUEUE; 863 if (!bitset(EF_FATALERRS, e->e_flags)) 864 { 865 e->e_status = "5.2.3"; 866 usrerrenh(e->e_status, 867 "552 Message exceeds maximum fixed size (%ld)", 868 MaxMessageSize); 869 if (LogLevel > 6) 870 sm_syslog(LOG_NOTICE, e->e_id, 871 "message size (%ld) exceeds maximum (%ld)", 872 PRT_NONNEGL(e->e_msgsize), 873 MaxMessageSize); 874 } 875 } 876 877 /* check for illegal 8-bit data */ 878 if (HasEightBits) 879 { 880 e->e_flags |= EF_HAS8BIT; 881 if (!bitset(MM_PASS8BIT|MM_MIME8BIT, MimeMode) && 882 !bitset(EF_IS_MIME, e->e_flags)) 883 { 884 e->e_status = "5.6.1"; 885 usrerrenh(e->e_status, "554 Eight bit data not allowed"); 886 } 887 } 888 else 889 { 890 /* if it claimed to be 8 bits, well, it lied.... */ 891 if (e->e_bodytype != NULL && 892 sm_strcasecmp(e->e_bodytype, "8BITMIME") == 0) 893 e->e_bodytype = "7BIT"; 894 } 895 896 if (SuperSafe == SAFE_REALLY && !bitset(EF_FATALERRS, e->e_flags)) 897 { 898 char *dfname = queuename(e, DATAFL_LETTER); 899 if ((e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname, 900 SM_IO_RDONLY_B, NULL)) == NULL) 901 { 902 /* we haven't acked receipt yet, so just chuck this */ 903 syserr("@Cannot reopen %s", dfname); 904 finis(true, true, ExitStat); 905 /* NOTREACHED */ 906 } 907 } 908 else 909 e->e_dfp = df; 910 911 /* collect statistics */ 912 if (OpMode != MD_VERIFY) 913 { 914 /* 915 ** Recalculate e_msgpriority, it is done at in eatheader() 916 ** which is called (in 8.12) after the header is collected, 917 ** hence e_msgsize is (most likely) incorrect. 918 */ 919 920 e->e_msgpriority = e->e_msgsize 921 - e->e_class * WkClassFact 922 + e->e_nrcpts * WkRecipFact; 923 markstats(e, (ADDRESS *) NULL, STATS_NORMAL); 924 } 925 } 926 927 /* 928 ** DFERROR -- signal error on writing the data file. 929 ** 930 ** Called by collect(). Collect() always terminates the process 931 ** immediately after calling dferror(), which means that the SMTP 932 ** session will be terminated, which means that any error message 933 ** issued by dferror must be a 421 error, as per RFC 821. 934 ** 935 ** Parameters: 936 ** df -- the file pointer for the data file. 937 ** msg -- detailed message. 938 ** e -- the current envelope. 939 ** 940 ** Returns: 941 ** none. 942 ** 943 ** Side Effects: 944 ** Gives an error message. 945 ** Arranges for following output to go elsewhere. 946 */ 947 948 void 949 dferror(df, msg, e) 950 SM_FILE_T *volatile df; 951 char *msg; 952 register ENVELOPE *e; 953 { 954 char *dfname; 955 956 dfname = queuename(e, DATAFL_LETTER); 957 setstat(EX_IOERR); 958 if (errno == ENOSPC) 959 { 960 #if STAT64 > 0 961 struct stat64 st; 962 #else /* STAT64 > 0 */ 963 struct stat st; 964 #endif /* STAT64 > 0 */ 965 long avail; 966 long bsize; 967 968 e->e_flags |= EF_NO_BODY_RETN; 969 970 if ( 971 #if STAT64 > 0 972 fstat64(sm_io_getinfo(df, SM_IO_WHAT_FD, NULL), &st) 973 #else /* STAT64 > 0 */ 974 fstat(sm_io_getinfo(df, SM_IO_WHAT_FD, NULL), &st) 975 #endif /* STAT64 > 0 */ 976 < 0) 977 st.st_size = 0; 978 (void) sm_io_reopen(SmFtStdio, SM_TIME_DEFAULT, dfname, 979 SM_IO_WRONLY_B, NULL, df); 980 if (st.st_size <= 0) 981 (void) sm_io_fprintf(df, SM_TIME_DEFAULT, 982 "\n*** Mail could not be accepted"); 983 else 984 (void) sm_io_fprintf(df, SM_TIME_DEFAULT, 985 "\n*** Mail of at least %llu bytes could not be accepted\n", 986 (ULONGLONG_T) st.st_size); 987 (void) sm_io_fprintf(df, SM_TIME_DEFAULT, 988 "*** at %s due to lack of disk space for temp file.\n", 989 MyHostName); 990 avail = freediskspace(qid_printqueue(e->e_qgrp, e->e_qdir), 991 &bsize); 992 if (avail > 0) 993 { 994 if (bsize > 1024) 995 avail *= bsize / 1024; 996 else if (bsize < 1024) 997 avail /= 1024 / bsize; 998 (void) sm_io_fprintf(df, SM_TIME_DEFAULT, 999 "*** Currently, %ld kilobytes are available for mail temp files.\n", 1000 avail); 1001 } 1002 #if 0 1003 /* Wrong response code; should be 421. */ 1004 e->e_status = "4.3.1"; 1005 usrerrenh(e->e_status, "452 Out of disk space for temp file"); 1006 #else /* 0 */ 1007 syserr("421 4.3.1 Out of disk space for temp file"); 1008 #endif /* 0 */ 1009 } 1010 else 1011 syserr("421 4.3.0 collect: Cannot write %s (%s, uid=%d, gid=%d)", 1012 dfname, msg, (int) geteuid(), (int) getegid()); 1013 if (sm_io_reopen(SmFtStdio, SM_TIME_DEFAULT, SM_PATH_DEVNULL, 1014 SM_IO_WRONLY, NULL, df) == NULL) 1015 sm_syslog(LOG_ERR, e->e_id, 1016 "dferror: sm_io_reopen(\"/dev/null\") failed: %s", 1017 sm_errstring(errno)); 1018 } 1019 /* 1020 ** EATFROM -- chew up a UNIX style from line and process 1021 ** 1022 ** This does indeed make some assumptions about the format 1023 ** of UNIX messages. 1024 ** 1025 ** Parameters: 1026 ** fm -- the from line. 1027 ** e -- envelope 1028 ** 1029 ** Returns: 1030 ** none. 1031 ** 1032 ** Side Effects: 1033 ** extracts what information it can from the header, 1034 ** such as the date. 1035 */ 1036 1037 #ifndef NOTUNIX 1038 1039 static char *DowList[] = 1040 { 1041 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL 1042 }; 1043 1044 static char *MonthList[] = 1045 { 1046 "Jan", "Feb", "Mar", "Apr", "May", "Jun", 1047 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", 1048 NULL 1049 }; 1050 1051 static void 1052 eatfrom(fm, e) 1053 char *volatile fm; 1054 register ENVELOPE *e; 1055 { 1056 register char *p; 1057 register char **dt; 1058 1059 if (tTd(30, 2)) 1060 sm_dprintf("eatfrom(%s)\n", fm); 1061 1062 /* find the date part */ 1063 p = fm; 1064 while (*p != '\0') 1065 { 1066 /* skip a word */ 1067 while (*p != '\0' && *p != ' ') 1068 p++; 1069 while (*p == ' ') 1070 p++; 1071 if (strlen(p) < 17) 1072 { 1073 /* no room for the date */ 1074 return; 1075 } 1076 if (!(isascii(*p) && isupper(*p)) || 1077 p[3] != ' ' || p[13] != ':' || p[16] != ':') 1078 continue; 1079 1080 /* we have a possible date */ 1081 for (dt = DowList; *dt != NULL; dt++) 1082 if (strncmp(*dt, p, 3) == 0) 1083 break; 1084 if (*dt == NULL) 1085 continue; 1086 1087 for (dt = MonthList; *dt != NULL; dt++) 1088 { 1089 if (strncmp(*dt, &p[4], 3) == 0) 1090 break; 1091 } 1092 if (*dt != NULL) 1093 break; 1094 } 1095 1096 if (*p != '\0') 1097 { 1098 char *q, buf[25]; 1099 1100 /* we have found a date */ 1101 (void) sm_strlcpy(buf, p, sizeof(buf)); 1102 q = arpadate(buf); 1103 macdefine(&e->e_macro, A_TEMP, 'a', q); 1104 } 1105 } 1106 #endif /* ! NOTUNIX */ 1107