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

1.1       root        1: /* tp0bridge.c - TCP/X.25 TP0 bridge */
                      2: 
                      3: #ifndef        lint
                      4: static char *rcsid = "$Header: /f/osi/others/tp0bridge/RCS/tp0bridge.c,v 7.1 90/07/09 14:42:52 mrose Exp $";
                      5: #endif
                      6: 
                      7: /* 
                      8:  * $Header: /f/osi/others/tp0bridge/RCS/tp0bridge.c,v 7.1 90/07/09 14:42:52 mrose Exp $
                      9:  *
                     10:  * Contributed by Julian Onions, Nottingham University in the UK
                     11:  *
                     12:  *
                     13:  * $Log:       tp0bridge.c,v $
                     14:  * Revision 7.1  90/07/09  14:42:52  mrose
                     15:  * sync
                     16:  * 
                     17:  * Revision 7.0  89/11/23  22:11:02  mrose
                     18:  * Release 6.0
                     19:  * 
                     20:  */
                     21: 
                     22: /*
                     23:  *                               NOTICE
                     24:  *
                     25:  *    Acquisition, use, and distribution of this module and related
                     26:  *    materials are subject to the restrictions of a license agreement.
                     27:  *    Consult the Preface in the User's Manual for the full terms of
                     28:  *    this agreement.
                     29:  *
                     30:  */
                     31: 
                     32: 
                     33: #include <signal.h>
                     34: #include <stdio.h>
                     35: #include <varargs.h>
                     36: #include "tpkt.h"
                     37: #include <sys/ioctl.h>
                     38: #ifdef BSD42
                     39: #include <sys/file.h>
                     40: #endif
                     41: #ifdef SYS5
                     42: #include <fcntl.h>
                     43: #endif
                     44: #include "internet.h"
                     45: #include "x25.h"
                     46: #include "logger.h"
                     47: #include "tailor.h"
                     48: 
                     49: /*  */
                     50: 
                     51: static int debug = 0;
                     52: static int options = 0;
                     53: static int  nbits = FD_SETSIZE;
                     54: 
                     55: static LLog _pgm_log = {
                     56:     "tp0bridge.log", NULLCP, NULLCP,
                     57:     LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, LLOG_FATAL, -1,
                     58:     LLOGCLS | LLOGCRT | LLOGZER, NOTOK
                     59: };
                     60: LLog *pgm_log = &_pgm_log;
                     61: 
                     62: static char *myname = "tp0bridge";
                     63: static char myhost[64];
                     64: 
                     65: static char *myprotocol = "tcp";
                     66: static char *myservice = "x25bridge";
                     67: 
                     68: static int     tcp_fd;
                     69: static int      nfds;
                     70: static fd_set  ifds;
                     71: static struct sockaddr_in   main_in_socket;
                     72: static struct sockaddr_in  *mainisock = &main_in_socket;
                     73: static struct sockaddr_in   emptyaddr;
                     74: 
                     75: static fd_set  sentinel;
                     76: static int     sent2list[FD_SETSIZE];
                     77: static int     list2sent[FD_SETSIZE];
                     78: static struct sockaddr_in   callbacks[FD_SETSIZE];
                     79: #ifdef CAMTEC
                     80: static struct NSAPaddr             listens[FD_SETSIZE];
                     81: #define        FORK_LISTENER           /* new process per listener */
                     82: #endif
                     83: 
                     84: 
                     85: void   abortfd (), shuffle ();
                     86: void   adios (), advise ();
                     87: #ifdef BSD42
                     88: int    chldser ();
                     89: #else
                     90: int    alrmser ();
                     91: #endif
                     92: 
                     93: 
                     94: extern int  errno;
                     95: 
                     96: /*  */
                     97: 
                     98: /* ARGSUSED */
                     99: 
                    100: main (argc, argv, envp)
                    101: int    argc;
                    102: char  **argv,
                    103:       **envp;
                    104: {
                    105:     int     fd;
                    106:     fd_set  mask;
                    107: 
                    108:     arginit (argv);
                    109:     envinit ();
                    110: 
                    111:     nfds = 0;
                    112:     FD_ZERO (&ifds);
                    113:     FD_ZERO (&sentinel);
                    114: 
                    115:     if ((tcp_fd = start_tcp_server (mainisock, SOMAXCONN, options & SO_DEBUG
                    116:                    ? SO_DEBUG : 0, 0)) == NOTOK)
                    117:        adios ("failed", "start_tcp_server");
                    118:     FD_SET (tcp_fd, &ifds);
                    119:     if (tcp_fd >= nfds)
                    120:        nfds = tcp_fd + 1;
                    121: 
                    122: #ifdef BSD42
                    123:     (void) signal (SIGCHLD, chldser);
                    124: #endif
                    125: 
                    126:     for (;;) {
                    127:        mask = ifds;
                    128: 
                    129: #ifdef CAMTEC
                    130:        /* due to problems in select when camtec is enabled, a small
                    131:           timeout is given. This should not affect anything I hope.
                    132:          */
                    133:        (void) xselect (nfds, &mask, NULLFD, NULLFD, 1);
                    134: #else
                    135:        (void) xselect (nfds, &mask, NULLFD, NULLFD, NOTOK);
                    136: #endif
                    137: 
                    138:        for (fd = 0; fd < nbits; fd++)
                    139:            if (FD_ISSET (fd, &mask)) {
                    140:                if (fd == tcp_fd)
                    141:                    do_new_fd ();
                    142:                else if (FD_ISSET (fd, &sentinel))
                    143:                    abortfd (fd);
                    144:                else
                    145:                    do_old_fd (fd);
                    146:            }
                    147: 
                    148: #ifndef        BSD42
                    149:        while (mywait3 (NULLIP) != NOTOK)
                    150:            continue;
                    151: #endif
                    152:     }
                    153: }
                    154: 
                    155: /*  */
                    156: 
                    157: static do_new_fd ()
                    158: {
                    159:     int     fd;
                    160:     char    c;
                    161:     struct sockaddr_in zosock;
                    162:     struct sockaddr_in *osock = & zosock;
                    163:        
                    164:     if ((fd = join_tcp_client (tcp_fd, osock)) == NOTOK) {
                    165:        if (errno != EINTR)
                    166:            advise (LLOG_EXCEPTIONS, "failed", "join_tcp_client");
                    167:        return;
                    168:     }
                    169: 
                    170:     if (read_tcp_socket (fd, &c, 1) != 1) {
                    171:        advise (LLOG_EXCEPTIONS, "failed", "initial read_tcp_socket");
                    172:        goto out;
                    173:     }
                    174: 
                    175:     switch (c) {
                    176:        case 1:
                    177: #ifdef DEBUG
                    178:            advise (LLOG_DEBUG, NULLCP, "outgoing connection");
                    179: #endif
                    180:            switch (fork ()) {
                    181:                case OK: 
                    182:                    do_outgoing (fd);
                    183:                    _exit (1);          /* NOTREACHED */
                    184: 
                    185:                case NOTOK: 
                    186:                    advise (LLOG_EXCEPTIONS, "TCP socket",
                    187:                            "no forks, so rejecting connection on");
                    188:                default: 
                    189:                    (void) close_tcp_socket (fd);
                    190: #ifdef EXOS
                    191:                    FD_CLR (tcp_fd, &ifds);
                    192:                    if ((tcp_fd = start_tcp_server (isock, SOMAXCONN,
                    193:                                    options & SO_DEBUG ? SO_DEBUG : 0, 0))
                    194:                            == NOTOK)
                    195:                        adios ("failed", "start_tcp_server");
                    196:                    FD_SET (tcp_fd, &ifds);
                    197:                    if (tcp_fd >= nfds)
                    198:                        nfds = tcp_fd + 1;
                    199: #endif
                    200:                    break;
                    201:            }
                    202:            break;
                    203: 
                    204:        case 2:
                    205: #ifdef DEBUG
                    206:            advise (LLOG_DEBUG, NULLCP, "setup listen address");
                    207: #endif
                    208:            do_listen (fd);
                    209:            break;
                    210: 
                    211:        default:
                    212:            advise (LLOG_NOTICE, NULLCP, "unknown dialogue mode 0x%x", c);
                    213:     out:    ;
                    214:            (void) close_tcp_socket (fd);
                    215:            break;
                    216: 
                    217:     }
                    218: }
                    219: 
                    220: /*  */
                    221: 
                    222: static do_outgoing (fd)
                    223: int    fd;
                    224: {
                    225:     int                sd;
                    226:     struct NSAPaddr    znsap;
                    227:     register struct NSAPaddr *nsap = &znsap;
                    228: 
                    229: #ifdef SOCKETS
                    230:     (void) close_tcp_socket (tcp_fd);
                    231: #endif
                    232:     for (sd = 0; sd < nbits; sd++)
                    233:        if (sd != fd && FD_ISSET (sd, &ifds))
                    234:            (void) close (sd);
                    235: #ifdef BSD42
                    236:     (void) signal (SIGCHLD, SIG_DFL);
                    237: #endif
                    238: 
                    239:     (void) ll_close (pgm_log);
                    240: 
                    241:     if (bridge_read_nsap_addr (fd, nsap, read_tcp_socket) == NOTOK)
                    242:        adios ("failed", "read of NSAP");
                    243: 
                    244:     switch (nsap -> na_stack) {
                    245:         case NA_BRG:
                    246:            nsap -> na_stack = NA_X25;  /* we use real X.25 here */
                    247:            break;
                    248:        case NA_X25:
                    249:            break;
                    250:        case NA_NSAP:
                    251:        case NA_TCP:
                    252:        default:
                    253:            adios (NULLCP, "Addressing style not supported (type %d)",
                    254:                   nsap -> na_stack);
                    255:            break;
                    256:     }
                    257:        
                    258: #ifdef DEBUG
                    259:     advise(LLOG_DEBUG, NULLCP, "x25 call on to %*s\n",
                    260:           nsap->na_dtelen, nsap->na_dte);
                    261: #endif
                    262:     if ((sd = start_x25_client (nsap)) == NOTOK)
                    263:        adios ("failed", "start_x25_client");
                    264: 
                    265:     if (join_x25_server (sd, nsap) == NOTOK)
                    266:        adios ("failed", "join_x25_server");
                    267: 
                    268:     transfer (sd, fd);
                    269: }
                    270: 
                    271: /*  */
                    272: 
                    273: static do_listen (fd)
                    274: int    fd;
                    275: {
                    276:     struct sockaddr_in  in_socket;
                    277:     register struct sockaddr_in *isock = &in_socket;
                    278:     struct NSAPaddr    znsap;
                    279:     register struct NSAPaddr *nsap = &znsap;
                    280:     int                newfd;
                    281: 
                    282:     if (bridge_read_nsap_addr (fd, nsap, read_tcp_socket) == NOTOK) {
                    283:        advise (LLOG_EXCEPTIONS, "failed", "read of NSAP");
                    284:        goto out;
                    285:     }
                    286:     switch (nsap -> na_stack) {
                    287:         case NA_BRG:
                    288:            nsap -> na_stack = NA_X25;  /* we use real X.25 here */
                    289:            break;
                    290:        case NA_X25:
                    291:            break;
                    292:        case NA_NSAP:
                    293:        case NA_TCP:
                    294:        default:
                    295:            adios (NULLCP, "Addressing style not supported (type %d)",
                    296:                   nsap -> na_stack);
                    297:            break;
                    298:     }
                    299: 
                    300: #ifdef DEBUG
                    301:     advise (LLOG_DEBUG, NULLCP, "type=%d Listening on '%s' len=%d",
                    302:            nsap -> na_stack, nsap -> na_dte, nsap -> na_dtelen);
                    303:     advise (LLOG_DEBUG, NULLCP, "pid='%s'(%d) fac='%s'(%d) cudf='%s'(%d)",
                    304:            nsap -> na_pid, nsap -> na_pidlen,
                    305:            nsap -> na_fac, nsap -> na_faclen,
                    306:            nsap -> na_pid, nsap -> na_pidlen,
                    307:            nsap -> na_cudf, nsap -> na_cudflen);
                    308: #endif
                    309:     if (readx (fd, (char *) isock, sizeof *isock, read_tcp_socket)
                    310:        != sizeof *isock) {
                    311:        advise (LLOG_EXCEPTIONS, "failed",
                    312:                "read_tcp_socket of sockaddr_in");
                    313:        goto out;
                    314:     }
                    315:     isock -> sin_family = ntohs (isock -> sin_family);
                    316: 
                    317: #ifdef FORK_LISTENER
                    318:     switch (fork ()) {
                    319:        case OK:
                    320:        {
                    321:            int i;
                    322: 
                    323:            for (i = 0; i < nbits; i++)
                    324:                if (i != fd && FD_ISSET (i, &ifds))
                    325:                    (void) close (i);
                    326:            break;
                    327:        }
                    328:        case NOTOK: 
                    329:            advise (LLOG_EXCEPTIONS, "X25 socket",
                    330:                    "no forks, so rejecting listen on");
                    331:        default: 
                    332:            (void) close_tcp_socket (fd);
                    333:            return;
                    334:     }
                    335:        /* more from the 'stamp out boring names' committee */
                    336: #define iso_defining_new_protocols 1
                    337:     while (iso_defining_new_protocols)
                    338:     {
                    339: #endif
                    340:     if ((newfd = start_x25_server (nsap, SOMAXCONN, options & SO_DEBUG
                    341:                    ? SO_DEBUG : 0, 0)) == NOTOK) {
                    342:        advise (LLOG_EXCEPTIONS, "failed", "start_x25_server");
                    343: #ifdef FORK_LISTENER
                    344:        _exit (0);
                    345: #endif
                    346:        return;
                    347:     }
                    348: #ifdef CAMTEC
                    349:     listens[newfd] = *nsap;    /* struct copy */
                    350: #endif
                    351:     callbacks[newfd] = *isock; /* struct copy */
                    352: 
                    353:     /* set up the admin stuff */
                    354:     FD_SET (newfd, &ifds);     /* listen for new connections */
                    355:     FD_SET (fd, &ifds);                /* listen for problems */
                    356:     FD_SET (fd, &sentinel);
                    357:     sent2list[fd] = newfd;
                    358:     list2sent[newfd] = fd;
                    359:     if (newfd >= nfds)
                    360:        nfds = newfd + 1;
                    361: #ifdef FORK_LISTENER
                    362:     do_old_fd (newfd);
                    363:     (void) close (newfd);
                    364:     } /* loop again */
                    365: #endif
                    366:     return;
                    367: 
                    368: out: ;
                    369:     (void) close_tcp_socket (fd);
                    370: }
                    371: 
                    372: 
                    373: /*  */
                    374: 
                    375: static do_old_fd (fd)
                    376: int    fd;
                    377: {
                    378:     int            sd;
                    379:     register struct sockaddr_in *isock = &callbacks[fd];
                    380:     struct NSAPaddr    znsap;
                    381:     register struct NSAPaddr *nsap = &znsap;
                    382: 
                    383: #ifdef DEBUG
                    384:     advise (LLOG_DEBUG, NULLCP, "callback");
                    385: #endif
                    386:     if (isock == NULL || isock -> sin_family != AF_INET) {
                    387:        advise (LLOG_EXCEPTIONS, NULLCP, "Callback has bogus address");
                    388:        return;
                    389:     }
                    390: 
                    391:     if ((sd = join_x25_client (fd, nsap)) == NOTOK) {
                    392:        if (errno != EINTR) {
                    393:            advise (LLOG_EXCEPTIONS, "failed", "join_x25_client");
                    394:            abortfd (list2sent[fd]);
                    395:        }
                    396:        return;
                    397:     }
                    398: #ifdef DEBUG
                    399:     advise (LLOG_DEBUG, NULLCP, "type=%d Accepted '%s' len=%d",
                    400:            nsap -> na_stack, nsap -> na_dte, nsap -> na_dtelen);
                    401:     advise (LLOG_DEBUG, NULLCP, "pid='%s'(%d) fac='%s'(%d) cudf='%s'(%d)",
                    402:            nsap -> na_pid, nsap -> na_pidlen,
                    403:            nsap -> na_fac, nsap -> na_faclen,
                    404:            nsap -> na_pid, nsap -> na_pidlen,
                    405:            nsap -> na_cudf, nsap -> na_cudflen);
                    406: #endif
                    407:     nsap -> na_stack = NA_BRG;
                    408: 
                    409: #ifdef CAMTEC
                    410:        /* get back addressing info for this fd into nsap
                    411:         */
                    412:        nsap = &listens[fd];
                    413: #endif
                    414: 
                    415:     switch (fork ()) {
                    416:        case OK: 
                    417:            break;
                    418: 
                    419:        case NOTOK: 
                    420:            advise (LLOG_EXCEPTIONS, "X.25 socket",
                    421:                    "no forks, so rejecting connection on");
                    422:        default: 
                    423:            (void) close (sd);
                    424:            return;
                    425:     }
                    426: 
                    427: #ifndef        CAMTEC
                    428:     (void) close (fd);
                    429: #endif
                    430:     for (fd = 0; fd < nbits; fd++)
                    431:        if (fd != sd && FD_ISSET (fd, &ifds))
                    432:            (void) close (fd);
                    433: #ifdef BSD42
                    434:     (void) signal (SIGCHLD, SIG_DFL);
                    435: #endif
                    436: 
                    437:     (void) ll_close (pgm_log);
                    438: 
                    439: #ifdef DEBUG
                    440:     advise (LLOG_DEBUG, NULLCP, "connecting to %s", inet_ntoa (isock -> sin_addr));
                    441:     advise (LLOG_DEBUG, NULLCP, "port=%d", (int) ntohs (isock -> sin_port));
                    442: #endif
                    443: 
                    444:     if ((fd = start_tcp_client ((struct sockaddr_in *) NULL, 0)) == NOTOK)
                    445:        adios ("failed", "start_tcp_client");
                    446:     if (join_tcp_server (fd, isock) == NOTOK)
                    447:        adios ("failed", "join_tcp_server");
                    448: 
                    449:     if (bridge_write_nsap_addr (fd, nsap, write_tcp_socket) == NOTOK)
                    450:        adios ("failed", "write of NSAP");
                    451: 
                    452:     transfer (sd, fd);
                    453:     _exit (1);         /* NOTREACHED */
                    454: }
                    455: 
                    456: /*  */
                    457: 
                    458: static transfer (sd, fd)
                    459: int    sd,
                    460:        fd;
                    461: {
                    462:     int            mfds;
                    463:     fd_set  rfds,
                    464:             mask;
                    465:     struct tsapblk *tcpb,
                    466:                    *x25b;
                    467: 
                    468:     FD_ZERO (&rfds);
                    469:     mfds = (sd > fd ? sd : fd) + 1;
                    470:     FD_SET (sd, &rfds);
                    471:     FD_SET (fd, &rfds);
                    472: 
                    473:     if ((tcpb = newtblk ()) == NULL)
                    474:        adios (NULLCP, "out of memory");
                    475:     tcpb -> tb_fd = fd;
                    476:     (void) TTService (tcpb);
                    477: 
                    478:     if ((x25b = newtblk ()) == NULL)
                    479:        adios (NULLCP, "out of memory");
                    480:     x25b -> tb_fd = sd;
                    481:     (void) XTService (x25b);
                    482: 
                    483: #ifndef        CAMTEC
                    484:     for (;;) {
                    485:        mask = rfds;
                    486:        if (xselect (mfds, &mask, NULLFD, NULLFD, NOTOK) == NOTOK)
                    487:            adios ("failed", "xselect");
                    488:        if (FD_ISSET (sd, &mask))
                    489:            shuffle (x25b, tcpb);
                    490:        if (FD_ISSET (fd, &mask))
                    491:            shuffle (tcpb, x25b);
                    492:     }
                    493: #else
                    494:     for (;;) {
                    495:        FD_ZERO (&mask);
                    496:        mfds = fd + 1;
                    497:        FD_SET (fd, &mask);
                    498:        if (xselect (mfds, &mask, NULLFD, NULLFD, 1) == NOTOK)
                    499:            adios ("failed", "xselect tcp");
                    500:        if (FD_ISSET (fd, &mask)) {
                    501:            advise (LLOG_DEBUG, NULLCP, "tcp -> x25");
                    502:            shuffle (tcpb, x25b);
                    503:        }
                    504: 
                    505:        FD_ZERO (&mask);
                    506:        mfds = sd + 1;
                    507:        FD_SET (sd, &mask);
                    508:        if (xselect (mfds, &mask, NULLFD, NULLFD, 1) == NOTOK)
                    509:            adios ("failed", "xselect x25");
                    510:        if (FD_ISSET (sd, &mask)) {
                    511:            advise (LLOG_DEBUG, NULLCP, "x25 -> tcp");
                    512:            shuffle (x25b, tcpb);
                    513:        }
                    514:     }
                    515: #endif
                    516: }
                    517: 
                    518: /*  */
                    519: 
                    520: static void    shuffle (from, to)
                    521: register struct tsapblk *from,
                    522:                        *to;
                    523: {
                    524:     register struct udvec  *uv;
                    525:     register struct tsapkt *t;
                    526: 
                    527:     if ((t = fd2tpkt (from -> tb_fd, from -> tb_initfnx, from -> tb_readfnx))
                    528:            == NULL || t -> t_errno != OK)
                    529:        adios (NULLCP, "fd2tpkt failed (%d)", t ? t -> t_errno : NOTOK);
                    530: #ifdef DEBUG
                    531:     advise (LLOG_DEBUG, NULLCP, "read: code=0x%x user len=%d",
                    532:            TPDU_CODE (t), t -> t_qbuf ? t -> t_qbuf -> qb_len : 0);
                    533: #endif
                    534: 
                    535:     uv = t -> t_udvec;
                    536:     if (t -> t_qbuf) {
                    537:        uv -> uv_base = t -> t_qbuf -> qb_data;
                    538:        uv -> uv_len = t -> t_qbuf -> qb_len;
                    539:        uv++;
                    540:     }
                    541:     uv -> uv_base = NULL;
                    542: 
                    543:     if (tpkt2fd (to -> tb_fd, t, to -> tb_writefnx) == NOTOK)
                    544:        adios (NULLCP, "tpkt2fd failed (%d)", t -> t_errno);
                    545: 
                    546:     freetpkt (t);
                    547: }
                    548: 
                    549: static void    abortfd (fd)
                    550: int    fd;
                    551: {
                    552:     int        assocfd = sent2list[fd];        /* get fd that is listening on */
                    553: 
                    554: #ifdef DEBUG
                    555:     advise (LLOG_DEBUG, NULLCP, "Shutdown listen (%d,%d)", fd, assocfd);
                    556: #endif
                    557:     FD_CLR (fd, &sentinel);
                    558:     FD_CLR (fd, &ifds);
                    559:     FD_CLR (assocfd, &ifds);
                    560:     (void) close_tcp_socket (fd);
                    561:     (void) close_x25_socket (assocfd);
                    562:     sent2list[fd] = -1;
                    563:     list2sent[assocfd] = -1;
                    564:     callbacks[assocfd] = emptyaddr;    /* struct copy */
                    565: }
                    566: 
                    567: /*  */
                    568: 
                    569: static arginit (vec)
                    570: char   **vec;
                    571: {
                    572:     int            port;
                    573:     register char  *ap;
                    574:     struct hostent *hp;
                    575:     struct servent *sp;
                    576: 
                    577:     if (myname = rindex (*vec, '/'))
                    578:        myname++;
                    579:     if (myname == NULL || *myname == NULL)
                    580:        myname = *vec;
                    581: 
                    582:     isodetailor (myname, 0);
                    583:     ll_hdinit (pgm_log, myname);
                    584: 
                    585:     (void) gethostname (myhost, sizeof myhost);
                    586:     if (hp = gethostbyname (myhost))
                    587:        (void) strcpy (myhost, hp -> h_name);
                    588: 
                    589:     if ((sp = getservbyname (myservice, myprotocol)) == NULL)
                    590:        mainisock -> sin_port = x25_bridge_port;
                    591:     else
                    592:        mainisock -> sin_port = sp -> s_port;   
                    593:     mainisock -> sin_family = AF_INET;
                    594:     mainisock -> sin_addr.s_addr = INADDR_ANY;
                    595:     if ((nbits = getdtablesize ()) > FD_SETSIZE)
                    596:        nbits = FD_SETSIZE;
                    597: 
                    598:     for (vec++; ap = *vec; vec++) {
                    599:        if (*ap == '-')
                    600:            switch (*++ap) {
                    601:                case 'd':
                    602:                    debug++;
                    603:                    continue;
                    604: 
                    605:                case 'p': 
                    606:                    if ((ap = *++vec) == NULL
                    607:                            || *ap == '-'
                    608:                            || (port = atoi (ap)) <= 0)
                    609:                        adios (NULLCP, "usage: %s -p portno", myname);
                    610:                    mainisock -> sin_port = htons ((u_short) port);
                    611:                    continue;
                    612: 
                    613:                default: 
                    614:                    adios (NULLCP, "-%s: unknown switch", ap);
                    615:            }
                    616: 
                    617:        adios (NULLCP, "usage: %s [switches]", myname);
                    618:     }
                    619: }
                    620: 
                    621: /*  */
                    622: 
                    623: static  envinit () {
                    624:     int     i,
                    625:             sd;
                    626: 
                    627:     if (debug == 0 && !(debug = isatty (2))) {
                    628:        for (i = 0; i < 5; i++) {
                    629:            switch (fork ()) {
                    630:                case NOTOK: 
                    631:                    sleep (5);
                    632:                    continue;
                    633: 
                    634:                case OK: 
                    635:                    break;
                    636: 
                    637:                default: 
                    638:                    _exit (0);
                    639:            }
                    640:            break;
                    641:        }
                    642: 
                    643:        (void) chdir ("/");
                    644: 
                    645:        if ((sd = open ("/dev/null", O_RDWR)) == NOTOK)
                    646:            adios ("/dev/null", "unable to read");
                    647:        if (sd != 0)
                    648:            (void) dup2 (sd, 0), (void) close (sd);
                    649:        (void) dup2 (0, 1);
                    650:        (void) dup2 (0, 2);
                    651: 
                    652: #ifdef SETSID
                    653:        if (setsid () == NOTOK)
                    654:            advise (LLOG_EXCEPTIONS, "failed", "setsid");
                    655: #endif
                    656: #ifdef TIOCNOTTY
                    657:        if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) {
                    658:            (void) ioctl (sd, TIOCNOTTY, NULLCP);
                    659:            (void) close (sd);
                    660:        }
                    661: #endif
                    662:     }
                    663:     else {
                    664:        options |= SO_DEBUG;
                    665:        ll_dbinit (pgm_log, myname);
                    666:     }
                    667: 
                    668: #ifndef        sun             /* damn YP... */
                    669:     for (sd = 3; sd < nbits; sd++)
                    670:        if (pgm_log -> ll_fd != sd)
                    671:            (void) close (sd);
                    672: #endif
                    673: 
                    674:     (void) signal (SIGPIPE, SIG_IGN);
                    675: 
                    676:     ll_hdinit (pgm_log, myname);
                    677:     advise (LLOG_NOTICE, NULLCP, "starting");
                    678: #ifdef DEBUG
                    679:     advise (LLOG_DEBUG, NULLCP, "options=0x%x port=%d",
                    680:            options, ntohs (mainisock -> sin_port));
                    681: #endif
                    682: }
                    683: 
                    684: /*    Berkeley UNIX: 4.2 */
                    685: 
                    686: #ifdef BSD42
                    687: 
                    688: #include <sys/wait.h>
                    689: 
                    690: /* ARGSUSED */
                    691: 
                    692: static int  chldser (sig, code, sc)
                    693: int    sig;
                    694: long    code;
                    695: struct sigcontext *sc;
                    696: {
                    697:     union wait status;
                    698: 
                    699:     while (wait3 (&status, WNOHANG, (struct rusage *) NULL) > 0)
                    700:        continue;
                    701: }
                    702: 
                    703: #else
                    704: 
                    705: /*    AT&T UNIX: 5 */
                    706: 
                    707: #include <setjmp.h>
                    708: 
                    709: #define        WAITSECS        ((unsigned) 2)
                    710: 
                    711: 
                    712: static jmp_buf jmpenv;
                    713: 
                    714: 
                    715: /* ARGSUSED */
                    716: 
                    717: static int  alrmser (sig)
                    718: int    sig;
                    719: {
                    720:      (void) signal (SIGALRM, alrmser);
                    721: 
                    722:      longjmp (jmpenv, NOTOK);
                    723: }
                    724: 
                    725: 
                    726: static int  mywait3 (status)
                    727: int    *status;
                    728: {
                    729:     int     result;
                    730: 
                    731:     switch (setjmp (jmpenv)) {
                    732:        case OK:
                    733:             (void) signal (SIGALRM, alrmser);
                    734:             (void) alarm (WAITSECS);
                    735:             result = wait (status);
                    736:             (void) alarm (0);
                    737:             break;
                    738: 
                    739:        default:
                    740:             result = NOTOK;
                    741:             break;
                    742:      }
                    743: 
                    744:     return result;
                    745: }
                    746: #endif
                    747: 
                    748: /*  */
                    749: 
                    750: static int  readx (fd, buffer, n, readfnx)
                    751: int     fd;
                    752: char    *buffer;
                    753: int     n;
                    754: IFP     readfnx;
                    755: {
                    756:     register int    i,
                    757:     cc;
                    758:     register char   *bp;
                    759: 
                    760:     for (bp = buffer, i = n; i > 0; bp += cc, i -= cc) {
                    761:        switch (cc = (*readfnx) (fd, bp, i)) {
                    762:            case NOTOK:
                    763:                return (i = bp - buffer) ? i : NOTOK;
                    764: 
                    765:            case OK:
                    766:                break;
                    767: 
                    768:            default:
                    769:                continue;
                    770:        }
                    771:        break;
                    772:     }
                    773: 
                    774:     return (bp - buffer);
                    775: }
                    776: 
                    777: /*    ERRORS */
                    778: 
                    779: #ifndef        lint
                    780: void   adios (va_alist)
                    781: va_dcl
                    782: {
                    783:     va_list ap;
                    784: 
                    785:     va_start (ap);
                    786:     
                    787:     _ll_log (pgm_log, LLOG_FATAL, ap);
                    788: 
                    789:     va_end (ap);
                    790: 
                    791:     _exit (1);
                    792: }
                    793: #else
                    794: /* VARARGS */
                    795: 
                    796: void   adios (what, fmt)
                    797: char   *what,
                    798:        *fmt;
                    799: {
                    800:     adios (what, fmt);
                    801: }
                    802: #endif
                    803: 
                    804: 
                    805: #ifndef        lint
                    806: void   advise (va_alist)
                    807: va_dcl
                    808: {
                    809:     int            code;
                    810:     va_list ap;
                    811: 
                    812:     va_start (ap);
                    813:     
                    814:     code = va_arg (ap, int);
                    815: 
                    816:     _ll_log (pgm_log, code, ap);
                    817: 
                    818:     va_end (ap);
                    819: }
                    820: #else
                    821: /* VARARGS */
                    822: 
                    823: void   advise (code, what, fmt)
                    824: char   *what,
                    825:        *fmt;
                    826: int    code;
                    827: {
                    828:     advise (code, what, fmt);
                    829: }
                    830: #endif

unix.superglobalmegacorp.com

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