# 2.11BSD#431 - /usr/src/usr.sbin/sendmail.MX/src/deliver.c

##### Functions

    deliver           X
    dofork            X
    endmailer         X
    giveresponse      X
    logdelivery       X
    mailfile          X
    markfailure       X
    openmailer        X
    putbody           X
    putfromline       X
    sendall           X

##### Macros

    DOFORK            X
    NFORKTRIES        X
    XFORK             X

       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

- in line 1440
- in /usr/src/usr.sbin/sendmail.MX/src/savemail.c line 290

dofork defined in line 586; used 2 times

- in /usr/src/usr.sbin/sendmail.MX/src/queue.c line 296
- in /usr/src/usr.sbin/sendmail.MX/src/srvrsmtp.c line 654

endmailer defined in line 669; used 2 times

- in line 639
- in /usr/src/usr.sbin/sendmail.MX/src/usersmtp.c line 359

giveresponse defined in line 972; used 7 times

- in line 253-258(2), 310, 435, 474
- in /usr/src/usr.sbin/sendmail.MX/src/recipient.c line 296, 309

logdelivery defined in line 1087; used 3 times

- in line 120, 1061
- in /usr/src/usr.sbin/sendmail.MX/src/queue.c line 153

mailfile defined in line 1238; used 1 times

- in line 309

markfailure defined in line 500; used 2 times

- in line 434, 477

openmailer defined in line 719; used 2 times

- in line 625
- in /usr/src/usr.sbin/sendmail.MX/src/usersmtp.c line 97

putbody defined in line 1164; used 7 times

- in /usr/src/usr.sbin/sendmail.MX/src/envelope.c line 46, 61
- in /usr/src/usr.sbin/sendmail.MX/src/main.c line 113, 157
- in /usr/src/usr.sbin/sendmail.MX/src/queue.c line 103, 116
- in /usr/src/usr.sbin/sendmail.MX/src/savemail.c line 505

putfromline defined in line 1118; used 3 times

- in line 633, 1291
- in /usr/src/usr.sbin/sendmail.MX/src/savemail.c line 314

sendall defined in line 1334; used 4 times

- in /usr/src/usr.sbin/sendmail.MX/src/main.c line 712
- in /usr/src/usr.sbin/sendmail.MX/src/queue.c line 646
- in /usr/src/usr.sbin/sendmail.MX/src/savemail.c line 431
- in /usr/src/usr.sbin/sendmail.MX/src/srvrsmtp.c line 348

sendoff defined in line 609; used 1 times

- in line 462

#### Defined variables

sccsid defined in line 23; never used

#### Defined macros

DOFORK defined in line 558; used 3 times

- in line 590, 856, 1251

NFORKTRIES defined in line 551; used 2 times

- in line 562, 568

XFORK defined in line 555; used 1 times

- in line 856

Last modified: 1993-02-01 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2990 |