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