collect.c revision 159609
1/*
2 * Copyright (c) 1998-2006 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
16SM_RCSID("@(#)$Id: collect.c,v 8.273 2006/03/31 18:51:47 ca Exp $")
17
18static void	eatfrom __P((char *volatile, ENVELOPE *));
19static void	collect_doheader __P((ENVELOPE *));
20static SM_FILE_T *collect_dfopen __P((ENVELOPE *));
21static 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
46static SM_FILE_T *
47collect_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);
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
91static void
92collect_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);
148			break;
149
150		  case NRA_ADD_TO_UNDISCLOSED:
151			addheader("To", "undisclosed-recipients:;", 0, e);
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);
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
193static SM_FILE_T *
194collect_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
278void
279collect(fp, smtpmode, hdrp, e, rsetsize)
280	SM_FILE_T *fp;
281	bool smtpmode;
282	HDR **hdrp;
283	register ENVELOPE *e;
284	bool rsetsize;
285{
286	register SM_FILE_T *df;
287	bool ignrdot;
288	int dbto;
289	register char *bp;
290	int c;
291	bool inputerr;
292	bool headeronly;
293	char *buf;
294	int buflen;
295	int istate;
296	int mstate;
297	int hdrslen;
298	int numhdrs;
299	int afd;
300	unsigned char *pbp;
301	unsigned char peekbuf[8];
302	char bufbuf[MAXLINE];
303
304	df = NULL;
305	ignrdot = smtpmode ? false : IgnrDot;
306
307	/* timeout for I/O functions is in milliseconds */
308	dbto = smtpmode ? ((int) TimeOuts.to_datablock * 1000)
309			: SM_TIME_FOREVER;
310	sm_io_setinfo(fp, SM_IO_WHAT_TIMEOUT, &dbto);
311	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
323	/*
324	**  Tell ARPANET to go ahead.
325	*/
326
327	if (smtpmode)
328		message("354 Enter mail, end with \".\" on a line by itself");
329
330	/* simulate an I/O timeout when used as sink */
331	if (tTd(83, 101))
332		sleep(319);
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 (rsetsize)
347		e->e_msgsize = 0;
348	for (;;)
349	{
350		if (tTd(30, 35))
351			sm_dprintf("top, istate=%d, mstate=%d\n", istate,
352				   mstate);
353		for (;;)
354		{
355			if (pbp > peekbuf)
356				c = *--pbp;
357			else
358			{
359				while (!sm_io_eof(fp) && !sm_io_error(fp))
360				{
361					errno = 0;
362					c = sm_io_getc(fp, SM_TIME_DEFAULT);
363					if (c == SM_IO_EOF && errno == EINTR)
364					{
365						/* Interrupted, retry */
366						sm_io_clearerr(fp);
367						continue;
368					}
369
370					/* timeout? */
371					if (c == SM_IO_EOF && errno == EAGAIN
372					    && smtpmode)
373					{
374						/*
375						**  Override e_message in
376						**  usrerr() as this is the
377						**  reason for failure that
378						**  should be logged for
379						**  undelivered recipients.
380						*/
381
382						e->e_message = NULL;
383						errno = 0;
384						inputerr = true;
385						goto readabort;
386					}
387					break;
388				}
389				if (TrafficLogFile != NULL && !headeronly)
390				{
391					if (istate == IS_BOL)
392						(void) sm_io_fprintf(TrafficLogFile,
393							SM_TIME_DEFAULT,
394							"%05d <<< ",
395							(int) CurrentPid);
396					if (c == SM_IO_EOF)
397						(void) sm_io_fprintf(TrafficLogFile,
398							SM_TIME_DEFAULT,
399							"[EOF]\n");
400					else
401						(void) sm_io_putc(TrafficLogFile,
402							SM_TIME_DEFAULT,
403							c);
404				}
405				if (c == SM_IO_EOF)
406					goto readerr;
407				if (SevenBitInput)
408					c &= 0x7f;
409				else
410					HasEightBits |= bitset(0x80, c);
411			}
412			if (tTd(30, 94))
413				sm_dprintf("istate=%d, c=%c (0x%x)\n",
414					istate, (char) c, c);
415			switch (istate)
416			{
417			  case IS_BOL:
418				if (c == '.')
419				{
420					istate = IS_DOT;
421					continue;
422				}
423				break;
424
425			  case IS_DOT:
426				if (c == '\n' && !ignrdot &&
427				    !bitset(EF_NL_NOT_EOL, e->e_flags))
428					goto readerr;
429				else if (c == '\r' &&
430					 !bitset(EF_CRLF_NOT_EOL, e->e_flags))
431				{
432					istate = IS_DOTCR;
433					continue;
434				}
435				else if (ignrdot ||
436					 (c != '.' &&
437					  OpMode != MD_SMTP &&
438					  OpMode != MD_DAEMON &&
439					  OpMode != MD_ARPAFTP))
440
441				{
442					SM_ASSERT(pbp < peekbuf +
443							sizeof(peekbuf));
444					*pbp++ = c;
445					c = '.';
446				}
447				break;
448
449			  case IS_DOTCR:
450				if (c == '\n' && !ignrdot)
451					goto readerr;
452				else
453				{
454					/* push back the ".\rx" */
455					SM_ASSERT(pbp < peekbuf +
456							sizeof(peekbuf));
457					*pbp++ = c;
458					if (OpMode != MD_SMTP &&
459					    OpMode != MD_DAEMON &&
460					    OpMode != MD_ARPAFTP)
461					{
462						SM_ASSERT(pbp < peekbuf +
463							 sizeof(peekbuf));
464						*pbp++ = '\r';
465						c = '.';
466					}
467					else
468						c = '\r';
469				}
470				break;
471
472			  case IS_CR:
473				if (c == '\n')
474					istate = IS_BOL;
475				else
476				{
477					(void) sm_io_ungetc(fp, SM_TIME_DEFAULT,
478							    c);
479					c = '\r';
480					istate = IS_NORM;
481				}
482				goto bufferchar;
483			}
484
485			if (c == '\r' && !bitset(EF_CRLF_NOT_EOL, e->e_flags))
486			{
487				istate = IS_CR;
488				continue;
489			}
490			else if (c == '\n' && !bitset(EF_NL_NOT_EOL,
491						      e->e_flags))
492				istate = IS_BOL;
493			else
494				istate = IS_NORM;
495
496bufferchar:
497			if (!headeronly)
498			{
499				/* no overflow? */
500				if (e->e_msgsize >= 0)
501				{
502					e->e_msgsize++;
503					if (MaxMessageSize > 0 &&
504					    !bitset(EF_TOOBIG, e->e_flags) &&
505					    e->e_msgsize > MaxMessageSize)
506						 e->e_flags |= EF_TOOBIG;
507				}
508			}
509			switch (mstate)
510			{
511			  case MS_BODY:
512				/* just put the character out */
513				if (!bitset(EF_TOOBIG, e->e_flags))
514					(void) sm_io_putc(df, SM_TIME_DEFAULT,
515							  c);
516
517				/* FALLTHROUGH */
518
519			  case MS_DISCARD:
520				continue;
521			}
522
523			SM_ASSERT(mstate == MS_UFROM || mstate == MS_HEADER);
524
525			/* header -- buffer up */
526			if (bp >= &buf[buflen - 2])
527			{
528				char *obuf;
529
530				/* out of space for header */
531				obuf = buf;
532				if (buflen < MEMCHUNKSIZE)
533					buflen *= 2;
534				else
535					buflen += MEMCHUNKSIZE;
536				if (buflen <= 0)
537				{
538					sm_syslog(LOG_NOTICE, e->e_id,
539						  "header overflow from %s during message collect",
540						  CURHOSTNAME);
541					errno = 0;
542					e->e_flags |= EF_CLRQUEUE;
543					e->e_status = "5.6.0";
544					usrerrenh(e->e_status,
545						  "552 Headers too large");
546					goto discard;
547				}
548				buf = xalloc(buflen);
549				memmove(buf, obuf, bp - obuf);
550				bp = &buf[bp - obuf];
551				if (obuf != bufbuf)
552					sm_free(obuf);  /* XXX */
553			}
554
555			/*
556			**  XXX Notice: the logic here is broken.
557			**  An input to sendmail that doesn't contain a
558			**  header but starts immediately with the body whose
559			**  first line contain characters which match the
560			**  following "if" will cause problems: those
561			**  characters will NOT appear in the output...
562			**  Do we care?
563			*/
564
565			if (c >= 0200 && c <= 0237)
566			{
567#if 0	/* causes complaints -- figure out something for 8.n+1 */
568				usrerr("Illegal character 0x%x in header", c);
569#else /* 0 */
570				/* EMPTY */
571#endif /* 0 */
572			}
573			else if (c != '\0')
574			{
575				*bp++ = c;
576				++hdrslen;
577				if (!headeronly &&
578				    MaxHeadersLength > 0 &&
579				    hdrslen > MaxHeadersLength)
580				{
581					sm_syslog(LOG_NOTICE, e->e_id,
582						  "headers too large (%d max) from %s during message collect",
583						  MaxHeadersLength,
584						  CURHOSTNAME);
585					errno = 0;
586					e->e_flags |= EF_CLRQUEUE;
587					e->e_status = "5.6.0";
588					usrerrenh(e->e_status,
589						  "552 Headers too large (%d max)",
590						  MaxHeadersLength);
591  discard:
592					mstate = MS_DISCARD;
593				}
594			}
595			if (istate == IS_BOL)
596				break;
597		}
598		*bp = '\0';
599
600nextstate:
601		if (tTd(30, 35))
602			sm_dprintf("nextstate, istate=%d, mstate=%d, line = \"%s\"\n",
603				istate, mstate, buf);
604		switch (mstate)
605		{
606		  case MS_UFROM:
607			mstate = MS_HEADER;
608#ifndef NOTUNIX
609			if (strncmp(buf, "From ", 5) == 0)
610			{
611				bp = buf;
612				eatfrom(buf, e);
613				continue;
614			}
615#endif /* ! NOTUNIX */
616			/* FALLTHROUGH */
617
618		  case MS_HEADER:
619			if (!isheader(buf))
620			{
621				mstate = MS_BODY;
622				goto nextstate;
623			}
624
625			/* check for possible continuation line */
626			do
627			{
628				sm_io_clearerr(fp);
629				errno = 0;
630				c = sm_io_getc(fp, SM_TIME_DEFAULT);
631
632				/* timeout? */
633				if (c == SM_IO_EOF && errno == EAGAIN
634				    && smtpmode)
635				{
636					/*
637					**  Override e_message in
638					**  usrerr() as this is the
639					**  reason for failure that
640					**  should be logged for
641					**  undelivered recipients.
642					*/
643
644					e->e_message = NULL;
645					errno = 0;
646					inputerr = true;
647					goto readabort;
648				}
649			} while (c == SM_IO_EOF && errno == EINTR);
650			if (c != SM_IO_EOF)
651				(void) sm_io_ungetc(fp, SM_TIME_DEFAULT, c);
652			if (c == ' ' || c == '\t')
653			{
654				/* yep -- defer this */
655				continue;
656			}
657
658			SM_ASSERT(bp > buf);
659
660			/* guaranteed by isheader(buf) */
661			SM_ASSERT(*(bp - 1) != '\n' || bp > buf + 1);
662
663			/* trim off trailing CRLF or NL */
664			if (*--bp != '\n' || *--bp != '\r')
665				bp++;
666			*bp = '\0';
667
668			if (bitset(H_EOH, chompheader(buf,
669						      CHHDR_CHECK | CHHDR_USER,
670						      hdrp, e)))
671			{
672				mstate = MS_BODY;
673				goto nextstate;
674			}
675			numhdrs++;
676			break;
677
678		  case MS_BODY:
679			if (tTd(30, 1))
680				sm_dprintf("EOH\n");
681
682			if (headeronly)
683				goto readerr;
684
685			df = collect_eoh(e, numhdrs, hdrslen);
686			if (df == NULL)
687				e->e_flags |= EF_TOOBIG;
688
689			bp = buf;
690
691			/* toss blank line */
692			if ((!bitset(EF_CRLF_NOT_EOL, e->e_flags) &&
693				bp[0] == '\r' && bp[1] == '\n') ||
694			    (!bitset(EF_NL_NOT_EOL, e->e_flags) &&
695				bp[0] == '\n'))
696			{
697				break;
698			}
699
700			/* if not a blank separator, write it out */
701			if (!bitset(EF_TOOBIG, e->e_flags))
702			{
703				while (*bp != '\0')
704					(void) sm_io_putc(df, SM_TIME_DEFAULT,
705							  *bp++);
706			}
707			break;
708		}
709		bp = buf;
710	}
711
712readerr:
713	if ((sm_io_eof(fp) && smtpmode) || sm_io_error(fp))
714	{
715		const char *errmsg;
716
717		if (sm_io_eof(fp))
718			errmsg = "unexpected close";
719		else
720			errmsg = sm_errstring(errno);
721		if (tTd(30, 1))
722			sm_dprintf("collect: premature EOM: %s\n", errmsg);
723		if (LogLevel > 1)
724			sm_syslog(LOG_WARNING, e->e_id,
725				"collect: premature EOM: %s", errmsg);
726		inputerr = true;
727	}
728
729	if (headeronly)
730		return;
731
732	if (mstate != MS_BODY)
733	{
734		/* no body or discard, so we never opened the data file */
735		SM_ASSERT(df == NULL);
736		df = collect_eoh(e, numhdrs, hdrslen);
737	}
738
739	if (df == NULL)
740	{
741		/* skip next few clauses */
742		/* EMPTY */
743	}
744	else if (sm_io_flush(df, SM_TIME_DEFAULT) != 0 || sm_io_error(df))
745	{
746		dferror(df, "sm_io_flush||sm_io_error", e);
747		flush_errors(true);
748		finis(true, true, ExitStat);
749		/* NOTREACHED */
750	}
751	else if (SuperSafe == SAFE_NO ||
752		 SuperSafe == SAFE_INTERACTIVE ||
753		 (SuperSafe == SAFE_REALLY_POSTMILTER && smtpmode))
754	{
755		/* skip next few clauses */
756		/* EMPTY */
757		/* Note: updfs() is not called in this case! */
758	}
759	else if (sm_io_setinfo(df, SM_BF_COMMIT, NULL) < 0 && errno != EINVAL)
760	{
761		int save_errno = errno;
762
763		if (save_errno == EEXIST)
764		{
765			char *dfile;
766			struct stat st;
767			int dfd;
768
769			dfile = queuename(e, DATAFL_LETTER);
770			if (stat(dfile, &st) < 0)
771				st.st_size = -1;
772			errno = EEXIST;
773			syserr("@collect: bfcommit(%s): already on disk, size=%ld",
774			       dfile, (long) st.st_size);
775			dfd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL);
776			if (dfd >= 0)
777				dumpfd(dfd, true, true);
778		}
779		errno = save_errno;
780		dferror(df, "bfcommit", e);
781		flush_errors(true);
782		finis(save_errno != EEXIST, true, ExitStat);
783	}
784	else if ((afd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL)) < 0)
785	{
786		dferror(df, "sm_io_getinfo", e);
787		flush_errors(true);
788		finis(true, true, ExitStat);
789		/* NOTREACHED */
790	}
791	else if (fsync(afd) < 0)
792	{
793		dferror(df, "fsync", e);
794		flush_errors(true);
795		finis(true, true, ExitStat);
796		/* NOTREACHED */
797	}
798	else if (sm_io_close(df, SM_TIME_DEFAULT) < 0)
799	{
800		dferror(df, "sm_io_close", e);
801		flush_errors(true);
802		finis(true, true, ExitStat);
803		/* NOTREACHED */
804	}
805	else
806	{
807		/* everything is happily flushed to disk */
808		df = NULL;
809
810		/* remove from available space in filesystem */
811		updfs(e, 0, 1, "collect");
812	}
813
814	/* An EOF when running SMTP is an error */
815  readabort:
816	if (inputerr && (OpMode == MD_SMTP || OpMode == MD_DAEMON))
817	{
818		char *host;
819		char *problem;
820		ADDRESS *q;
821
822		host = RealHostName;
823		if (host == NULL)
824			host = "localhost";
825
826		if (sm_io_eof(fp))
827			problem = "unexpected close";
828		else if (sm_io_error(fp))
829			problem = "I/O error";
830		else
831			problem = "read timeout";
832		if (LogLevel > 0 && sm_io_eof(fp))
833			sm_syslog(LOG_NOTICE, e->e_id,
834				"collect: %s on connection from %.100s, sender=%s",
835				problem, host,
836				shortenstring(e->e_from.q_paddr, MAXSHORTSTR));
837		if (sm_io_eof(fp))
838			usrerr("421 4.4.1 collect: %s on connection from %s, from=%s",
839				problem, host,
840				shortenstring(e->e_from.q_paddr, MAXSHORTSTR));
841		else
842			syserr("421 4.4.1 collect: %s on connection from %s, from=%s",
843				problem, host,
844				shortenstring(e->e_from.q_paddr, MAXSHORTSTR));
845		flush_errors(true);
846
847		/* don't return an error indication */
848		e->e_to = NULL;
849		e->e_flags &= ~EF_FATALERRS;
850		e->e_flags |= EF_CLRQUEUE;
851
852		/* Don't send any message notification to sender */
853		for (q = e->e_sendqueue; q != NULL; q = q->q_next)
854		{
855			if (QS_IS_DEAD(q->q_state))
856				continue;
857			q->q_state = QS_FATALERR;
858		}
859
860		(void) sm_io_close(df, SM_TIME_DEFAULT);
861		df = NULL;
862		finis(true, true, ExitStat);
863		/* NOTREACHED */
864	}
865
866	/* Log collection information. */
867	if (bitset(EF_LOGSENDER, e->e_flags) && LogLevel > 4)
868	{
869		logsender(e, e->e_msgid);
870		e->e_flags &= ~EF_LOGSENDER;
871	}
872
873	/* check for message too large */
874	if (bitset(EF_TOOBIG, e->e_flags))
875	{
876		e->e_flags |= EF_NO_BODY_RETN|EF_CLRQUEUE;
877		if (!bitset(EF_FATALERRS, e->e_flags))
878		{
879			e->e_status = "5.2.3";
880			usrerrenh(e->e_status,
881				"552 Message exceeds maximum fixed size (%ld)",
882				MaxMessageSize);
883			if (LogLevel > 6)
884				sm_syslog(LOG_NOTICE, e->e_id,
885					"message size (%ld) exceeds maximum (%ld)",
886					e->e_msgsize, MaxMessageSize);
887		}
888	}
889
890	/* check for illegal 8-bit data */
891	if (HasEightBits)
892	{
893		e->e_flags |= EF_HAS8BIT;
894		if (!bitset(MM_PASS8BIT|MM_MIME8BIT, MimeMode) &&
895		    !bitset(EF_IS_MIME, e->e_flags))
896		{
897			e->e_status = "5.6.1";
898			usrerrenh(e->e_status, "554 Eight bit data not allowed");
899		}
900	}
901	else
902	{
903		/* if it claimed to be 8 bits, well, it lied.... */
904		if (e->e_bodytype != NULL &&
905		    sm_strcasecmp(e->e_bodytype, "8BITMIME") == 0)
906			e->e_bodytype = "7BIT";
907	}
908
909	if (SuperSafe == SAFE_REALLY && !bitset(EF_FATALERRS, e->e_flags))
910	{
911		char *dfname = queuename(e, DATAFL_LETTER);
912		if ((e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname,
913					   SM_IO_RDONLY_B, NULL)) == NULL)
914		{
915			/* we haven't acked receipt yet, so just chuck this */
916			syserr("@Cannot reopen %s", dfname);
917			finis(true, true, ExitStat);
918			/* NOTREACHED */
919		}
920	}
921	else
922		e->e_dfp = df;
923
924	/* collect statistics */
925	if (OpMode != MD_VERIFY)
926	{
927		/*
928		**  Recalculate e_msgpriority, it is done at in eatheader()
929		**  which is called (in 8.12) after the header is collected,
930		**  hence e_msgsize is (most likely) incorrect.
931		*/
932
933		e->e_msgpriority = e->e_msgsize
934				 - e->e_class * WkClassFact
935				 + e->e_nrcpts * WkRecipFact;
936		markstats(e, (ADDRESS *) NULL, STATS_NORMAL);
937	}
938}
939
940/*
941**  DFERROR -- signal error on writing the data file.
942**
943**	Called by collect().  Collect() always terminates the process
944**	immediately after calling dferror(), which means that the SMTP
945**	session will be terminated, which means that any error message
946**	issued by dferror must be a 421 error, as per RFC 821.
947**
948**	Parameters:
949**		df -- the file pointer for the data file.
950**		msg -- detailed message.
951**		e -- the current envelope.
952**
953**	Returns:
954**		none.
955**
956**	Side Effects:
957**		Gives an error message.
958**		Arranges for following output to go elsewhere.
959*/
960
961void
962dferror(df, msg, e)
963	SM_FILE_T *volatile df;
964	char *msg;
965	register ENVELOPE *e;
966{
967	char *dfname;
968
969	dfname = queuename(e, DATAFL_LETTER);
970	setstat(EX_IOERR);
971	if (errno == ENOSPC)
972	{
973#if STAT64 > 0
974		struct stat64 st;
975#else /* STAT64 > 0 */
976		struct stat st;
977#endif /* STAT64 > 0 */
978		long avail;
979		long bsize;
980
981		e->e_flags |= EF_NO_BODY_RETN;
982
983		if (
984#if STAT64 > 0
985		    fstat64(sm_io_getinfo(df, SM_IO_WHAT_FD, NULL), &st)
986#else /* STAT64 > 0 */
987		    fstat(sm_io_getinfo(df, SM_IO_WHAT_FD, NULL), &st)
988#endif /* STAT64 > 0 */
989		    < 0)
990		  st.st_size = 0;
991		(void) sm_io_reopen(SmFtStdio, SM_TIME_DEFAULT, dfname,
992				    SM_IO_WRONLY_B, NULL, df);
993		if (st.st_size <= 0)
994			(void) sm_io_fprintf(df, SM_TIME_DEFAULT,
995				"\n*** Mail could not be accepted");
996		else
997			(void) sm_io_fprintf(df, SM_TIME_DEFAULT,
998				"\n*** Mail of at least %llu bytes could not be accepted\n",
999				(ULONGLONG_T) st.st_size);
1000		(void) sm_io_fprintf(df, SM_TIME_DEFAULT,
1001			"*** at %s due to lack of disk space for temp file.\n",
1002			MyHostName);
1003		avail = freediskspace(qid_printqueue(e->e_qgrp, e->e_qdir),
1004				      &bsize);
1005		if (avail > 0)
1006		{
1007			if (bsize > 1024)
1008				avail *= bsize / 1024;
1009			else if (bsize < 1024)
1010				avail /= 1024 / bsize;
1011			(void) sm_io_fprintf(df, SM_TIME_DEFAULT,
1012				"*** Currently, %ld kilobytes are available for mail temp files.\n",
1013				avail);
1014		}
1015#if 0
1016		/* Wrong response code; should be 421. */
1017		e->e_status = "4.3.1";
1018		usrerrenh(e->e_status, "452 Out of disk space for temp file");
1019#else /* 0 */
1020		syserr("421 4.3.1 Out of disk space for temp file");
1021#endif /* 0 */
1022	}
1023	else
1024		syserr("421 4.3.0 collect: Cannot write %s (%s, uid=%d, gid=%d)",
1025			dfname, msg, (int) geteuid(), (int) getegid());
1026	if (sm_io_reopen(SmFtStdio, SM_TIME_DEFAULT, SM_PATH_DEVNULL,
1027			 SM_IO_WRONLY, NULL, df) == NULL)
1028		sm_syslog(LOG_ERR, e->e_id,
1029			  "dferror: sm_io_reopen(\"/dev/null\") failed: %s",
1030			  sm_errstring(errno));
1031}
1032/*
1033**  EATFROM -- chew up a UNIX style from line and process
1034**
1035**	This does indeed make some assumptions about the format
1036**	of UNIX messages.
1037**
1038**	Parameters:
1039**		fm -- the from line.
1040**		e -- envelope
1041**
1042**	Returns:
1043**		none.
1044**
1045**	Side Effects:
1046**		extracts what information it can from the header,
1047**		such as the date.
1048*/
1049
1050#ifndef NOTUNIX
1051
1052static char	*DowList[] =
1053{
1054	"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL
1055};
1056
1057static char	*MonthList[] =
1058{
1059	"Jan", "Feb", "Mar", "Apr", "May", "Jun",
1060	"Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
1061	NULL
1062};
1063
1064static void
1065eatfrom(fm, e)
1066	char *volatile fm;
1067	register ENVELOPE *e;
1068{
1069	register char *p;
1070	register char **dt;
1071
1072	if (tTd(30, 2))
1073		sm_dprintf("eatfrom(%s)\n", fm);
1074
1075	/* find the date part */
1076	p = fm;
1077	while (*p != '\0')
1078	{
1079		/* skip a word */
1080		while (*p != '\0' && *p != ' ')
1081			p++;
1082		while (*p == ' ')
1083			p++;
1084		if (strlen(p) < 17)
1085		{
1086			/* no room for the date */
1087			return;
1088		}
1089		if (!(isascii(*p) && isupper(*p)) ||
1090		    p[3] != ' ' || p[13] != ':' || p[16] != ':')
1091			continue;
1092
1093		/* we have a possible date */
1094		for (dt = DowList; *dt != NULL; dt++)
1095			if (strncmp(*dt, p, 3) == 0)
1096				break;
1097		if (*dt == NULL)
1098			continue;
1099
1100		for (dt = MonthList; *dt != NULL; dt++)
1101		{
1102			if (strncmp(*dt, &p[4], 3) == 0)
1103				break;
1104		}
1105		if (*dt != NULL)
1106			break;
1107	}
1108
1109	if (*p != '\0')
1110	{
1111		char *q, buf[25];
1112
1113		/* we have found a date */
1114		(void) sm_strlcpy(buf, p, sizeof(buf));
1115		q = arpadate(buf);
1116		macdefine(&e->e_macro, A_TEMP, 'a', q);
1117	}
1118}
1119#endif /* ! NOTUNIX */
1120