Annotation of researchv10no/cmd/nupas/smtp/conversed.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char *sccsid = "@(#)converse.c  1.9 87/07/31";
        !             3: #endif lint
        !             4: /*  Copyright 1984 Massachusetts Institute of Technology
        !             5: 
        !             6: Permission to use, copy, modify, and distribute this program
        !             7: for any purpose and without fee is hereby granted, provided
        !             8: that this copyright and permission notice appear on all copies
        !             9: and supporting documentation, the name of M.I.T. not be used
        !            10: in advertising or publicity pertaining to distribution of the
        !            11: program without specific prior permission, and notice be given
        !            12: in supporting documentation that copying and distribution is
        !            13: by permission of M.I.T.  M.I.T. makes no representations about
        !            14: the suitability of this software for any purpose.  It is pro-
        !            15: vided "as is" without express or implied warranty.             */
        !            16: 
        !            17: /*
        !            18:  *  I've raped this code severely.  Bugs could be
        !            19:  *  MIT's or mine. -- presotto
        !            20:  *
        !            21:  *  Me too.  -- ches
        !            22:  */
        !            23: 
        !            24: /*
        !            25:  * smtpd - World's most trivial SMTP server.  Only accepts the MAIL, FROM,
        !            26:  * RCPT, and DATA commands.  Generates a data file for the mail
        !            27:  * daemon and kicks the mail daemon off.
        !            28:  */
        !            29: 
        !            30: #include <stdio.h>
        !            31: #include <signal.h>
        !            32: #include <ctype.h>
        !            33: 
        !            34: #include <fcntl.h>
        !            35: #include <string.h>
        !            36: #include <sysexits.h>
        !            37: 
        !            38: #include "mail.h"
        !            39: #include "smtp.h"
        !            40: #include "cmds.h"
        !            41: #include "string.h"
        !            42: 
        !            43: /* fundamental constants */
        !            44: #define TRUE 1
        !            45: #define FALSE 0
        !            46: #define SECONDS                1
        !            47: #define MINUTES                60
        !            48: #define HOURS          (60 * MINUTES)
        !            49: 
        !            50: /* tunable constants */
        !            51: #define        SHORTTIME       (5 * MINUTES)   /* enough time for easy stuff */
        !            52: #define        LONGTIME        (2 * HOURS)     /* max time, DATA to `.' */
        !            53: 
        !            54: 
        !            55: static string *rcvrs;
        !            56: 
        !            57: FILE   *datafd;                        /* data file descriptor */
        !            58: FILE   *fi;                            /* fd from remote host */
        !            59: FILE   *fo;                            /* fd to remote host */
        !            60: 
        !            61: char   dataname[NAMSIZ], rcptto[BUFSIZ];               /* data file name */
        !            62: 
        !            63: typedef int event;
        !            64: 
        !            65: static void terminate();
        !            66: 
        !            67: extern char *convertaddr();
        !            68: extern char *UPASROOT;
        !            69: extern int death();
        !            70: extern int alarmsend();
        !            71: extern char *helohost;
        !            72: extern char *thishost;
        !            73: extern int queuing;
        !            74: extern int norun;
        !            75: extern char *spoolsubdir[];
        !            76: 
        !            77: int    n_rcpt = 0;
        !            78: long   nbytes = 0;
        !            79: int    virus = 0;
        !            80: 
        !            81: static char mailfrom[BUFSIZ];
        !            82: static char *fromaddr;
        !            83: 
        !            84: 
        !            85: #ifndef NOFILE
        !            86: #define NOFILE 32
        !            87: #endif /*NOFILE*/
        !            88: 
        !            89: SIGRETURN
        !            90: alarmtr(s)
        !            91:        int s;
        !            92: {
        !            93:        Syslog(LOG_INFO, "timed out");
        !            94:        death(EX_TEMPFAIL);
        !            95: }
        !            96: 
        !            97: /*
        !            98:  * This is the routine which processes incoming smtp commands from the
        !            99:  * user.  It goes to sleep awaiting network input.  When a complete
        !           100:  * command is received, the tcp receiver task awakens us to process it.
        !           101:  * Currently only the commands listed in the command table are accepted.
        !           102:  * This routine never returns.
        !           103:  */
        !           104: converse(rfi, rfo)
        !           105:        FILE *rfi, *rfo;
        !           106: {
        !           107:        char greeting[MAXSTR];
        !           108: 
        !           109:        fo = rfo;
        !           110:        fi = rfi;
        !           111: 
        !           112:        (void) signal(SIGALRM, alarmtr);
        !           113:        (void) alarm(SHORTTIME);        /* make sure we eventually go away */
        !           114:        (void) sprintf(greeting, "220 %s SMTP\n", helohost);
        !           115:        csend(LOG_DEBUG, greeting);
        !           116: 
        !           117:        do_helo(fi, fo);                /* wait for the hello */
        !           118: 
        !           119:        /*
        !           120:         *  avoid annoying interuptions
        !           121:         */
        !           122:        signal(SIGHUP, SIG_IGN);
        !           123:        signal(SIGPIPE, SIG_IGN);
        !           124: 
        !           125:        for (;;) {                      /* until QUIT */
        !           126:                n_rcpt = 0;
        !           127:                rcvrs = s_reset(rcvrs);
        !           128:                *dataname = *rcptto = 0;
        !           129:                fromaddr = 0;
        !           130:                if (!do_mail(fi, fo))
        !           131:                        continue;       /* wait for the mail command */
        !           132:                while (do_rcpt(fi, fo)) /* do all the recipients */
        !           133:                        n_rcpt++;
        !           134:                (void) alarm(LONGTIME);
        !           135:                do_data(fi, fo);        /* do the data */
        !           136:        }
        !           137: }
        !           138: 
        !           139: /*
        !           140:  *  Wait for the user to send the HELO command.  Punt out if he sends
        !           141:  *  QUIT or RSET.
        !           142:  *
        !           143:  *  The spooling directory depends on the calling host.  The host name
        !           144:  *  is used to connect to the appropriate spool directory.
        !           145:  */
        !           146: do_helo(fi, fo)
        !           147: FILE *fi, *fo;
        !           148: {
        !           149:        char    cmdbuf[MAXSTR];
        !           150:        char    greeting[MAXSTR], *nlptr;
        !           151:        int     buflen;
        !           152:        char    *hp;
        !           153:        char    *parse_hello();
        !           154: 
        !           155:        for (;;) {              /* until HELO, or QUIT */
        !           156:                buflen = crecv(cmdbuf, sizeof cmdbuf, fi);      /* wait for command */
        !           157:                switch (cmdparse(cmdbuf, buflen)) {
        !           158:                case QUIT:
        !           159:                        quit(fi, fo);
        !           160:                case RSET:
        !           161:                case NOOP:
        !           162:                        csend(LOG_DEBUG, "250 OK\n");
        !           163:                        continue;
        !           164:                case HELO:
        !           165:                        hp = parse_hello(cmdbuf, sizeof(cmdbuf));
        !           166:                        Syslog(LOG_DEBUG, "HELO from %s", hp);
        !           167:                        if(gotodir(hp)<0){      
        !           168:                                csend(LOG_ALERT, "451 Transaction failed -- Could not access spool directory.\n");
        !           169:                                death(EX_OSERR);
        !           170:                        }
        !           171:                        (void) sprintf(greeting, "250 %s\n", helohost);
        !           172:                        csend(LOG_DEBUG, greeting);
        !           173:                        return;
        !           174:                case DEBG:
        !           175:                        Syslog(LOG_ALERT, "DEBUG attempt");
        !           176:                        csend(LOG_DEBUG, "200 OK\n");
        !           177:                        virus = 1;
        !           178:                        continue;
        !           179:                case NONE:
        !           180:                        bitch(cmdbuf, fo);
        !           181:                        continue;
        !           182:                default:
        !           183:                        csend(LOG_DEBUG, "503 Expecting HELO\n");
        !           184:                        continue;
        !           185:                }
        !           186:        }
        !           187: }
        !           188: 
        !           189: /*
        !           190:  * Wait for the user to send the MAIL command.  Punt out if he sends
        !           191:  * QUIT.  Return false if he said RSET, so we can start over.
        !           192:  */
        !           193: do_mail(fi, fo)
        !           194: FILE *fi, *fo;
        !           195: {
        !           196:        char    cmdbuf[MAXSTR];
        !           197:        char    gripe[MAXSTR], *nlptr;
        !           198:        int     buflen;
        !           199: 
        !           200:        for (;;) {              /* until MAIL, QUIT, or RSET */
        !           201:                buflen = crecv(cmdbuf, sizeof cmdbuf, fi);      /* wait for command */
        !           202:                switch (cmdparse(cmdbuf, buflen)) {
        !           203:                case QUIT:
        !           204:                        quit(fi, fo);
        !           205:                case NOOP:
        !           206:                        csend(LOG_DEBUG, "250 OK\n");
        !           207:                        continue;
        !           208:                case MAIL:
        !           209:                        strcpy(mailfrom, cmdbuf);
        !           210:                        csend(LOG_DEBUG, "250 OK\n");
        !           211:                        return(TRUE);
        !           212:                case DEBG:
        !           213:                        Syslog(LOG_ALERT, "DEBUG attempt");
        !           214:                        csend(LOG_WARNING, "200 OK\n");
        !           215:                        virus = 1;
        !           216:                        continue;
        !           217:                case VRFY:
        !           218:                        csend(LOG_INFO, "252 Cannot VRFY user\n");
        !           219:                        continue;
        !           220:                case NONE:
        !           221:                        bitch(cmdbuf, fo);
        !           222:                        continue;
        !           223:                case RSET:
        !           224:                        csend(LOG_DEBUG, "250 OK\n");
        !           225:                        return(FALSE);
        !           226:                default:
        !           227:                        csend(LOG_DEBUG, "503 Expecting MAIL\n");
        !           228:                        continue;
        !           229:                }
        !           230:        }
        !           231: }
        !           232: 
        !           233: /*
        !           234:  * Wait for the user to send the RCPT command.  Punt out if he sends
        !           235:  * QUIT or RSET.  Returns TRUE if a RCPT command was received, FALSE
        !           236:  * if a DATA command was received.
        !           237:  */
        !           238: do_rcpt(fi, fo)
        !           239: FILE *fi, *fo;
        !           240: {
        !           241:        char    cmdbuf[MAXSTR];
        !           242:        char    gripe[MAXSTR], *nlptr;
        !           243:        int     buflen;
        !           244:        int     i;
        !           245: 
        !           246:        for (;;) {              /* until RCPT, DATA, QUIT, or RSET */
        !           247:                buflen = crecv(cmdbuf, sizeof cmdbuf, fi);      /* wait for command */
        !           248:                switch (cmdparse(cmdbuf, buflen)) {
        !           249:                case QUIT:
        !           250:                        quit(fi, fo);
        !           251:                case NOOP:
        !           252:                        csend(LOG_DEBUG, "250 OK\n");
        !           253:                        continue;
        !           254:                case RCPT:
        !           255:                        if (!parse_rcpt(cmdbuf, buflen)) {
        !           256:                                csend(LOG_DEBUG, "501 Syntax error in recipient name\n");
        !           257:                                continue;
        !           258:                        }
        !           259:                        csend(LOG_DEBUG, "250 OK\n");
        !           260:                        return(TRUE);
        !           261:                case DATA:
        !           262:                        if (*s_to_c(rcvrs) == 0) {
        !           263:                                csend(LOG_DEBUG, "503 Expecting RCPT\n");
        !           264:                                continue;
        !           265:                        }
        !           266:                        if ((i=init_xfr()) < 0) {       /* set up data file */
        !           267:                                char buf[100];
        !           268:                                sprintf(buf, "451 Can't initialize files in spool directory  %s(%d)\n",
        !           269:                                        dataname, i);
        !           270:                                csend(LOG_ALERT, buf);
        !           271:                                death(EX_CANTCREAT);
        !           272:                        }
        !           273:                        csend(LOG_DEBUG, "354 Start mail input; end with <CRLF>.<CRLF>\n");
        !           274:                        return(FALSE);
        !           275:                case VRFY:
        !           276:                        csend(LOG_INFO, "252 Cannot VRFY user\n");
        !           277:                        continue;
        !           278:                case DEBG:
        !           279:                        Syslog(LOG_ALERT, "DEBUG attempt");
        !           280:                        csend(LOG_WARNING, "200 OK\n");
        !           281:                        virus = 1;
        !           282:                        continue;
        !           283:                case RSET:  /* this code doesn't handle this here.  Feign ignorance. */
        !           284:                case NONE:
        !           285:                        bitch(cmdbuf, fo);
        !           286:                        continue;
        !           287:                default:
        !           288:                        csend(LOG_DEBUG, "503 Expecting RCPT or DATA\n");
        !           289:                        continue;
        !           290:                }
        !           291:        }
        !           292: }
        !           293: 
        !           294: /*
        !           295:  *  input a line at a time till a <cr>.<cr>.  return the count of the characters
        !           296:  *  input.  if EOF is reached, return -1.  if <cr>.<cr> is reached, return 0.
        !           297:  */
        !           298: static int atend;              /* true when <cr>.<cr> is reached */
        !           299: 
        !           300: char *
        !           301: smfgets(buf, len, fi)
        !           302:        char *buf;
        !           303:        int len;
        !           304:        FILE *fi;
        !           305: {
        !           306:        int n;
        !           307:        int i;
        !           308: 
        !           309:        if(atend)
        !           310:                return NULL;
        !           311:        n = tgets(buf, len, fi);
        !           312:        if (n < 0)
        !           313:                return NULL;
        !           314:        if (buf[0] == '.') {
        !           315:                if(buf[1] == '\n'){
        !           316:                        atend = 1;
        !           317:                        return NULL;
        !           318:                } else if(buf[1] == '.'){
        !           319:                        for(i=1; i<=n; i++)
        !           320:                                buf[i-1] = buf[i];
        !           321:                }
        !           322:        }
        !           323:        nbytes += n;
        !           324:        return buf;
        !           325: }
        !           326: 
        !           327: do_data(fi, fo)
        !           328: FILE *fi, *fo;
        !           329: {
        !           330:        string *cc;
        !           331:        int pid, wpid;
        !           332:        char gripe[MAXSTR];
        !           333:        char cmd[MAXSTR];
        !           334:        char ctlfile[MAXSTR];
        !           335:        int ac, i;
        !           336:        char *cp;
        !           337: 
        !           338:        clearerr(fi);
        !           339:        clearerr(datafd);
        !           340: 
        !           341:        /*
        !           342:         *  read data message
        !           343:         */
        !           344:        atend = nbytes = 0;
        !           345:        from822(thishost, smfgets, fi, datafd, fromaddr, helohost);
        !           346:        fflush(datafd);
        !           347:        if(ferror(datafd) || ferror(fi)){
        !           348:                fclose(datafd);
        !           349:                unlink(dataname);
        !           350:                csend(LOG_ALERT, "451 Transaction failed -- error writing data file\n");
        !           351:                death(EX_IOERR);
        !           352:        }
        !           353:        fclose(datafd);
        !           354: 
        !           355:        /*
        !           356:         *  create a control file.  the two lines are
        !           357:         *      <reply-address> <recipients>
        !           358:         *      <recipients>
        !           359:         */
        !           360:        cc = s_new();
        !           361:        if (fromaddr == (char *)0 || *fromaddr == '\0')
        !           362:                fromaddr = "postmaster";
        !           363:        s_append(cc, fromaddr);
        !           364:        s_append(cc, " ");
        !           365:        s_append(cc, s_to_c(rcvrs));
        !           366:        s_append(cc, "\n");
        !           367:        s_append(cc, s_to_c(rcvrs));
        !           368:        s_append(cc, "\n");
        !           369:        if(mkctlfile('X', dataname, s_to_c(cc))<0){
        !           370:                unlink(dataname);
        !           371:                csend(LOG_ALERT, "451 Transaction failed -- can't make control file\n");
        !           372:                death(EX_CANTCREAT);
        !           373:        }
        !           374:        s_free(cc);
        !           375:        csend(LOG_DEBUG, "250 OK\n");
        !           376:        Syslog(LOG_INFO, "%s  sent %d bytes to  %s\n",
        !           377:                fromaddr ? fromaddr : "postmaster", nbytes,
        !           378:                s_to_c(rcvrs));
        !           379:        
        !           380: 
        !           381:        /*
        !           382:         *  reinitialize all the data pointers
        !           383:         */
        !           384:        rcvrs = s_reset(rcvrs);
        !           385:        nbytes = 0;
        !           386:        *dataname = *rcptto = 0;
        !           387:        fromaddr = 0;
        !           388: 
        !           389: }
        !           390: 
        !           391: /*
        !           392:  * Create the data file for the transfer.  Get unique
        !           393:  * names and create the files.
        !           394:  */
        !           395: init_xfr()
        !           396: {
        !           397:        int     dfd;                    /* file desc. for data file */
        !           398:        char    *cp;
        !           399: 
        !           400:        strcpy(dataname, "D.xxxxxxxxxxxx");
        !           401:        if((dfd = mkdatafile(dataname)) < 0)
        !           402:                return -1;
        !           403:        datafd = fdopen(dfd, "w");      /* make stdio descriptor */
        !           404:        if (datafd == NULL)
        !           405:                return -2;
        !           406: 
        !           407:        /*
        !           408:         *  find the sender name if any
        !           409:         */
        !           410:        if(*mailfrom){
        !           411: 
        !           412:                /* skip noise */
        !           413:                for(cp=mailfrom+sizeof("MAIL FROM:")-1; *cp; cp++)
        !           414:                        if(strchr(";<>{}()\n| \t", *cp)==NULL)
        !           415:                                break;
        !           416:                fromaddr = cp;
        !           417: 
        !           418:                /* find address */
        !           419:                for(; *cp; cp++)
        !           420:                        if(strchr(";<>{}()\n| \t", *cp)!=NULL){
        !           421:                                *cp = '\0';
        !           422:                                break;
        !           423:                        }
        !           424:        }
        !           425:        if(fromaddr)
        !           426:                fromaddr = convertaddr(fromaddr);
        !           427:        
        !           428:        return 1;
        !           429: }
        !           430: 
        !           431: /*
        !           432:  * Give up on the transfer.  Unlink the data file (if any),
        !           433:  * close the tcp connection, and exit.
        !           434:  */
        !           435: quit(fi, fo)
        !           436: FILE *fi, *fo;
        !           437: {
        !           438:        int i;
        !           439:        char greeting[MAXSTR];
        !           440: 
        !           441:        (void) sprintf(greeting, "221 %s Terminating\n", helohost);
        !           442:        csend(LOG_DEBUG, greeting);
        !           443:        (void) fclose(fi);
        !           444:        (void) fclose(fo);
        !           445:        Syslog(LOG_DEBUG, "finished.\n");
        !           446: 
        !           447:        /*
        !           448:         *  run the queue from this caller
        !           449:         */
        !           450:        for(i=0; i<NOFILE; i++)
        !           451:                close(i);
        !           452:        open("/dev/null", 0);
        !           453:        open("/dev/null", 1);
        !           454:        open("/dev/null", 1);
        !           455:        if(!norun)
        !           456:                smtpsched("Dsmtpsched", spoolsubdir);
        !           457: 
        !           458:        exit(0);
        !           459: }
        !           460: 
        !           461: /*
        !           462:  * Parse the command part off the specified buffer.  Return the strchr
        !           463:  * of the command in the command table(or 0 if the command is not
        !           464:  * recognized).
        !           465:  * The commands and indices accepted are listed in the include file
        !           466:  * "cmds.h".
        !           467:  * If the len parameter is -1 (as returned by tgets), issue the QUIT command.
        !           468:  * This non-protocol extension was added to cool the jets of sail.stanford.edu.
        !           469:  */
        !           470: cmdparse(buf, len)
        !           471: char *buf;
        !           472: int len;
        !           473: {
        !           474:        register char *cmdp, *bufp;     /* command, buffer ptrs. */
        !           475:        register struct cmdtab  *ct;    /* cmd table ptr */
        !           476:        register int i;                 /* strchr in cmd table */
        !           477:        int     clen;                   /* length of this command */
        !           478:        
        !           479:        if (len == -1) {                /* EOF */
        !           480:                buf = "QUIT";
        !           481:                len = strlen(buf);
        !           482:        }
        !           483:        for (ct = &cmdtab[1], i = 1; ct->c_name != NULL; ct++, i++) {
        !           484:                clen = ct->c_len;
        !           485:                if (len < clen)         /* buffer shorter than command? */
        !           486:                        continue;
        !           487:                /* case-insensitive matching of command names */
        !           488:                for (cmdp = ct->c_name, bufp = buf;
        !           489:                     clen > 0 && *cmdp == (ISLOWER(*bufp) ? TOUPPER(*bufp) : *bufp);
        !           490:                     cmdp++, bufp++, clen--)
        !           491:                        ;
        !           492:                if (clen == 0) {                /* success */
        !           493:                        /* sendmail compatibility */
        !           494:                        if (i == ONEX || i == VERB)
        !           495:                                i = NOOP;
        !           496:                        return i;
        !           497:                }
        !           498:        }
        !           499:        return 0;
        !           500: }
        !           501: 
        !           502: /*
        !           503:  *  Parse a hello and return a pointer to name of the last two elements
        !           504:  *  of the calling machine's domain name (or last 14 chars).
        !           505:  */
        !           506: char *
        !           507: parse_hello(buf, len)
        !           508:        char *buf;
        !           509:        int len;
        !           510: {
        !           511:        char *bp = buf;
        !           512:        char *lp;
        !           513:        int dots;
        !           514: 
        !           515:        /* skip command */
        !           516:        bp[len-1] = 0;
        !           517:        for(; *bp && !isspace(*bp); bp++)
        !           518:                ;
        !           519:        /* skip white */
        !           520:        for(; isspace(*bp); bp++)
        !           521:                ;
        !           522:        /* skip arg */
        !           523:        lp = bp;
        !           524:        for(; *bp && !isspace(*bp); bp++)
        !           525:                ;
        !           526:        /* null terminate */
        !           527:        *bp = 0;
        !           528: 
        !           529:        return lp;
        !           530: }
        !           531: 
        !           532: static char    *to;                    /* ptr. into request buffer */
        !           533: 
        !           534: /*
        !           535:  * Parse the recipient spec in the buffer.  Start by stripping the
        !           536:  * command off the front of the buffer.  Then call canon() to convert
        !           537:  * the recpient name into a format acceptable to the mailer daemon
        !           538:  * (ie. !-format).
        !           539:  * Returns TRUE if parsed successfully, FALSE otherwise.
        !           540:  */
        !           541: /* ARGSUSED len */
        !           542: parse_rcpt(buf, len)
        !           543: char *buf;                             /* command buffer */
        !           544: int len;                               /* size of buffer string */
        !           545: {
        !           546:        register char *from;            /* ptr to recipient name */
        !           547:        char *end;
        !           548:        char *rv;
        !           549:        char *sysname_read();
        !           550:        char *thissys;
        !           551:        
        !           552:        from = &buf[cmdtab[RCPT].c_len];
        !           553:        while (*from == ' ' || *from == '\t')
        !           554:                from++;
        !           555:        if (*from == '<') {
        !           556:                end = strchr(from++, '>');
        !           557:                if (end == 0) {
        !           558:                        return FALSE;
        !           559:                }
        !           560:                *end = 0;
        !           561:        }
        !           562: 
        !           563:        /*
        !           564:         *  convert to lower case (this is wrong but rfc822 is case
        !           565:         *  insensitive)
        !           566:         */
        !           567:        for(rv = from; *rv; rv++)
        !           568:                if(isupper(*rv))
        !           569:                        *rv = tolower(*rv);
        !           570: 
        !           571:        /*
        !           572:         * convert address to bang format.  Assume the first site
        !           573:         * in the list is us and take it out.
        !           574:         */
        !           575:        rv=convertaddr(from);
        !           576:        if(end=strchr(rv, '!')){
        !           577:                thissys = sysname_read();
        !           578:                *end = '\0';
        !           579:                if(strcmp(rv, thissys)==0)
        !           580:                        rv = end+1;
        !           581:                else
        !           582:                        *end = '!';
        !           583:        }
        !           584: 
        !           585:        /*
        !           586:         *  check for address syntax
        !           587:         */
        !           588:        if(shellchars(rv)){
        !           589:                Syslog(LOG_ALERT, "shell characters in address: %s", rv);
        !           590:                if(virus)
        !           591:                        rv = "upas.security";
        !           592:                else
        !           593:                        return FALSE;
        !           594:        }
        !           595: 
        !           596:        /*
        !           597:         *  add to list of recipients
        !           598:         */
        !           599:        if(*s_to_c(rcvrs))
        !           600:                s_append(rcvrs, " ");
        !           601:        s_append(rcvrs, rv);
        !           602:        return TRUE;
        !           603: }
        !           604: 
        !           605: 
        !           606: /* Time to live elapsed or io error. */
        !           607: death(weapon)
        !           608: {
        !           609:        (void) unlink(dataname);
        !           610:        exit(1);
        !           611: }
        !           612: 
        !           613: alarmsend()
        !           614: {
        !           615:        csend(LOG_WARNING, "451 Our mailer appears to be hung.\n");
        !           616:        death(EX_TEMPFAIL);
        !           617: }
        !           618: 
        !           619: funnychars(str)
        !           620: register char *str;
        !           621: {
        !           622:        for (;;)
        !           623:                switch(*str++) {
        !           624:                case '^':
        !           625:                case '&':
        !           626:                case '>':
        !           627:                case '<':
        !           628:                case '`':
        !           629:                case '|':
        !           630:                case ';':
        !           631:                case '\'':
        !           632:                        return TRUE;
        !           633: 
        !           634:                case 0:
        !           635:                        return FALSE;
        !           636:                }
        !           637: }
        !           638: 
        !           639: bitch(buf, fo)
        !           640: char *buf;
        !           641: FILE *fo;
        !           642: {
        !           643:        char gripe[BUFSIZ], *nlptr;
        !           644: 
        !           645:        if ((nlptr = strchr(buf, '\n')) != 0)
        !           646:                *nlptr = 0;
        !           647:        (void) sprintf(gripe, "502 %s ... Not recognized\n", buf);
        !           648:        csend(LOG_DEBUG, gripe);
        !           649: }
        !           650: 
        !           651: bomb(err)
        !           652: int err;
        !           653: {
        !           654:        death(err);
        !           655: }
        !           656: 
        !           657: csend(loglevel, message)
        !           658: int loglevel;
        !           659: char *message;
        !           660: {
        !           661:        Syslog(loglevel, "<--- %s", message);
        !           662:        (void) tputs(message, fo);
        !           663: }
        !           664: 
        !           665: int
        !           666: crecv(buf, len, fd)
        !           667: char *buf;
        !           668: int len, fd;
        !           669: {
        !           670:        int n = tgets(buf, len, fi);
        !           671:        Syslog(LOG_DEBUG, "-------> %s", buf);
        !           672:        return n;
        !           673: }

unix.superglobalmegacorp.com

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