1: /*
   2:  * Copyright (c) 1988 Regents of the University of California.
   3:  * All rights reserved.
   4:  *
   5:  * Redistribution and use in source and binary forms are permitted
   6:  * provided that this notice is preserved and that due credit is given
   7:  * to the University of California at Berkeley. The name of the University
   8:  * may not be used to endorse or promote products derived from this
   9:  * software without specific prior written permission. This software
  10:  * is provided ``as is'' without express or implied warranty.
  11:  *
  12:  *  Sendmail
  13:  *  Copyright (c) 1983  Eric P. Allman
  14:  *  Berkeley, California
  15:  *
  16:  *  Bugfix:
  17:  *    1993 Jan 30 Lasse Ylitalo && Johnny Billquist
  18:  *    When delivering mail via smtp the mail went into
  19:  *    the bit bucket. Only smtpinit was called...
  20:  */
  21: 
  22: #if !defined(lint) && !defined(NOSCCS)
  23: static char sccsid[] = "@(#)deliver.c	5.21 (Berkeley) 5/5/88";
  24: #endif /* not lint */
  25: 
  26: #include <sendmail.h>
  27: #include <sys/signal.h>
  28: #include <sys/stat.h>
  29: #include <sys/ioctl.h>
  30: #include <netdb.h>
  31: #include <errno.h>
  32: #include <arpa/nameser.h>
  33: #include <resolv.h>
  34: 
  35: /*
  36: **  DELIVER -- Deliver a message to a list of addresses.
  37: **
  38: **	This routine delivers to everyone on the same host as the
  39: **	user on the head of the list.  It is clever about mailers
  40: **	that don't handle multiple users.  It is NOT guaranteed
  41: **	that it will deliver to all these addresses however -- so
  42: **	deliver should be called once for each address on the
  43: **	list.
  44: **
  45: **	Parameters:
  46: **		e -- the envelope to deliver.
  47: **		firstto -- head of the address list to deliver to.
  48: **
  49: **	Returns:
  50: **		zero -- successfully delivered.
  51: **		else -- some failure, see ExitStat for more info.
  52: **
  53: **	Side Effects:
  54: **		The standard input is passed off to someone.
  55: */
  56: 
  57: deliver(e, firstto)
  58:     register ENVELOPE *e;
  59:     ADDRESS *firstto;
  60: {
  61:     char *host;         /* host being sent to */
  62:     char *user;         /* user being sent to */
  63:     char **pvp;
  64:     register char **mvp;
  65:     register char *p;
  66:     register MAILER *m;     /* mailer for this recipient */
  67:     ADDRESS *ctladdr;
  68:     register ADDRESS *to = firstto;
  69:     bool clever = FALSE;        /* running user smtp to this mailer */
  70:     ADDRESS *tochain = NULL;    /* chain of users in this mailer call */
  71:     int rcode;      /* response code */
  72:     char *pv[MAXPV+1];
  73:     char tobuf[MAXLINE-50];     /* text line of to people */
  74:     char buf[MAXNAME];
  75:     char tfrombuf[MAXNAME];     /* translated from person */
  76:     extern bool checkcompat();
  77:     extern ADDRESS *getctladdr();
  78:     extern char *remotename();
  79: 
  80:     errno = 0;
  81:     if (bitset(QDONTSEND, to->q_flags))
  82:         return (0);
  83: 
  84:     /* unless interactive, try twice, over a minute */
  85:     if (OpMode == MD_DAEMON || OpMode == MD_SMTP) {
  86:         _res.retrans = 30;
  87:         _res.retry = 2;
  88:     }
  89: 
  90:     m = to->q_mailer;
  91:     host = to->q_host;
  92: 
  93: # ifdef DEBUG
  94:     if (tTd(10, 1))
  95:         printf("\n--deliver, mailer=%d, host=`%s', first user=`%s'\n",
  96:             m->m_mno, host, to->q_user);
  97: # endif DEBUG
  98: 
  99:     /*
 100: 	**  If this mailer is expensive, and if we don't want to make
 101: 	**  connections now, just mark these addresses and return.
 102: 	**	This is useful if we want to batch connections to
 103: 	**	reduce load.  This will cause the messages to be
 104: 	**	queued up, and a daemon will come along to send the
 105: 	**	messages later.
 106: 	**		This should be on a per-mailer basis.
 107: 	*/
 108: 
 109:     if (NoConnect && !QueueRun && bitnset(M_EXPENSIVE, m->m_flags) &&
 110:         !Verbose)
 111:     {
 112:         for (; to != NULL; to = to->q_next)
 113:         {
 114:             if (bitset(QDONTSEND, to->q_flags) || to->q_mailer != m)
 115:                 continue;
 116:             to->q_flags |= QQUEUEUP|QDONTSEND;
 117:             e->e_to = to->q_paddr;
 118:             message(Arpa_Info, "queued");
 119:             if (LogLevel > 4)
 120:                 logdelivery("queued");
 121:         }
 122:         e->e_to = NULL;
 123:         return (0);
 124:     }
 125: 
 126:     /*
 127: 	**  Do initial argv setup.
 128: 	**	Insert the mailer name.  Notice that $x expansion is
 129: 	**	NOT done on the mailer name.  Then, if the mailer has
 130: 	**	a picky -f flag, we insert it as appropriate.  This
 131: 	**	code does not check for 'pv' overflow; this places a
 132: 	**	manifest lower limit of 4 for MAXPV.
 133: 	**		The from address rewrite is expected to make
 134: 	**		the address relative to the other end.
 135: 	*/
 136: 
 137:     /* rewrite from address, using rewriting rules */
 138:     expand("\001f", buf, &buf[sizeof buf - 1], e);
 139:     (void) strcpy(tfrombuf, remotename(buf, m, TRUE, TRUE));
 140: 
 141:     define('g', tfrombuf, e);       /* translated sender address */
 142:     define('h', host, e);           /* to host */
 143:     Errors = 0;
 144:     pvp = pv;
 145:     *pvp++ = m->m_argv[0];
 146: 
 147:     /* insert -f or -r flag as appropriate */
 148:     if (FromFlag && (bitnset(M_FOPT, m->m_flags) || bitnset(M_ROPT, m->m_flags)))
 149:     {
 150:         if (bitnset(M_FOPT, m->m_flags))
 151:             *pvp++ = "-f";
 152:         else
 153:             *pvp++ = "-r";
 154:         expand("\001g", buf, &buf[sizeof buf - 1], e);
 155:         *pvp++ = newstr(buf);
 156:     }
 157: 
 158:     /*
 159: 	**  Append the other fixed parts of the argv.  These run
 160: 	**  up to the first entry containing "$u".  There can only
 161: 	**  be one of these, and there are only a few more slots
 162: 	**  in the pv after it.
 163: 	*/
 164: 
 165:     for (mvp = m->m_argv; (p = *++mvp) != NULL; )
 166:     {
 167:         while ((p = index(p, '\001')) != NULL)
 168:             if (*++p == 'u')
 169:                 break;
 170:         if (p != NULL)
 171:             break;
 172: 
 173:         /* this entry is safe -- go ahead and process it */
 174:         expand(*mvp, buf, &buf[sizeof buf - 1], e);
 175:         *pvp++ = newstr(buf);
 176:         if (pvp >= &pv[MAXPV - 3])
 177:         {
 178:             syserr("Too many parameters to %s before $u", pv[0]);
 179:             return (-1);
 180:         }
 181:     }
 182: 
 183:     /*
 184: 	**  If we have no substitution for the user name in the argument
 185: 	**  list, we know that we must supply the names otherwise -- and
 186: 	**  SMTP is the answer!!
 187: 	*/
 188: 
 189:     if (*mvp == NULL)
 190:     {
 191:         /* running SMTP */
 192: # ifdef SMTP
 193:         clever = TRUE;
 194:         *pvp = NULL;
 195: # else SMTP
 196:         /* oops!  we don't implement SMTP */
 197:         syserr("SMTP style mailer");
 198:         return (EX_SOFTWARE);
 199: # endif SMTP
 200:     }
 201: 
 202:     /*
 203: 	**  At this point *mvp points to the argument with $u.  We
 204: 	**  run through our address list and append all the addresses
 205: 	**  we can.  If we run out of space, do not fret!  We can
 206: 	**  always send another copy later.
 207: 	*/
 208: 
 209:     tobuf[0] = '\0';
 210:     e->e_to = tobuf;
 211:     ctladdr = NULL;
 212:     for (; to != NULL; to = to->q_next)
 213:     {
 214:         /* avoid sending multiple recipients to dumb mailers */
 215:         if (tobuf[0] != '\0' && !bitnset(M_MUSER, m->m_flags))
 216:             break;
 217: 
 218:         /* if already sent or not for this host, don't send */
 219:         if (bitset(QDONTSEND, to->q_flags) ||
 220:             strcmp(to->q_host, host) != 0 ||
 221:             to->q_mailer != firstto->q_mailer)
 222:             continue;
 223: 
 224:         /* avoid overflowing tobuf */
 225:         if (sizeof tobuf - (strlen(to->q_paddr) + strlen(tobuf) + 2) < 0)
 226:             break;
 227: 
 228: # ifdef DEBUG
 229:         if (tTd(10, 1))
 230:         {
 231:             printf("\nsend to ");
 232:             printaddr(to, FALSE);
 233:         }
 234: # endif DEBUG
 235: 
 236:         /* compute effective uid/gid when sending */
 237:         if (to->q_mailer == ProgMailer)
 238:             ctladdr = getctladdr(to);
 239: 
 240:         user = to->q_user;
 241:         e->e_to = to->q_paddr;
 242:         to->q_flags |= QDONTSEND;
 243: 
 244:         /*
 245: 		**  Check to see that these people are allowed to
 246: 		**  talk to each other.
 247: 		*/
 248: 
 249:         if (m->m_maxsize != 0 && e->e_msgsize > m->m_maxsize)
 250:         {
 251:             NoReturn = TRUE;
 252:             usrerr("Message is too large; %ld bytes max", m->m_maxsize);
 253:             giveresponse(EX_UNAVAILABLE, m, e);
 254:             continue;
 255:         }
 256:         if (!checkcompat(to))
 257:         {
 258:             giveresponse(EX_UNAVAILABLE, m, e);
 259:             continue;
 260:         }
 261: 
 262:         /*
 263: 		**  Strip quote bits from names if the mailer is dumb
 264: 		**	about them.
 265: 		*/
 266: 
 267:         if (bitnset(M_STRIPQ, m->m_flags))
 268:         {
 269:             stripquotes(user, TRUE);
 270:             stripquotes(host, TRUE);
 271:         }
 272:         else
 273:         {
 274:             stripquotes(user, FALSE);
 275:             stripquotes(host, FALSE);
 276:         }
 277: 
 278:         /* hack attack -- delivermail compatibility */
 279:         if (m == ProgMailer && *user == '|')
 280:             user++;
 281: 
 282:         /*
 283: 		**  If an error message has already been given, don't
 284: 		**	bother to send to this address.
 285: 		**
 286: 		**	>>>>>>>>>> This clause assumes that the local mailer
 287: 		**	>> NOTE >> cannot do any further aliasing; that
 288: 		**	>>>>>>>>>> function is subsumed by sendmail.
 289: 		*/
 290: 
 291:         if (bitset(QBADADDR|QQUEUEUP, to->q_flags))
 292:             continue;
 293: 
 294:         /* save statistics.... */
 295:         markstats(e, to);
 296: 
 297:         /*
 298: 		**  See if this user name is "special".
 299: 		**	If the user name has a slash in it, assume that this
 300: 		**	is a file -- send it off without further ado.  Note
 301: 		**	that this type of addresses is not processed along
 302: 		**	with the others, so we fudge on the To person.
 303: 		*/
 304: 
 305:         if (m == LocalMailer)
 306:         {
 307:             if (user[0] == '/')
 308:             {
 309:                 rcode = mailfile(user, getctladdr(to));
 310:                 giveresponse(rcode, m, e);
 311:                 continue;
 312:             }
 313:         }
 314: 
 315:         /*
 316: 		**  Address is verified -- add this user to mailer
 317: 		**  argv, and add it to the print list of recipients.
 318: 		*/
 319: 
 320:         /* link together the chain of recipients */
 321:         to->q_tchain = tochain;
 322:         tochain = to;
 323: 
 324:         /* create list of users for error messages */
 325:         (void) strcat(tobuf, ",");
 326:         (void) strcat(tobuf, to->q_paddr);
 327:         define('u', user, e);       /* to user */
 328:         define('z', to->q_home, e); /* user's home */
 329: 
 330:         /*
 331: 		**  Expand out this user into argument list.
 332: 		*/
 333: 
 334:         if (!clever)
 335:         {
 336:             expand(*mvp, buf, &buf[sizeof buf - 1], e);
 337:             *pvp++ = newstr(buf);
 338:             if (pvp >= &pv[MAXPV - 2])
 339:             {
 340:                 /* allow some space for trailing parms */
 341:                 break;
 342:             }
 343:         }
 344:     }
 345: 
 346:     /* see if any addresses still exist */
 347:     if (tobuf[0] == '\0')
 348:     {
 349:         define('g', (char *) NULL, e);
 350:         return (0);
 351:     }
 352: 
 353:     /* print out messages as full list */
 354:     e->e_to = tobuf + 1;
 355: 
 356:     /*
 357: 	**  Fill out any parameters after the $u parameter.
 358: 	*/
 359: 
 360:     while (!clever && *++mvp != NULL)
 361:     {
 362:         expand(*mvp, buf, &buf[sizeof buf - 1], e);
 363:         *pvp++ = newstr(buf);
 364:         if (pvp >= &pv[MAXPV])
 365:             syserr("deliver: pv overflow after $u for %s", pv[0]);
 366:     }
 367:     *pvp++ = NULL;
 368: 
 369:     /*
 370: 	**  Call the mailer.
 371: 	**	The argument vector gets built, pipes
 372: 	**	are created as necessary, and we fork & exec as
 373: 	**	appropriate.
 374: 	**	If we are running SMTP, we just need to clean up.
 375: 	*/
 376: 
 377:     if (ctladdr == NULL)
 378:         ctladdr = &e->e_from;
 379:     _res.options &= ~(RES_DEFNAMES | RES_DNSRCH);       /* XXX */
 380: #ifdef SMTP
 381:     if (clever)
 382:     {
 383: #ifdef MXDOMAIN
 384:         /*
 385:  		**  Let makeconnection handle [a.b.c.d] address
 386:  		**  specifications -- getmxrr gets confused by them ...
 387:  		*/
 388:         if (host[0] != '[')
 389:         {
 390:             expand("\001w", buf, &buf[sizeof buf - 1], e);
 391:             if ((Nmx = getmxrr(host, MxHosts, MAXMXHOSTS, buf)) < 0)
 392:             {
 393:                 /*
 394:  				 * Map errors into standard values
 395:  				 */
 396:                 if (Nmx == -1)
 397:                     rcode = EX_TEMPFAIL;
 398:                 else if (Nmx == -3)
 399:                     rcode = EX_NOHOST;
 400:                 else
 401:                     rcode = EX_UNAVAILABLE;
 402:             }
 403:             else
 404:                 rcode = EX_OK;
 405:         }
 406:         else
 407: #endif MXDOMAIN
 408:         {
 409:             Nmx = 1;
 410:             MxHosts[0] = host;
 411:             rcode = EX_OK;
 412:         }
 413: 
 414:         /* send the initial SMTP protocol */
 415:         if (rcode == EX_OK)
 416:         {
 417:             rcode = smtpinit(m, pv);
 418: 
 419:             /* Added some delivering of mail via
 420: 			 * SMTP...  LY&&JB 93Jan30
 421: 			 */
 422:             if (rcode == EX_OK)
 423:             {
 424:                 /* send the recipient list */
 425:                 tobuf[0] = '\0';
 426:                 for (to = tochain; to != NULL; to = to->q_tchain)
 427:                 {
 428:                     int i;
 429: 
 430:                     e->e_to = to->q_paddr;
 431:                     i = smtprcpt(to, m);
 432:                     if (i != EX_OK)
 433:                     {
 434:                         markfailure(e, to, i);
 435:                         giveresponse(i, m, e);
 436:                     }
 437:                     else
 438:                     {
 439:                         (void) strcat(tobuf, ",");
 440:                         (void) strcat(tobuf, to->q_paddr);
 441:                     }
 442:                 }
 443: 
 444:                 /* now send the data */
 445:                 if (tobuf[0] == '\0')
 446:                     e->e_to = NULL;
 447:                 else
 448:                 {
 449:                     e->e_to = tobuf + 1;
 450:                     rcode = smtpdata(m, e);
 451:                 }
 452: 
 453:                 /* now close the connection */
 454:                 smtpquit(m);
 455:             }
 456:         }
 457:     }
 458:     else
 459: #endif /* SMTP */
 460:     {
 461:         message(Arpa_Info, "Connecting to %s (%s)...", host, m->m_name);
 462:         rcode = sendoff(e, m, pv, ctladdr);
 463:     }
 464:     _res.options |= RES_DEFNAMES | RES_DNSRCH;  /* XXX */
 465: 
 466:     /*
 467: 	**  Do final status disposal.
 468: 	**	We check for something in tobuf for the SMTP case.
 469: 	**	If we got a temporary failure, arrange to queue the
 470: 	**		addressees.
 471: 	*/
 472: 
 473:     if (tobuf[0] != '\0')
 474:         giveresponse(rcode, m, e);
 475:     if (rcode != EX_OK)
 476:         for (to = tochain; to != NULL; to = to->q_tchain)
 477:             markfailure(e, to, rcode);
 478: 
 479:     errno = 0;
 480:     define('g', (char *) NULL, e);
 481:     return (rcode);
 482: }
 483: /*
 484: **  MARKFAILURE -- mark a failure on a specific address.
 485: **
 486: **	Parameters:
 487: **		e -- the envelope we are sending.
 488: **		q -- the address to mark.
 489: **		rcode -- the code signifying the particular failure.
 490: **
 491: **	Returns:
 492: **		none.
 493: **
 494: **	Side Effects:
 495: **		marks the address (and possibly the envelope) with the
 496: **			failure so that an error will be returned or
 497: **			the message will be queued, as appropriate.
 498: */
 499: 
 500: markfailure(e, q, rcode)
 501:     register ENVELOPE *e;
 502:     register ADDRESS *q;
 503:     int rcode;
 504: {
 505:     if (rcode == EX_OK)
 506:         return;
 507:     else if (rcode != EX_TEMPFAIL)
 508:         q->q_flags |= QBADADDR;
 509:     else if (curtime() > e->e_ctime + TimeOut)
 510:     {
 511:         extern char *pintvl();
 512:         char buf[MAXLINE];
 513: 
 514:         if (!bitset(EF_TIMEOUT, e->e_flags))
 515:         {
 516:             (void) sprintf(buf, "Cannot send message for %s",
 517:                 pintvl(TimeOut, FALSE));
 518:             if (e->e_message != NULL)
 519:                 free(e->e_message);
 520:             e->e_message = newstr(buf);
 521:             message(Arpa_Info, buf);
 522:         }
 523:         q->q_flags |= QBADADDR;
 524:         e->e_flags |= EF_TIMEOUT;
 525:     }
 526:     else
 527:         q->q_flags |= QQUEUEUP;
 528: }
 529: /*
 530: **  DOFORK -- do a fork, retrying a couple of times on failure.
 531: **
 532: **	This MUST be a macro, since after a vfork we are running
 533: **	two processes on the same stack!!!
 534: **
 535: **	Parameters:
 536: **		none.
 537: **
 538: **	Returns:
 539: **		From a macro???  You've got to be kidding!
 540: **
 541: **	Side Effects:
 542: **		Modifies the ==> LOCAL <== variable 'pid', leaving:
 543: **			pid of child in parent, zero in child.
 544: **			-1 on unrecoverable error.
 545: **
 546: **	Notes:
 547: **		I'm awfully sorry this looks so awful.  That's
 548: **		vfork for you.....
 549: */
 550: 
 551: # define NFORKTRIES 5
 552: # ifdef VMUNIX
 553: # define XFORK  vfork
 554: # else VMUNIX
 555: # define XFORK  fork
 556: # endif VMUNIX
 557: 
 558: # define DOFORK(fORKfN) \
 559: {\
 560:     register int i;\
 561: \
 562:     for (i = NFORKTRIES; --i >= 0; )\
 563:     {\
 564:         pid = fORKfN();\
 565:         if (pid >= 0)\
 566:             break;\
 567:         if (i > 0)\
 568:             sleep((unsigned) NFORKTRIES - i);\
 569:     }\
 570: }
 571: /*
 572: **  DOFORK -- simple fork interface to DOFORK.
 573: **
 574: **	Parameters:
 575: **		none.
 576: **
 577: **	Returns:
 578: **		pid of child in parent.
 579: **		zero in child.
 580: **		-1 on error.
 581: **
 582: **	Side Effects:
 583: **		returns twice, once in parent and once in child.
 584: */
 585: 
 586: dofork()
 587: {
 588:     register int pid;
 589: 
 590:     DOFORK(fork);
 591:     return (pid);
 592: }
 593: /*
 594: **  SENDOFF -- send off call to mailer & collect response.
 595: **
 596: **	Parameters:
 597: **		e -- the envelope to mail.
 598: **		m -- mailer descriptor.
 599: **		pvp -- parameter vector to send to it.
 600: **		ctladdr -- an address pointer controlling the
 601: **			user/groupid etc. of the mailer.
 602: **
 603: **	Returns:
 604: **		exit status of mailer.
 605: **
 606: **	Side Effects:
 607: **		none.
 608: */
 609: static
 610: sendoff(e, m, pvp, ctladdr)
 611:     register ENVELOPE *e;
 612:     MAILER *m;
 613:     char **pvp;
 614:     ADDRESS *ctladdr;
 615: {
 616:     auto FILE *mfile;
 617:     auto FILE *rfile;
 618:     register int i;
 619:     int pid;
 620: 
 621:     /*
 622: 	**  Create connection to mailer.
 623: 	*/
 624: 
 625:     pid = openmailer(m, pvp, ctladdr, FALSE, &mfile, &rfile);
 626:     if (pid < 0)
 627:         return (-1);
 628: 
 629:     /*
 630: 	**  Format and send message.
 631: 	*/
 632: 
 633:     putfromline(mfile, m);
 634:     (*e->e_puthdr)(mfile, m, e);
 635:     putline("\n", mfile, m);
 636:     (*e->e_putbody)(mfile, m, e);
 637:     (void) fclose(mfile);
 638: 
 639:     i = endmailer(pid, pvp[0]);
 640: 
 641:     /* arrange a return receipt if requested */
 642:     if (e->e_receiptto != NULL && bitnset(M_LOCAL, m->m_flags))
 643:     {
 644:         e->e_flags |= EF_SENDRECEIPT;
 645:         /* do we want to send back more info? */
 646:     }
 647: 
 648:     return (i);
 649: }
 650: /*
 651: **  ENDMAILER -- Wait for mailer to terminate.
 652: **
 653: **	We should never get fatal errors (e.g., segmentation
 654: **	violation), so we report those specially.  For other
 655: **	errors, we choose a status message (into statmsg),
 656: **	and if it represents an error, we print it.
 657: **
 658: **	Parameters:
 659: **		pid -- pid of mailer.
 660: **		name -- name of mailer (for error messages).
 661: **
 662: **	Returns:
 663: **		exit code of mailer.
 664: **
 665: **	Side Effects:
 666: **		none.
 667: */
 668: 
 669: endmailer(pid, name)
 670:     int pid;
 671:     char *name;
 672: {
 673:     int st;
 674: 
 675:     /* in the IPC case there is nothing to wait for */
 676:     if (pid == 0)
 677:         return (EX_OK);
 678: 
 679:     /* wait for the mailer process to die and collect status */
 680:     st = waitfor(pid);
 681:     if (st == -1)
 682:     {
 683:         syserr("endmailer %s: wait", name);
 684:         return (EX_SOFTWARE);
 685:     }
 686: 
 687:     /* see if it died a horrid death */
 688:     if ((st & 0377) != 0)
 689:     {
 690:         syserr("mailer %s died with signal %o", name, st);
 691:         ExitStat = EX_TEMPFAIL;
 692:         return (EX_TEMPFAIL);
 693:     }
 694: 
 695:     /* normal death -- return status */
 696:     st = (st >> 8) & 0377;
 697:     return (st);
 698: }
 699: /*
 700: **  OPENMAILER -- open connection to mailer.
 701: **
 702: **	Parameters:
 703: **		m -- mailer descriptor.
 704: **		pvp -- parameter vector to pass to mailer.
 705: **		ctladdr -- controlling address for user.
 706: **		clever -- create a full duplex connection.
 707: **		pmfile -- pointer to mfile (to mailer) connection.
 708: **		prfile -- pointer to rfile (from mailer) connection.
 709: **
 710: **	Returns:
 711: **		pid of mailer ( > 0 ).
 712: **		-1 on error.
 713: **		zero on an IPC connection.
 714: **
 715: **	Side Effects:
 716: **		creates a mailer in a subprocess.
 717: */
 718: 
 719: openmailer(m, pvp, ctladdr, clever, pmfile, prfile)
 720:     MAILER *m;
 721:     char **pvp;
 722:     ADDRESS *ctladdr;
 723:     bool clever;
 724:     FILE **pmfile;
 725:     FILE **prfile;
 726: {
 727:     int pid;
 728:     int mpvect[2];
 729:     int rpvect[2];
 730:     FILE *mfile;
 731:     FILE *rfile;
 732:     extern FILE *fdopen();
 733: 
 734: # ifdef DEBUG
 735:     if (tTd(11, 1))
 736:     {
 737:         printf("openmailer:");
 738:         printav(pvp);
 739:     }
 740: # endif DEBUG
 741:     errno = 0;
 742: 
 743:     CurHostName = m->m_mailer;
 744: 
 745:     /*
 746: 	**  Deal with the special case of mail handled through an IPC
 747: 	**  connection.
 748: 	**	In this case we don't actually fork.  We must be
 749: 	**	running SMTP for this to work.  We will return a
 750: 	**	zero pid to indicate that we are running IPC.
 751: 	**  We also handle a debug version that just talks to stdin/out.
 752: 	*/
 753: 
 754: #ifdef DEBUG
 755:     /* check for Local Person Communication -- not for mortals!!! */
 756:     if (strcmp(m->m_mailer, "[LPC]") == 0)
 757:     {
 758:         *pmfile = stdout;
 759:         *prfile = stdin;
 760:         return (0);
 761:     }
 762: #endif DEBUG
 763: 
 764:     if (strcmp(m->m_mailer, "[IPC]") == 0)
 765:     {
 766: #ifdef HOSTINFO
 767:         register STAB *st;
 768:         extern STAB *stab();
 769: #endif HOSTINFO
 770: #ifdef DAEMON
 771:         register int i, j;
 772:         register u_short port;
 773: 
 774:         CurHostName = pvp[1];
 775:         if (!clever)
 776:             syserr("non-clever IPC");
 777:         if (pvp[2] != NULL)
 778:             port = atoi(pvp[2]);
 779:         else
 780:             port = 0;
 781:         for (j = 0; j < Nmx; j++)
 782:         {
 783:             CurHostName = MxHosts[j];
 784: #ifdef HOSTINFO
 785:         /* see if we have already determined that this host is fried */
 786:             st = stab(MxHosts[j], ST_HOST, ST_FIND);
 787:             if (st == NULL || st->s_host.ho_exitstat == EX_OK) {
 788:                 if (j > 1)
 789:                     message(Arpa_Info,
 790:                         "Connecting to %s (%s)...",
 791:                         MxHosts[j], m->m_name);
 792:                 i = makeconnection(MxHosts[j], port, pmfile, prfile);
 793:             }
 794:             else
 795:             {
 796:                 i = st->s_host.ho_exitstat;
 797:                 errno = st->s_host.ho_errno;
 798:             }
 799: #else HOSTINFO
 800:             i = makeconnection(MxHosts[j], port, pmfile, prfile);
 801: #endif HOSTINFO
 802:             if (i != EX_OK)
 803:             {
 804: #ifdef HOSTINFO
 805:                 /* enter status of this host */
 806:                 if (st == NULL)
 807:                     st = stab(MxHosts[j], ST_HOST, ST_ENTER);
 808:                 st->s_host.ho_exitstat = i;
 809:                 st->s_host.ho_errno = errno;
 810: #endif HOSTINFO
 811:                 ExitStat = i;
 812:                 continue;
 813:             }
 814:             else
 815:                 return (0);
 816:         }
 817:         return (-1);
 818: #else DAEMON
 819:         syserr("openmailer: no IPC");
 820:         return (-1);
 821: #endif DAEMON
 822:     }
 823: 
 824:     /* create a pipe to shove the mail through */
 825:     if (pipe(mpvect) < 0)
 826:     {
 827:         syserr("openmailer: pipe (to mailer)");
 828:         return (-1);
 829:     }
 830: 
 831: #ifdef SMTP
 832:     /* if this mailer speaks smtp, create a return pipe */
 833:     if (clever && pipe(rpvect) < 0)
 834:     {
 835:         syserr("openmailer: pipe (from mailer)");
 836:         (void) close(mpvect[0]);
 837:         (void) close(mpvect[1]);
 838:         return (-1);
 839:     }
 840: #endif SMTP
 841: 
 842:     /*
 843: 	**  Actually fork the mailer process.
 844: 	**	DOFORK is clever about retrying.
 845: 	**
 846: 	**	Dispose of SIGCHLD signal catchers that may be laying
 847: 	**	around so that endmail will get it.
 848: 	*/
 849: 
 850:     if (CurEnv->e_xfp != NULL)
 851:         (void) fflush(CurEnv->e_xfp);       /* for debugging */
 852:     (void) fflush(stdout);
 853: # ifdef SIGCHLD
 854:     (void) signal(SIGCHLD, SIG_DFL);
 855: # endif SIGCHLD
 856:     DOFORK(XFORK);
 857:     /* pid is set by DOFORK */
 858:     if (pid < 0)
 859:     {
 860:         /* failure */
 861:         syserr("openmailer: cannot fork");
 862:         (void) close(mpvect[0]);
 863:         (void) close(mpvect[1]);
 864: #ifdef SMTP
 865:         if (clever)
 866:         {
 867:             (void) close(rpvect[0]);
 868:             (void) close(rpvect[1]);
 869:         }
 870: #endif SMTP
 871:         return (-1);
 872:     }
 873:     else if (pid == 0)
 874:     {
 875:         int i;
 876:         extern int DtableSize;
 877: 
 878:         /* child -- set up input & exec mailer */
 879:         /* make diagnostic output be standard output */
 880:         (void) signal(SIGINT, SIG_IGN);
 881:         (void) signal(SIGHUP, SIG_IGN);
 882:         (void) signal(SIGTERM, SIG_DFL);
 883: 
 884:         /* arrange to filter standard & diag output of command */
 885:         if (clever)
 886:         {
 887:             (void) close(rpvect[0]);
 888:             (void) close(1);
 889:             (void) dup(rpvect[1]);
 890:             (void) close(rpvect[1]);
 891:         }
 892:         else if (OpMode == MD_SMTP || HoldErrs)
 893:         {
 894:             /* put mailer output in transcript */
 895:             (void) close(1);
 896:             (void) dup(fileno(CurEnv->e_xfp));
 897:         }
 898:         (void) close(2);
 899:         (void) dup(1);
 900: 
 901:         /* arrange to get standard input */
 902:         (void) close(mpvect[1]);
 903:         (void) close(0);
 904:         if (dup(mpvect[0]) < 0)
 905:         {
 906:             syserr("Cannot dup to zero!");
 907:             _exit(EX_OSERR);
 908:         }
 909:         (void) close(mpvect[0]);
 910:         if (!bitnset(M_RESTR, m->m_flags))
 911:         {
 912:             if (ctladdr == NULL || ctladdr->q_uid == 0)
 913:             {
 914:                 (void) setgid(DefGid);
 915:                 (void) setuid(DefUid);
 916:             }
 917:             else
 918:             {
 919:                 (void) setgid(ctladdr->q_gid);
 920:                 (void) setuid(ctladdr->q_uid);
 921:             }
 922:         }
 923: 
 924:         /* arrange for all the files to be closed */
 925:         for (i = 3; i < DtableSize; i++)
 926:             (void) ioctl(i, FIOCLEX, 0);
 927: 
 928:         /* try to execute the mailer */
 929:         execve(m->m_mailer, pvp, UserEnviron);
 930:         syserr("Cannot exec %s", m->m_mailer);
 931:         if (m == LocalMailer || errno == EIO || errno == EAGAIN ||
 932:             errno == ENOMEM || errno == EPROCLIM)
 933:             _exit(EX_TEMPFAIL);
 934:         else
 935:             _exit(EX_UNAVAILABLE);
 936:     }
 937: 
 938:     /*
 939: 	**  Set up return value.
 940: 	*/
 941: 
 942:     (void) close(mpvect[0]);
 943:     mfile = fdopen(mpvect[1], "w");
 944:     if (clever)
 945:     {
 946:         (void) close(rpvect[1]);
 947:         rfile = fdopen(rpvect[0], "r");
 948:     }
 949: 
 950:     *pmfile = mfile;
 951:     *prfile = rfile;
 952: 
 953:     return (pid);
 954: }
 955: /*
 956: **  GIVERESPONSE -- Interpret an error response from a mailer
 957: **
 958: **	Parameters:
 959: **		stat -- the status code from the mailer (high byte
 960: **			only; core dumps must have been taken care of
 961: **			already).
 962: **		m -- the mailer descriptor for this mailer.
 963: **
 964: **	Returns:
 965: **		none.
 966: **
 967: **	Side Effects:
 968: **		Errors may be incremented.
 969: **		ExitStat may be set.
 970: */
 971: 
 972: giveresponse(stat, m, e)
 973:     int stat;
 974:     register MAILER *m;
 975:     ENVELOPE *e;
 976: {
 977:     register char *statmsg;
 978:     extern char *SysExMsg[];
 979:     register int i;
 980:     extern int N_SysEx, h_errno;
 981:     char buf[MAXLINE];
 982: 
 983: #ifdef lint
 984:     if (m == NULL)
 985:         return;
 986: #endif lint
 987: 
 988:     /*
 989: 	**  Compute status message from code.
 990: 	*/
 991: 
 992:     i = stat - EX__BASE;
 993:     if (stat == 0)
 994:         statmsg = "250 Sent";
 995:     else if (i < 0 || i > N_SysEx)
 996:     {
 997:         (void) sprintf(buf, "554 unknown mailer error %d", stat);
 998:         stat = EX_UNAVAILABLE;
 999:         statmsg = buf;
1000:     }
1001:     else if (stat == EX_TEMPFAIL)
1002:     {
1003:         (void) strcpy(buf, SysExMsg[i]);
1004:         if (h_errno == TRY_AGAIN)
1005:         {
1006:             extern char *errstring();
1007: 
1008:             statmsg = errstring(h_errno+MAX_ERRNO);
1009:         }
1010:         else
1011:         {
1012:             if (errno != 0)
1013:             {
1014:                 extern char *errstring();
1015: 
1016:                 statmsg = errstring(errno);
1017:             }
1018:             else
1019:             {
1020: #ifdef SMTP
1021:                 extern char SmtpError[];
1022: 
1023:                 statmsg = SmtpError;
1024: #else SMTP
1025:                 statmsg = NULL;
1026: #endif SMTP
1027:             }
1028:         }
1029:         if (statmsg != NULL && statmsg[0] != '\0')
1030:         {
1031:             (void) strcat(buf, ": ");
1032:             (void) strcat(buf, statmsg);
1033:         }
1034:         statmsg = buf;
1035:     }
1036:     else
1037:     {
1038:         statmsg = SysExMsg[i];
1039:     }
1040: 
1041:     /*
1042: 	**  Print the message as appropriate
1043: 	*/
1044: 
1045:     if (stat == EX_OK || stat == EX_TEMPFAIL)
1046:         message(Arpa_Info, &statmsg[4]);
1047:     else
1048:     {
1049:         Errors++;
1050:         usrerr(statmsg);
1051:     }
1052: 
1053:     /*
1054: 	**  Final cleanup.
1055: 	**	Log a record of the transaction.  Compute the new
1056: 	**	ExitStat -- if we already had an error, stick with
1057: 	**	that.
1058: 	*/
1059: 
1060:     if (LogLevel > ((stat == 0 || stat == EX_TEMPFAIL) ? 3 : 2))
1061:         logdelivery(&statmsg[4]);
1062: 
1063:     if (stat != EX_TEMPFAIL)
1064:         setstat(stat);
1065:     if (stat != EX_OK)
1066:     {
1067:         if (e->e_message != NULL)
1068:             free(e->e_message);
1069:         e->e_message = newstr(&statmsg[4]);
1070:     }
1071:     errno = 0;
1072:     h_errno = 0;
1073: }
1074: /*
1075: **  LOGDELIVERY -- log the delivery in the system log
1076: **
1077: **	Parameters:
1078: **		stat -- the message to print for the status
1079: **
1080: **	Returns:
1081: **		none
1082: **
1083: **	Side Effects:
1084: **		none
1085: */
1086: 
1087: logdelivery(stat)
1088:     char *stat;
1089: {
1090:     extern char *pintvl();
1091: 
1092: # ifdef LOG
1093:     syslog(LOG_INFO, "%s: to=%s, delay=%s, stat=%s", CurEnv->e_id,
1094:            CurEnv->e_to, pintvl(curtime() - CurEnv->e_ctime, TRUE), stat);
1095: # endif LOG
1096: }
1097: /*
1098: **  PUTFROMLINE -- output a UNIX-style from line (or whatever)
1099: **
1100: **	This can be made an arbitrary message separator by changing $l
1101: **
1102: **	One of the ugliest hacks seen by human eyes is contained herein:
1103: **	UUCP wants those stupid "remote from <host>" lines.  Why oh why
1104: **	does a well-meaning programmer such as myself have to deal with
1105: **	this kind of antique garbage????
1106: **
1107: **	Parameters:
1108: **		fp -- the file to output to.
1109: **		m -- the mailer describing this entry.
1110: **
1111: **	Returns:
1112: **		none
1113: **
1114: **	Side Effects:
1115: **		outputs some text to fp.
1116: */
1117: 
1118: putfromline(fp, m)
1119:     register FILE *fp;
1120:     register MAILER *m;
1121: {
1122:     char *template = "\001l\n";
1123:     char buf[MAXLINE];
1124: 
1125:     if (bitnset(M_NHDR, m->m_flags))
1126:         return;
1127: 
1128: # ifdef UGLYUUCP
1129:     if (bitnset(M_UGLYUUCP, m->m_flags))
1130:     {
1131:         char *bang;
1132:         char xbuf[MAXLINE];
1133: 
1134:         expand("\001g", buf, &buf[sizeof buf - 1], CurEnv);
1135:         bang = index(buf, '!');
1136:         if (bang == NULL)
1137:             syserr("No ! in UUCP! (%s)", buf);
1138:         else
1139:         {
1140:             *bang++ = '\0';
1141:             (void) sprintf(xbuf, "From %s  \001d remote from %s\n", bang, buf);
1142:             template = xbuf;
1143:         }
1144:     }
1145: # endif UGLYUUCP
1146:     expand(template, buf, &buf[sizeof buf - 1], CurEnv);
1147:     putline(buf, fp, m);
1148: }
1149: /*
1150: **  PUTBODY -- put the body of a message.
1151: **
1152: **	Parameters:
1153: **		fp -- file to output onto.
1154: **		m -- a mailer descriptor to control output format.
1155: **		e -- the envelope to put out.
1156: **
1157: **	Returns:
1158: **		none.
1159: **
1160: **	Side Effects:
1161: **		The message is written onto fp.
1162: */
1163: 
1164: putbody(fp, m, e)
1165:     FILE *fp;
1166:     MAILER *m;
1167:     register ENVELOPE *e;
1168: {
1169:     char buf[MAXLINE];
1170: 
1171:     /*
1172: 	**  Output the body of the message
1173: 	*/
1174: 
1175:     if (e->e_dfp == NULL)
1176:     {
1177:         if (e->e_df != NULL)
1178:         {
1179:             e->e_dfp = fopen(e->e_df, "r");
1180:             if (e->e_dfp == NULL)
1181:                 syserr("Cannot open %s", e->e_df);
1182:         }
1183:         else
1184:             putline("<<< No Message Collected >>>", fp, m);
1185:     }
1186:     if (e->e_dfp != NULL)
1187:     {
1188:         rewind(e->e_dfp);
1189:         while (!ferror(fp) && fgets(buf, sizeof buf, e->e_dfp) != NULL)
1190:         {
1191:             if (buf[0] == 'F' && bitnset(M_ESCFROM, m->m_flags) &&
1192:                 strncmp(buf, "From", 4) == 0)
1193:                 (void) putc('>', fp);
1194:             putline(buf, fp, m);
1195:         }
1196: 
1197:         if (ferror(e->e_dfp))
1198:         {
1199:             syserr("putbody: read error");
1200:             ExitStat = EX_IOERR;
1201:         }
1202:     }
1203: 
1204:     (void) fflush(fp);
1205:     if (ferror(fp) && errno != EPIPE)
1206:     {
1207:         syserr("putbody: write error");
1208:         ExitStat = EX_IOERR;
1209:     }
1210:     errno = 0;
1211: }
1212: /*
1213: **  MAILFILE -- Send a message to a file.
1214: **
1215: **	If the file has the setuid/setgid bits set, but NO execute
1216: **	bits, sendmail will try to become the owner of that file
1217: **	rather than the real user.  Obviously, this only works if
1218: **	sendmail runs as root.
1219: **
1220: **	This could be done as a subordinate mailer, except that it
1221: **	is used implicitly to save messages in ~/dead.letter.  We
1222: **	view this as being sufficiently important as to include it
1223: **	here.  For example, if the system is dying, we shouldn't have
1224: **	to create another process plus some pipes to save the message.
1225: **
1226: **	Parameters:
1227: **		filename -- the name of the file to send to.
1228: **		ctladdr -- the controlling address header -- includes
1229: **			the userid/groupid to be when sending.
1230: **
1231: **	Returns:
1232: **		The exit code associated with the operation.
1233: **
1234: **	Side Effects:
1235: **		none.
1236: */
1237: 
1238: mailfile(filename, ctladdr)
1239:     char *filename;
1240:     ADDRESS *ctladdr;
1241: {
1242:     register FILE *f;
1243:     register int pid;
1244: 
1245:     /*
1246: 	**  Fork so we can change permissions here.
1247: 	**	Note that we MUST use fork, not vfork, because of
1248: 	**	the complications of calling subroutines, etc.
1249: 	*/
1250: 
1251:     DOFORK(fork);
1252: 
1253:     if (pid < 0)
1254:         return (EX_OSERR);
1255:     else if (pid == 0)
1256:     {
1257:         /* child -- actually write to file */
1258:         struct stat stb;
1259: 
1260:         (void) signal(SIGINT, SIG_DFL);
1261:         (void) signal(SIGHUP, SIG_DFL);
1262:         (void) signal(SIGTERM, SIG_DFL);
1263:         (void) umask(OldUmask);
1264:         if (stat(filename, &stb) < 0)
1265:         {
1266:             errno = 0;
1267:             stb.st_mode = 0666;
1268:         }
1269:         if (bitset(0111, stb.st_mode))
1270:             exit(EX_CANTCREAT);
1271:         if (ctladdr == NULL)
1272:             ctladdr = &CurEnv->e_from;
1273:         if (!bitset(S_ISGID, stb.st_mode) || setgid(stb.st_gid) < 0)
1274:         {
1275:             if (ctladdr->q_uid == 0)
1276:                 (void) setgid(DefGid);
1277:             else
1278:                 (void) setgid(ctladdr->q_gid);
1279:         }
1280:         if (!bitset(S_ISUID, stb.st_mode) || setuid(stb.st_uid) < 0)
1281:         {
1282:             if (ctladdr->q_uid == 0)
1283:                 (void) setuid(DefUid);
1284:             else
1285:                 (void) setuid(ctladdr->q_uid);
1286:         }
1287:         f = dfopen(filename, "a");
1288:         if (f == NULL)
1289:             exit(EX_CANTCREAT);
1290: 
1291:         putfromline(f, ProgMailer);
1292:         (*CurEnv->e_puthdr)(f, ProgMailer, CurEnv);
1293:         putline("\n", f, ProgMailer);
1294:         (*CurEnv->e_putbody)(f, ProgMailer, CurEnv);
1295:         putline("\n", f, ProgMailer);
1296:         (void) fclose(f);
1297:         (void) fflush(stdout);
1298: 
1299:         /* reset ISUID & ISGID bits for paranoid systems */
1300:         (void) chmod(filename, (int) stb.st_mode);
1301:         exit(EX_OK);
1302:         /*NOTREACHED*/
1303:     }
1304:     else
1305:     {
1306:         /* parent -- wait for exit status */
1307:         int st;
1308: 
1309:         st = waitfor(pid);
1310:         if ((st & 0377) != 0)
1311:             return (EX_UNAVAILABLE);
1312:         else
1313:             return ((st >> 8) & 0377);
1314:     }
1315: }
1316: /*
1317: **  SENDALL -- actually send all the messages.
1318: **
1319: **	Parameters:
1320: **		e -- the envelope to send.
1321: **		mode -- the delivery mode to use.  If SM_DEFAULT, use
1322: **			the current SendMode.
1323: **
1324: **	Returns:
1325: **		none.
1326: **
1327: **	Side Effects:
1328: **		Scans the send lists and sends everything it finds.
1329: **		Delivers any appropriate error messages.
1330: **		If we are running in a non-interactive mode, takes the
1331: **			appropriate action.
1332: */
1333: 
1334: sendall(e, mode)
1335:     ENVELOPE *e;
1336:     char mode;
1337: {
1338:     register ADDRESS *q;
1339:     bool oldverbose;
1340:     int pid;
1341: 
1342:     /* determine actual delivery mode */
1343:     if (mode == SM_DEFAULT)
1344:     {
1345:         extern bool shouldqueue();
1346: 
1347:         if (shouldqueue(e->e_msgpriority))
1348:             mode = SM_QUEUE;
1349:         else
1350:             mode = SendMode;
1351:     }
1352: 
1353: #ifdef DEBUG
1354:     if (tTd(13, 1))
1355:     {
1356:         printf("\nSENDALL: mode %c, sendqueue:\n", mode);
1357:         printaddr(e->e_sendqueue, TRUE);
1358:     }
1359: #endif DEBUG
1360: 
1361:     /*
1362: 	**  Do any preprocessing necessary for the mode we are running.
1363: 	**	Check to make sure the hop count is reasonable.
1364: 	**	Delete sends to the sender in mailing lists.
1365: 	*/
1366: 
1367:     CurEnv = e;
1368: 
1369:     if (e->e_hopcount > MAXHOP)
1370:     {
1371:         syserr("sendall: too many hops (%d max)", MAXHOP);
1372:         return;
1373:     }
1374: 
1375:     if (!MeToo)
1376:     {
1377:         extern ADDRESS *recipient();
1378: 
1379:         e->e_from.q_flags |= QDONTSEND;
1380:         (void) recipient(&e->e_from, &e->e_sendqueue);
1381:     }
1382: 
1383: # ifdef QUEUE
1384:     if ((mode == SM_QUEUE || mode == SM_FORK ||
1385:          (mode != SM_VERIFY && SuperSafe)) &&
1386:         !bitset(EF_INQUEUE, e->e_flags))
1387:         queueup(e, TRUE, mode == SM_QUEUE);
1388: #endif QUEUE
1389: 
1390:     oldverbose = Verbose;
1391:     switch (mode)
1392:     {
1393:       case SM_VERIFY:
1394:         Verbose = TRUE;
1395:         break;
1396: 
1397:       case SM_QUEUE:
1398:         e->e_flags |= EF_INQUEUE|EF_KEEPQUEUE;
1399:         return;
1400: 
1401:       case SM_FORK:
1402:         if (e->e_xfp != NULL)
1403:             (void) fflush(e->e_xfp);
1404:         pid = fork();
1405:         if (pid < 0)
1406:         {
1407:             mode = SM_DELIVER;
1408:             break;
1409:         }
1410:         else if (pid > 0)
1411:         {
1412:             /* be sure we leave the temp files to our child */
1413:             e->e_id = e->e_df = NULL;
1414:             return;
1415:         }
1416: 
1417:         /* double fork to avoid zombies */
1418:         if (fork() > 0)
1419:             exit(EX_OK);
1420: 
1421:         /* be sure we are immune from the terminal */
1422:         disconnect(FALSE);
1423: 
1424:         break;
1425:     }
1426: 
1427:     /*
1428: 	**  Run through the list and send everything.
1429: 	*/
1430: 
1431:     for (q = e->e_sendqueue; q != NULL; q = q->q_next)
1432:     {
1433:         if (mode == SM_VERIFY)
1434:         {
1435:             e->e_to = q->q_paddr;
1436:             if (!bitset(QDONTSEND|QBADADDR, q->q_flags))
1437:                 message(Arpa_Info, "deliverable");
1438:         }
1439:         else
1440:             (void) deliver(e, q);
1441:     }
1442:     Verbose = oldverbose;
1443: 
1444:     /*
1445: 	**  Now run through and check for errors.
1446: 	*/
1447: 
1448:     if (mode == SM_VERIFY)
1449:         return;
1450: 
1451:     for (q = e->e_sendqueue; q != NULL; q = q->q_next)
1452:     {
1453:         register ADDRESS *qq;
1454: 
1455: # ifdef DEBUG
1456:         if (tTd(13, 3))
1457:         {
1458:             printf("Checking ");
1459:             printaddr(q, FALSE);
1460:         }
1461: # endif DEBUG
1462: 
1463:         /* only send errors if the message failed */
1464:         if (!bitset(QBADADDR, q->q_flags))
1465:             continue;
1466: 
1467:         /* we have an address that failed -- find the parent */
1468:         for (qq = q; qq != NULL; qq = qq->q_alias)
1469:         {
1470:             char obuf[MAXNAME + 6];
1471:             extern char *aliaslookup();
1472: 
1473:             /* we can only have owners for local addresses */
1474:             if (!bitnset(M_LOCAL, qq->q_mailer->m_flags))
1475:                 continue;
1476: 
1477:             /* see if the owner list exists */
1478:             (void) strcpy(obuf, "owner-");
1479:             if (strncmp(qq->q_user, "owner-", 6) == 0)
1480:                 (void) strcat(obuf, "owner");
1481:             else
1482:                 (void) strcat(obuf, qq->q_user);
1483:             if (aliaslookup(obuf) == NULL)
1484:                 continue;
1485: 
1486: # ifdef DEBUG
1487:             if (tTd(13, 4))
1488:                 printf("Errors to %s\n", obuf);
1489: # endif DEBUG
1490: 
1491:             /* owner list exists -- add it to the error queue */
1492:             sendtolist(obuf, (ADDRESS *) NULL, &e->e_errorqueue);
1493:             ErrorMode = EM_MAIL;
1494:             break;
1495:         }
1496: 
1497:         /* if we did not find an owner, send to the sender */
1498:         if (qq == NULL && bitset(QBADADDR, q->q_flags))
1499:             sendtolist(e->e_from.q_paddr, qq, &e->e_errorqueue);
1500:     }
1501: 
1502:     if (mode == SM_FORK)
1503:         finis();
1504: }

Defined functions

deliver defined in line 57; used 2 times
endmailer defined in line 669; used 2 times
giveresponse defined in line 972; used 7 times
logdelivery defined in line 1087; used 3 times
mailfile defined in line 1238; used 1 times
markfailure defined in line 500; used 2 times
openmailer defined in line 719; used 2 times
putfromline defined in line 1118; used 3 times
sendoff defined in line 609; used 1 times

Defined variables

sccsid defined in line 23; never used

Defined macros

DOFORK defined in line 558; used 3 times
NFORKTRIES defined in line 551; used 2 times
XFORK defined in line 555; used 1 times
Last modified: 1993-02-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 307
Valid CSS Valid XHTML 1.0 Strict