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