]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/sendmail/src/collect.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / sendmail / src / collect.c
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.286 2013/03/15 17:54:12 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 #if _FFR_REJECT_NUL_BYTE
304         bool hasNUL;            /* has at least one NUL input byte */
305 #endif /* _FFR_REJECT_NUL_BYTE */
306
307         df = NULL;
308         ignrdot = smtpmode ? false : IgnrDot;
309
310         /* timeout for I/O functions is in milliseconds */
311         dbto = smtpmode ? ((int) TimeOuts.to_datablock * 1000)
312                         : SM_TIME_FOREVER;
313         sm_io_setinfo(fp, SM_IO_WHAT_TIMEOUT, &dbto);
314         set_tls_rd_tmo(TimeOuts.to_datablock);
315         c = SM_IO_EOF;
316         inputerr = false;
317         headeronly = hdrp != NULL;
318         hdrslen = 0;
319         numhdrs = 0;
320         HasEightBits = false;
321 #if _FFR_REJECT_NUL_BYTE
322         hasNUL = false;
323 #endif /* _FFR_REJECT_NUL_BYTE */
324         buf = bp = bufbuf;
325         buflen = sizeof(bufbuf);
326         pbp = peekbuf;
327         istate = IS_BOL;
328         mstate = SaveFrom ? MS_HEADER : MS_UFROM;
329
330         /*
331         **  Tell ARPANET to go ahead.
332         */
333
334         if (smtpmode)
335                 message("354 Enter mail, end with \".\" on a line by itself");
336
337         /* simulate an I/O timeout when used as sink */
338         if (tTd(83, 101))
339                 sleep(319);
340
341         if (tTd(30, 2))
342                 sm_dprintf("collect\n");
343
344         /*
345         **  Read the message.
346         **
347         **      This is done using two interleaved state machines.
348         **      The input state machine is looking for things like
349         **      hidden dots; the message state machine is handling
350         **      the larger picture (e.g., header versus body).
351         */
352
353         if (rsetsize)
354                 e->e_msgsize = 0;
355         for (;;)
356         {
357                 if (tTd(30, 35))
358                         sm_dprintf("top, istate=%d, mstate=%d\n", istate,
359                                    mstate);
360                 for (;;)
361                 {
362                         if (pbp > peekbuf)
363                                 c = *--pbp;
364                         else
365                         {
366                                 while (!sm_io_eof(fp) && !sm_io_error(fp))
367                                 {
368                                         errno = 0;
369                                         c = sm_io_getc(fp, SM_TIME_DEFAULT);
370                                         if (c == SM_IO_EOF && errno == EINTR)
371                                         {
372                                                 /* Interrupted, retry */
373                                                 sm_io_clearerr(fp);
374                                                 continue;
375                                         }
376
377                                         /* timeout? */
378                                         if (c == SM_IO_EOF && errno == EAGAIN
379                                             && smtpmode)
380                                         {
381                                                 /*
382                                                 **  Override e_message in
383                                                 **  usrerr() as this is the
384                                                 **  reason for failure that
385                                                 **  should be logged for
386                                                 **  undelivered recipients.
387                                                 */
388
389                                                 e->e_message = NULL;
390                                                 errno = 0;
391                                                 inputerr = true;
392                                                 goto readabort;
393                                         }
394                                         break;
395                                 }
396                                 if (TrafficLogFile != NULL && !headeronly)
397                                 {
398                                         if (istate == IS_BOL)
399                                                 (void) sm_io_fprintf(TrafficLogFile,
400                                                         SM_TIME_DEFAULT,
401                                                         "%05d <<< ",
402                                                         (int) CurrentPid);
403                                         if (c == SM_IO_EOF)
404                                                 (void) sm_io_fprintf(TrafficLogFile,
405                                                         SM_TIME_DEFAULT,
406                                                         "[EOF]\n");
407                                         else
408                                                 (void) sm_io_putc(TrafficLogFile,
409                                                         SM_TIME_DEFAULT,
410                                                         c);
411                                 }
412 #if _FFR_REJECT_NUL_BYTE
413                                 if (c == '\0')
414                                         hasNUL = true;
415 #endif /* _FFR_REJECT_NUL_BYTE */
416                                 if (c == SM_IO_EOF)
417                                         goto readerr;
418                                 if (SevenBitInput)
419                                         c &= 0x7f;
420                                 else
421                                         HasEightBits |= bitset(0x80, c);
422                         }
423                         if (tTd(30, 94))
424                                 sm_dprintf("istate=%d, c=%c (0x%x)\n",
425                                         istate, (char) c, c);
426                         switch (istate)
427                         {
428                           case IS_BOL:
429                                 if (c == '.')
430                                 {
431                                         istate = IS_DOT;
432                                         continue;
433                                 }
434                                 break;
435
436                           case IS_DOT:
437                                 if (c == '\n' && !ignrdot &&
438                                     !bitset(EF_NL_NOT_EOL, e->e_flags))
439                                         goto readerr;
440                                 else if (c == '\r' &&
441                                          !bitset(EF_CRLF_NOT_EOL, e->e_flags))
442                                 {
443                                         istate = IS_DOTCR;
444                                         continue;
445                                 }
446                                 else if (ignrdot ||
447                                          (c != '.' &&
448                                           OpMode != MD_SMTP &&
449                                           OpMode != MD_DAEMON &&
450                                           OpMode != MD_ARPAFTP))
451
452                                 {
453                                         SM_ASSERT(pbp < peekbuf +
454                                                         sizeof(peekbuf));
455                                         *pbp++ = c;
456                                         c = '.';
457                                 }
458                                 break;
459
460                           case IS_DOTCR:
461                                 if (c == '\n' && !ignrdot)
462                                         goto readerr;
463                                 else
464                                 {
465                                         /* push back the ".\rx" */
466                                         SM_ASSERT(pbp < peekbuf +
467                                                         sizeof(peekbuf));
468                                         *pbp++ = c;
469                                         if (OpMode != MD_SMTP &&
470                                             OpMode != MD_DAEMON &&
471                                             OpMode != MD_ARPAFTP)
472                                         {
473                                                 SM_ASSERT(pbp < peekbuf +
474                                                          sizeof(peekbuf));
475                                                 *pbp++ = '\r';
476                                                 c = '.';
477                                         }
478                                         else
479                                                 c = '\r';
480                                 }
481                                 break;
482
483                           case IS_CR:
484                                 if (c == '\n')
485                                         istate = IS_BOL;
486                                 else
487                                 {
488                                         (void) sm_io_ungetc(fp, SM_TIME_DEFAULT,
489                                                             c);
490                                         c = '\r';
491                                         istate = IS_NORM;
492                                 }
493                                 goto bufferchar;
494                         }
495
496                         if (c == '\r' && !bitset(EF_CRLF_NOT_EOL, e->e_flags))
497                         {
498                                 istate = IS_CR;
499                                 continue;
500                         }
501                         else if (c == '\n' && !bitset(EF_NL_NOT_EOL,
502                                                       e->e_flags))
503                                 istate = IS_BOL;
504                         else
505                                 istate = IS_NORM;
506
507 bufferchar:
508                         if (!headeronly)
509                         {
510                                 /* no overflow? */
511                                 if (e->e_msgsize >= 0)
512                                 {
513                                         e->e_msgsize++;
514                                         if (MaxMessageSize > 0 &&
515                                             !bitset(EF_TOOBIG, e->e_flags) &&
516                                             e->e_msgsize > MaxMessageSize)
517                                                  e->e_flags |= EF_TOOBIG;
518                                 }
519                         }
520                         switch (mstate)
521                         {
522                           case MS_BODY:
523                                 /* just put the character out */
524                                 if (!bitset(EF_TOOBIG, e->e_flags))
525                                         (void) sm_io_putc(df, SM_TIME_DEFAULT,
526                                                           c);
527
528                                 /* FALLTHROUGH */
529
530                           case MS_DISCARD:
531                                 continue;
532                         }
533
534                         SM_ASSERT(mstate == MS_UFROM || mstate == MS_HEADER);
535
536                         /* header -- buffer up */
537                         if (bp >= &buf[buflen - 2])
538                         {
539                                 char *obuf;
540
541                                 /* out of space for header */
542                                 obuf = buf;
543                                 if (buflen < MEMCHUNKSIZE)
544                                         buflen *= 2;
545                                 else
546                                         buflen += MEMCHUNKSIZE;
547                                 if (buflen <= 0)
548                                 {
549                                         sm_syslog(LOG_NOTICE, e->e_id,
550                                                   "header overflow from %s during message collect",
551                                                   CURHOSTNAME);
552                                         errno = 0;
553                                         e->e_flags |= EF_CLRQUEUE;
554                                         e->e_status = "5.6.0";
555                                         usrerrenh(e->e_status,
556                                                   "552 Headers too large");
557                                         goto discard;
558                                 }
559                                 buf = xalloc(buflen);
560                                 memmove(buf, obuf, bp - obuf);
561                                 bp = &buf[bp - obuf];
562                                 if (obuf != bufbuf)
563                                         sm_free(obuf);  /* XXX */
564                         }
565
566                         if (c != '\0')
567                         {
568                                 *bp++ = c;
569                                 ++hdrslen;
570                                 if (!headeronly &&
571                                     MaxHeadersLength > 0 &&
572                                     hdrslen > MaxHeadersLength)
573                                 {
574                                         sm_syslog(LOG_NOTICE, e->e_id,
575                                                   "headers too large (%d max) from %s during message collect",
576                                                   MaxHeadersLength,
577                                                   CURHOSTNAME);
578                                         errno = 0;
579                                         e->e_flags |= EF_CLRQUEUE;
580                                         e->e_status = "5.6.0";
581                                         usrerrenh(e->e_status,
582                                                   "552 Headers too large (%d max)",
583                                                   MaxHeadersLength);
584   discard:
585                                         mstate = MS_DISCARD;
586                                 }
587                         }
588                         if (istate == IS_BOL)
589                                 break;
590                 }
591                 *bp = '\0';
592
593 nextstate:
594                 if (tTd(30, 35))
595                         sm_dprintf("nextstate, istate=%d, mstate=%d, line=\"%s\"\n",
596                                 istate, mstate, buf);
597                 switch (mstate)
598                 {
599                   case MS_UFROM:
600                         mstate = MS_HEADER;
601 #ifndef NOTUNIX
602                         if (strncmp(buf, "From ", 5) == 0)
603                         {
604                                 bp = buf;
605                                 eatfrom(buf, e);
606                                 continue;
607                         }
608 #endif /* ! NOTUNIX */
609                         /* FALLTHROUGH */
610
611                   case MS_HEADER:
612                         if (!isheader(buf))
613                         {
614                                 mstate = MS_BODY;
615                                 goto nextstate;
616                         }
617
618                         /* check for possible continuation line */
619                         do
620                         {
621                                 sm_io_clearerr(fp);
622                                 errno = 0;
623                                 c = sm_io_getc(fp, SM_TIME_DEFAULT);
624
625                                 /* timeout? */
626                                 if (c == SM_IO_EOF && errno == EAGAIN
627                                     && smtpmode)
628                                 {
629                                         /*
630                                         **  Override e_message in
631                                         **  usrerr() as this is the
632                                         **  reason for failure that
633                                         **  should be logged for
634                                         **  undelivered recipients.
635                                         */
636
637                                         e->e_message = NULL;
638                                         errno = 0;
639                                         inputerr = true;
640                                         goto readabort;
641                                 }
642                         } while (c == SM_IO_EOF && errno == EINTR);
643                         if (c != SM_IO_EOF)
644                                 (void) sm_io_ungetc(fp, SM_TIME_DEFAULT, c);
645                         if (c == ' ' || c == '\t')
646                         {
647                                 /* yep -- defer this */
648                                 continue;
649                         }
650
651                         SM_ASSERT(bp > buf);
652
653                         /* guaranteed by isheader(buf) */
654                         SM_ASSERT(*(bp - 1) != '\n' || bp > buf + 1);
655
656                         /* trim off trailing CRLF or NL */
657                         if (*--bp != '\n' || *--bp != '\r')
658                                 bp++;
659                         *bp = '\0';
660
661                         if (bitset(H_EOH, chompheader(buf,
662                                                       CHHDR_CHECK | CHHDR_USER,
663                                                       hdrp, e)))
664                         {
665                                 mstate = MS_BODY;
666                                 goto nextstate;
667                         }
668                         numhdrs++;
669                         break;
670
671                   case MS_BODY:
672                         if (tTd(30, 1))
673                                 sm_dprintf("EOH\n");
674
675                         if (headeronly)
676                                 goto readerr;
677
678                         df = collect_eoh(e, numhdrs, hdrslen);
679                         if (df == NULL)
680                                 e->e_flags |= EF_TOOBIG;
681
682                         bp = buf;
683
684                         /* toss blank line */
685                         if ((!bitset(EF_CRLF_NOT_EOL, e->e_flags) &&
686                                 bp[0] == '\r' && bp[1] == '\n') ||
687                             (!bitset(EF_NL_NOT_EOL, e->e_flags) &&
688                                 bp[0] == '\n'))
689                         {
690                                 break;
691                         }
692
693                         /* if not a blank separator, write it out */
694                         if (!bitset(EF_TOOBIG, e->e_flags))
695                         {
696                                 while (*bp != '\0')
697                                         (void) sm_io_putc(df, SM_TIME_DEFAULT,
698                                                           *bp++);
699                         }
700                         break;
701                 }
702                 bp = buf;
703         }
704
705 readerr:
706         if ((sm_io_eof(fp) && smtpmode) || sm_io_error(fp))
707         {
708                 const char *errmsg;
709
710                 if (sm_io_eof(fp))
711                         errmsg = "unexpected close";
712                 else
713                         errmsg = sm_errstring(errno);
714                 if (tTd(30, 1))
715                         sm_dprintf("collect: premature EOM: %s\n", errmsg);
716                 if (LogLevel > 1)
717                         sm_syslog(LOG_WARNING, e->e_id,
718                                 "collect: premature EOM: %s", errmsg);
719                 inputerr = true;
720         }
721
722         if (headeronly)
723                 return;
724
725         if (mstate != MS_BODY)
726         {
727                 /* no body or discard, so we never opened the data file */
728                 SM_ASSERT(df == NULL);
729                 df = collect_eoh(e, numhdrs, hdrslen);
730         }
731
732         if (df == NULL)
733         {
734                 /* skip next few clauses */
735                 /* EMPTY */
736         }
737         else if (sm_io_flush(df, SM_TIME_DEFAULT) != 0 || sm_io_error(df))
738         {
739                 dferror(df, "sm_io_flush||sm_io_error", e);
740                 flush_errors(true);
741                 finis(true, true, ExitStat);
742                 /* NOTREACHED */
743         }
744         else if (SuperSafe == SAFE_NO ||
745                  SuperSafe == SAFE_INTERACTIVE ||
746                  (SuperSafe == SAFE_REALLY_POSTMILTER && smtpmode))
747         {
748                 /* skip next few clauses */
749                 /* EMPTY */
750                 /* Note: updfs() is not called in this case! */
751         }
752         else if (sm_io_setinfo(df, SM_BF_COMMIT, NULL) < 0 && errno != EINVAL)
753         {
754                 int save_errno = errno;
755
756                 if (save_errno == EEXIST)
757                 {
758                         char *dfile;
759                         struct stat st;
760                         int dfd;
761
762                         dfile = queuename(e, DATAFL_LETTER);
763                         if (stat(dfile, &st) < 0)
764                                 st.st_size = -1;
765                         errno = EEXIST;
766                         syserr("@collect: bfcommit(%s): already on disk, size=%ld",
767                                dfile, (long) st.st_size);
768                         dfd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL);
769                         if (dfd >= 0)
770                                 dumpfd(dfd, true, true);
771                 }
772                 errno = save_errno;
773                 dferror(df, "bfcommit", e);
774                 flush_errors(true);
775                 finis(save_errno != EEXIST, true, ExitStat);
776         }
777         else if ((afd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL)) < 0)
778         {
779                 dferror(df, "sm_io_getinfo", e);
780                 flush_errors(true);
781                 finis(true, true, ExitStat);
782                 /* NOTREACHED */
783         }
784         else if (fsync(afd) < 0)
785         {
786                 dferror(df, "fsync", e);
787                 flush_errors(true);
788                 finis(true, true, ExitStat);
789                 /* NOTREACHED */
790         }
791         else if (sm_io_close(df, SM_TIME_DEFAULT) < 0)
792         {
793                 dferror(df, "sm_io_close", e);
794                 flush_errors(true);
795                 finis(true, true, ExitStat);
796                 /* NOTREACHED */
797         }
798         else
799         {
800                 /* everything is happily flushed to disk */
801                 df = NULL;
802
803                 /* remove from available space in filesystem */
804                 updfs(e, 0, 1, "collect");
805         }
806
807         /* An EOF when running SMTP is an error */
808   readabort:
809         if (inputerr && (OpMode == MD_SMTP || OpMode == MD_DAEMON))
810         {
811                 char *host;
812                 char *problem;
813                 ADDRESS *q;
814
815                 host = RealHostName;
816                 if (host == NULL)
817                         host = "localhost";
818
819                 if (sm_io_eof(fp))
820                         problem = "unexpected close";
821                 else if (sm_io_error(fp))
822                         problem = "I/O error";
823                 else
824                         problem = "read timeout";
825                 if (LogLevel > 0 && sm_io_eof(fp))
826                         sm_syslog(LOG_NOTICE, e->e_id,
827                                 "collect: %s on connection from %.100s, sender=%s",
828                                 problem, host,
829                                 shortenstring(e->e_from.q_paddr, MAXSHORTSTR));
830                 if (sm_io_eof(fp))
831                         usrerr("421 4.4.1 collect: %s on connection from %s, from=%s",
832                                 problem, host,
833                                 shortenstring(e->e_from.q_paddr, MAXSHORTSTR));
834                 else
835                         syserr("421 4.4.1 collect: %s on connection from %s, from=%s",
836                                 problem, host,
837                                 shortenstring(e->e_from.q_paddr, MAXSHORTSTR));
838                 flush_errors(true);
839
840                 /* don't return an error indication */
841                 e->e_to = NULL;
842                 e->e_flags &= ~EF_FATALERRS;
843                 e->e_flags |= EF_CLRQUEUE;
844
845                 /* Don't send any message notification to sender */
846                 for (q = e->e_sendqueue; q != NULL; q = q->q_next)
847                 {
848                         if (QS_IS_DEAD(q->q_state))
849                                 continue;
850                         q->q_state = QS_FATALERR;
851                 }
852
853                 (void) sm_io_close(df, SM_TIME_DEFAULT);
854                 df = NULL;
855                 finis(true, true, ExitStat);
856                 /* NOTREACHED */
857         }
858
859         /* Log collection information. */
860         if (tTd(92, 2))
861                 sm_dprintf("collect: e_id=%s, EF_LOGSENDER=%d, LogLevel=%d\n",
862                         e->e_id, bitset(EF_LOGSENDER, e->e_flags), LogLevel);
863         if (bitset(EF_LOGSENDER, e->e_flags) && LogLevel > 4)
864         {
865                 logsender(e, e->e_msgid);
866                 e->e_flags &= ~EF_LOGSENDER;
867         }
868
869         /* check for message too large */
870         if (bitset(EF_TOOBIG, e->e_flags))
871         {
872                 e->e_flags |= EF_NO_BODY_RETN|EF_CLRQUEUE;
873                 if (!bitset(EF_FATALERRS, e->e_flags))
874                 {
875                         e->e_status = "5.2.3";
876                         usrerrenh(e->e_status,
877                                 "552 Message exceeds maximum fixed size (%ld)",
878                                 MaxMessageSize);
879                         if (LogLevel > 6)
880                                 sm_syslog(LOG_NOTICE, e->e_id,
881                                         "message size (%ld) exceeds maximum (%ld)",
882                                         PRT_NONNEGL(e->e_msgsize),
883                                         MaxMessageSize);
884                 }
885         }
886
887         /* check for illegal 8-bit data */
888         if (HasEightBits)
889         {
890                 e->e_flags |= EF_HAS8BIT;
891                 if (!bitset(MM_PASS8BIT|MM_MIME8BIT, MimeMode) &&
892                     !bitset(EF_IS_MIME, e->e_flags))
893                 {
894                         e->e_status = "5.6.1";
895                         usrerrenh(e->e_status, "554 Eight bit data not allowed");
896                 }
897         }
898         else
899         {
900                 /* if it claimed to be 8 bits, well, it lied.... */
901                 if (e->e_bodytype != NULL &&
902                     sm_strcasecmp(e->e_bodytype, "8BITMIME") == 0)
903                         e->e_bodytype = "7BIT";
904         }
905
906 #if _FFR_REJECT_NUL_BYTE
907         if (hasNUL && RejectNUL)
908         {
909                 e->e_status = "5.6.1";
910                 usrerrenh(e->e_status, "554 NUL byte not allowed");
911         }
912 #endif /* _FFR_REJECT_NUL_BYTE */
913
914         if (SuperSafe == SAFE_REALLY && !bitset(EF_FATALERRS, e->e_flags))
915         {
916                 char *dfname = queuename(e, DATAFL_LETTER);
917                 if ((e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname,
918                                            SM_IO_RDONLY_B, NULL)) == NULL)
919                 {
920                         /* we haven't acked receipt yet, so just chuck this */
921                         syserr("@Cannot reopen %s", dfname);
922                         finis(true, true, ExitStat);
923                         /* NOTREACHED */
924                 }
925         }
926         else
927                 e->e_dfp = df;
928
929         /* collect statistics */
930         if (OpMode != MD_VERIFY)
931         {
932                 /*
933                 **  Recalculate e_msgpriority, it is done at in eatheader()
934                 **  which is called (in 8.12) after the header is collected,
935                 **  hence e_msgsize is (most likely) incorrect.
936                 */
937
938                 e->e_msgpriority = e->e_msgsize
939                                  - e->e_class * WkClassFact
940                                  + e->e_nrcpts * WkRecipFact;
941                 markstats(e, (ADDRESS *) NULL, STATS_NORMAL);
942         }
943 }
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 */