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