Annotation of 43BSDTahoe/new/xns/examples/gap/gap2d.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char RCSid[] = "$Header: gap2d.c,v 2.0 85/11/21 07:23:00 jqj Exp $";
                      3: #endif
                      4: /*
                      5:  * server for GAP-style (TransportObject=server,teletype) telnet connections
                      6:  * Note that we support only GAP version 2, although a server for version 3
                      7:  * exists.  The version 2 server has not been tested as thoroughly as has the
                      8:  * version 3; it does NOT support RESERVE functionality.
                      9:  */
                     10: 
                     11: /* $Log:       gap2d.c,v $
                     12:  * Revision 2.0  85/11/21  07:23:00  jqj
                     13:  * 4.3BSD standard release
                     14:  * 
                     15:  * Revision 1.2  85/05/23  06:22:18  jqj
                     16:  * *** empty log message ***
                     17:  * 
                     18:  * Revision 1.2  85/05/23  06:22:18  jqj
                     19:  * *** empty log message ***
                     20:  * 
                     21:  * Revision 1.1  85/05/22  09:46:52  jqj
                     22:  * Initial revision
                     23:  */
                     24: #include <stdio.h>
                     25: #include <signal.h>
                     26: #include <sgtty.h>
                     27: #include <sys/types.h>
                     28: #include <sys/time.h>
                     29: #include <sys/uio.h>
                     30: #include <sys/socket.h>
                     31: #include <netns/ns.h>
                     32: #include <netns/idp.h>
                     33: #include <netns/sp.h>
                     34: #include <sys/wait.h>
                     35: #include <xnscourier/realcourierconnection.h>
                     36: #include "GAP2.h"
                     37: #include "gapcontrols.h"
                     38: #include <xnscourier/except.h>
                     39: #include <errno.h>
                     40: 
                     41: #define        BELL    '\07'
                     42: #define BANNER "\r\n\r\n4.3 BSD UNIX (%s)\r\n\r\r\n\r%s"
                     43: 
                     44: int pty, net;
                     45: extern CourierConnection *_serverConnection;
                     46: char buf[sizeof(struct sphdr)+SPPMAXDATA];
                     47: struct sphdr our_sphdr;
                     48: struct iovec our_iovec[2] = {{((caddr_t)&our_sphdr), sizeof(our_sphdr)}};
                     49: /*
                     50:  * I/O data buffers, pointers, and counters.
                     51:  */
                     52: char   ptyibuf[512], *ptyip = ptyibuf;
                     53: char   ptyobuf[BUFSIZ], *pfrontp = ptyobuf, *pbackp = ptyobuf;
                     54: char   *netip = buf;
                     55: char   netobuf[512], *nfrontp = netobuf, *nbackp = netobuf;
                     56: int    pcc, ncc;
                     57: char   line[12];
                     58: extern char **environ;
                     59: extern int errno;
                     60: 
                     61: char *envinit[3];
                     62: char wsenv[50];
                     63: 
                     64: /*
                     65:  * session parameters
                     66:  */
                     67: Cardinal frametimeout;         /* 0 or time in seconds to wait */
                     68: 
                     69: 
                     70: /*
                     71:  * This modified version of the server is necessary since GAP specifies
                     72:  * that the telnet data-transfer session occurs after the RPC to create
                     73:  * it has returned!
                     74:  */
                     75: Server(skipcount,skippedwords)
                     76:        int skipcount;
                     77:        Unspecified skippedwords[];
                     78: {
                     79:        Cardinal _procedure;
                     80:        register Unspecified *_buf;
                     81:        LongCardinal programnum;
                     82:        Cardinal versionnum;
                     83:        Cardinal _n;
                     84: 
                     85: #ifdef DEBUG
                     86:        BUGOUT("Server: %d %d",skipcount,skippedwords);
                     87: #endif
                     88:        for (;;) {
                     89:                _buf = ReceiveCallMessage(&_procedure, skipcount, skippedwords);
                     90:                DURING switch (_procedure) {
                     91:                case 3:
                     92:                        server_GAP2_Delete(_buf);
                     93:                        break;
                     94:                case 2:
                     95:                        server_GAP2_Create(_buf);
                     96:                        net = _serverConnection->fd;
                     97:                        gaptelnet(); /* returns on connection close */
                     98:                        break;
                     99:                case 0:
                    100:                        server_GAP2_Reset(_buf);
                    101:                        break;
                    102:                default:
                    103:                        NoSuchProcedureValue("GAP", _procedure);
                    104:                        break;
                    105:                } HANDLER {
                    106:                    Deallocate(_buf);
                    107:                    switch (Exception.Code) {
                    108:                    case GAP2_terminalAddressInvalid:
                    109:                    case GAP2_terminalAddressInUse:
                    110:                    case GAP2_controllerDoesNotExist:
                    111:                    case GAP2_controllerAlreadyExists:
                    112:                    case GAP2_gapCommunicationError:
                    113:                    case GAP2_gapNotExported:
                    114:                    case GAP2_bugInGAPCode:
                    115:                    case GAP2_tooManyGateStreams:
                    116:                    case GAP2_inconsistentParams:
                    117:                    case GAP2_transmissionMediumUnavailable:
                    118:                    case GAP2_dialingHardwareProblem:
                    119:                    case GAP2_noDialingHardware:
                    120:                    case GAP2_badAddressFormat:
                    121:                    case GAP2_mediumConnectFailed:
                    122:                    case GAP2_illegalTransport:
                    123:                    case GAP2_noCommunicationHardware:
                    124:                    case GAP2_unimplemented:
                    125:                        _buf = Allocate(0);
                    126:                        SendAbortMessage(Exception.Code-ERROR_OFFSET, 0, _buf);
                    127:                        break;
                    128:                    default:
                    129:                        _buf = Allocate(0);
                    130:                        SendRejectMessage(unspecifiedError, 0, _buf);
                    131:                        break;
                    132:                    }
                    133:                } END_HANDLER;
                    134:                Deallocate(_buf);
                    135:                for (;;) {
                    136:                        skipcount = LookAheadCallMsg(&programnum, &versionnum,
                    137:                                        skippedwords);
                    138:                        if (skipcount < 0) return(0);   /* timed out */
                    139:                        if (programnum != 3 || versionnum != 2)
                    140:                                ExecCourierProgram(programnum, versionnum,
                    141:                                                skipcount, skippedwords);
                    142:                }  /* loop if can't exec that program */
                    143:        }
                    144: }
                    145: 
                    146: void
                    147: GAP2_Delete(session)
                    148:        GAP2_SessionHandle session; 
                    149: {
                    150: }
                    151: 
                    152: void
                    153: GAP2_Reset()
                    154: {
                    155: }
                    156: 
                    157: GAP2_CreateResults
                    158: GAP2_Create(conn, BDTproc, sessionparams, transports,
                    159:            createTimeout)
                    160:        CourierConnection *conn;
                    161:        int BDTproc;
                    162:        GAP2_SessionParameterObject sessionparams;
                    163:        struct {Cardinal length;
                    164:                GAP2_TransportObject *sequence;
                    165:        } transports;
                    166:        GAP2_WaitTime createTimeout;
                    167: {
                    168:        GAP2_CreateResults result;
                    169:        char *c1, *c2, *host;
                    170:        int t, pid;
                    171:        struct sgttyb b;
                    172:        char *xntoa(), *wsname();
                    173:        struct sockaddr_ns who;
                    174:        int whosize = sizeof(who);
                    175:        LongCardinal servicetype;
                    176:        GAP2_CommParamObject *cp;
                    177:        GAP2_Duplexity duplexity;       /* fullDuplex, halfDuplex */
                    178: 
                    179: #ifdef DEBUG
                    180:        BUGOUT("CREATE");
                    181: #endif
                    182:        switch (sessionparams.designator) {
                    183:        case ttyHost:
                    184:                frametimeout = sessionparams.ttyHost_case.frameTimeout/1000;
                    185:                /* could set other parameters here */
                    186:                break;
                    187:        default:
                    188:                raise(GAP2_unimplemented, 0);
                    189:                /*NOTREACHED*/
                    190:        }
                    191:        if (transports.length != 2) {
                    192:                raise(GAP2_illegalTransport);
                    193:                /*NOTREACHED*/
                    194:        }
                    195:        switch (transports.sequence[0].designator) {
                    196:        case rs232c:    /* maybe some day */
                    197:                cp = &transports.sequence[0].rs232c_case.commParams;
                    198:                if (cp->accessDetail.designator == directConn) {
                    199:                        duplexity = cp->duplex;
                    200:                        servicetype = 0; /* fake it */
                    201:                        break;
                    202:                }
                    203:                raise(GAP2_noCommunicationHardware, 0);
                    204:                /*NOTREACHED*/
                    205:        default:
                    206:                raise(GAP2_illegalTransport, 0);
                    207:                /*NOTREACHED*/
                    208:        }
                    209:        if (transports.sequence[1].designator != teletype)
                    210:          raise(GAP2_illegalTransport, 0);
                    211:        /* ignore createTimeout */
                    212:        /* ignore credentials and verifier */
                    213:        
                    214:        for (c1 = "pq"; *c1 != 0; c1++)
                    215:          for (c2 = "0123456789abcdef"; *c2 != 0; c2++) {
                    216:                  sprintf(line, "/dev/pty%c%c", *c1, *c2);
                    217:                  pty = open(line, 2);
                    218:                  if (pty < 0) continue;
                    219:                  line[strlen("/dev/")] = 't';
                    220:                  t = open(line, 2);
                    221:                  if (t > 0) goto gotpty;
                    222:                  close(pty);
                    223:          }
                    224:        raise(GAP2_tooManyGateStreams, 0);
                    225:        /*NOTREACHED*/
                    226:  gotpty:
                    227:        getpeername(_serverConnection->fd, &who, &whosize);
                    228:        host = wsname(who.sns_addr);
                    229: #ifdef DEBUG
                    230:        BUGOUT("gotpty <%s> %d <%s>",line, pty, host);
                    231: #endif
                    232:        ioctl(t, TIOCGETP, &b);
                    233:        b.sg_flags = CRMOD|XTABS|ANYP;
                    234:        ioctl(t, TIOCSETP, &b);
                    235:        ioctl(pty, TIOCGETP, &b);
                    236:        if (duplexity == fullduplex)
                    237:          b.sg_flags |= ECHO;
                    238:        else
                    239:          b.sg_flags &= ~ECHO;
                    240:        ioctl(pty, TIOCSETP, &b);
                    241:        /* we do the fork now so we can return failures as REPORTS */
                    242:        pid = fork();
                    243:        if (pid < 0) {
                    244:                close(pty); close(t);
                    245:                raise(GAP2_tooManyGateStreams, 0);
                    246:                /*NOTREACHED*/
                    247:        }
                    248:        else if (pid == 0) {    /* in the execed fork */
                    249:                sleep(1);       /* let parent get ready for us */
                    250:                close(_serverConnection->fd); /* close net */
                    251:                close(pty);
                    252:                dup2(t, 0);
                    253:                dup2(t, 1);
                    254:                dup2(t, 2);
                    255:                if (t > 2) close(t);
                    256:                envinit[0] = "TERM=network";
                    257:                (void)sprintf(wsenv, "WORKSTATION=%s", xntoa(who.sns_addr));
                    258:                envinit[1] = wsenv;
                    259:                envinit[2] = (char*) 0;
                    260: #ifdef DEBUG
                    261:                BUGOUT("about to exec /bin/login");
                    262: #endif
                    263:                execl("/bin/login","login", "-h", host, 0);
                    264: #ifdef DEBUG
                    265:                BUGOUT("exec of /bin/login failed");
                    266: #endif
                    267:                perror("/bin/login");
                    268:                exit(1);
                    269:                /*NOTREACHED*/
                    270:        }
                    271:        close(t);
                    272: #ifdef DEBUG
                    273:        BUGOUT("fork successful");
                    274: #endif
                    275:        result.session[0] = pid;
                    276:        return(result);
                    277: }
                    278: 
                    279: jmp_buf childdiedbuf;
                    280: 
                    281: /*
                    282:  * Main loop.  Select from pty and network, and
                    283:  * hand data to telnet receiver finite state machine.
                    284:  * Returns 0 on orderly shutdown, 1 on abnormal shutdown.
                    285:  */
                    286: gaptelnet()
                    287: {
                    288:        int on = 1;
                    289:        char hostname[32];
                    290:        int childdied();
                    291:        int ibits = 0, obits = 0;
                    292:        register int c;
                    293:        struct sphdr *si = (struct sphdr *)buf;
                    294:        static struct timeval timeout = {600,0};
                    295:        int keepalives = 0;
                    296:        int i;
                    297: 
                    298: #ifdef DEBUG
                    299:        BUGOUT("gaptelnet net=%d,pty=%d",net,pty);
                    300: #endif
                    301:        if (setjmp(childdiedbuf) != 0)
                    302:          return(0);            /* child died */
                    303:        signal(SIGCHLD, childdied);
                    304:        signal(SIGTSTP, SIG_IGN);
                    305:        ioctl(net, FIONBIO, &on);
                    306:        ioctl(pty, FIONBIO, &on);
                    307: 
                    308: 
                    309:        /*
                    310:         * Show banner that getty never gave.
                    311:         */
                    312:        gethostname(hostname, sizeof (hostname));
                    313:        sprintf(nfrontp, BANNER, hostname, "");
                    314:        nfrontp += strlen(nfrontp);
                    315:        /*
                    316:         * Send status message indicating we're ready to go
                    317:         */
                    318:        changeSPPopts(net, GAPCTLnone, 1);
                    319:        sendoobdata(GAPCTLmediumUp);
                    320:        for (;;) {
                    321: #ifdef DEBUG
                    322:                BUGOUT("looping in gaptelnet");
                    323: #endif
                    324:                ibits = obits = 0;
                    325:                /*
                    326:                 * Never look for input if there's still
                    327:                 * stuff in the corresponding output buffer
                    328:                 */
                    329:                if (nfrontp - nbackp || pcc > 0)
                    330:                        obits |= (1 << net);
                    331:                else
                    332:                        ibits |= (1 << pty);
                    333:                if (pfrontp - pbackp || ncc > 0)
                    334:                        obits |= (1 << pty);
                    335:                else
                    336:                        ibits |= (1 << net);
                    337:                if (ncc < 0 && pcc < 0)
                    338:                        break;
                    339:                timeout.tv_sec = 600;
                    340:                timeout.tv_usec = 0;
                    341:                select(16, &ibits, &obits, 0, &timeout);
                    342:                if (ibits == 0 && obits == 0) {
                    343:                        /* timeout means no activity for a long time */
                    344: #ifdef DEBUG
                    345:                        BUGOUT("timeout from select");
                    346: #endif
                    347:                        if (keepalives++ < 2) {
                    348:                          /* first 2 times through send warning */
                    349:                                if (nfrontp == nbackp && pcc == 0) {
                    350:                                        /* but only if not blocked on output */
                    351: #define WARNING "\r\nYou've been idle much too long.  Respond or log off.\r\n"
                    352:                                        strcpy(nfrontp, WARNING);
                    353:                                        nfrontp += sizeof(WARNING);
                    354:                                }
                    355:                                sleep(5);
                    356:                                continue;
                    357:                        }
                    358: #ifdef DEBUG
                    359:                        BUGOUT("keepalive expired -- calling cleanup");
                    360: #endif
                    361:                        /* keepalive count has expired */
                    362:                        cleanup();
                    363:                        return(1);
                    364:                }
                    365: 
                    366:                /*
                    367:                 * Something to read from the network...
                    368:                 */
                    369:                if (ibits & (1 << net)) {
                    370:                        ncc = read(net, buf, sizeof(buf));
                    371: #ifdef DEBUG
                    372:                        BUGOUT("read from net %d",ncc);
                    373: #endif
                    374:                        if (ncc < 0 && errno == EWOULDBLOCK)
                    375:                                ncc = 0;
                    376:                        else if (ncc < sizeof(struct sphdr)) {
                    377: #ifdef DEBUG
                    378:                                BUGOUT("short read, %d.  calling cleanup",ncc);
                    379: #endif
                    380:                                cleanup(); /* will probably fail or block */
                    381:                                return(1);
                    382:                        }
                    383:                        else if (si->sp_cc & SP_OB) {
                    384:                                /* a status or OOB control */
                    385:                                switch (buf[sizeof(struct sphdr)]) {
                    386:                                case GAPCTLinterrupt:
                    387:                                        /* shove interrupt char in buffer */
                    388:                                        interrupt();
                    389:                                        break; /* from switch */
                    390:                                case GAPCTLareYouThere:
                    391:                                        sendoobdata(GAPCTLiAmHere);
                    392:                                        break; /* from switch */
                    393:                                default:
                    394:                                        /* Ignore other controls instead of:
                    395:                                         * sendoobdata(
                    396:                                         *     GAPCTLunexpectedRemoteBehavior);
                    397:                                         */
                    398:                                        break; /* from switch */
                    399:                                }
                    400:                                ncc = 0; /* no chars here */
                    401:                        }
                    402:                        else if (si->sp_dt==GAPCTLnone) {
                    403:                                /* the normal case */
                    404:                                ncc -= sizeof(struct sphdr);
                    405:                                netip = buf + sizeof(struct sphdr);
                    406:                                keepalives = 0;
                    407:                        }
                    408:                        else if(si->sp_dt==GAPCTLcleanup) {
                    409: #ifdef DEBUG
                    410:                                BUGOUT("got CLEANUP packet.  Done");
                    411: #endif
                    412:                                cleanup(); /* normal termination */
                    413:                                return(0);
                    414:                        }
                    415:                        else if (si->sp_dt==SPPSST_END) {
                    416:                                /* got premature termination */
                    417:                                quitquit(net, pty);
                    418:                                return(1);
                    419:                        }
                    420:                }
                    421: 
                    422:                /*
                    423:                 * Something to read from the pty...
                    424:                 */
                    425:                if (ibits & (1 << pty)) {
                    426:                        if (frametimeout > 0) sleep(frametimeout);
                    427:                        pcc = read(pty, ptyibuf, sizeof(ptyibuf));
                    428: #ifdef DEBUG
                    429:                        BUGOUT("read from pty %d",pcc);
                    430: #endif
                    431:                        if (pcc < 0 && errno == EWOULDBLOCK)
                    432:                                pcc = 0;
                    433:                        else if (pcc <= 0) {
                    434: #ifdef DEBUG
                    435:                                BUGOUT("short read from pty. Calling cleanup");
                    436: #endif
                    437:                                cleanup();
                    438:                                return(1); /* ?? abnormal termination */
                    439:                        }
                    440:                        ptyip = ptyibuf;
                    441:                }
                    442: 
                    443:                while (pcc > 0) {
                    444:                        if ((&netobuf[sizeof(netobuf)] - nfrontp) < 2)
                    445:                                break;
                    446:                        *nfrontp++ = *ptyip++ & 0377; pcc--;
                    447:                }
                    448:                if ((obits & (1 << net)) && (nfrontp - nbackp) > 0)
                    449:                        netflush();
                    450:                while (ncc > 0) {
                    451:                        if ((&ptyobuf[sizeof(ptyobuf)] - pfrontp) < 2) break;
                    452:                        *pfrontp++ = *netip++ & 0377;
                    453:                        ncc--;
                    454:                }
                    455:                if ((obits & (1 << pty)) && (pfrontp - pbackp) > 0)
                    456:                        ptyflush();
                    457:        }
                    458:        /* we should never get to here */
                    459: #ifdef DEBUG
                    460:        BUGOUT("broke out of for(;;) somehow.  calling cleanup");
                    461: #endif
                    462:        cleanup();
                    463:        return(0);
                    464: }
                    465: 
                    466: /*
                    467:  * Send out of band data to other end of network
                    468:  */
                    469: sendoobdata(value)
                    470:        u_char value;
                    471: {
                    472:        struct {
                    473:                struct sphdr hdr;
                    474:                char val;
                    475:        } oob;
                    476:        oob.hdr = our_sphdr;
                    477:        oob.val = value;
                    478: #ifdef DEBUG
                    479:        BUGOUT("sendoobdata 0%o",value);
                    480: #endif
                    481:        send(net, &oob, sizeof(oob), MSG_OOB);
                    482: }
                    483: 
                    484: /*
                    485:  * Send interrupt to process on other side of pty.
                    486:  * If it is in raw mode, just write NULL;
                    487:  * otherwise, write intr char.
                    488:  */
                    489: interrupt()
                    490: {
                    491:        struct sgttyb b;
                    492:        struct tchars tchars;
                    493: 
                    494:        ptyflush();     /* half-hearted */
                    495:        ioctl(pty, TIOCGETP, &b);
                    496:        if (b.sg_flags & RAW) {
                    497:                *pfrontp++ = '\0';
                    498:                return;
                    499:        }
                    500:        *pfrontp++ = ioctl(pty, TIOCGETC, &tchars) < 0 ?
                    501:                '\177' : tchars.t_intrc;
                    502: }
                    503: 
                    504: ptyflush()
                    505: {
                    506:        register int n;
                    507: 
                    508:        if ((n = pfrontp - pbackp) > 0)
                    509:                n = write(pty, pbackp, n);
                    510: #ifdef DEBUG
                    511:        BUGOUT("ptyflush wrote %d",n);
                    512: #endif
                    513:        if (n < 0)
                    514:                return;
                    515:        pbackp += n;
                    516:        if (pbackp >= pfrontp)  /* actually, > is an error */
                    517:                pbackp = pfrontp = ptyobuf;
                    518: }
                    519: 
                    520: netflush()
                    521: {
                    522:        register int n;
                    523: 
                    524:        if ((n = nfrontp - nbackp) > 0) {
                    525:                our_iovec[1].iov_len = ((n > SPPMAXDATA) ? SPPMAXDATA : n);
                    526:                our_iovec[1].iov_base = nbackp;
                    527:                n = writev(net, our_iovec, 2) - sizeof(struct sphdr);
                    528:        }
                    529: #ifdef DEBUG
                    530:        BUGOUT("netflush wrote %d",n);
                    531:        if (our_iovec[0].iov_base != (char*)&our_sphdr)
                    532:                BUGOUT("Oops:  our_iovec clobbered");
                    533:        BUGOUT("header: %d %d, %d %d %d %d %d %d",
                    534:                our_sphdr.sp_cc, our_sphdr.sp_dt, 
                    535:                our_sphdr.sp_sid, our_sphdr.sp_did, our_sphdr.sp_seq, 
                    536:                our_sphdr.sp_ack, our_sphdr.sp_alo);
                    537: #endif
                    538:        if (n < 0) {
                    539:                if (errno == EWOULDBLOCK)
                    540:                        return;
                    541:                /* should blow this guy away... */
                    542:                return;
                    543:        }
                    544:        nbackp += n;
                    545:        if (nbackp >= nfrontp)  /* actually , > is an error */
                    546:                nbackp = nfrontp = netobuf;
                    547: }
                    548: 
                    549: /*
                    550:  * handle receipt of an SPPSST_END packet
                    551:  * This is currently an error, since client didn't send "cleanup" first
                    552:  */
                    553: quitquit()
                    554: {
                    555:        changeSPPopts(net, SPPSST_ENDREPLY, 1);
                    556:        write(net, &our_sphdr, sizeof(our_sphdr));
                    557:        sleep(3);
                    558: 
                    559:        rmut();
                    560:        vhangup();      /* XXX */
                    561:        shutdown(net, 1);
                    562:        close(net);
                    563: }
                    564: 
                    565: /*
                    566:  * shut down the data connection for one reason or another
                    567:  */
                    568: cleanup()
                    569: {
                    570:        int fdmask;
                    571:        struct timeval timeout;
                    572:        struct sphdr *si = (struct sphdr *)buf;
                    573:        int off = 0;
                    574: 
                    575:        signal(SIGCHLD, SIG_IGN);
                    576:        sendoobdata(GAPCTLcleanup);
                    577:        changeSPPopts(net, SPPSST_END, 1);
                    578:        if (write(net, &our_sphdr, sizeof(our_sphdr)) < 0) {
                    579:                fdmask = 1<<net;
                    580:                timeout.tv_sec = 10;
                    581:                while (select(net+1,&fdmask,(int*)0, (int*)0, &timeout) > 0 &&
                    582:                       read(net,buf,sizeof(buf)) >= sizeof(struct sphdr)) {
                    583: #ifdef DEBUG
                    584:                        BUGOUT("cleanup -- got packet");
                    585: #endif
                    586:                        if ((si->sp_cc & SP_OB)
                    587:                            && si->sp_dt == SPPSST_ENDREPLY) {
                    588:                                changeSPPopts(net, SPPSST_ENDREPLY, 1);
                    589:                                write(net, &our_sphdr, sizeof(our_sphdr));
                    590: #ifdef DEBUG
                    591:                                BUGOUT("cleanup -- wrote ENDREPLY");
                    592: #endif
                    593:                                sleep(1);
                    594:                                changeSPPopts(net,0,0);
                    595:                                ioctl(net, FIONBIO, &off);
                    596:                                rmut();
                    597:                                vhangup();      /* XXX */
                    598:                                return;
                    599:                        }
                    600:                        /* loop: ignore everything except ENDREPLY */
                    601:                        fdmask = 1<<net;
                    602:                        timeout.tv_sec = 10;
                    603:                }
                    604:                /* timed out or read failed */
                    605:                changeSPPopts(net, SPPSST_ENDREPLY, 1);
                    606:                write(net, &our_sphdr, sizeof(our_sphdr));
                    607:                sleep(1);
                    608:        }
                    609:        shutdown(net, 1);
                    610:        close(net);
                    611:        rmut();
                    612:        vhangup();      /* XXX */
                    613: }
                    614: 
                    615: /*
                    616:  * SIGCHLD interrupt handler
                    617:  */
                    618: childdied()
                    619: {
                    620: #ifdef DEBUG
                    621:        BUGOUT("child died");
                    622: #endif
                    623:        cleanup();
                    624:        longjmp(childdiedbuf, -1);
                    625: }
                    626: 
                    627: changeSPPopts(s, stream, eom)
                    628:        int s;                  /* SPP socket */
                    629:        u_char stream;          /* datastream type */
                    630:        char eom;               /* Boolean EOM */
                    631: {
                    632:        our_sphdr.sp_dt = stream;
                    633:        our_sphdr.sp_cc = (eom ? SP_EM : 0);
                    634: }
                    635: 
                    636: 
                    637: #include <utmp.h>
                    638: 
                    639: struct utmp wtmp;
                    640: char   wtmpf[] = "/usr/adm/wtmp";
                    641: char   utmp[] = "/etc/utmp";
                    642: #define SCPYN(a, b)    strncpy(a, b, sizeof (a))
                    643: #define SCMPN(a, b)    strncmp(a, b, sizeof (a))
                    644: 
                    645: rmut()
                    646: {
                    647:        register f;
                    648:        int found = 0;
                    649: 
                    650:        f = open(utmp, 2);
                    651:        if (f >= 0) {
                    652:                while(read(f, (char *)&wtmp, sizeof (wtmp)) == sizeof (wtmp)) {
                    653:                        if (SCMPN(wtmp.ut_line, line+5) || wtmp.ut_name[0]==0)
                    654:                                continue;
                    655:                        lseek(f, -(long)sizeof (wtmp), 1);
                    656:                        SCPYN(wtmp.ut_name, "");
                    657:                        SCPYN(wtmp.ut_host, "");
                    658:                        time(&wtmp.ut_time);
                    659:                        write(f, (char *)&wtmp, sizeof (wtmp));
                    660:                        found++;
                    661:                }
                    662:                close(f);
                    663:        }
                    664:        if (found) {
                    665:                f = open(wtmpf, 1);
                    666:                if (f >= 0) {
                    667:                        SCPYN(wtmp.ut_line, line+5);
                    668:                        SCPYN(wtmp.ut_name, "");
                    669:                        SCPYN(wtmp.ut_host, "");
                    670:                        time(&wtmp.ut_time);
                    671:                        lseek(f, (long)0, 2);
                    672:                        write(f, (char *)&wtmp, sizeof (wtmp));
                    673:                        close(f);
                    674:                }
                    675:        }
                    676:        chmod(line, 0666);
                    677:        chown(line, 0, 0);
                    678:        line[strlen("/dev/")] = 'p';
                    679:        chmod(line, 0666);
                    680:        chown(line, 0, 0);
                    681: }
                    682: 
                    683: /*
                    684:  * Convert network-format xns address
                    685:  * to ascii
                    686:  * --Replace this with a clearinghouse name lookup someday.
                    687:  */
                    688: char *
                    689: wsname(addr)
                    690:        struct ns_addr addr;
                    691: {
                    692:        static char b[50];
                    693:        char temp[10];
                    694:        int i;
                    695: 
                    696:        /* net */
                    697:        sprintf(b, "%D.", ntohl(ns_netof(addr)));
                    698:        /* skip leading zeros */
                    699:        for(i=0; (addr.x_host.c_host[i] == (char) 0); i++) ;
                    700:        /* print the rest */
                    701:        for(; i < 6; i++) {
                    702:                sprintf(temp,"%x", addr.x_host.c_host[i]);
                    703:                strcat(b, temp);
                    704:                if(i != 5) strcat(b, ":");
                    705:        }
                    706:        return (b);
                    707: }
                    708: 
                    709: /*
                    710:   * generate an xns address that "DE" can parse.
                    711:   * This goes in the environment.  Should be the same as above
                    712:   */
                    713: char *
                    714: xntoa(addr)
                    715:        struct ns_addr addr;
                    716: {
                    717:        static char b[50];
                    718:        char temp[10];
                    719:        int i;
                    720: 
                    721:        /* net */
                    722:        sprintf(b, "%X#", ntohl(ns_netof(addr)));
                    723:        /* print the rest */
                    724:        for(i=0; i < 6; i++) {
                    725:                sprintf(temp,"%x", addr.x_host.c_host[i]);
                    726:                strcat(b, temp);
                    727:                if(i != 5) strcat(b, ".");
                    728:        }
                    729:        return (b);
                    730: }
                    731: 
                    732: #ifdef DEBUG
                    733: BUGOUT(str,a,b,c,d,e,f,g,h)
                    734:        char *str;
                    735: {
                    736:        FILE *fd;
                    737:        fd = fopen("/tmp/GAP2d.log","a");
                    738:        fprintf(fd,str,a,b,c,d,e,f,g,h);
                    739:        putc('\n',fd);
                    740:        fclose(fd);
                    741: }
                    742: #endif

unix.superglobalmegacorp.com

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