Annotation of researchv10no/ipc/bin/ocon.c, revision 1.1.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.