Annotation of 43BSDReno/contrib/isode-beta/others/tsbridge/tsbridge.c, revision 1.1.1.1

1.1       root        1: /* tsbridge.c: transport bridge - jpo version ! */
                      2: 
                      3: #ifndef lint
                      4: static char *rcsid = "$Header: /f/osi/others/tsbridge/RCS/tsbridge.c,v 7.5 90/07/09 14:43:01 mrose Exp $";
                      5: #endif
                      6: 
                      7: /*
                      8:  * $Header: /f/osi/others/tsbridge/RCS/tsbridge.c,v 7.5 90/07/09 14:43:01 mrose Exp $
                      9:  *
                     10:  * Contributed by Julian Onions, Nottingham University in the UK
                     11:  *
                     12:  *
                     13:  * $Log:       tsbridge.c,v $
                     14:  * Revision 7.5  90/07/09  14:43:01  mrose
                     15:  * sync
                     16:  * 
                     17:  * Revision 7.4  90/03/19  14:27:00  mrose
                     18:  * jpo
                     19:  * 
                     20:  * Revision 7.2  90/01/11  18:36:55  mrose
                     21:  * real-sync
                     22:  * 
                     23:  * Revision 7.1  89/11/27  05:43:28  mrose
                     24:  * sync
                     25:  * 
                     26:  * Revision 7.0  89/11/23  22:11:12  mrose
                     27:  * Release 6.0
                     28:  * 
                     29:  */
                     30: 
                     31: /*
                     32:  *                               NOTICE
                     33:  *
                     34:  *    Acquisition, use, and distribution of this module and related
                     35:  *    materials are subject to the restrictions of a license agreement.
                     36:  *    Consult the Preface in the User's Manual for the full terms of
                     37:  *    this agreement.
                     38:  *
                     39:  */
                     40: 
                     41: 
                     42: #include <signal.h>
                     43: #include <stdio.h>
                     44: #include <varargs.h>
                     45: #include "manifest.h"
                     46: #include <sys/ioctl.h>
                     47: #ifdef BSD42
                     48: #include <sys/file.h>
                     49: #endif
                     50: #ifdef SYS5
                     51: #include <fcntl.h>
                     52: #endif
                     53: #include "tsap.h"
                     54: #include "logger.h"
                     55: #include "psap.h"
                     56: #include "tailor.h"
                     57: 
                     58: /*  */
                     59: 
                     60: static int debug = 0;
                     61: static int nbits = FD_SETSIZE;
                     62: 
                     63: static LLog _pgm_log = {
                     64:        "tsbridge.log", NULLCP, NULLCP,
                     65:        LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, LLOG_FATAL,
                     66:        -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK
                     67: };
                     68: 
                     69: LLog   *pgm_log = &_pgm_log;
                     70: 
                     71: static char    *myname = "tsbridge";
                     72: 
                     73: typedef struct ContTbl {
                     74:        struct TSAPaddr src;
                     75:        struct TSAPaddr dest;
                     76:        unsigned int flags;
                     77: #define CONN_STRICT    01
                     78: #define CONN_TRANS     02
                     79: #define CONN_NOMUNGE   04
                     80: #define CONN_FORCEMUNGE        010
                     81: } ContTbl;
                     82: ContTbl con_tbl[FD_SETSIZE];
                     83: int con_tbl_cnt = 0;
                     84: 
                     85: static struct TSAPaddr *maketa ();
                     86: static struct TSAPaddr *getnewta ();
                     87: static ContTbl *find_connection ();
                     88: 
                     89: static void read_file ();
                     90: 
                     91: static void adios (), advise ();
                     92: 
                     93: static void ts_adios (), ts_advise ();
                     94: static void ts_close (), ts_discon ();
                     95: static void tsbridge (), do_the_biz (), copy_tsdu (), arginit (), envinit ();
                     96: /*  */
                     97: 
                     98: /* ARGSUSED */
                     99: 
                    100: main (argc, argv, envp)
                    101: int    argc;
                    102: char   **argv,
                    103:         **envp;
                    104: {
                    105:        struct TSAPdisconnect   tds;
                    106:        register struct TSAPdisconnect  *td = &tds;
                    107:        struct TSAPaddr tas, *ta = &tas;
                    108:        int     vecp;
                    109:        char    *vec[4];
                    110: 
                    111:        arginit (argv);
                    112: 
                    113:        envinit ();
                    114: 
                    115:        for (vecp = 0; vecp < con_tbl_cnt; vecp++) {
                    116:            advise (LLOG_TRACE, NULLCP, "Listening on %s",
                    117:                     taddr2str (&con_tbl[vecp].src));
                    118:            if (TNetListen (&con_tbl[vecp].src, td) == NOTOK) {
                    119:                advise (LLOG_FATAL, NULLCP, "Listen failed on \"%s\"",
                    120:                        taddr2str (&con_tbl[vecp].src));
                    121:                ts_adios (td, "listen failed");
                    122:            }
                    123:        }
                    124: 
                    125:        for (;;) {
                    126:                if (TNetAcceptAux (&vecp, vec, NULLIP, ta, 0, NULLFD, NULLFD,
                    127:                                   NULLFD, NOTOK, td) == NOTOK)
                    128:                        ts_adios (td, "accept failed");
                    129: 
                    130:                if (vecp <= 0)
                    131:                        continue;
                    132: 
                    133:                advise (LLOG_TRACE, NULLCP, "accepted new connection");
                    134:                switch (TNetFork (vecp, vec, td)) {
                    135:                    case OK:
                    136:                        tsbridge (vecp, vec, ta);
                    137:                        exit (1);
                    138:                        /* NOTREACHED */
                    139: 
                    140:                    case NOTOK:
                    141:                        ts_advise (td, LLOG_EXCEPTIONS, "fork failed");
                    142:                        break;
                    143: 
                    144:                    default:
                    145:                        break;
                    146:                }
                    147:        }
                    148: }
                    149: 
                    150: /*  */
                    151: 
                    152: static void tsbridge (vecp, vec, ta)
                    153: int    vecp;
                    154: char   **vec;
                    155: struct TSAPaddr *ta;
                    156: {
                    157:        struct TSAPstart tss;
                    158:        register struct TSAPstart *ts = &tss;
                    159:        struct TSAPdisconnect   tds;
                    160:        register struct TSAPdisconnect  *td = &tds;
                    161:        struct TSAPaddr *tota;
                    162:        struct TSAPaddr *fromta;
                    163:        struct TSAPconnect tcs;
                    164:        struct TSAPconnect *tc = &tcs;
                    165:        int     sd;
                    166:        ContTbl *ctp;
                    167: 
                    168:        if (TInit (vecp, vec, ts, td) == NOTOK)
                    169:                ts_adios (td, "T-CONNECT.INDICATION failed");
                    170:                
                    171:        sd = ts -> ts_sd;
                    172:        advise (LLOG_NOTICE, NULLCP,
                    173:                "T-CONNECT.INDICATION: <%d, %s, %s, %d, %d>",
                    174:                ts -> ts_sd, taddr2str (&ts -> ts_calling),
                    175:                taddr2str (&ts -> ts_called),
                    176:                ts -> ts_expedited, ts -> ts_tsdusize);
                    177: 
                    178:        ctp = find_connection (ta);
                    179:        if (ctp == NULL) {
                    180:            ts_close (sd, "Unknown listener address");
                    181:            exit (1);
                    182:        }
                    183:        advise (LLOG_TRACE, NULLCP, "Accepted from address %s",
                    184:                taddr2str (&ctp -> src));
                    185: 
                    186:        tota = getnewta (&ts -> ts_called, sd, ctp);
                    187: 
                    188:        fromta = maketa (&ts -> ts_calling, tota -> ta_addrs[0].na_stack, ctp);
                    189: 
                    190:        if ((ctp -> flags & CONN_TRANS) == 0) {
                    191:            ts -> ts_expedited = 0;
                    192:            if (ts -> ts_cc > 0) {
                    193:                advise (LLOG_EXCEPTIONS, NULLCP,
                    194:                        "%d octets initial user-data",
                    195:                        ts -> ts_cc);
                    196:                ts_close (sd, "initial user-data not allowed");
                    197:                exit (1);
                    198:            }
                    199:        }
                    200:        
                    201:        advise (LLOG_NOTICE, NULLCP,
                    202:                "T-CONNECT.REQUEST: <%s, %s, %d, 0x%x/%d>",
                    203:                taddr2str (fromta), taddr2str (tota), ts -> ts_expedited,
                    204:                ts -> ts_data, ts -> ts_cc);
                    205: 
                    206:        if (TConnRequest (fromta, tota, ts -> ts_expedited,
                    207:                          ts -> ts_data, ts -> ts_cc, &ts -> ts_qos,
                    208:                          tc, td) == NOTOK) {
                    209:                ts_close (sd, "connection establishment failed");
                    210:                ts_adios(td, "T-CONNECT.REQUEST");
                    211:        }
                    212:        if (TConnResponse (sd, &tc -> tc_responding,
                    213:                           tc -> tc_expedited, tc -> tc_data, tc -> tc_cc,
                    214:                           &tc -> tc_qos, td) == NOTOK) {
                    215:                ts_close (sd, "connection establishment failed");
                    216:                ts_close (tc -> tc_sd, "connection establishment failed");
                    217:                ts_adios (td, "T-CONNECT.RESPONSE");
                    218:        }
                    219:        
                    220:        do_the_biz (sd, tc -> tc_sd);
                    221: }
                    222: 
                    223: /*  */
                    224: 
                    225: static void    do_the_biz (sd1, sd2)
                    226: int    sd1, sd2;
                    227: {
                    228:        int nfds = 0;
                    229:        fd_set rmask, imask;
                    230:        struct TSAPdisconnect   tds;
                    231:        register struct TSAPdisconnect  *td = &tds;
                    232: 
                    233:        FD_ZERO (&rmask);
                    234:        
                    235:        if (TSelectMask (sd1, &rmask, &nfds, td) == NOTOK
                    236:                || TSelectMask (sd2, &rmask, &nfds, td) == NOTOK)
                    237:            ts_adios (td, "TSelectMask failed");
                    238: 
                    239:        for (;;) {
                    240:                imask = rmask;
                    241:                if (xselect (nfds, &imask, NULLFD, NULLFD, NOTOK) == NOTOK)
                    242:                        adios ("select", "failed");
                    243: 
                    244:                if (FD_ISSET (sd1, &imask))
                    245:                        copy_tsdu (sd1, sd2);
                    246:                if (FD_ISSET (sd2, &imask))
                    247:                        copy_tsdu (sd2, sd1);
                    248:        }
                    249: }
                    250: 
                    251: /*  */
                    252: 
                    253: static void copy_tsdu (s1, s2)
                    254: int    s1, s2;
                    255: {
                    256:        struct TSAPdisconnect   tds;
                    257:        register struct TSAPdisconnect  *td = &tds;
                    258:        struct TSAPdata txs;
                    259:        register struct TSAPdata *tx = &txs;
                    260:        int     result;
                    261:        char    *p;
                    262: 
                    263:        SLOG (pgm_log, LLOG_DEBUG, NULLCP, ("copy_tsdu (%d -> %d)", s1, s2));
                    264: 
                    265:        if (TReadRequest (s1, tx, OK, td) == NOTOK) {
                    266:                switch (td -> td_reason) {
                    267:                    case DR_TIMER:
                    268:                    case DR_WAITING:
                    269:                    case DR_OPERATION:
                    270:                    case DR_PARAMETER:
                    271:                        ts_advise (td, LLOG_TRACE, "TReadRequest");
                    272:                        return;
                    273: 
                    274:                    case DR_NORMAL:
                    275:                        ts_discon (td, s2);
                    276:                        break;
                    277: 
                    278:                    default:
                    279:                        ts_adios (td, "TReadRequest");
                    280:                }
                    281:        }
                    282: 
                    283:        if (tx -> tx_expedited) {
                    284:                SLOG (pgm_log, LLOG_DEBUG, NULLCP, ("TExpdRequest"));
                    285:                p = qb2str (&tx -> tx_qbuf);
                    286:                result = TExpdRequest (s2, p, tx -> tx_cc, td);
                    287:                free (p);
                    288:        }
                    289:        else {
                    290:                struct qbuf *qb;
                    291:                int     uiocnt = 0;
                    292:                struct udvec uvec[100];
                    293:                int total;
                    294: 
                    295:                total = uiocnt = 0;
                    296:                for (qb = tx-> tx_qbuf.qb_forw; qb != &tx -> tx_qbuf;
                    297:                     qb = qb -> qb_forw) {
                    298:                        uvec[uiocnt].uv_base = qb -> qb_data;
                    299:                        uvec[uiocnt++].uv_len = qb -> qb_len;
                    300:                        total += qb -> qb_len;
                    301:                        if (uiocnt > 100)
                    302:                                adios (NULLCP, "Internal buffer overflow");
                    303:                }
                    304:                uvec[uiocnt].uv_base = NULLCP;
                    305:                uvec[uiocnt].uv_len = 0;
                    306:                if (tx -> tx_cc != total)
                    307:                        advise (NULLCP, LLOG_EXCEPTIONS,
                    308:                                "Mismatch in data %d != %d",
                    309:                                tx -> tx_cc, total);
                    310:                SLOG (pgm_log, LLOG_DEBUG, NULLCP, ("TWriteRequest"));
                    311:                result = TWriteRequest (s2, uvec, td);
                    312:        }
                    313:        TXFREE (tx);
                    314: 
                    315:        if (result == NOTOK) {
                    316:                if (td -> td_reason == DR_NORMAL)
                    317:                        ts_discon (td, s1);
                    318: 
                    319:                ts_adios (td, tx -> tx_expedited ? "T-EXPEDITED-DATA.REQUEST"
                    320:                                                 : "T-DATA.REQUEST");
                    321:        }
                    322: }
                    323: 
                    324: /*  */
                    325: 
                    326: static void ts_discon (td, sd)
                    327: struct TSAPdisconnect *td;
                    328: int    sd;
                    329: {
                    330:        ts_close (sd, "Normal Disconnect");
                    331:        ts_advise (td, LLOG_NOTICE, "T-DISCONNECT.INDICATION");
                    332: 
                    333:        exit (0);
                    334: }
                    335: 
                    336: /*  */
                    337: 
                    338: static void ts_close (sd, event)
                    339: int    sd;
                    340: char   *event;
                    341: {
                    342:        struct TSAPdisconnect tds;
                    343:        register struct TSAPdisconnect *td = &tds;
                    344: 
                    345:        if (strlen (event) >= TD_SIZE)
                    346:            event = NULLCP;
                    347:        if (TDiscRequest (sd, event, event ? strlen (event) + 1: 0, td)
                    348:                == NOTOK)
                    349:            ts_advise (td, LLOG_EXCEPTIONS, "T-DISCONNECT.REQUEST");
                    350: }
                    351: 
                    352: /*  */
                    353: 
                    354: static void  ts_adios (td, event)
                    355: register struct TSAPdisconnect *td;
                    356: char   *event;
                    357: {
                    358:        ts_advise (td, LLOG_EXCEPTIONS, event);
                    359: 
                    360:        exit (1);
                    361: }
                    362: 
                    363: /*  */
                    364: 
                    365: static void  ts_advise (td, code, event)
                    366: register struct TSAPdisconnect *td;
                    367: int     code;
                    368: char   *event;
                    369: {
                    370:     char    buffer[BUFSIZ];
                    371: 
                    372:     if (td -> td_cc > 0)
                    373:        (void) sprintf (buffer, "[%s] %*.*s",
                    374:                TErrString (td -> td_reason),
                    375:                td -> td_cc, td -> td_cc, td -> td_data);
                    376:     else
                    377:        (void) sprintf (buffer, "[%s]", TErrString (td -> td_reason));
                    378: 
                    379:     advise (code, NULLCP, "%s: %s", event, buffer);
                    380: }
                    381: 
                    382: /*  */
                    383: 
                    384: static struct TSAPaddr *getnewta (ta, sd, ctp)
                    385: struct TSAPaddr *ta;
                    386: int    sd;
                    387: ContTbl *ctp;
                    388: {
                    389:        static struct TSAPaddr newta;
                    390:        struct TSAPaddr *nta = &newta;
                    391:        char    buffer[TSSIZE + 1];
                    392: 
                    393:        if (ctp -> flags & CONN_TRANS) {        /* make transparent address */
                    394:                *nta = ctp -> dest;     /* struct copy */
                    395:                nta -> ta_selectlen = ta -> ta_selectlen;
                    396:                bcopy (ta -> ta_selector, nta -> ta_selector,
                    397:                       ta -> ta_selectlen);
                    398:                return nta;
                    399:        }
                    400: 
                    401:        /* do the real TS bridge stuff */
                    402:        if (ta -> ta_selectlen == 0) {
                    403:                ts_close (sd, "no transport selector");
                    404:                adios (NULLCP, "no transport selector");
                    405:        }
                    406: 
                    407:        bcopy (ta -> ta_selector, buffer, ta -> ta_selectlen);
                    408:        buffer[ta -> ta_selectlen] = NULL;
                    409: 
                    410:        if ((nta = str2taddr (buffer)) == NULLTA) {
                    411:                ts_close (sd, "unable to translate address");
                    412:                adios (NULLCP, "unable to translate \"%s\"", buffer);
                    413:        }
                    414:        newta = *nta;
                    415: 
                    416:        return &newta;
                    417: }
                    418: 
                    419: /*  */
                    420: 
                    421: static struct TSAPaddr *maketa (ta, type, ctp)
                    422: struct TSAPaddr *ta;
                    423: long   type;
                    424: ContTbl *ctp;
                    425: {
                    426:     static struct TSAPaddr newta;
                    427:     register struct TSAPaddr *nta = &newta;
                    428:     char       *p;
                    429:     int        i;
                    430:     struct PSAPaddr pas;
                    431:     struct PSAPaddr *pa = &pas;
                    432: 
                    433:     if (ctp -> flags & CONN_NOMUNGE) {
                    434:        *nta = *ta;     /* struct copy */
                    435:     }
                    436:     if (!(ctp -> flags & CONN_NOMUNGE) || (ctp -> flags & CONN_FORCEMUNGE)) {
                    437:        bzero ((char *)pa, sizeof *pa);
                    438:        pa -> pa_addr.sa_addr = *ta;
                    439:        if ((p = _paddr2str (pa, NULLNA, -1)) == NULL) {
                    440:            if (ctp -> flags & CONN_STRICT)
                    441:                adios (NULLCP, "unable to convert address to text");
                    442:            advise (LLOG_NOTICE, NULLCP,
                    443:                    "unable to convert address to text");
                    444:            return ta;          /* this may work... */
                    445:        }
                    446:        else {
                    447:            if ((nta -> ta_selectlen = strlen (p)) >= TSSIZE) {
                    448:                if (ctp -> flags & CONN_STRICT)
                    449:                    adios (NULLCP, "new selector \"%s\" is too big",
                    450:                           p);
                    451: 
                    452:                advise (LLOG_NOTICE, NULLCP,
                    453:                        "new selector \"%s\" is too big", p);
                    454:                return ta;
                    455:            }
                    456:            else
                    457:                bcopy (p, nta -> ta_selector, TSSIZE);
                    458:        }
                    459:     }
                    460:     for (i = 0; i < ctp -> src.ta_naddr; i++) {
                    461:        if (ctp -> src.ta_addrs[i].na_stack == type) {
                    462:            /* our address */
                    463:            nta -> ta_addrs[0] = ctp->src.ta_addrs[i]; 
                    464:            nta -> ta_naddr = 1;
                    465:            return nta;
                    466:        }
                    467:     }
                    468:     /*
                    469:      * This requires an explanation:
                    470:      * If NOMUNGE && FORCEMUNGE  we have a semi-transparent bridge
                    471:      * and since [at least on my machine] the recipient of a "transparent"
                    472:      * call sees it as coming from the bridge host, ie the effect is that
                    473:      * of a strict call, the structure that is now in nta, viz:
                    474:      * "calling address"/calling address
                    475:      * is going to get clobbered and appear at the final host as originating
                    476:      * "calling address"/bridge host
                    477:      * anyway.  This is what I want.
                    478:      * => return nta
                    479:      */
                    480:     if ((ctp -> flags & CONN_NOMUNGE) 
                    481:        && (ctp -> flags & CONN_FORCEMUNGE)
                    482:        && !(ctp -> flags & CONN_STRICT)) {
                    483:        return nta;
                    484:     }
                    485:     if (ctp -> flags & CONN_STRICT)
                    486:        adios (NULLCP, "not listening on this network (%d)", type);
                    487: 
                    488:     advise (LLOG_NOTICE, NULLCP,
                    489:            "not listening on this network (%d)", type);
                    490: 
                    491:     return ta;
                    492: }
                    493: 
                    494: /*  */
                    495: 
                    496: static ContTbl *find_connection (ta)
                    497: struct TSAPaddr *ta;
                    498: {
                    499:     ContTbl *ctp;
                    500:     struct NSAPaddr *na1, *na2;
                    501: 
                    502:     for (ctp = con_tbl; ctp < &con_tbl[con_tbl_cnt]; ctp ++) {
                    503:        for (na1 = &ctp -> src.ta_addrs[0];
                    504:             na1 < &ctp -> src.ta_addrs[ctp->src.ta_naddr]; na1++) {
                    505:            for (na2 = &ta -> ta_addrs[0];
                    506:                 na2 < &ta -> ta_addrs[ta->ta_naddr]; na2 ++) {
                    507:                if (na1 -> na_stack != na2 -> na_stack)
                    508:                    continue;
                    509: 
                    510:                switch (na1 -> na_stack) {
                    511:                case NA_NSAP:
                    512:                    if (na1 -> na_addrlen == na2 -> na_addrlen &&
                    513:                        bcmp (na1 -> na_address, na2 -> na_address,
                    514:                              na1 -> na_addrlen) == 0)
                    515:                        return ctp;
                    516:                    break;
                    517: 
                    518:                case NA_TCP:
                    519:                    if (na1 -> na_port == na2 -> na_port &&
                    520:                       strcmp (na1 -> na_domain, na2 -> na_domain) == 0)
                    521:                        return ctp;
                    522:                    break;
                    523: 
                    524:                case NA_X25:
                    525:                case NA_BRG:
                    526:                    if (na1 -> na_dtelen == na2 -> na_dtelen &&
                    527:                        bcmp (na1 -> na_dte, na2 -> na_dte,
                    528:                              na1 -> na_dtelen) == 0 &&
                    529:                        na1 -> na_pidlen == na2 -> na_pidlen &&
                    530:                        bcmp (na1 -> na_pid, na2 -> na_pid,
                    531:                              na1 -> na_pidlen) == 0)
                    532:                        return ctp;
                    533:                    break;
                    534:                }
                    535:            }
                    536:        }
                    537:     }
                    538:     return NULL;
                    539: }
                    540: 
                    541: /*  */
                    542: 
                    543: static void    arginit (vec)
                    544: char   **vec;
                    545: {
                    546:        register char   *ap;
                    547:        register struct TSAPaddr *ta;
                    548: 
                    549:        if (myname = rindex (*vec, '/'))
                    550:                myname++;
                    551:        if (myname == NULL || *myname == NULL)
                    552:                myname = *vec;
                    553: 
                    554:        for (vec++; ap = *vec; vec++) {
                    555:            if (*ap == '-' && ap[1])
                    556:                switch (*++ap) {
                    557:                    case 'T':
                    558:                        if ((ap = *++vec) == NULL || *ap == '-')
                    559:                            adios (NULLCP, "usage: %s -T tailorfile", myname);
                    560:                        (void) isodesetailor (ap);
                    561:                        isodetailor (myname, 0);
                    562:                        ll_hdinit (pgm_log, myname);
                    563:                        continue;
                    564: 
                    565:                    case 'a':
                    566:                        if ((ap = *++vec) == NULL || *ap == '-')
                    567:                            adios (NULLCP, "usage: %s -a address", myname);
                    568:                        if ((ta = str2taddr (ap)) == NULLTA)
                    569:                            adios (NULLCP, "bad address \"%s\"", ap);
                    570:                        con_tbl[0].src = *ta; /* struct copy */
                    571:                        con_tbl[0].flags =  0;
                    572:                        con_tbl_cnt = 1;
                    573:                        continue;
                    574: 
                    575:                    case 's':
                    576:                        con_tbl[0].flags |= CONN_STRICT;
                    577:                        continue;
                    578: 
                    579:                    default:
                    580:                        adios (NULLCP, "unknown switch -%s", ap);
                    581:                }
                    582:            else
                    583:                break;
                    584:            
                    585:        }
                    586:        isodetailor (myname, 0);
                    587:        ll_hdinit (pgm_log, myname);
                    588: 
                    589:        for (; ap = *vec; vec++)
                    590:            read_file (ap);
                    591: 
                    592:        if (con_tbl_cnt <= 0) {
                    593:            if ((ta = str2taddr (tsb_default_address)) == NULLTA)
                    594:                adios (NULLCP, "bad default address \"%s\"",
                    595:                       tsb_default_address);
                    596:            con_tbl[0].src = *ta; /* struct copy */
                    597:            con_tbl_cnt = 1;
                    598:        }
                    599: }
                    600: 
                    601: /*  */
                    602: 
                    603: static void read_file (file)
                    604: char   *file;
                    605: {
                    606:     FILE       *fp;
                    607:     char       buf[BUFSIZ];
                    608:     char       *vec[50];
                    609:     char       *ap;
                    610:     int                vecp, i;
                    611:     ContTbl    *ctp;
                    612:     struct TSAPaddr *ta;
                    613: 
                    614:     if (strcmp (file, "-") == 0)
                    615:        fp = stdin;
                    616:     else if ((fp = fopen (file, "r")) == NULL)
                    617:        adios (file, "Can't open ");
                    618: 
                    619:     while (fgets (buf, sizeof buf, fp) != NULLCP) {
                    620:        if (buf[0] == '#' || buf[0] == '\n')
                    621:            continue;
                    622: 
                    623:        vecp = sstr2arg (buf, 50, vec, " \t,\n");
                    624:        if (vecp <= 0)
                    625:            continue;
                    626: 
                    627:        if ((ta = str2taddr (vec[0])) == NULLTA)
                    628:            adios (NULLCP, "Bad address \"%s\" in file %s", vec[0], file);
                    629: 
                    630:        ctp = &con_tbl[con_tbl_cnt];
                    631:        ctp -> src = *ta; /* struct copy */
                    632:        con_tbl_cnt ++;
                    633: 
                    634:        for (i = 1; i < vecp; i++) {
                    635:            ap = vec[i];
                    636:            if (*ap == '\0')
                    637:                continue;
                    638:            if (*ap == '-') {
                    639:                switch (*++ap) {
                    640:                case 's':
                    641:                    ctp -> flags |= CONN_STRICT;
                    642:                    break;
                    643:                case 't':
                    644:                    ctp -> flags |= CONN_TRANS;
                    645:                    break;
                    646:                case 'n':
                    647:                    ctp -> flags |= CONN_NOMUNGE;
                    648:                    break;
                    649:                case 'f':
                    650:                    ctp -> flags |= CONN_FORCEMUNGE;
                    651:                    break;
                    652: 
                    653:                default:
                    654:                    adios (NULLCP, "Unknown option -%c", *ap);
                    655:                }
                    656:            }
                    657:            else {
                    658:                if ((ta = str2taddr (ap)) == NULLTA)
                    659:                    adios (NULLCP, "Bad address \"%s\" in file %s",
                    660:                           ap, file);
                    661:                ctp -> dest = *ta; /* struct copy */
                    662:                ctp -> flags |= (CONN_TRANS|CONN_NOMUNGE);
                    663:            }
                    664:        }
                    665: 
                    666:     }
                    667: 
                    668:     if (strcmp (file, "-") != 0)
                    669:        (void) fclose (fp);
                    670: }
                    671: 
                    672: /*  */
                    673: 
                    674: static void envinit () {
                    675:        int     i,
                    676:                sd;
                    677: 
                    678:        nbits = getdtablesize ();
                    679: 
                    680:        if (!(debug = isatty (2))) {
                    681:                for (i = 0; i < 5; i++) {
                    682:                        switch (fork ()) {
                    683:                            case NOTOK: 
                    684:                                sleep (5);
                    685:                                continue;
                    686: 
                    687:                            case OK: 
                    688:                                break;
                    689: 
                    690:                            default: 
                    691:                                _exit (0);
                    692:                        }
                    693:                        break;
                    694:                }
                    695: 
                    696:                (void) chdir ("/");
                    697: 
                    698:                if ((sd = open ("/dev/null", O_RDWR)) == NOTOK)
                    699:                        adios ("/dev/null", "unable to read");
                    700:                if (sd != 0)
                    701:                        (void) dup2 (sd, 0), (void) close (sd);
                    702:                (void) dup2 (0, 1);
                    703:                (void) dup2 (0, 2);
                    704: 
                    705: #ifdef SETSID
                    706:                if (setsid () == NOTOK)
                    707:                    advise (LLOG_EXCEPTIONS, "failed", "setsid");
                    708: #endif
                    709: #ifdef  TIOCNOTTY
                    710:                if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) {
                    711:                        (void) ioctl (sd, TIOCNOTTY, NULLCP);
                    712:                        (void) close (sd);
                    713:                }
                    714: #else
                    715: #ifdef  SYS5
                    716:                (void) setpgrp ();
                    717:                (void) signal (SIGINT, SIG_IGN);
                    718:                (void) signal (SIGQUIT, SIG_IGN);
                    719: #endif
                    720: #endif
                    721:        }
                    722:        else
                    723:                ll_dbinit (pgm_log, myname);
                    724: 
                    725: #ifndef sun                    /* damn YP... */
                    726:        for (sd = 3; sd < nbits; sd++)
                    727:            if (pgm_log -> ll_fd != sd)
                    728:                (void) close (sd);
                    729: #endif
                    730: 
                    731:        (void) signal (SIGPIPE, SIG_IGN);
                    732: 
                    733:        ll_hdinit (pgm_log, myname);
                    734:        advise (LLOG_NOTICE, NULLCP, "starting");
                    735: }
                    736: 
                    737: /*    ERRORS */
                    738: 
                    739: #ifndef lint
                    740: static void    adios (va_alist)
                    741: va_dcl
                    742: {
                    743:     va_list ap;
                    744: 
                    745:     va_start (ap);
                    746: 
                    747:     _ll_log (pgm_log, LLOG_FATAL, ap);
                    748: 
                    749:     va_end (ap);
                    750: 
                    751:     _exit (1);
                    752: }
                    753: #else
                    754: /* VARARGS */
                    755: 
                    756: static void    adios (what, fmt)
                    757: char   *what,
                    758:        *fmt;
                    759: {
                    760:     adios (what, fmt);
                    761: }
                    762: #endif
                    763: 
                    764: 
                    765: #ifndef lint
                    766: static void    advise (va_alist)
                    767: va_dcl
                    768: {
                    769:     int     code;
                    770:     va_list ap;
                    771: 
                    772:     va_start (ap);
                    773: 
                    774:     code = va_arg (ap, int);
                    775: 
                    776:     _ll_log (pgm_log, code, ap);
                    777: 
                    778:     va_end (ap);
                    779: }
                    780: #else
                    781: /* VARARGS */
                    782: 
                    783: static void    advise (code, what, fmt)
                    784: char   *what,
                    785:        *fmt;
                    786: int     code;
                    787: {
                    788:     advise (code, what, fmt);
                    789: }
                    790: #endif
                    791: 

unix.superglobalmegacorp.com

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