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