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