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