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

unix.superglobalmegacorp.com

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