home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.sbin / sendmail / src / deliver.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-20  |  33.3 KB  |  1,554 lines

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