xref: /freebsd/contrib/sendmail/src/envelope.c (revision 5521ff5a4d1929056e7ffc982fac3341ca54df7c)
1 /*
2  * Copyright (c) 1998-2001 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 #ifndef lint
15 static char id[] = "@(#)$Id: envelope.c,v 8.180.14.10 2001/05/03 17:24:06 gshapiro Exp $";
16 #endif /* ! lint */
17 
18 #include <sendmail.h>
19 
20 
21 /*
22 **  NEWENVELOPE -- allocate a new envelope
23 **
24 **	Supports inheritance.
25 **
26 **	Parameters:
27 **		e -- the new envelope to fill in.
28 **		parent -- the envelope to be the parent of e.
29 **
30 **	Returns:
31 **		e.
32 **
33 **	Side Effects:
34 **		none.
35 */
36 
37 ENVELOPE *
38 newenvelope(e, parent)
39 	register ENVELOPE *e;
40 	register ENVELOPE *parent;
41 {
42 	if (e == parent && e->e_parent != NULL)
43 		parent = e->e_parent;
44 	clearenvelope(e, TRUE);
45 	if (e == CurEnv)
46 		memmove((char *) &e->e_from,
47 			(char *) &NullAddress,
48 			sizeof e->e_from);
49 	else
50 		memmove((char *) &e->e_from,
51 			(char *) &CurEnv->e_from,
52 			sizeof e->e_from);
53 	e->e_parent = parent;
54 	assign_queueid(e);
55 	e->e_ctime = curtime();
56 	if (parent != NULL)
57 		e->e_msgpriority = parent->e_msgsize;
58 	e->e_puthdr = putheader;
59 	e->e_putbody = putbody;
60 	if (CurEnv->e_xfp != NULL)
61 		(void) fflush(CurEnv->e_xfp);
62 
63 	return e;
64 }
65 /*
66 **  DROPENVELOPE -- deallocate an envelope.
67 **
68 **	Parameters:
69 **		e -- the envelope to deallocate.
70 **		fulldrop -- if set, do return receipts.
71 **
72 **	Returns:
73 **		none.
74 **
75 **	Side Effects:
76 **		housekeeping necessary to dispose of an envelope.
77 **		Unlocks this queue file.
78 */
79 
80 void
81 dropenvelope(e, fulldrop)
82 	register ENVELOPE *e;
83 	bool fulldrop;
84 {
85 	bool queueit = FALSE;
86 	bool message_timeout = FALSE;
87 	bool failure_return = FALSE;
88 	bool delay_return = FALSE;
89 	bool success_return = FALSE;
90 	bool pmnotify = bitset(EF_PM_NOTIFY, e->e_flags);
91 	bool done = FALSE;
92 	register ADDRESS *q;
93 	char *id = e->e_id;
94 	time_t now;
95 	char buf[MAXLINE];
96 
97 	if (tTd(50, 1))
98 	{
99 		dprintf("dropenvelope %lx: id=", (u_long) e);
100 		xputs(e->e_id);
101 		dprintf(", flags=");
102 		printenvflags(e);
103 		if (tTd(50, 10))
104 		{
105 			dprintf("sendq=");
106 			printaddr(e->e_sendqueue, TRUE);
107 		}
108 	}
109 
110 	if (LogLevel > 84)
111 		sm_syslog(LOG_DEBUG, id,
112 			  "dropenvelope, e_flags=0x%lx, OpMode=%c, pid=%d",
113 			  e->e_flags, OpMode, getpid());
114 
115 	/* we must have an id to remove disk files */
116 	if (id == NULL)
117 		return;
118 
119 	/* if verify-only mode, we can skip most of this */
120 	if (OpMode == MD_VERIFY)
121 		goto simpledrop;
122 
123 	if (LogLevel > 4 && bitset(EF_LOGSENDER, e->e_flags))
124 		logsender(e, NULL);
125 	e->e_flags &= ~EF_LOGSENDER;
126 
127 	/* post statistics */
128 	poststats(StatFile);
129 
130 	/*
131 	**  Extract state information from dregs of send list.
132 	*/
133 
134 	now = curtime();
135 	if (now >= e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass])
136 		message_timeout = TRUE;
137 
138 	if (TimeOuts.to_q_return[e->e_timeoutclass] == NOW &&
139 	    !bitset(EF_RESPONSE, e->e_flags))
140 	{
141 		message_timeout = TRUE;
142 		e->e_flags |= EF_FATALERRS|EF_CLRQUEUE;
143 	}
144 
145 	e->e_flags &= ~EF_QUEUERUN;
146 	for (q = e->e_sendqueue; q != NULL; q = q->q_next)
147 	{
148 		if (QS_IS_UNDELIVERED(q->q_state))
149 			queueit = TRUE;
150 
151 		/* see if a notification is needed */
152 		if (bitset(QPINGONFAILURE, q->q_flags) &&
153 		    ((message_timeout && QS_IS_UNDELIVERED(q->q_state)) ||
154 		     QS_IS_BADADDR(q->q_state) ||
155 		     (TimeOuts.to_q_return[e->e_timeoutclass] == NOW &&
156 		      !bitset(EF_RESPONSE, e->e_flags))))
157 
158 		{
159 			failure_return = TRUE;
160 			if (!done && q->q_owner == NULL &&
161 			    !emptyaddr(&e->e_from))
162 			{
163 				(void) sendtolist(e->e_from.q_paddr, NULLADDR,
164 						  &e->e_errorqueue, 0, e);
165 				done = TRUE;
166 			}
167 		}
168 		else if (bitset(QPINGONSUCCESS, q->q_flags) &&
169 			 ((QS_IS_SENT(q->q_state) &&
170 			   bitnset(M_LOCALMAILER, q->q_mailer->m_flags)) ||
171 			  bitset(QRELAYED|QEXPANDED|QDELIVERED, q->q_flags)))
172 		{
173 			success_return = TRUE;
174 		}
175 	}
176 
177 	if (e->e_class < 0)
178 		e->e_flags |= EF_NO_BODY_RETN;
179 
180 	/*
181 	**  See if the message timed out.
182 	*/
183 
184 	if (!queueit)
185 		/* EMPTY */
186 		/* nothing to do */ ;
187 	else if (message_timeout)
188 	{
189 		if (failure_return)
190 		{
191 			(void) snprintf(buf, sizeof buf,
192 					"Cannot send message for %s",
193 					pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE));
194 			if (e->e_message != NULL)
195 				sm_free(e->e_message);
196 			e->e_message = newstr(buf);
197 			message(buf);
198 			e->e_flags |= EF_CLRQUEUE;
199 		}
200 		fprintf(e->e_xfp, "Message could not be delivered for %s\n",
201 			pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE));
202 		fprintf(e->e_xfp, "Message will be deleted from queue\n");
203 		for (q = e->e_sendqueue; q != NULL; q = q->q_next)
204 		{
205 			if (QS_IS_UNDELIVERED(q->q_state))
206 			{
207 				q->q_state = QS_BADADDR;
208 				q->q_status = "4.4.7";
209 			}
210 		}
211 	}
212 	else if (TimeOuts.to_q_warning[e->e_timeoutclass] > 0 &&
213 		 now >= e->e_ctime + TimeOuts.to_q_warning[e->e_timeoutclass])
214 	{
215 		if (!bitset(EF_WARNING|EF_RESPONSE, e->e_flags) &&
216 		    e->e_class >= 0 &&
217 		    e->e_from.q_paddr != NULL &&
218 		    strcmp(e->e_from.q_paddr, "<>") != 0 &&
219 		    strncasecmp(e->e_from.q_paddr, "owner-", 6) != 0 &&
220 		    (strlen(e->e_from.q_paddr) <= (SIZE_T) 8 ||
221 		     strcasecmp(&e->e_from.q_paddr[strlen(e->e_from.q_paddr) - 8], "-request") != 0))
222 		{
223 			for (q = e->e_sendqueue; q != NULL; q = q->q_next)
224 			{
225 				if (QS_IS_UNDELIVERED(q->q_state) &&
226 #if _FFR_NODELAYDSN_ON_HOLD
227 				    !bitnset(M_HOLD, q->q_mailer->m_flags) &&
228 #endif /* _FFR_NODELAYDSN_ON_HOLD */
229 				    bitset(QPINGONDELAY, q->q_flags))
230 				{
231 					q->q_flags |= QDELAYED;
232 					delay_return = TRUE;
233 				}
234 			}
235 		}
236 		if (delay_return)
237 		{
238 			(void) snprintf(buf, sizeof buf,
239 				"Warning: could not send message for past %s",
240 				pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE));
241 			if (e->e_message != NULL)
242 				sm_free(e->e_message);
243 			e->e_message = newstr(buf);
244 			message(buf);
245 			e->e_flags |= EF_WARNING;
246 		}
247 		fprintf(e->e_xfp,
248 			"Warning: message still undelivered after %s\n",
249 			pintvl(TimeOuts.to_q_warning[e->e_timeoutclass], FALSE));
250 		fprintf(e->e_xfp, "Will keep trying until message is %s old\n",
251 			pintvl(TimeOuts.to_q_return[e->e_timeoutclass], FALSE));
252 	}
253 
254 	if (tTd(50, 2))
255 		dprintf("failure_return=%d delay_return=%d success_return=%d queueit=%d\n",
256 			failure_return, delay_return, success_return, queueit);
257 
258 	/*
259 	**  If we had some fatal error, but no addresses are marked as
260 	**  bad, mark them _all_ as bad.
261 	*/
262 
263 	if (bitset(EF_FATALERRS, e->e_flags) && !failure_return)
264 	{
265 		for (q = e->e_sendqueue; q != NULL; q = q->q_next)
266 		{
267 			if ((QS_IS_OK(q->q_state) ||
268 			     QS_IS_VERIFIED(q->q_state)) &&
269 			    bitset(QPINGONFAILURE, q->q_flags))
270 			{
271 				failure_return = TRUE;
272 				q->q_state = QS_BADADDR;
273 			}
274 		}
275 	}
276 
277 	/*
278 	**  Send back return receipts as requested.
279 	*/
280 
281 	if (success_return && !failure_return && !delay_return && fulldrop &&
282 	    !bitset(PRIV_NORECEIPTS, PrivacyFlags) &&
283 	    strcmp(e->e_from.q_paddr, "<>") != 0)
284 	{
285 		auto ADDRESS *rlist = NULL;
286 
287 		if (tTd(50, 8))
288 			dprintf("dropenvelope(%s): sending return receipt\n",
289 				id);
290 		e->e_flags |= EF_SENDRECEIPT;
291 		(void) sendtolist(e->e_from.q_paddr, NULLADDR, &rlist, 0, e);
292 		(void) returntosender("Return receipt", rlist, RTSF_NO_BODY, e);
293 	}
294 	e->e_flags &= ~EF_SENDRECEIPT;
295 
296 	/*
297 	**  Arrange to send error messages if there are fatal errors.
298 	*/
299 
300 	if ((failure_return || delay_return) && e->e_errormode != EM_QUIET)
301 	{
302 		if (tTd(50, 8))
303 			dprintf("dropenvelope(%s): saving mail\n", id);
304 		savemail(e, !bitset(EF_NO_BODY_RETN, e->e_flags));
305 	}
306 
307 	/*
308 	**  Arrange to send warning messages to postmaster as requested.
309 	*/
310 
311 	if ((failure_return || pmnotify) &&
312 	    PostMasterCopy != NULL &&
313 	    !bitset(EF_RESPONSE, e->e_flags) &&
314 	    e->e_class >= 0)
315 	{
316 		auto ADDRESS *rlist = NULL;
317 		char pcopy[MAXNAME];
318 
319 		if (failure_return)
320 		{
321 			expand(PostMasterCopy, pcopy, sizeof pcopy, e);
322 
323 			if (tTd(50, 8))
324 				dprintf("dropenvelope(%s): sending postmaster copy to %s\n",
325 					id, pcopy);
326 			(void) sendtolist(pcopy, NULLADDR, &rlist, 0, e);
327 		}
328 		if (pmnotify)
329 			(void) sendtolist("postmaster", NULLADDR,
330 					  &rlist, 0, e);
331 		(void) returntosender(e->e_message, rlist,
332 				      RTSF_PM_BOUNCE|RTSF_NO_BODY, e);
333 	}
334 
335 	/*
336 	**  Instantiate or deinstantiate the queue.
337 	*/
338 
339 simpledrop:
340 	if (tTd(50, 8))
341 		dprintf("dropenvelope(%s): at simpledrop, queueit=%d\n",
342 			id, queueit);
343 	if (!queueit || bitset(EF_CLRQUEUE, e->e_flags))
344 	{
345 		if (tTd(50, 1))
346 		{
347 			dprintf("\n===== Dropping [dq]f%s... queueit=%d, e_flags=",
348 				e->e_id, queueit);
349 			printenvflags(e);
350 		}
351 		xunlink(queuename(e, 'd'));
352 		xunlink(queuename(e, 'q'));
353 
354 		if (e->e_ntries > 0 && LogLevel > 9)
355 			sm_syslog(LOG_INFO, id, "done; delay=%s, ntries=%d",
356 				  pintvl(curtime() - e->e_ctime, TRUE),
357 				  e->e_ntries);
358 	}
359 	else if (queueit || !bitset(EF_INQUEUE, e->e_flags))
360 	{
361 #if QUEUE
362 		queueup(e, FALSE);
363 #else /* QUEUE */
364 		syserr("554 5.3.0 dropenvelope: queueup");
365 #endif /* QUEUE */
366 	}
367 
368 	/* now unlock the job */
369 	if (tTd(50, 8))
370 		dprintf("dropenvelope(%s): unlocking job\n", id);
371 	closexscript(e);
372 	unlockqueue(e);
373 
374 	/* make sure that this envelope is marked unused */
375 	if (e->e_dfp != NULL)
376 		(void) bfclose(e->e_dfp);
377 	e->e_dfp = NULL;
378 	e->e_id = NULL;
379 	e->e_flags &= ~EF_HAS_DF;
380 }
381 /*
382 **  CLEARENVELOPE -- clear an envelope without unlocking
383 **
384 **	This is normally used by a child process to get a clean
385 **	envelope without disturbing the parent.
386 **
387 **	Parameters:
388 **		e -- the envelope to clear.
389 **		fullclear - if set, the current envelope is total
390 **			garbage and should be ignored; otherwise,
391 **			release any resources it may indicate.
392 **
393 **	Returns:
394 **		none.
395 **
396 **	Side Effects:
397 **		Closes files associated with the envelope.
398 **		Marks the envelope as unallocated.
399 */
400 
401 void
402 clearenvelope(e, fullclear)
403 	register ENVELOPE *e;
404 	bool fullclear;
405 {
406 	register HDR *bh;
407 	register HDR **nhp;
408 	extern ENVELOPE BlankEnvelope;
409 
410 	if (!fullclear)
411 	{
412 		/* clear out any file information */
413 		if (e->e_xfp != NULL)
414 			(void) bfclose(e->e_xfp);
415 		if (e->e_dfp != NULL)
416 			(void) bfclose(e->e_dfp);
417 		e->e_xfp = e->e_dfp = NULL;
418 	}
419 
420 	/* now clear out the data */
421 	STRUCTCOPY(BlankEnvelope, *e);
422 	e->e_message = NULL;
423 	if (Verbose)
424 		set_delivery_mode(SM_DELIVER, e);
425 	bh = BlankEnvelope.e_header;
426 	nhp = &e->e_header;
427 	while (bh != NULL)
428 	{
429 		*nhp = (HDR *) xalloc(sizeof *bh);
430 		memmove((char *) *nhp, (char *) bh, sizeof *bh);
431 		bh = bh->h_link;
432 		nhp = &(*nhp)->h_link;
433 	}
434 }
435 /*
436 **  INITSYS -- initialize instantiation of system
437 **
438 **	In Daemon mode, this is done in the child.
439 **
440 **	Parameters:
441 **		e -- the envelope to use.
442 **
443 **	Returns:
444 **		none.
445 **
446 **	Side Effects:
447 **		Initializes the system macros, some global variables,
448 **		etc.  In particular, the current time in various
449 **		forms is set.
450 */
451 
452 void
453 initsys(e)
454 	register ENVELOPE *e;
455 {
456 	char cbuf[5];				/* holds hop count */
457 	char pbuf[10];				/* holds pid */
458 #ifdef TTYNAME
459 	static char ybuf[60];			/* holds tty id */
460 	register char *p;
461 	extern char *ttyname();
462 #endif /* TTYNAME */
463 
464 	/*
465 	**  Give this envelope a reality.
466 	**	I.e., an id, a transcript, and a creation time.
467 	*/
468 
469 	setnewqueue(e);
470 	openxscript(e);
471 	e->e_ctime = curtime();
472 #if _FFR_QUEUEDELAY
473 	e->e_queuealg = QueueAlg;
474 	e->e_queuedelay = QueueInitDelay;
475 #endif /* _FFR_QUEUEDELAY */
476 
477 	/*
478 	**  Set OutChannel to something useful if stdout isn't it.
479 	**	This arranges that any extra stuff the mailer produces
480 	**	gets sent back to the user on error (because it is
481 	**	tucked away in the transcript).
482 	*/
483 
484 	if (OpMode == MD_DAEMON && bitset(EF_QUEUERUN, e->e_flags) &&
485 	    e->e_xfp != NULL)
486 		OutChannel = e->e_xfp;
487 
488 	/*
489 	**  Set up some basic system macros.
490 	*/
491 
492 	/* process id */
493 	(void) snprintf(pbuf, sizeof pbuf, "%d", (int) getpid());
494 	define('p', newstr(pbuf), e);
495 
496 	/* hop count */
497 	(void) snprintf(cbuf, sizeof cbuf, "%d", e->e_hopcount);
498 	define('c', newstr(cbuf), e);
499 
500 	/* time as integer, unix time, arpa time */
501 	settime(e);
502 
503 	/* Load average */
504 	(void)sm_getla(e);
505 
506 #ifdef TTYNAME
507 	/* tty name */
508 	if (macvalue('y', e) == NULL)
509 	{
510 		p = ttyname(2);
511 		if (p != NULL)
512 		{
513 			if (strrchr(p, '/') != NULL)
514 				p = strrchr(p, '/') + 1;
515 			snprintf(ybuf, sizeof ybuf, "%s", p);
516 			define('y', ybuf, e);
517 		}
518 	}
519 #endif /* TTYNAME */
520 }
521 /*
522 **  SETTIME -- set the current time.
523 **
524 **	Parameters:
525 **		e -- the envelope in which the macros should be set.
526 **
527 **	Returns:
528 **		none.
529 **
530 **	Side Effects:
531 **		Sets the various time macros -- $a, $b, $d, $t.
532 */
533 
534 void
535 settime(e)
536 	register ENVELOPE *e;
537 {
538 	register char *p;
539 	auto time_t now;
540 	char tbuf[20];				/* holds "current" time */
541 	char dbuf[30];				/* holds ctime(tbuf) */
542 	register struct tm *tm;
543 
544 	now = curtime();
545 	tm = gmtime(&now);
546 	(void) snprintf(tbuf, sizeof tbuf, "%04d%02d%02d%02d%02d", tm->tm_year + 1900,
547 			tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min);
548 	define('t', newstr(tbuf), e);
549 	(void) strlcpy(dbuf, ctime(&now), sizeof dbuf);
550 	p = strchr(dbuf, '\n');
551 	if (p != NULL)
552 		*p = '\0';
553 	define('d', newstr(dbuf), e);
554 	p = arpadate(dbuf);
555 	p = newstr(p);
556 	if (macvalue('a', e) == NULL)
557 		define('a', p, e);
558 	define('b', p, e);
559 }
560 /*
561 **  OPENXSCRIPT -- Open transcript file
562 **
563 **	Creates a transcript file for possible eventual mailing or
564 **	sending back.
565 **
566 **	Parameters:
567 **		e -- the envelope to create the transcript in/for.
568 **
569 **	Returns:
570 **		none
571 **
572 **	Side Effects:
573 **		Creates the transcript file.
574 */
575 
576 #ifndef O_APPEND
577 # define O_APPEND	0
578 #endif /* ! O_APPEND */
579 
580 void
581 openxscript(e)
582 	register ENVELOPE *e;
583 {
584 	register char *p;
585 
586 	if (e->e_xfp != NULL)
587 		return;
588 
589 #if 0
590 	if (e->e_lockfp == NULL && bitset(EF_INQUEUE, e->e_flags))
591 		syserr("openxscript: job not locked");
592 #endif /* 0 */
593 
594 	p = queuename(e, 'x');
595 	e->e_xfp = bfopen(p, FileMode, XscriptFileBufferSize,
596 			  SFF_NOTEXCL|SFF_OPENASROOT);
597 
598 	if (e->e_xfp == NULL)
599 	{
600 		syserr("Can't create transcript file %s", p);
601 		e->e_xfp = fopen("/dev/null", "r+");
602 		if (e->e_xfp == NULL)
603 			syserr("!Can't open /dev/null");
604 	}
605 #if HASSETVBUF
606 	(void) setvbuf(e->e_xfp, NULL, _IOLBF, 0);
607 #else /* HASSETVBUF */
608 	(void) setlinebuf(e->e_xfp);
609 #endif /* HASSETVBUF */
610 	if (tTd(46, 9))
611 	{
612 		dprintf("openxscript(%s):\n  ", p);
613 		dumpfd(fileno(e->e_xfp), TRUE, FALSE);
614 	}
615 }
616 /*
617 **  CLOSEXSCRIPT -- close the transcript file.
618 **
619 **	Parameters:
620 **		e -- the envelope containing the transcript to close.
621 **
622 **	Returns:
623 **		none.
624 **
625 **	Side Effects:
626 **		none.
627 */
628 
629 void
630 closexscript(e)
631 	register ENVELOPE *e;
632 {
633 	if (e->e_xfp == NULL)
634 		return;
635 #if 0
636 	if (e->e_lockfp == NULL)
637 		syserr("closexscript: job not locked");
638 #endif /* 0 */
639 	(void) bfclose(e->e_xfp);
640 	e->e_xfp = NULL;
641 }
642 /*
643 **  SETSENDER -- set the person who this message is from
644 **
645 **	Under certain circumstances allow the user to say who
646 **	s/he is (using -f or -r).  These are:
647 **	1.  The user's uid is zero (root).
648 **	2.  The user's login name is in an approved list (typically
649 **	    from a network server).
650 **	3.  The address the user is trying to claim has a
651 **	    "!" character in it (since #2 doesn't do it for
652 **	    us if we are dialing out for UUCP).
653 **	A better check to replace #3 would be if the
654 **	effective uid is "UUCP" -- this would require me
655 **	to rewrite getpwent to "grab" uucp as it went by,
656 **	make getname more nasty, do another passwd file
657 **	scan, or compile the UID of "UUCP" into the code,
658 **	all of which are reprehensible.
659 **
660 **	Assuming all of these fail, we figure out something
661 **	ourselves.
662 **
663 **	Parameters:
664 **		from -- the person we would like to believe this message
665 **			is from, as specified on the command line.
666 **		e -- the envelope in which we would like the sender set.
667 **		delimptr -- if non-NULL, set to the location of the
668 **			trailing delimiter.
669 **		delimchar -- the character that will delimit the sender
670 **			address.
671 **		internal -- set if this address is coming from an internal
672 **			source such as an owner alias.
673 **
674 **	Returns:
675 **		none.
676 **
677 **	Side Effects:
678 **		sets sendmail's notion of who the from person is.
679 */
680 
681 void
682 setsender(from, e, delimptr, delimchar, internal)
683 	char *from;
684 	register ENVELOPE *e;
685 	char **delimptr;
686 	int delimchar;
687 	bool internal;
688 {
689 	register char **pvp;
690 	char *realname = NULL;
691 	register struct passwd *pw;
692 	char *bp;
693 	char buf[MAXNAME + 2];
694 	char pvpbuf[PSBUFSIZE];
695 	extern char *FullName;
696 
697 	if (tTd(45, 1))
698 		dprintf("setsender(%s)\n", from == NULL ? "" : from);
699 
700 	/*
701 	**  Figure out the real user executing us.
702 	**	Username can return errno != 0 on non-errors.
703 	*/
704 
705 	if (bitset(EF_QUEUERUN, e->e_flags) || OpMode == MD_SMTP ||
706 	    OpMode == MD_ARPAFTP || OpMode == MD_DAEMON)
707 		realname = from;
708 	if (realname == NULL || realname[0] == '\0')
709 		realname = username();
710 
711 	if (ConfigLevel < 2)
712 		SuprErrs = TRUE;
713 
714 #if _FFR_ADDR_TYPE
715 	define(macid("{addr_type}", NULL), "e s", e);
716 #endif /* _FFR_ADDR_TYPE */
717 	/* preset state for then clause in case from == NULL */
718 	e->e_from.q_state = QS_BADADDR;
719 	e->e_from.q_flags = 0;
720 	if (from == NULL ||
721 	    parseaddr(from, &e->e_from, RF_COPYALL|RF_SENDERADDR,
722 		      delimchar, delimptr, e) == NULL ||
723 	    QS_IS_BADADDR(e->e_from.q_state) ||
724 	    e->e_from.q_mailer == ProgMailer ||
725 	    e->e_from.q_mailer == FileMailer ||
726 	    e->e_from.q_mailer == InclMailer)
727 	{
728 		/* log garbage addresses for traceback */
729 		if (from != NULL && LogLevel > 2)
730 		{
731 			char *p;
732 			char ebuf[MAXNAME * 2 + 2];
733 
734 			p = macvalue('_', e);
735 			if (p == NULL)
736 			{
737 				char *host = RealHostName;
738 
739 				if (host == NULL)
740 					host = MyHostName;
741 				(void) snprintf(ebuf, sizeof ebuf, "%.*s@%.*s",
742 					MAXNAME, realname,
743 					MAXNAME, host);
744 				p = ebuf;
745 			}
746 			sm_syslog(LOG_NOTICE, e->e_id,
747 				  "setsender: %s: invalid or unparsable, received from %s",
748 				  shortenstring(from, 83), p);
749 		}
750 		if (from != NULL)
751 		{
752 			if (!QS_IS_BADADDR(e->e_from.q_state))
753 			{
754 				/* it was a bogus mailer in the from addr */
755 				e->e_status = "5.1.7";
756 				usrerrenh(e->e_status,
757 					  "553 Invalid sender address");
758 			}
759 			SuprErrs = TRUE;
760 		}
761 		if (from == realname ||
762 		    parseaddr(from = newstr(realname), &e->e_from,
763 			      RF_COPYALL|RF_SENDERADDR, ' ', NULL, e) == NULL)
764 		{
765 			char nbuf[100];
766 
767 			SuprErrs = TRUE;
768 			expand("\201n", nbuf, sizeof nbuf, e);
769 			if (parseaddr(from = newstr(nbuf), &e->e_from,
770 				      RF_COPYALL, ' ', NULL, e) == NULL &&
771 			    parseaddr(from = "postmaster", &e->e_from,
772 				      RF_COPYALL, ' ', NULL, e) == NULL)
773 				syserr("553 5.3.0 setsender: can't even parse postmaster!");
774 		}
775 	}
776 	else
777 		FromFlag = TRUE;
778 	e->e_from.q_state = QS_SENDER;
779 	if (tTd(45, 5))
780 	{
781 		dprintf("setsender: QS_SENDER ");
782 		printaddr(&e->e_from, FALSE);
783 	}
784 	SuprErrs = FALSE;
785 
786 #if USERDB
787 	if (bitnset(M_CHECKUDB, e->e_from.q_mailer->m_flags))
788 	{
789 		register char *p;
790 
791 		p = udbsender(e->e_from.q_user);
792 		if (p != NULL)
793 			from = p;
794 	}
795 #endif /* USERDB */
796 
797 	if (bitnset(M_HASPWENT, e->e_from.q_mailer->m_flags))
798 	{
799 		if (!internal)
800 		{
801 			/* if the user already given fullname don't redefine */
802 			if (FullName == NULL)
803 				FullName = macvalue('x', e);
804 			if (FullName != NULL && FullName[0] == '\0')
805 				FullName = NULL;
806 		}
807 
808 		if (e->e_from.q_user[0] != '\0' &&
809 		    (pw = sm_getpwnam(e->e_from.q_user)) != NULL)
810 		{
811 			/*
812 			**  Process passwd file entry.
813 			*/
814 
815 			/* extract home directory */
816 			if (*pw->pw_dir == '\0')
817 				e->e_from.q_home = NULL;
818 			else if (strcmp(pw->pw_dir, "/") == 0)
819 				e->e_from.q_home = newstr("");
820 			else
821 				e->e_from.q_home = newstr(pw->pw_dir);
822 			define('z', e->e_from.q_home, e);
823 
824 			/* extract user and group id */
825 			e->e_from.q_uid = pw->pw_uid;
826 			e->e_from.q_gid = pw->pw_gid;
827 			e->e_from.q_flags |= QGOODUID;
828 
829 			/* extract full name from passwd file */
830 			if (FullName == NULL && pw->pw_gecos != NULL &&
831 			    strcmp(pw->pw_name, e->e_from.q_user) == 0 &&
832 			    !internal)
833 			{
834 				buildfname(pw->pw_gecos, e->e_from.q_user, buf, sizeof buf);
835 				if (buf[0] != '\0')
836 					FullName = newstr(buf);
837 			}
838 		}
839 		else
840 		{
841 			e->e_from.q_home = NULL;
842 		}
843 		if (FullName != NULL && !internal)
844 			define('x', FullName, e);
845 	}
846 	else if (!internal && OpMode != MD_DAEMON && OpMode != MD_SMTP)
847 	{
848 		if (e->e_from.q_home == NULL)
849 		{
850 			e->e_from.q_home = getenv("HOME");
851 			if (e->e_from.q_home != NULL)
852 			{
853 				if (*e->e_from.q_home == '\0')
854 					e->e_from.q_home = NULL;
855 				else if (strcmp(e->e_from.q_home, "/") == 0)
856 					e->e_from.q_home++;
857 			}
858 		}
859 		e->e_from.q_uid = RealUid;
860 		e->e_from.q_gid = RealGid;
861 		e->e_from.q_flags |= QGOODUID;
862 	}
863 
864 	/*
865 	**  Rewrite the from person to dispose of possible implicit
866 	**	links in the net.
867 	*/
868 
869 	pvp = prescan(from, delimchar, pvpbuf, sizeof pvpbuf, NULL, NULL);
870 	if (pvp == NULL)
871 	{
872 		/* don't need to give error -- prescan did that already */
873 		if (LogLevel > 2)
874 			sm_syslog(LOG_NOTICE, e->e_id,
875 				  "cannot prescan from (%s)",
876 				  shortenstring(from, MAXSHORTSTR));
877 		finis(TRUE, ExitStat);
878 	}
879 	(void) rewrite(pvp, 3, 0, e);
880 	(void) rewrite(pvp, 1, 0, e);
881 	(void) rewrite(pvp, 4, 0, e);
882 #if _FFR_ADDR_TYPE
883 	define(macid("{addr_type}", NULL), NULL, e);
884 #endif /* _FFR_ADDR_TYPE */
885 	bp = buf + 1;
886 	cataddr(pvp, NULL, bp, sizeof buf - 2, '\0');
887 	if (*bp == '@' && !bitnset(M_NOBRACKET, e->e_from.q_mailer->m_flags))
888 	{
889 		/* heuristic: route-addr: add angle brackets */
890 		(void) strlcat(bp, ">", sizeof buf - 1);
891 		*--bp = '<';
892 	}
893 	e->e_sender = newstr(bp);
894 	define('f', e->e_sender, e);
895 
896 	/* save the domain spec if this mailer wants it */
897 	if (e->e_from.q_mailer != NULL &&
898 	    bitnset(M_CANONICAL, e->e_from.q_mailer->m_flags))
899 	{
900 		char **lastat;
901 
902 		/* get rid of any pesky angle brackets */
903 #if _FFR_ADDR_TYPE
904 		define(macid("{addr_type}", NULL), "e s", e);
905 #endif /* _FFR_ADDR_TYPE */
906 		(void) rewrite(pvp, 3, 0, e);
907 		(void) rewrite(pvp, 1, 0, e);
908 		(void) rewrite(pvp, 4, 0, e);
909 #if _FFR_ADDR_TYPE
910 		define(macid("{addr_type}", NULL), NULL, e);
911 #endif /* _FFR_ADDR_TYPE */
912 
913 		/* strip off to the last "@" sign */
914 		for (lastat = NULL; *pvp != NULL; pvp++)
915 			if (strcmp(*pvp, "@") == 0)
916 				lastat = pvp;
917 		if (lastat != NULL)
918 		{
919 			e->e_fromdomain = copyplist(lastat, TRUE);
920 			if (tTd(45, 3))
921 			{
922 				dprintf("Saving from domain: ");
923 				printav(e->e_fromdomain);
924 			}
925 		}
926 	}
927 }
928 /*
929 **  PRINTENVFLAGS -- print envelope flags for debugging
930 **
931 **	Parameters:
932 **		e -- the envelope with the flags to be printed.
933 **
934 **	Returns:
935 **		none.
936 */
937 
938 struct eflags
939 {
940 	char	*ef_name;
941 	u_long	ef_bit;
942 };
943 
944 static struct eflags	EnvelopeFlags[] =
945 {
946 	{ "OLDSTYLE",		EF_OLDSTYLE	},
947 	{ "INQUEUE",		EF_INQUEUE	},
948 	{ "NO_BODY_RETN",	EF_NO_BODY_RETN	},
949 	{ "CLRQUEUE",		EF_CLRQUEUE	},
950 	{ "SENDRECEIPT",	EF_SENDRECEIPT	},
951 	{ "FATALERRS",		EF_FATALERRS	},
952 	{ "DELETE_BCC",		EF_DELETE_BCC	},
953 	{ "RESPONSE",		EF_RESPONSE	},
954 	{ "RESENT",		EF_RESENT	},
955 	{ "VRFYONLY",		EF_VRFYONLY	},
956 	{ "WARNING",		EF_WARNING	},
957 	{ "QUEUERUN",		EF_QUEUERUN	},
958 	{ "GLOBALERRS",		EF_GLOBALERRS	},
959 	{ "PM_NOTIFY",		EF_PM_NOTIFY	},
960 	{ "METOO",		EF_METOO	},
961 	{ "LOGSENDER",		EF_LOGSENDER	},
962 	{ "NORECEIPT",		EF_NORECEIPT	},
963 	{ "HAS8BIT",		EF_HAS8BIT	},
964 	{ "NL_NOT_EOL",		EF_NL_NOT_EOL	},
965 	{ "CRLF_NOT_EOL",	EF_CRLF_NOT_EOL	},
966 	{ "RET_PARAM",		EF_RET_PARAM	},
967 	{ "HAS_DF",		EF_HAS_DF	},
968 	{ "IS_MIME",		EF_IS_MIME	},
969 	{ "DONT_MIME",		EF_DONT_MIME	},
970 	{ NULL,			0		}
971 };
972 
973 void
974 printenvflags(e)
975 	register ENVELOPE *e;
976 {
977 	register struct eflags *ef;
978 	bool first = TRUE;
979 
980 	printf("%lx", e->e_flags);
981 	for (ef = EnvelopeFlags; ef->ef_name != NULL; ef++)
982 	{
983 		if (!bitset(ef->ef_bit, e->e_flags))
984 			continue;
985 		if (first)
986 			printf("<%s", ef->ef_name);
987 		else
988 			printf(",%s", ef->ef_name);
989 		first = FALSE;
990 	}
991 	if (!first)
992 		printf(">\n");
993 }
994