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