Annotation of researchv9/ipc/src/bin/con.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 (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.