Annotation of researchv10dc/ipc/bin/ocon.c, revision 1.1

1.1     ! root        1: #include <stdio.h>
        !             2: #include <ipc.h>
        !             3: #include <sgtty.h>
        !             4: #include <sys/stream.h>
        !             5: #include <errno.h>
        !             6: #include <signal.h>
        !             7: #include <sys/stat.h>
        !             8: #include <libc.h>
        !             9: 
        !            10: /*
        !            11:  * program to connect to
        !            12:  * another cpu on Datakit w/ transparent ioctls
        !            13:  */
        !            14: 
        !            15: int     rem=-1;                /* remote file descriptor */
        !            16: extern int mesg_ld;
        !            17: struct sgttyb sgbuf;
        !            18: struct tchars tcbuf;
        !            19: int    ttyrem=0;       /* true if tty ld is remote */
        !            20: char   *ttyn;
        !            21: int    perms;
        !            22: 
        !            23: struct sigmsg {
        !            24:        struct  mesg m;
        !            25:        char    sig[1];
        !            26: };
        !            27: 
        !            28: struct buffer {
        !            29:        int     rfd,wfd;
        !            30:        int     mesgld;
        !            31:        char    *rptr;
        !            32:        char    *wptr;
        !            33:        char    data[4096+MSGHLEN];
        !            34: };
        !            35: 
        !            36: struct mesg *getmsg();
        !            37: int fillbuf();
        !            38: 
        !            39: #define        msglen(mp)      ((mp)->losize + ((mp)->hisize<<8))
        !            40: 
        !            41: int lfd;
        !            42: char *av0;
        !            43: int notdef;
        !            44: 
        !            45: usage()
        !            46: {
        !            47:        fprintf(stderr, "usage: %s [-l] host\n");
        !            48:        exit(1);
        !            49: }
        !            50: 
        !            51: main(argc, argv)
        !            52: char **argv;
        !            53: {
        !            54:        char *host;
        !            55:        struct stat sb;
        !            56:        int all;
        !            57:        extern int hupcatch();
        !            58:        char *ttyname();
        !            59: 
        !            60:        av0 = strrchr(argv[0], '/');
        !            61:        av0 = av0==NULL ? argv[0] : av0+1;
        !            62:                while(argc>1 && argv[1][0]=='-'){
        !            63:                char *cp;
        !            64:                for(cp=&argv[1][1]; *cp; cp++)
        !            65:                        switch (*cp) {
        !            66:                        case 'l':
        !            67:                                av0 = "con-l";
        !            68:                                break;
        !            69:                        default:
        !            70:                                usage(); 
        !            71:                        }
        !            72:                argv++;
        !            73:                argc--;
        !            74:        }
        !            75:        host=argv[1];
        !            76: /*
        !            77:        if (host==NULL)
        !            78:                usage();
        !            79: */
        !            80:        ioctl(0, TIOCGETP, &sgbuf);
        !            81:        ioctl(0, TIOCGETC, &tcbuf);
        !            82: 
        !            83:        all = strcmp(av0, "con")==0;
        !            84:        if (strcmp(av0, "nogin")==0)
        !            85:                rem = trynogin(host);
        !            86:        if (all || strcmp(av0, "ndcon")==0)
        !            87:                rem = trymesg(host);
        !            88:        if (rem<0 && (all || strcmp(av0, "dcon")==0))
        !            89:                rem = trynomesg(host);
        !            90:        if (rem<0 && (all || strcmp(av0, "rogin")==0 || strcmp(av0, "rlogin")==0))
        !            91:                rem = tryrogin(host);
        !            92:        if (rem<0 && (all || strcmp(av0, "con-l")==0))
        !            93:                rem = trysimple(host);
        !            94:        if (rem<0) {
        !            95:                fprintf(stderr, "%s: %s connecting to %s\n", av0, errstr, host);
        !            96:                exit(1);
        !            97:        }
        !            98: 
        !            99:        signal(SIGHUP, hupcatch);
        !           100:        signal(SIGPIPE, hupcatch);
        !           101:        if ((ttyn = ttyname(0)) != NULL
        !           102:        &&   stat(ttyn, &sb) >= 0) {
        !           103:                perms = sb.st_mode & ~S_IFMT;
        !           104:                chmod(ttyn, 0);
        !           105:        }
        !           106:        ioctl(0, TIOCFLUSH, (char *)0); /* race with readahead still possible */
        !           107:        if(ioctl(0, FIOPUSHLD, &mesg_ld) < 0)
        !           108:                go(rem, 0);
        !           109:        else
        !           110:                go(rem, 1);
        !           111: 
        !           112:        finish(0);
        !           113:        /* NOTREACHED */
        !           114: }
        !           115: 
        !           116: /* try to set up a message line discipline connection */
        !           117: trymesg(host)
        !           118:        char *host;
        !           119: {
        !           120:        int fd;
        !           121: 
        !           122:        fd = ipcopen(ipcpath(host, "dk", "mesgdcon"), "light");
        !           123:        if (fd<0)
        !           124:                return fd;
        !           125:        if (ipclogin(fd)<0) {
        !           126:                fprintf(stderr, "%s: can't log in\n", av0);
        !           127:                exit(1);
        !           128:        }
        !           129:        return fd;
        !           130: }
        !           131: 
        !           132: /* try to set up a no line discipline connection */
        !           133: trynomesg(host)
        !           134:        char *host;
        !           135: {
        !           136:        int fd;
        !           137: 
        !           138:        fd = ipcopen(ipcpath(host, "dk", "dcon"), "light");
        !           139:        if (fd<0)
        !           140:                return fd;
        !           141:        if (ipclogin(fd)<0) {
        !           142:                fprintf(stderr, "%s: can't log in\n", av0);
        !           143:                exit(1);
        !           144:        }
        !           145:        remtty();
        !           146:        return fd;
        !           147: }
        !           148: 
        !           149: /* try to set up a rlogin-like connection */
        !           150: trynogin(host)
        !           151:        char *host;
        !           152: {
        !           153:        int fd;
        !           154:        char *term;
        !           155: 
        !           156:        fd = ipcopen(ipcpath(host, "tcp", "tcp.513"), "light hup");
        !           157:        if (fd<0)
        !           158:                return fd;
        !           159:        term = getenv("TERM");
        !           160:        ipcrogin(fd, term?term:"");
        !           161:        ttyrem = 1;
        !           162:        return fd;
        !           163: }
        !           164: 
        !           165: /* try to set up a rlogin-like connection */
        !           166: tryrogin(host)
        !           167:        char *host;
        !           168: {
        !           169:        int fd;
        !           170:        char *term;
        !           171: 
        !           172:        fd = ipcopen(ipcpath(host, "tcp", "tcp.513"), "light hup");
        !           173:        if (fd<0)
        !           174:                return fd;
        !           175:        term = getenv("TERM");
        !           176:        ipcrogin(fd, term?term:"");
        !           177:        remtty();
        !           178:        return fd;
        !           179: }
        !           180: 
        !           181: /* try to set up a non-authenticated connection */
        !           182: trysimple(host)
        !           183:        char *host;
        !           184: {
        !           185:        int fd;
        !           186: 
        !           187:        fd = ipcopen(ipcpath(host, "dk", ""), "light 1200");
        !           188:        if (fd<0)
        !           189:                return fd;
        !           190:        remtty();
        !           191:        return fd;
        !           192: }
        !           193: 
        !           194: /* set up for tty control to be remote */
        !           195: remtty()
        !           196: {
        !           197:        struct  sgttyb sg;
        !           198:        struct  tchars tc;
        !           199: 
        !           200:        sg = sgbuf;
        !           201:        sg.sg_flags &= ~(CRMOD|ECHO|XTABS);
        !           202:        sg.sg_flags |= CBREAK;
        !           203:        ioctl(0, TIOCSETP, &sg);
        !           204:        tc.t_quitc = tcbuf.t_quitc;
        !           205:        tc.t_intrc = tc.t_startc = tc.t_stopc = tc.t_eofc = tc.t_brkc = -1;
        !           206:        ioctl(0, TIOCSETC, &tc);
        !           207:        ttyrem = 1;
        !           208: }
        !           209:        
        !           210: 
        !           211: static struct buffer ttyb;
        !           212: static struct buffer netb;
        !           213: 
        !           214: go(fd, mesg)
        !           215: {
        !           216:        int rbits, wbits;
        !           217:        struct mesg *mp;
        !           218:        int dgenerated=0;
        !           219:        int lasttype=0;
        !           220: 
        !           221:        wbits = 0;
        !           222:        ttyb.rptr = ttyb.wptr = ttyb.data;
        !           223:        ttyb.rfd = 0;
        !           224:        ttyb.wfd = 1;
        !           225:        ttyb.mesgld = mesg;
        !           226:        netb.rptr = netb.wptr = netb.data;
        !           227:        netb.rfd = fd;
        !           228:        netb.wfd = fd;
        !           229:        netb.mesgld = ttyrem==0;
        !           230:        while(1){
        !           231:                rbits = 1 | (1<<fd);
        !           232:                if(select(20, (fd_set*)&rbits, (fd_set*)&wbits, 20000) < 0){
        !           233:                        if(errno != EINTR)
        !           234:                                return;
        !           235:                        continue;
        !           236:                }
        !           237:                if(rbits & 1)
        !           238:                        if (fillbuf(&ttyb)<0)
        !           239:                                return;
        !           240:                if(rbits & (1<<fd))
        !           241:                        if (fillbuf(&netb)<0)
        !           242:                                return;
        !           243:                while(mp = getmsg(&ttyb)) {
        !           244:                        if (mp->type==M_DELIM) {
        !           245:                                if (ttyrem && lasttype==M_DELIM) {
        !           246:                                        sendmsg(&netb, M_DATA, &tcbuf.t_eofc, 1);
        !           247:                                        continue;
        !           248:                                }
        !           249:                        }
        !           250:                        lasttype = mp->type;
        !           251:                        if (mp->type==M_SIGNAL)
        !           252:                                switch(((struct sigmsg *)mp)->sig[0]) {
        !           253:                                case SIGQUIT:
        !           254:                                        dolocal(mp);
        !           255:                                        continue;
        !           256:                                case SIGINT:
        !           257:                                        if(!ttyrem)
        !           258:                                                break;
        !           259:                                        sendmsg(&netb, M_DATA, &tcbuf.t_intrc, 1);
        !           260:                                        continue;
        !           261:                                }
        !           262:                        mp->magic = MSGMAGIC;   /* temp safety */
        !           263:                        if(writemsg(&netb, mp)<0)
        !           264:                                return;
        !           265:                        if(!ttyrem && mp->type == M_FLUSH) {
        !           266:                                remflush();
        !           267:                                rbits = 0;
        !           268:                        }
        !           269:                }
        !           270:                while(mp = getmsg(&netb)){
        !           271:                        if(mp->type == M_HANGUP)
        !           272:                                return;
        !           273:                        if(mp->type == M_IOCTL){
        !           274:                                doioctl(mp);
        !           275:                        } else if(dgenerated && mp->type==M_DELIM){
        !           276:                                dgenerated = 0;
        !           277:                        } else {
        !           278:                                if(writemsg(&ttyb, mp)<0)
        !           279:                                        return;
        !           280:                                if(mp->type==M_DATA) {
        !           281:                                        sendmsg(&ttyb, M_DELIM, (char *)mp, 0);
        !           282:                                        dgenerated = 1;
        !           283:                                }
        !           284:                        }
        !           285:                }
        !           286:        }
        !           287: }
        !           288: 
        !           289: /* read in at least a complete message */
        !           290: fillbuf(bp)
        !           291:        register struct buffer *bp;
        !           292: {
        !           293:        register int n;
        !           294:        struct mesg *mp;
        !           295:        static int neofs;       
        !           296: 
        !           297:        if(!bp->mesgld) {
        !           298:                bp->rptr = bp->data;
        !           299:                bp->wptr = bp->data+MSGHLEN;
        !           300:                mp = (struct mesg *)bp->rptr;
        !           301:        } else {
        !           302:                /* compact */
        !           303:                n = bp->wptr-bp->rptr;
        !           304:                if (n > 0 && bp->rptr!=bp->data)
        !           305:                        memcpy(bp->data, bp->rptr, n);
        !           306:                bp->rptr = bp->data;
        !           307:                bp->wptr = bp->rptr + n;
        !           308:        }
        !           309: 
        !           310:        /* try reading */
        !           311:        n = bp->data+sizeof(bp->data) - bp->wptr;
        !           312:        if (n > 0) {
        !           313:                if ((n = read(bp->rfd, bp->wptr, n))<=0)
        !           314:                        if(n<0 || ++neofs>4)
        !           315:                                return -1;
        !           316:                bp->wptr += n;
        !           317:        } else
        !           318:                neofs = 0;
        !           319: 
        !           320:        if(!bp->mesgld) {
        !           321:                mp->type = M_DATA;
        !           322:                mp->magic = MSGMAGIC;
        !           323:                setmsgl(mp, n);
        !           324:        }
        !           325:        return 0;
        !           326: }
        !           327: 
        !           328: /* get the next (buffered) message */
        !           329: struct mesg *
        !           330: getmsg(bp)
        !           331:        struct buffer *bp;
        !           332: {
        !           333:        struct mesg *mp = (struct mesg *)bp->rptr;
        !           334:        int n = bp->wptr - bp->rptr;
        !           335: 
        !           336:        if (n<MSGHLEN || n<MSGHLEN+msglen(mp))
        !           337:                return NULL;
        !           338:        bp->rptr += MSGHLEN + msglen(mp);
        !           339:        mp->magic = MSGMAGIC;
        !           340:        return mp;
        !           341: }
        !           342: 
        !           343: int
        !           344: writemsg(bp, mp)
        !           345:        struct buffer *bp;
        !           346:        struct mesg *mp;
        !           347: {
        !           348:        int len;
        !           349:        char *cp;
        !           350: 
        !           351:        if(bp->mesgld) {
        !           352:                len = MSGHLEN + msglen(mp);
        !           353:                cp = (char *)mp;
        !           354:        } else if(mp->type==M_DATA){
        !           355:                len = msglen(mp);
        !           356:                cp = ((char *)mp)+MSGHLEN;
        !           357:        } else
        !           358:                return 0;
        !           359:        if(write(bp->wfd, cp, len)!=len)
        !           360:                return -1;
        !           361:        return 0;
        !           362: }
        !           363: 
        !           364: doioctl(mp)
        !           365:        struct mesg *mp;
        !           366: {
        !           367:        struct iofoo{
        !           368:                int cmd;
        !           369:                union{
        !           370:                        int i;
        !           371:                        char errno;
        !           372:                        struct insld insld;
        !           373:                } u;
        !           374:        } *iop;
        !           375:        int cmd, ld;
        !           376:        int n;
        !           377: 
        !           378:        iop = (struct iofoo *)(((char*)mp) + MSGHLEN);
        !           379:        cmd = iop->cmd;
        !           380:        n = msglen(mp);
        !           381:        n -= sizeof(iop->cmd);
        !           382:        switch(cmd){
        !           383:        case FIOLOOKLD:
        !           384:                if(n > 0)
        !           385:                        ld = iop->u.i;
        !           386:                else
        !           387:                        ld = 0;
        !           388:                ld++;
        !           389:                if(ioctl(1, FIOLOOKLD, &ld) < 0)
        !           390:                        goto bad;
        !           391:                iop->cmd = ld;
        !           392:                n = sizeof(iop->cmd);
        !           393:                break;
        !           394: 
        !           395:        case FIOPOPLD:
        !           396:                if(n > 0)
        !           397:                        ld = iop->u.i;
        !           398:                else
        !           399:                        ld = 0;
        !           400:                ld++;
        !           401:                if(ioctl(1, FIOPOPLD, &ld) < 0)
        !           402:                        goto bad;
        !           403:                n = 0;
        !           404:                break;
        !           405: 
        !           406:        case FIOPUSHLD:
        !           407:                iop->u.insld.level = 0;
        !           408:                /* fall through... */
        !           409:        case FIOINSLD:
        !           410:                iop->u.insld.level++;
        !           411:                if(ioctl(1, FIOINSLD, &(iop->u.insld)) < 0)
        !           412:                        goto bad;
        !           413:                n = 0;
        !           414:                break;
        !           415: 
        !           416:        default:
        !           417:                mp->magic = MSGMAGIC;   /* safety */
        !           418:                writemsg(&ttyb, mp);
        !           419:                return;
        !           420:        }
        !           421:        /* locally successful */
        !           422:        mp->type = M_IOCACK;
        !           423:        mp->magic = MSGMAGIC;
        !           424:        setmsgl(mp, n);
        !           425:        writemsg(&netb, mp);
        !           426:        return;
        !           427: bad:
        !           428:        mp->type = M_IOCNAK;
        !           429:        mp->magic = MSGMAGIC;
        !           430:        setmsgl(mp, sizeof(struct iofoo));
        !           431:        iop->u.errno = errno;
        !           432:        writemsg(&netb, mp);
        !           433: }
        !           434: 
        !           435: remflush()
        !           436: {
        !           437:        char buf[5000];
        !           438:        struct mesg *mp;
        !           439: 
        !           440:        mp = (struct mesg *) buf;
        !           441:        mp->type = M_IOCTL;
        !           442:        setmsgl(mp, sizeof(int));
        !           443:        mp->magic = MSGMAGIC;
        !           444:        writemsg(&netb, (struct mesg *)buf);
        !           445: 
        !           446:        while(read(rem, buf, sizeof(buf)) > 0){
        !           447:                if(mp->type == M_IOCNAK || mp->type == M_IOCACK)
        !           448:                        return;
        !           449:        }
        !           450: }
        !           451: 
        !           452: setmsgl(mp, n)
        !           453:        register struct mesg *mp;
        !           454:        int n;
        !           455: {
        !           456:        mp->losize = n;
        !           457:        mp->hisize = n >> 8;
        !           458: }
        !           459: 
        !           460: hupcatch()
        !           461: {
        !           462:        finish(0);
        !           463: }
        !           464: 
        !           465: finish(sts)
        !           466: {
        !           467:        struct mesg m;
        !           468: 
        !           469:        if(ioctl(0, FIOLOOKLD, 0) == mesg_ld)
        !           470:                ioctl(0, FIOPOPLD, 0);
        !           471:        if (ttyn)
        !           472:                chmod(ttyn, perms);
        !           473:        ioctl(0, TIOCSETP, &sgbuf);
        !           474:        ioctl(0, TIOCSETC, &tcbuf);
        !           475:        if (sts == 0)
        !           476:                printf("Eof\n");
        !           477:        exit(sts);
        !           478: }
        !           479: 
        !           480: dolocal(mp)
        !           481:        register struct mesg *mp;
        !           482: {
        !           483:        char lbuf[128+1];
        !           484:        register char *lp;
        !           485:        struct sgttyb nsgbuf;
        !           486:        struct tchars ntcbuf;
        !           487:        int done;
        !           488: 
        !           489:        ioctl(0, FIOPOPLD, (char *)0);
        !           490:        ioctl(0, TIOCFLUSH, (char *)0);
        !           491:        ioctl(0, TIOCGETP, &nsgbuf);
        !           492:        ioctl(0, TIOCSETP, &sgbuf);
        !           493:        ioctl(0, TIOCGETC, &ntcbuf);
        !           494:        ioctl(0, TIOCSETC, &tcbuf);
        !           495:        chmod(ttyn, perms);
        !           496:        for (done=0;!done;) {
        !           497:                lp = lbuf;
        !           498:                printf( "con>> ");
        !           499:                fflush(stdout);
        !           500:                while (lp < &lbuf[128] && read(0, lp, 1)>0 && *lp!='\n')
        !           501:                        lp++;
        !           502:                *lp = '\0';
        !           503:                switch(*lbuf) {
        !           504:                case 'b':
        !           505:                        if (!ttyrem)
        !           506:                                sendmsg(&netb, M_BREAK, (char *)NULL, 0);
        !           507:                        mp->type = 0;
        !           508:                        done = 1;
        !           509:                        break;
        !           510:                case 'i':
        !           511:                        if (ttyrem) {
        !           512:                                sendmsg(&netb, M_DATA, &tcbuf.t_quitc, 1);
        !           513:                                mp->type = 0;
        !           514:                        }
        !           515:                        done = 1;
        !           516:                        break;
        !           517:                case 'q':
        !           518:                case 'x':
        !           519:                case '.':
        !           520:                        finish(1);
        !           521:                case '!':
        !           522:                        system(lbuf+1);
        !           523:                        printf("!!\n");
        !           524:                        fflush(stdout);
        !           525:                        mp->type = 0;
        !           526:                        done = 1;
        !           527:                        break;
        !           528:                case '\0':
        !           529:                        mp->type = 0;
        !           530:                        done = 1;
        !           531:                        break;
        !           532:                default:
        !           533:                        printf("[qx.] to exit, i for quit signal, b for break, !cmd for shell\n");
        !           534:                        fflush(stdout);
        !           535:                }
        !           536:        }
        !           537:        ioctl(0, TIOCSETP, &nsgbuf);
        !           538:        ioctl(0, TIOCSETC, &ntcbuf);
        !           539:        ioctl(0, FIOPUSHLD, &mesg_ld);
        !           540:        chmod(ttyn, 0);
        !           541:        if (mp->type) {
        !           542:                mp->magic = MSGMAGIC;   /* safety */
        !           543:                writemsg(&netb, mp);
        !           544:        }
        !           545: }
        !           546: 
        !           547: sendmsg(bp, type, cp, len)
        !           548:        struct buffer *bp;
        !           549:        int type, len;
        !           550:        char *cp;
        !           551: {
        !           552:        struct amesg {
        !           553:                struct mesg m;
        !           554:                char body[128];
        !           555:        } am;
        !           556: 
        !           557:        am.m.magic = MSGMAGIC;
        !           558:        am.m.type = type;
        !           559:        setmsgl(&am.m, len);
        !           560:        if (cp!=NULL && len>0)
        !           561:                memcpy(am.body, cp, len);
        !           562:        writemsg(bp, (struct mesg *)&am);
        !           563: }

unix.superglobalmegacorp.com

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