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