Annotation of 43BSDReno/contrib/isode-beta/others/tsbridge/tsbridge.c, revision 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.