Annotation of 43BSD/contrib/xns/examples/gap/gap2d.c, revision 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:                envinit[1] = sprintf(wsenv, "WORKSTATION=%s",
        !           258:                                     xntoa(who.sns_addr));
        !           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.