Annotation of 43BSD/contrib/mh/mts/sendmail/smail.c, revision 1.1.1.1

1.1       root        1: /* smail.c - MH interface to SendMail/SMTP */
                      2: 
                      3: /* LINTLIBRARY */
                      4: 
                      5: /* This module implements an interface to SendMail very similar to the
                      6:    MMDF mm_(3) routines.  The sm_() routines herein talk SMTP to a
                      7:    sendmail process, mapping SMTP reply codes into RP_-style codes.
                      8:  */
                      9: 
                     10: #ifdef BSD42
                     11: /* Under 4.2BSD, the alarm handing stuff for time-outs will NOT work due to
                     12:    the way syscalls get restarted.  This really is not crucial, since we
                     13:    expect SendMail to be well-behaved and not hang on us.  The only time
                     14:    I've ever seen Sendmail hang was with a bogus configuration file...
                     15:  */
                     16: #endif BSD42
                     17: 
                     18: #ifndef        BSD42
                     19: #undef SMTP
                     20: #endif not BSD42
                     21: #ifdef SMTP
                     22: #undef SENDMAIL
                     23: #endif SMTP
                     24: 
                     25: 
                     26: #include "../h/strings.h"
                     27: #include <stdio.h>
                     28: #include "smail.h"
                     29: #include "../zotnet/mts.h"
                     30: #include <ctype.h>
                     31: #include <signal.h>
                     32: 
                     33: #define        NOTOK   (-1)
                     34: #define        OK      0
                     35: #define        DONE    1
                     36: 
                     37: #define        TRUE    1
                     38: #define        FALSE   0
                     39: 
                     40: #define        NBITS   ((sizeof (int)) * 8)
                     41: 
                     42: #define        min(a,b)        ((a) < (b) ? (a) : (b))
                     43: 
                     44: 
                     45: #define        SM_OPEN  30
                     46: #define        SM_HELO  20
                     47: #define        SM_RSET  15
                     48: #define        SM_MAIL  40
                     49: #define        SM_RCPT 120
                     50: #define        SM_DATA  20
                     51: #define        SM_TEXT 120
                     52: #define        SM_DOT  120
                     53: #define        SM_QUIT  20
                     54: #define        SM_CLOS  10
                     55: 
                     56: /*  */
                     57: 
                     58: int    alrmser ();
                     59: 
                     60: static int  sm_addrs = 0;
                     61: static int  sm_alarmed = 0;
                     62: #ifndef        SMTP
                     63: static int  sm_child = NOTOK;
                     64: #endif not SMTP
                     65: static int  sm_debug = 0;
                     66: static int  sm_nl = TRUE;
                     67: static int  sm_verbose = 0;
                     68: 
                     69: static  FILE * sm_rfp = NULL;
                     70: static  FILE * sm_wfp = NULL;
                     71: 
                     72: static char *sm_noreply = "No reply text given";
                     73: static char *sm_moreply = "; ";
                     74: 
                     75: struct smtp sm_reply;          /* global... */
                     76: 
                     77: 
                     78: char   *r1bindex ();
                     79: 
                     80: /*  */
                     81: 
                     82: #ifndef        SMTP
                     83: 
                     84: /* ARGSUSED */
                     85: 
                     86: int     sm_init (client, server, watch, verbose, debug)
                     87: register char   *client;
                     88: char   *server;
                     89: register int     watch,
                     90:                 verbose,
                     91:                 debug;
                     92: {
                     93:     register int    i,
                     94:                     result,
                     95:                     vecp;
                     96:     int     pdi[2],
                     97:             pdo[2];
                     98:     char   *vec[15];
                     99: 
                    100:     if (watch)
                    101:        verbose = TRUE;
                    102:     sm_verbose = verbose;
                    103:     sm_debug = debug;
                    104:     if (sm_rfp != NULL && sm_wfp != NULL)
                    105:        return RP_OK;
                    106: 
                    107:     if (pipe (pdi) == NOTOK)
                    108:        return sm_ierror ("no pipes");
                    109:     if (pipe (pdo) == NOTOK) {
                    110:        (void) close (pdi[0]);
                    111:        (void) close (pdi[1]);
                    112:        return sm_ierror ("no pipes");
                    113:     }
                    114: 
                    115:     for (i = 0; (sm_child = fork ()) == NOTOK && i < 5; i++)
                    116:        sleep (5);
                    117:     switch (sm_child) {
                    118:        case NOTOK: 
                    119:            (void) close (pdo[0]);
                    120:            (void) close (pdo[1]);
                    121:            (void) close (pdi[0]);
                    122:            (void) close (pdi[1]);
                    123:            return sm_ierror ("unable to fork");
                    124: 
                    125:        case OK: 
                    126:            if (pdo[0] != fileno (stdin))
                    127:                (void) dup2 (pdo[0], fileno (stdin));
                    128:            if (pdi[1] != fileno (stdout))
                    129:                (void) dup2 (pdi[1], fileno (stdout));
                    130:            if (pdi[1] != fileno (stderr))
                    131:                (void) dup2 (pdi[1], fileno (stderr));
                    132:            for (i = fileno (stderr) + 1; i < NBITS; i++)
                    133:                (void) close (i);
                    134: 
                    135:            vecp = 0;
                    136:            vec[vecp++] = r1bindex (sendmail, '/');
                    137:            vec[vecp++] = "-bs";
                    138:            vec[vecp++] = watch ? "-odi" : "-odb";
                    139:            vec[vecp++] = "-oem";
                    140:            vec[vecp++] = "-om";
                    141: #ifndef        RAND
                    142:            if (verbose)
                    143:                vec[vecp++] = "-ov";
                    144: #endif not RAND
                    145:            vec[vecp++] = NULL;
                    146: 
                    147:            (void) setgid (getegid ());
                    148:            (void) setuid (geteuid ());
                    149:            execvp (sendmail, vec);
                    150:            fprintf (stderr, "unable to exec ");
                    151:            perror (sendmail);
                    152:            _exit (-1);         /* NOTREACHED */
                    153: 
                    154:        default: 
                    155:            (void) signal (SIGALRM, alrmser);
                    156:            (void) signal (SIGPIPE, SIG_IGN);
                    157: 
                    158:            (void) close (pdi[1]);
                    159:            (void) close (pdo[0]);
                    160:            if ((sm_rfp = fdopen (pdi[0], "r")) == NULL
                    161:                    || (sm_wfp = fdopen (pdo[1], "w")) == NULL) {
                    162:                (void) close (pdi[0]);
                    163:                (void) close (pdo[1]);
                    164:                sm_rfp = sm_wfp = NULL;
                    165:                return sm_ierror ("unable to fdopen");
                    166:            }
                    167:            sm_alarmed = 0;
                    168:            (void) alarm (SM_OPEN);
                    169:            result = smhear ();
                    170:            (void) alarm (0);
                    171:            switch (result) {
                    172:                case 220: 
                    173:                    break;
                    174: 
                    175:                default: 
                    176:                    (void) sm_end (NOTOK);
                    177:                    return RP_RPLY;
                    178:            }
                    179:            if (client)
                    180:                switch (smtalk (SM_HELO, "HELO %s", client)) {
                    181:                    case 250: 
                    182:                        break;
                    183: 
                    184:                    default: 
                    185:                        (void) sm_end (NOTOK);
                    186:                        return RP_RPLY;
                    187:                }
                    188:            return RP_OK;
                    189:     }
                    190: }
                    191: #else  SMTP
                    192: 
                    193: /*  */
                    194: 
                    195: int     sm_init (client, server, watch, verbose, debug)
                    196: register char   *client,
                    197:                *server;
                    198: register int     watch,
                    199:                 verbose,
                    200:                 debug;
                    201: {
                    202:     register int    result,
                    203:                     sd1,
                    204:                     sd2;
                    205: 
                    206:     if (watch)
                    207:        verbose = TRUE;
                    208:     sm_verbose = verbose;
                    209:     sm_debug = debug;
                    210:     if (sm_rfp != NULL && sm_wfp != NULL)
                    211:        return RP_OK;
                    212: #ifndef        SENDMTS
                    213:     if (client == NULL || *client == NULL)
                    214:        client = LocalName ();
                    215: #endif not SENDMTS
                    216: 
                    217:     if ((sd1 = rclient (server, "tcp", "smtp")) == NOTOK)
                    218:        return RP_BHST;
                    219:     if ((sd2 = dup (sd1)) == NOTOK) {
                    220:        (void) close (sd1);
                    221:        return sm_ierror ("unable to dup");
                    222:     }
                    223: 
                    224:     (void) signal (SIGALRM, alrmser);
                    225:     (void) signal (SIGPIPE, SIG_IGN);
                    226: 
                    227:     if ((sm_rfp = fdopen (sd1, "r")) == NULL
                    228:            || (sm_wfp = fdopen (sd2, "w")) == NULL) {
                    229:        (void) close (sd1);
                    230:        (void) close (sd2);
                    231:        sm_rfp = sm_wfp = NULL;
                    232:        return sm_ierror ("unable to fdopen");
                    233:     }
                    234:     sm_alarmed = 0;
                    235:     (void) alarm (SM_OPEN);
                    236:     result = smhear ();
                    237:     (void) alarm (0);
                    238:     switch (result) {
                    239:        case 220: 
                    240:            break;
                    241: 
                    242:        default: 
                    243:            (void) sm_end (NOTOK);
                    244:            return RP_RPLY;
                    245:     }
                    246:     if (client && *client)
                    247:        switch (smtalk (SM_HELO, "HELO %s", client)) {
                    248:            case 250: 
                    249:                break;
                    250: 
                    251:            default: 
                    252:                (void) sm_end (NOTOK);
                    253:                return RP_RPLY;
                    254:        }
                    255: 
                    256:     return RP_OK;
                    257: }
                    258: 
                    259: 
                    260: static int rclient (server, protocol, service)
                    261: char   *server,
                    262:        *protocol,
                    263:        *service;
                    264: {
                    265:     int     sd;
                    266:     char    response[BUFSIZ];
                    267: 
                    268:     if ((sd = client (server, protocol, service, FALSE, response)) != NOTOK)
                    269:        return sd;
                    270: 
                    271:     (void) sm_ierror ("%s", response);
                    272:     return NOTOK;
                    273: }
                    274: #endif SMTP
                    275: 
                    276: /*  */
                    277: 
                    278: int     sm_winit (mode, from)
                    279: register int   mode;
                    280: register char   *from;
                    281: {
                    282:     switch (smtalk (SM_MAIL, "%s FROM:<%s>",
                    283:                mode == S_SEND ? "SEND" : mode == S_SOML ? "SOML"
                    284:                : mode == S_SAML ? "SAML" : "MAIL", from)) {
                    285:        case 250: 
                    286:            sm_addrs = 0;
                    287:            return RP_OK;
                    288: 
                    289:        case 500: 
                    290:        case 501: 
                    291:        case 552: 
                    292:            return RP_PARM;
                    293: 
                    294:        default: 
                    295:            return RP_RPLY;
                    296:     }
                    297: }
                    298: 
                    299: /*  */
                    300: 
                    301: #ifdef BERK
                    302: /* ARGUSED */
                    303: #endif BERK
                    304: 
                    305: int     sm_wadr (mbox, host, path)
                    306: register char   *mbox;
                    307: #ifndef        BERK
                    308: register
                    309: #endif not BERK
                    310:         char   *host,
                    311:                *path;
                    312: {
                    313: #ifndef        BERK
                    314:     switch (smtalk (SM_RCPT, host && *host ? "RCPT TO:<%s%s@%s>"
                    315:                                           : "RCPT TO:<%s%s>",
                    316:                             path ? path : "", mbox, host)) {
                    317: #else  BERK
                    318:     switch (smtalk (SM_RCPT, "RCPT TO:%s", mbox)) {
                    319: #endif BERK
                    320:        case 250: 
                    321:        case 251: 
                    322:            sm_addrs++;
                    323:            return RP_OK;
                    324: 
                    325:        case 421: 
                    326:        case 450: 
                    327:        case 451: 
                    328:        case 452: 
                    329:            return RP_NO;
                    330: 
                    331:        case 500: 
                    332:        case 501: 
                    333:            return RP_PARM;
                    334: 
                    335:        case 550: 
                    336:        case 551: 
                    337:        case 552: 
                    338:        case 553: 
                    339:            return RP_USER;
                    340: 
                    341:        default: 
                    342:            return RP_RPLY;
                    343:     }
                    344: }
                    345: 
                    346: /*  */
                    347: 
                    348: int     sm_waend () {
                    349:     switch (smtalk (SM_DATA, "DATA")) {
                    350:        case 354: 
                    351:            sm_nl = TRUE;
                    352:            return RP_OK;
                    353: 
                    354:        case 421: 
                    355:        case 451: 
                    356:            return RP_NO;
                    357: 
                    358:        case 500: 
                    359:        case 501: 
                    360:        case 503: 
                    361:        case 554: 
                    362:            return RP_NDEL;
                    363: 
                    364:        default: 
                    365:            return RP_RPLY;
                    366:     }
                    367: }
                    368: 
                    369: /*  */
                    370: 
                    371: int     sm_wtxt (buffer, len)
                    372: register char   *buffer;
                    373: register int     len;
                    374: {
                    375:     register int    result;
                    376: 
                    377:     sm_alarmed = 0;
                    378:     (void) alarm (SM_TEXT);
                    379:     result = sm_wstream (buffer, len);
                    380:     (void) alarm (0);
                    381: 
                    382:     return (result == NOTOK ? RP_BHST : RP_OK);
                    383: }
                    384: 
                    385: /*  */
                    386: 
                    387: int     sm_wtend () {
                    388:     if (sm_wstream ((char *) NULL, 0) == NOTOK)
                    389:        return RP_BHST;
                    390: 
                    391:     switch (smtalk (SM_DOT + 3 * sm_addrs, ".")) {
                    392:        case 250: 
                    393:        case 251: 
                    394:            return RP_OK;
                    395: 
                    396:        case 451: 
                    397:        case 452: 
                    398:        default: 
                    399:            return RP_NO;
                    400: 
                    401:        case 552: 
                    402:        case 554: 
                    403:            return RP_NDEL;
                    404:     }
                    405: }
                    406: 
                    407: /*  */
                    408: 
                    409: int     sm_end (type)
                    410: register int     type;
                    411: {
                    412:     register int    status;
                    413:     struct smtp sm_note;
                    414: 
                    415: #ifndef        SMTP
                    416:     switch (sm_child) {
                    417:        case NOTOK: 
                    418:        case OK: 
                    419:            return RP_OK;
                    420: 
                    421:        default: 
                    422:            break;
                    423:     }
                    424: #endif not SMTP
                    425:     if (sm_rfp == NULL && sm_wfp == NULL)
                    426:        return RP_OK;
                    427: 
                    428:     switch (type) {
                    429:        case OK: 
                    430:            (void) smtalk (SM_QUIT, "QUIT");
                    431:            break;
                    432: 
                    433:        case NOTOK: 
                    434:            sm_note.code = sm_reply.code;
                    435:            (void) strncpy (sm_note.text, sm_reply.text,
                    436:                    sm_note.length = sm_reply.length);/* fall */
                    437:        case DONE: 
                    438:            if (smtalk (SM_RSET, "RSET") == 250 && type == DONE)
                    439:                return RP_OK;
                    440: #ifndef        SMTP
                    441:            (void) kill (sm_child, SIGKILL);
                    442:            discard (sm_rfp);
                    443:            discard (sm_wfp);
                    444: #else  SMTP
                    445:            (void) smtalk (SM_QUIT, "QUIT");
                    446: #endif not SMTP
                    447:            if (type == NOTOK) {
                    448:                sm_reply.code = sm_note.code;
                    449:                (void) strncpy (sm_reply.text, sm_note.text,
                    450:                        sm_reply.length = sm_note.length);
                    451:            }
                    452:            break;
                    453:     }
                    454:     if (sm_rfp != NULL) {
                    455:        (void) alarm (SM_CLOS);
                    456:        (void) fclose (sm_rfp);
                    457:        (void) alarm (0);
                    458:     }
                    459:     if (sm_wfp != NULL) {
                    460:        (void) alarm (SM_CLOS);
                    461:        (void) fclose (sm_wfp);
                    462:        (void) alarm (0);
                    463:     }
                    464: 
                    465: #ifndef        SMTP
                    466:     status = pidwait (sm_child);
                    467: 
                    468:     sm_child = NOTOK;
                    469: #else  SMTP
                    470:     status = 0;
                    471: #endif SMTP
                    472:     sm_rfp = sm_wfp = NULL;
                    473: 
                    474:     return (status ? RP_BHST : RP_OK);
                    475: }
                    476: 
                    477: /*  */
                    478: 
                    479: /* VARARGS */
                    480: 
                    481: static int  sm_ierror (fmt, a, b, c, d)
                    482: char   *fmt,
                    483:        *a,
                    484:        *b,
                    485:        *c,
                    486:        *d;
                    487: {
                    488:     (void) sprintf (sm_reply.text, fmt, a, b, c, d);
                    489:     sm_reply.length = strlen (sm_reply.text);
                    490:     sm_reply.code = NOTOK;
                    491: 
                    492:     return RP_BHST;
                    493: }
                    494: 
                    495: /*  */
                    496: 
                    497: /* VARARGS2 */
                    498: 
                    499: static int  smtalk (time, fmt, a, b, c, d)
                    500: register int     time;
                    501: register char   *fmt;
                    502: {
                    503:     register int    result;
                    504:     char    buffer[BUFSIZ];
                    505: 
                    506:     (void) sprintf (buffer, fmt, a, b, c, d);
                    507:     if (sm_debug) {
                    508:        printf ("=> %s\n", buffer);
                    509:        (void) fflush (stdout);
                    510:     }
                    511: 
                    512:     sm_alarmed = 0;
                    513:     (void) alarm ((unsigned) time);
                    514:     if ((result = sm_wrecord (buffer, strlen (buffer))) != NOTOK)
                    515:        result = smhear ();
                    516:     (void) alarm (0);
                    517: 
                    518:     return result;
                    519: }
                    520: 
                    521: /*  */
                    522: 
                    523: static int  sm_wrecord (buffer, len)
                    524: register char   *buffer;
                    525: register int     len;
                    526: {
                    527:     if (sm_wfp == NULL)
                    528:        return sm_werror ();
                    529: 
                    530:     (void) fwrite (buffer, sizeof *buffer, len, sm_wfp);
                    531:     fputs ("\r\n", sm_wfp);
                    532:     (void) fflush (sm_wfp);
                    533: 
                    534:     return (ferror (sm_wfp) ? sm_werror () : OK);
                    535: }
                    536: 
                    537: /*  */
                    538: 
                    539: static int  sm_wstream (buffer, len)
                    540: register char   *buffer;
                    541: register int     len;
                    542: {
                    543:     register char  *bp;
                    544:     static char lc = NULL;
                    545: 
                    546:     if (sm_wfp == NULL)
                    547:        return sm_werror ();
                    548: 
                    549:     if (buffer == NULL && len == 0) {
                    550:        if (lc != '\n')
                    551:            fputs ("\r\n", sm_wfp);
                    552:        lc = NULL;
                    553:        return (ferror (sm_wfp) ? sm_werror () : OK);
                    554:     }
                    555: 
                    556:     for (bp = buffer; len > 0; bp++, len--) {
                    557:        switch (*bp) {
                    558:            case '\n': 
                    559:                sm_nl = TRUE;
                    560:                (void) fputc ('\r', sm_wfp);
                    561:                break;
                    562: 
                    563:            case '.': 
                    564:                if (sm_nl)
                    565:                    (void) fputc ('.', sm_wfp);/* FALL THROUGH */
                    566:            default: 
                    567:                sm_nl = FALSE;
                    568:        }
                    569:        (void) fputc (*bp, sm_wfp);
                    570:        if (ferror (sm_wfp))
                    571:            return sm_werror ();
                    572:     }
                    573: 
                    574:     if (bp > buffer)
                    575:        lc = *--bp;
                    576:     return (ferror (sm_wfp) ? sm_werror () : OK);
                    577: }
                    578: 
                    579: /*  */
                    580: 
                    581: static int  sm_werror () {
                    582:     sm_reply.length =
                    583: #ifdef SMTP
                    584:        strlen (strcpy (sm_reply.text, sm_wfp == NULL ? "no socket opened"
                    585:            : sm_alarmed ? "write to socket timed out"
                    586:            : "error writing to socket"));
                    587: #else  not SMTP
                    588:        strlen (strcpy (sm_reply.text, sm_wfp == NULL ? "no pipe opened"
                    589:            : sm_alarmed ? "write to pipe timed out"
                    590:            : "error writing to pipe"));
                    591: #endif not SMTP
                    592: 
                    593:     return (sm_reply.code = NOTOK);
                    594: }
                    595: 
                    596: /*  */
                    597: 
                    598: static int  smhear () {
                    599:     register int    i,
                    600:                     code,
                    601:                     cont,
                    602:                    rc,
                    603:                    more;
                    604:     int     bc;
                    605:     register char  *bp,
                    606:                    *rp;
                    607:     char    buffer[BUFSIZ];
                    608: 
                    609: again: ;
                    610: 
                    611:     sm_reply.text[sm_reply.length = 0] = NULL;
                    612: 
                    613:     rp = sm_reply.text, rc = sizeof sm_reply.text - 1;
                    614:     for (more = FALSE; sm_rrecord (bp = buffer, &bc) != NOTOK;) {
                    615:        if (sm_debug) {
                    616:            printf ("<= %s\n", buffer);
                    617:            (void) fflush (stdout);
                    618:        }
                    619: 
                    620:        for (; bc > 0 && (!isascii (*bp) || !isdigit (*bp)); bp++, bc--)
                    621:            continue;
                    622: 
                    623:        cont = FALSE;
                    624:        code = atoi (bp);
                    625:        bp += 3, bc -= 3;
                    626:        for (; bc > 0 && isspace (*bp); bp++, bc--)
                    627:            continue;
                    628:        if (bc > 0 && *bp == '-') {
                    629:            cont = TRUE;
                    630:            bp++, bc--;
                    631:            for (; bc > 0 && isspace (*bp); bp++, bc--)
                    632:                continue;
                    633:        }
                    634: 
                    635:        if (more) {
                    636:            if (code != sm_reply.code || cont)
                    637:                continue;
                    638:            more = FALSE;
                    639:        }
                    640:        else {
                    641:            sm_reply.code = code;
                    642:            more = cont;
                    643:            if (bc <= 0) {
                    644:                (void) strcpy (bp = buffer, sm_noreply);
                    645:                bc = strlen (sm_noreply);
                    646:            }
                    647:        }
                    648:        if ((i = min (bc, rc)) > 0) {
                    649:            (void) strncpy (rp, bp, i);
                    650:            rp += i, rc -= i;
                    651:            if (more && rc > strlen (sm_moreply) + 1) {
                    652:                (void) strcpy (sm_reply.text + rc, sm_moreply);
                    653:                rc += strlen (sm_moreply);
                    654:            }
                    655:        }
                    656:        if (more)
                    657:            continue;
                    658:        if (sm_reply.code < 100) {
                    659:            if (sm_verbose) {
                    660:                printf ("%s\n", sm_reply.text);
                    661:                (void) fflush (stdout);
                    662:            }
                    663:            goto again;
                    664:        }
                    665: 
                    666:        sm_reply.length = rp - sm_reply.text;
                    667:        return sm_reply.code;
                    668:     }
                    669: 
                    670:     return NOTOK;
                    671: }
                    672: 
                    673: /*  */
                    674: 
                    675: static int  sm_rrecord (buffer, len)
                    676: register char   *buffer;
                    677: register int    *len;
                    678: {
                    679:     if (sm_rfp == NULL)
                    680:        return sm_rerror ();
                    681: 
                    682:     buffer[*len = 0] = NULL;
                    683: 
                    684:     (void) fgets (buffer, BUFSIZ, sm_rfp);
                    685:     *len = strlen (buffer);
                    686:     if (ferror (sm_rfp) || feof (sm_rfp))
                    687:        return sm_rerror ();
                    688:     if (buffer[*len - 1] != '\n')
                    689:        while (getc (sm_rfp) != '\n' && !ferror (sm_rfp) && !feof (sm_rfp))
                    690:            continue;
                    691:     else
                    692:        if (buffer[*len - 2] == '\r')
                    693:            *len -= 1;
                    694:     buffer[*len - 1] = NULL;
                    695: 
                    696:     return OK;
                    697: }
                    698: 
                    699: /*  */
                    700: 
                    701: static int  sm_rerror () {
                    702:     sm_reply.length =
                    703: #ifdef SMTP
                    704:        strlen (strcpy (sm_reply.text, sm_rfp == NULL ? "no socket opened"
                    705:            : sm_alarmed ? "read from socket timed out"
                    706:            : feof (sm_rfp) ? "premature end-of-file on socket"
                    707:            : "error reading from socket"));
                    708: #else  not SMTP
                    709:        strlen (strcpy (sm_reply.text, sm_rfp == NULL ? "no pipe opened"
                    710:            : sm_alarmed ? "read from pipe timed out"
                    711:            : feof (sm_rfp) ? "premature end-of-file on pipe"
                    712:            : "error reading from pipe"));
                    713: #endif not SMTP
                    714: 
                    715:     return (sm_reply.code = NOTOK);
                    716: }
                    717: 
                    718: /*  */
                    719: 
                    720: /* ARGSUSED */
                    721: 
                    722: static int alrmser (i)
                    723: int     i;
                    724: {
                    725: #ifndef        BSD42
                    726:     signal (SIGALRM, alrmser);
                    727: #endif BSD42
                    728:     sm_alarmed++;
                    729: 
                    730:     if (sm_debug) {
                    731:        printf ("timed out...\n");
                    732:        (void) fflush (stdout);
                    733:     }
                    734: }
                    735: 
                    736: /*  */
                    737: 
                    738: char   *rp_string (code)
                    739: register int     code;
                    740: {
                    741:     register char  *text;
                    742:     static char buffer[BUFSIZ];
                    743: 
                    744:     switch (sm_reply.code != NOTOK ? code : NOTOK) {
                    745:        case RP_AOK:
                    746:            text = "AOK";
                    747:            break;
                    748: 
                    749:        case RP_MOK:
                    750:            text = "MOK";
                    751:            break;
                    752: 
                    753:        case RP_OK: 
                    754:            text = "OK";
                    755:            break;
                    756: 
                    757:        case RP_RPLY: 
                    758:            text = "RPLY";
                    759:            break;
                    760: 
                    761:        case RP_BHST: 
                    762:        default: 
                    763:            text = "BHST";
                    764:            (void) sprintf (buffer, "[%s] %s", text, sm_reply.text);
                    765:            return buffer;
                    766: 
                    767:        case RP_PARM: 
                    768:            text = "PARM";
                    769:            break;
                    770: 
                    771:        case RP_NO: 
                    772:            text = "NO";
                    773:            break;
                    774: 
                    775:        case RP_USER: 
                    776:            text = "USER";
                    777:            break;
                    778: 
                    779:        case RP_NDEL: 
                    780:            text = "NDEL";
                    781:            break;
                    782:     }
                    783: 
                    784:     (void) sprintf (buffer, "[%s] %3d %s", text, sm_reply.code, sm_reply.text);
                    785:     return buffer;
                    786: }

unix.superglobalmegacorp.com

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