Annotation of 43BSDReno/usr.sbin/sendmail/src/deliver.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.