Annotation of 43BSD/usr.lib/sendmail/src/srvrsmtp.c, revision 1.1

1.1     ! root        1: /*
        !             2: **  Sendmail
        !             3: **  Copyright (c) 1983  Eric P. Allman
        !             4: **  Berkeley, California
        !             5: **
        !             6: **  Copyright (c) 1983 Regents of the University of California.
        !             7: **  All rights reserved.  The Berkeley software License Agreement
        !             8: **  specifies the terms and conditions for redistribution.
        !             9: */
        !            10: 
        !            11: 
        !            12: # include <errno.h>
        !            13: # include "sendmail.h"
        !            14: # include <signal.h>
        !            15: 
        !            16: # ifndef SMTP
        !            17: # ifndef lint
        !            18: static char    SccsId[] = "@(#)srvrsmtp.c      5.18 (Berkeley) 1/5/86  (no SMTP)";
        !            19: # endif not lint
        !            20: # else SMTP
        !            21: 
        !            22: # ifndef lint
        !            23: static char    SccsId[] = "@(#)srvrsmtp.c      5.18 (Berkeley) 1/5/86";
        !            24: # endif not lint
        !            25: 
        !            26: /*
        !            27: **  SMTP -- run the SMTP protocol.
        !            28: **
        !            29: **     Parameters:
        !            30: **             none.
        !            31: **
        !            32: **     Returns:
        !            33: **             never.
        !            34: **
        !            35: **     Side Effects:
        !            36: **             Reads commands from the input channel and processes
        !            37: **                     them.
        !            38: */
        !            39: 
        !            40: struct cmd
        !            41: {
        !            42:        char    *cmdname;       /* command name */
        !            43:        int     cmdcode;        /* internal code, see below */
        !            44: };
        !            45: 
        !            46: /* values for cmdcode */
        !            47: # define CMDERROR      0       /* bad command */
        !            48: # define CMDMAIL       1       /* mail -- designate sender */
        !            49: # define CMDRCPT       2       /* rcpt -- designate recipient */
        !            50: # define CMDDATA       3       /* data -- send message text */
        !            51: # define CMDRSET       4       /* rset -- reset state */
        !            52: # define CMDVRFY       5       /* vrfy -- verify address */
        !            53: # define CMDHELP       6       /* help -- give usage info */
        !            54: # define CMDNOOP       7       /* noop -- do nothing */
        !            55: # define CMDQUIT       8       /* quit -- close connection and die */
        !            56: # define CMDHELO       9       /* helo -- be polite */
        !            57: # define CMDDBGQSHOW   10      /* showq -- show send queue (DEBUG) */
        !            58: # define CMDDBGDEBUG   11      /* debug -- set debug mode */
        !            59: # define CMDVERB       12      /* verb -- go into verbose mode */
        !            60: # define CMDDBGKILL    13      /* kill -- kill sendmail */
        !            61: # define CMDDBGWIZ     14      /* wiz -- become a wizard */
        !            62: # define CMDONEX       15      /* onex -- sending one transaction only */
        !            63: 
        !            64: static struct cmd      CmdTab[] =
        !            65: {
        !            66:        "mail",         CMDMAIL,
        !            67:        "rcpt",         CMDRCPT,
        !            68:        "data",         CMDDATA,
        !            69:        "rset",         CMDRSET,
        !            70:        "vrfy",         CMDVRFY,
        !            71:        "expn",         CMDVRFY,
        !            72:        "help",         CMDHELP,
        !            73:        "noop",         CMDNOOP,
        !            74:        "quit",         CMDQUIT,
        !            75:        "helo",         CMDHELO,
        !            76:        "verb",         CMDVERB,
        !            77:        "onex",         CMDONEX,
        !            78: # ifdef DEBUG
        !            79:        "showq",        CMDDBGQSHOW,
        !            80:        "debug",        CMDDBGDEBUG,
        !            81: # endif DEBUG
        !            82: # ifdef WIZ
        !            83:        "kill",         CMDDBGKILL,
        !            84: # endif WIZ
        !            85:        "wiz",          CMDDBGWIZ,
        !            86:        NULL,           CMDERROR,
        !            87: };
        !            88: 
        !            89: # ifdef WIZ
        !            90: bool   IsWiz = FALSE;                  /* set if we are a wizard */
        !            91: # endif WIZ
        !            92: char   *WizWord;                       /* the wizard word to compare against */
        !            93: bool   InChild = FALSE;                /* true if running in a subprocess */
        !            94: bool   OneXact = FALSE;                /* one xaction only this run */
        !            95: 
        !            96: #define EX_QUIT                22              /* special code for QUIT command */
        !            97: 
        !            98: smtp()
        !            99: {
        !           100:        register char *p;
        !           101:        register struct cmd *c;
        !           102:        char *cmd;
        !           103:        extern char *skipword();
        !           104:        extern bool sameword();
        !           105:        bool hasmail;                   /* mail command received */
        !           106:        auto ADDRESS *vrfyqueue;
        !           107:        ADDRESS *a;
        !           108:        char inp[MAXLINE];
        !           109:        char cmdbuf[100];
        !           110:        extern char Version[];
        !           111:        extern tick();
        !           112:        extern bool iswiz();
        !           113:        extern char *arpadate();
        !           114:        extern char *macvalue();
        !           115:        extern ADDRESS *recipient();
        !           116:        extern ENVELOPE BlankEnvelope;
        !           117:        extern ENVELOPE *newenvelope();
        !           118: 
        !           119:        hasmail = FALSE;
        !           120:        if (OutChannel != stdout)
        !           121:        {
        !           122:                /* arrange for debugging output to go to remote host */
        !           123:                (void) close(1);
        !           124:                (void) dup(fileno(OutChannel));
        !           125:        }
        !           126:        settime();
        !           127:        if (RealHostName != NULL)
        !           128:        {
        !           129:                CurHostName = RealHostName;
        !           130:                setproctitle("srvrsmtp %s", CurHostName);
        !           131:        }
        !           132:        else
        !           133:        {
        !           134:                /* this must be us!! */
        !           135:                CurHostName = MyHostName;
        !           136:        }
        !           137:        expand("\001e", inp, &inp[sizeof inp], CurEnv);
        !           138:        message("220", inp);
        !           139:        SmtpPhase = "startup";
        !           140:        for (;;)
        !           141:        {
        !           142:                /* arrange for backout */
        !           143:                if (setjmp(TopFrame) > 0 && InChild)
        !           144:                        finis();
        !           145:                QuickAbort = FALSE;
        !           146:                HoldErrs = FALSE;
        !           147: 
        !           148:                /* setup for the read */
        !           149:                CurEnv->e_to = NULL;
        !           150:                Errors = 0;
        !           151:                (void) fflush(stdout);
        !           152: 
        !           153:                /* read the input line */
        !           154:                p = sfgets(inp, sizeof inp, InChannel);
        !           155: 
        !           156:                /* handle errors */
        !           157:                if (p == NULL)
        !           158:                {
        !           159:                        /* end of file, just die */
        !           160:                        message("421", "%s Lost input channel to %s",
        !           161:                                MyHostName, CurHostName);
        !           162:                        finis();
        !           163:                }
        !           164: 
        !           165:                /* clean up end of line */
        !           166:                fixcrlf(inp, TRUE);
        !           167: 
        !           168:                /* echo command to transcript */
        !           169:                if (CurEnv->e_xfp != NULL)
        !           170:                        fprintf(CurEnv->e_xfp, "<<< %s\n", inp);
        !           171: 
        !           172:                /* break off command */
        !           173:                for (p = inp; isspace(*p); p++)
        !           174:                        continue;
        !           175:                cmd = p;
        !           176:                for (cmd = cmdbuf; *p != '\0' && !isspace(*p); )
        !           177:                        *cmd++ = *p++;
        !           178:                *cmd = '\0';
        !           179: 
        !           180:                /* throw away leading whitespace */
        !           181:                while (isspace(*p))
        !           182:                        p++;
        !           183: 
        !           184:                /* decode command */
        !           185:                for (c = CmdTab; c->cmdname != NULL; c++)
        !           186:                {
        !           187:                        if (sameword(c->cmdname, cmdbuf))
        !           188:                                break;
        !           189:                }
        !           190: 
        !           191:                /* process command */
        !           192:                switch (c->cmdcode)
        !           193:                {
        !           194:                  case CMDHELO:         /* hello -- introduce yourself */
        !           195:                        SmtpPhase = "HELO";
        !           196:                        setproctitle("%s: %s", CurHostName, inp);
        !           197:                        if (sameword(p, MyHostName))
        !           198:                        {
        !           199:                                /* connected to an echo server */
        !           200:                                message("553", "%s I refuse to talk to myself",
        !           201:                                        MyHostName);
        !           202:                                break;
        !           203:                        }
        !           204:                        if (RealHostName != NULL && !sameword(p, RealHostName))
        !           205:                        {
        !           206:                                char hostbuf[MAXNAME];
        !           207: 
        !           208:                                (void) sprintf(hostbuf, "%s (%s)", p, RealHostName);
        !           209:                                define('s', newstr(hostbuf), CurEnv);
        !           210:                        }
        !           211:                        else
        !           212:                                define('s', newstr(p), CurEnv);
        !           213:                        message("250", "%s Hello %s, pleased to meet you",
        !           214:                                MyHostName, p);
        !           215:                        break;
        !           216: 
        !           217:                  case CMDMAIL:         /* mail -- designate sender */
        !           218:                        SmtpPhase = "MAIL";
        !           219: 
        !           220:                        /* force a sending host even if no HELO given */
        !           221:                        if (RealHostName != NULL && macvalue('s', CurEnv) == NULL)
        !           222:                                define('s', RealHostName, CurEnv);
        !           223: 
        !           224:                        /* check for validity of this command */
        !           225:                        if (hasmail)
        !           226:                        {
        !           227:                                message("503", "Sender already specified");
        !           228:                                break;
        !           229:                        }
        !           230:                        if (InChild)
        !           231:                        {
        !           232:                                syserr("Nested MAIL command");
        !           233:                                exit(0);
        !           234:                        }
        !           235: 
        !           236:                        /* fork a subprocess to process this command */
        !           237:                        if (runinchild("SMTP-MAIL") > 0)
        !           238:                                break;
        !           239:                        initsys();
        !           240:                        setproctitle("%s %s: %s", CurEnv->e_id,
        !           241:                                CurHostName, inp);
        !           242: 
        !           243:                        /* child -- go do the processing */
        !           244:                        p = skipword(p, "from");
        !           245:                        if (p == NULL)
        !           246:                                break;
        !           247:                        setsender(p);
        !           248:                        if (Errors == 0)
        !           249:                        {
        !           250:                                message("250", "Sender ok");
        !           251:                                hasmail = TRUE;
        !           252:                        }
        !           253:                        else if (InChild)
        !           254:                                finis();
        !           255:                        break;
        !           256: 
        !           257:                  case CMDRCPT:         /* rcpt -- designate recipient */
        !           258:                        SmtpPhase = "RCPT";
        !           259:                        setproctitle("%s %s: %s", CurEnv->e_id,
        !           260:                                CurHostName, inp);
        !           261:                        if (setjmp(TopFrame) > 0)
        !           262:                        {
        !           263:                                CurEnv->e_flags &= ~EF_FATALERRS;
        !           264:                                break;
        !           265:                        }
        !           266:                        QuickAbort = TRUE;
        !           267:                        p = skipword(p, "to");
        !           268:                        if (p == NULL)
        !           269:                                break;
        !           270:                        a = parseaddr(p, (ADDRESS *) NULL, 1, '\0');
        !           271:                        if (a == NULL)
        !           272:                                break;
        !           273:                        a->q_flags |= QPRIMARY;
        !           274:                        a = recipient(a, &CurEnv->e_sendqueue);
        !           275:                        if (Errors != 0)
        !           276:                                break;
        !           277: 
        !           278:                        /* no errors during parsing, but might be a duplicate */
        !           279:                        CurEnv->e_to = p;
        !           280:                        if (!bitset(QBADADDR, a->q_flags))
        !           281:                                message("250", "Recipient ok");
        !           282:                        else
        !           283:                        {
        !           284:                                /* punt -- should keep message in ADDRESS.... */
        !           285:                                message("550", "Addressee unknown");
        !           286:                        }
        !           287:                        CurEnv->e_to = NULL;
        !           288:                        break;
        !           289: 
        !           290:                  case CMDDATA:         /* data -- text of mail */
        !           291:                        SmtpPhase = "DATA";
        !           292:                        if (!hasmail)
        !           293:                        {
        !           294:                                message("503", "Need MAIL command");
        !           295:                                break;
        !           296:                        }
        !           297:                        else if (CurEnv->e_nrcpts <= 0)
        !           298:                        {
        !           299:                                message("503", "Need RCPT (recipient)");
        !           300:                                break;
        !           301:                        }
        !           302: 
        !           303:                        /* collect the text of the message */
        !           304:                        SmtpPhase = "collect";
        !           305:                        setproctitle("%s %s: %s", CurEnv->e_id,
        !           306:                                CurHostName, inp);
        !           307:                        collect(TRUE);
        !           308:                        if (Errors != 0)
        !           309:                                break;
        !           310: 
        !           311:                        /*
        !           312:                        **  Arrange to send to everyone.
        !           313:                        **      If sending to multiple people, mail back
        !           314:                        **              errors rather than reporting directly.
        !           315:                        **      In any case, don't mail back errors for
        !           316:                        **              anything that has happened up to
        !           317:                        **              now (the other end will do this).
        !           318:                        **      Truncate our transcript -- the mail has gotten
        !           319:                        **              to us successfully, and if we have
        !           320:                        **              to mail this back, it will be easier
        !           321:                        **              on the reader.
        !           322:                        **      Then send to everyone.
        !           323:                        **      Finally give a reply code.  If an error has
        !           324:                        **              already been given, don't mail a
        !           325:                        **              message back.
        !           326:                        **      We goose error returns by clearing error bit.
        !           327:                        */
        !           328: 
        !           329:                        SmtpPhase = "delivery";
        !           330:                        if (CurEnv->e_nrcpts != 1)
        !           331:                        {
        !           332:                                HoldErrs = TRUE;
        !           333:                                ErrorMode = EM_MAIL;
        !           334:                        }
        !           335:                        CurEnv->e_flags &= ~EF_FATALERRS;
        !           336:                        CurEnv->e_xfp = freopen(queuename(CurEnv, 'x'), "w", CurEnv->e_xfp);
        !           337: 
        !           338:                        /* send to all recipients */
        !           339:                        sendall(CurEnv, SM_DEFAULT);
        !           340:                        CurEnv->e_to = NULL;
        !           341: 
        !           342:                        /* save statistics */
        !           343:                        markstats(CurEnv, (ADDRESS *) NULL);
        !           344: 
        !           345:                        /* issue success if appropriate and reset */
        !           346:                        if (Errors == 0 || HoldErrs)
        !           347:                                message("250", "Ok");
        !           348:                        else
        !           349:                                CurEnv->e_flags &= ~EF_FATALERRS;
        !           350: 
        !           351:                        /* if in a child, pop back to our parent */
        !           352:                        if (InChild)
        !           353:                                finis();
        !           354: 
        !           355:                        /* clean up a bit */
        !           356:                        hasmail = 0;
        !           357:                        dropenvelope(CurEnv);
        !           358:                        CurEnv = newenvelope(CurEnv);
        !           359:                        CurEnv->e_flags = BlankEnvelope.e_flags;
        !           360:                        break;
        !           361: 
        !           362:                  case CMDRSET:         /* rset -- reset state */
        !           363:                        message("250", "Reset state");
        !           364:                        if (InChild)
        !           365:                                finis();
        !           366:                        break;
        !           367: 
        !           368:                  case CMDVRFY:         /* vrfy -- verify address */
        !           369:                        if (runinchild("SMTP-VRFY") > 0)
        !           370:                                break;
        !           371:                        setproctitle("%s: %s", CurHostName, inp);
        !           372:                        vrfyqueue = NULL;
        !           373:                        QuickAbort = TRUE;
        !           374:                        sendtolist(p, (ADDRESS *) NULL, &vrfyqueue);
        !           375:                        if (Errors != 0)
        !           376:                        {
        !           377:                                if (InChild)
        !           378:                                        finis();
        !           379:                                break;
        !           380:                        }
        !           381:                        while (vrfyqueue != NULL)
        !           382:                        {
        !           383:                                register ADDRESS *a = vrfyqueue->q_next;
        !           384:                                char *code;
        !           385: 
        !           386:                                while (a != NULL && bitset(QDONTSEND|QBADADDR, a->q_flags))
        !           387:                                        a = a->q_next;
        !           388: 
        !           389:                                if (!bitset(QDONTSEND|QBADADDR, vrfyqueue->q_flags))
        !           390:                                {
        !           391:                                        if (a != NULL)
        !           392:                                                code = "250-";
        !           393:                                        else
        !           394:                                                code = "250";
        !           395:                                        if (vrfyqueue->q_fullname == NULL)
        !           396:                                                message(code, "<%s>", vrfyqueue->q_paddr);
        !           397:                                        else
        !           398:                                                message(code, "%s <%s>",
        !           399:                                                    vrfyqueue->q_fullname, vrfyqueue->q_paddr);
        !           400:                                }
        !           401:                                else if (a == NULL)
        !           402:                                        message("554", "Self destructive alias loop");
        !           403:                                vrfyqueue = a;
        !           404:                        }
        !           405:                        if (InChild)
        !           406:                                finis();
        !           407:                        break;
        !           408: 
        !           409:                  case CMDHELP:         /* help -- give user info */
        !           410:                        if (*p == '\0')
        !           411:                                p = "SMTP";
        !           412:                        help(p);
        !           413:                        break;
        !           414: 
        !           415:                  case CMDNOOP:         /* noop -- do nothing */
        !           416:                        message("200", "OK");
        !           417:                        break;
        !           418: 
        !           419:                  case CMDQUIT:         /* quit -- leave mail */
        !           420:                        message("221", "%s closing connection", MyHostName);
        !           421:                        if (InChild)
        !           422:                                ExitStat = EX_QUIT;
        !           423:                        finis();
        !           424: 
        !           425:                  case CMDVERB:         /* set verbose mode */
        !           426:                        Verbose = TRUE;
        !           427:                        SendMode = SM_DELIVER;
        !           428:                        message("200", "Verbose mode");
        !           429:                        break;
        !           430: 
        !           431:                  case CMDONEX:         /* doing one transaction only */
        !           432:                        OneXact = TRUE;
        !           433:                        message("200", "Only one transaction");
        !           434:                        break;
        !           435: 
        !           436: # ifdef DEBUG
        !           437:                  case CMDDBGQSHOW:     /* show queues */
        !           438:                        printf("Send Queue=");
        !           439:                        printaddr(CurEnv->e_sendqueue, TRUE);
        !           440:                        break;
        !           441: 
        !           442:                  case CMDDBGDEBUG:     /* set debug mode */
        !           443:                        tTsetup(tTdvect, sizeof tTdvect, "0-99.1");
        !           444:                        tTflag(p);
        !           445:                        message("200", "Debug set");
        !           446:                        break;
        !           447: # endif DEBUG
        !           448: 
        !           449: # ifdef WIZ
        !           450:                  case CMDDBGKILL:      /* kill the parent */
        !           451:                        if (!iswiz())
        !           452:                                break;
        !           453:                        if (kill(MotherPid, SIGTERM) >= 0)
        !           454:                                message("200", "Mother is dead");
        !           455:                        else
        !           456:                                message("500", "Can't kill Mom");
        !           457:                        break;
        !           458: 
        !           459:                  case CMDDBGWIZ:       /* become a wizard */
        !           460:                        if (WizWord != NULL)
        !           461:                        {
        !           462:                                char seed[3];
        !           463:                                extern char *crypt();
        !           464: 
        !           465:                                (void) strncpy(seed, WizWord, 2);
        !           466:                                if (strcmp(WizWord, crypt(p, seed)) == 0)
        !           467:                                {
        !           468:                                        IsWiz = TRUE;
        !           469:                                        message("200", "Please pass, oh mighty wizard");
        !           470:                                        break;
        !           471:                                }
        !           472:                        }
        !           473:                        message("500", "You are no wizard!");
        !           474:                        break;
        !           475: 
        !           476: # else WIZ
        !           477:                  case CMDDBGWIZ:       /* try to become a wizard */
        !           478:                        message("500", "You wascal wabbit!  Wandering wizards won't win!");
        !           479:                        break;
        !           480: # endif WIZ
        !           481: 
        !           482:                  case CMDERROR:        /* unknown command */
        !           483:                        message("500", "Command unrecognized");
        !           484:                        break;
        !           485: 
        !           486:                  default:
        !           487:                        syserr("smtp: unknown code %d", c->cmdcode);
        !           488:                        break;
        !           489:                }
        !           490:        }
        !           491: }
        !           492: /*
        !           493: **  SKIPWORD -- skip a fixed word.
        !           494: **
        !           495: **     Parameters:
        !           496: **             p -- place to start looking.
        !           497: **             w -- word to skip.
        !           498: **
        !           499: **     Returns:
        !           500: **             p following w.
        !           501: **             NULL on error.
        !           502: **
        !           503: **     Side Effects:
        !           504: **             clobbers the p data area.
        !           505: */
        !           506: 
        !           507: static char *
        !           508: skipword(p, w)
        !           509:        register char *p;
        !           510:        char *w;
        !           511: {
        !           512:        register char *q;
        !           513:        extern bool sameword();
        !           514: 
        !           515:        /* find beginning of word */
        !           516:        while (isspace(*p))
        !           517:                p++;
        !           518:        q = p;
        !           519: 
        !           520:        /* find end of word */
        !           521:        while (*p != '\0' && *p != ':' && !isspace(*p))
        !           522:                p++;
        !           523:        while (isspace(*p))
        !           524:                *p++ = '\0';
        !           525:        if (*p != ':')
        !           526:        {
        !           527:          syntax:
        !           528:                message("501", "Syntax error");
        !           529:                Errors++;
        !           530:                return (NULL);
        !           531:        }
        !           532:        *p++ = '\0';
        !           533:        while (isspace(*p))
        !           534:                p++;
        !           535: 
        !           536:        /* see if the input word matches desired word */
        !           537:        if (!sameword(q, w))
        !           538:                goto syntax;
        !           539: 
        !           540:        return (p);
        !           541: }
        !           542: /*
        !           543: **  HELP -- implement the HELP command.
        !           544: **
        !           545: **     Parameters:
        !           546: **             topic -- the topic we want help for.
        !           547: **
        !           548: **     Returns:
        !           549: **             none.
        !           550: **
        !           551: **     Side Effects:
        !           552: **             outputs the help file to message output.
        !           553: */
        !           554: 
        !           555: help(topic)
        !           556:        char *topic;
        !           557: {
        !           558:        register FILE *hf;
        !           559:        int len;
        !           560:        char buf[MAXLINE];
        !           561:        bool noinfo;
        !           562: 
        !           563:        if (HelpFile == NULL || (hf = fopen(HelpFile, "r")) == NULL)
        !           564:        {
        !           565:                /* no help */
        !           566:                errno = 0;
        !           567:                message("502", "HELP not implemented");
        !           568:                return;
        !           569:        }
        !           570: 
        !           571:        len = strlen(topic);
        !           572:        makelower(topic);
        !           573:        noinfo = TRUE;
        !           574: 
        !           575:        while (fgets(buf, sizeof buf, hf) != NULL)
        !           576:        {
        !           577:                if (strncmp(buf, topic, len) == 0)
        !           578:                {
        !           579:                        register char *p;
        !           580: 
        !           581:                        p = index(buf, '\t');
        !           582:                        if (p == NULL)
        !           583:                                p = buf;
        !           584:                        else
        !           585:                                p++;
        !           586:                        fixcrlf(p, TRUE);
        !           587:                        message("214-", p);
        !           588:                        noinfo = FALSE;
        !           589:                }
        !           590:        }
        !           591: 
        !           592:        if (noinfo)
        !           593:                message("504", "HELP topic unknown");
        !           594:        else
        !           595:                message("214", "End of HELP info");
        !           596:        (void) fclose(hf);
        !           597: }
        !           598: /*
        !           599: **  ISWIZ -- tell us if we are a wizard
        !           600: **
        !           601: **     If not, print a nasty message.
        !           602: **
        !           603: **     Parameters:
        !           604: **             none.
        !           605: **
        !           606: **     Returns:
        !           607: **             TRUE if we are a wizard.
        !           608: **             FALSE if we are not a wizard.
        !           609: **
        !           610: **     Side Effects:
        !           611: **             Prints a 500 exit stat if we are not a wizard.
        !           612: */
        !           613: 
        !           614: #ifdef WIZ
        !           615: 
        !           616: bool
        !           617: iswiz()
        !           618: {
        !           619:        if (!IsWiz)
        !           620:                message("500", "Mere mortals musn't mutter that mantra");
        !           621:        return (IsWiz);
        !           622: }
        !           623: 
        !           624: #endif WIZ
        !           625: /*
        !           626: **  RUNINCHILD -- return twice -- once in the child, then in the parent again
        !           627: **
        !           628: **     Parameters:
        !           629: **             label -- a string used in error messages
        !           630: **
        !           631: **     Returns:
        !           632: **             zero in the child
        !           633: **             one in the parent
        !           634: **
        !           635: **     Side Effects:
        !           636: **             none.
        !           637: */
        !           638: 
        !           639: runinchild(label)
        !           640:        char *label;
        !           641: {
        !           642:        int childpid;
        !           643: 
        !           644:        if (!OneXact)
        !           645:        {
        !           646:                childpid = dofork();
        !           647:                if (childpid < 0)
        !           648:                {
        !           649:                        syserr("%s: cannot fork", label);
        !           650:                        return (1);
        !           651:                }
        !           652:                if (childpid > 0)
        !           653:                {
        !           654:                        auto int st;
        !           655: 
        !           656:                        /* parent -- wait for child to complete */
        !           657:                        st = waitfor(childpid);
        !           658:                        if (st == -1)
        !           659:                                syserr("%s: lost child", label);
        !           660: 
        !           661:                        /* if we exited on a QUIT command, complete the process */
        !           662:                        if (st == (EX_QUIT << 8))
        !           663:                                finis();
        !           664: 
        !           665:                        return (1);
        !           666:                }
        !           667:                else
        !           668:                {
        !           669:                        /* child */
        !           670:                        InChild = TRUE;
        !           671:                        QuickAbort = FALSE;
        !           672:                        clearenvelope(CurEnv, FALSE);
        !           673:                }
        !           674:        }
        !           675: 
        !           676:        /* open alias database */
        !           677:        initaliases(AliasFile, FALSE);
        !           678: 
        !           679:        return (0);
        !           680: }
        !           681: 
        !           682: # endif SMTP

unix.superglobalmegacorp.com

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