Annotation of researchv10no/dk/cmd/odcon.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * DCON
                      3:  * Connect terminal to Datakit network
                      4:  * Operation is line-at-a-time with remote echo.
                      5:  */
                      6: #include <stdio.h>
                      7: #include <sys/param.h>
                      8: #include <sys/types.h>
                      9: #include <sgtty.h>
                     10: #include <signal.h>
                     11: #include <dk.h>
                     12: #include <errno.h>
                     13: 
                     14: #define        CEOT    04
                     15: #define        NULL    0
                     16: 
                     17: 
                     18: struct sgttyb  locvec, savloc;
                     19: struct tchars savechars;
                     20: struct ltchars lsavechars;
                     21: struct ltchars nlchars = { -1, -1, -1, -1, -1, -1 };
                     22: 
                     23: int    rem;    /* remote descriptor */
                     24: int    rembit; /* 1<<rem; for select */
                     25: extern int dkp_ld, dt_ld, pk_ld, mesg_ld;
                     26: int    which_ld;
                     27: char   serv[32];               /* .login, .dcon, etc. */
                     28: int    autologin;
                     29: int    noflush;
                     30: fd_set rdfd_set;
                     31: #define        NSELFD  (rem+1)
                     32: #define LINSIZ 128
                     33: char *space = " \r\t\n";
                     34: int    neofs = 0;              /* die when greater than N */
                     35: 
                     36: int    sigint();
                     37: extern dt_ld;  /* TDK protocol line discipline */
                     38: extern int     dkverbose ;
                     39: char   *mytty;
                     40: extern char *strtok();
                     41: extern char *strchr();
                     42: extern char *strcpy();
                     43: extern char *strcat();
                     44: extern char *malloc();
                     45: extern FILE *scriptopen();
                     46: SIG_TYP savint, savquit;
                     47: 
                     48: intcatch(){    /* catch interrupts, turn them into rubouts */
                     49:        signal(SIGINT, intcatch);
                     50:        ioctl(rem, TIOCFLUSH, 0);
                     51:        write(rem, &savechars.t_intrc, 1);
                     52:        ioctl(rem, TIOCFLUSH, 0);
                     53:        ioctl(0, TIOCFLUSH, 0);
                     54:        rdfd_set.fds_bits[0] = 0;
                     55: }
                     56: 
                     57: quitcatch(){   /* catch quits, turn them into FS's */
                     58:        ioctl(0, TIOCFLUSH, 0);
                     59:        signal(SIGQUIT, quitcatch);
                     60:        write(rem, &savechars.t_quitc, 1);
                     61: }
                     62: 
                     63: main(argc,argv)
                     64:        char **argv;
                     65: {
                     66:        int     i, traffic;
                     67:        char dialstr[64] ;
                     68:        int scriptlogin;
                     69:        FILE *script;
                     70:        extern char *getenv();
                     71:        extern char *ttyname();
                     72: 
                     73:        ioctl(0, TIOCGETC, &savechars);
                     74:        ioctl(0, TIOCGLTC, &lsavechars);
                     75:        ioctl(0, TIOCGETP, &savloc);
                     76:        locvec = savloc;
                     77:        which_ld = dkp_ld;
                     78:        strcpy(serv, ".dcon");
                     79:        if(strcmp(argv[0], "tdcon") == 0 || getenv("TDCON") != NULL){
                     80:                strcpy(serv, ".tdcon");
                     81:                which_ld = dkp_ld;
                     82:                if(strcmp(argv[1], "-x") == 0){
                     83:                        argv[1][1] = 't';
                     84:                }
                     85:        }
                     86:        traffic = 0;
                     87:        autologin = 1;
                     88:        scriptlogin = 0;
                     89:        for(i=1; i<argc && argv[i][0]=='-'; i++) {
                     90:                switch(argv[i][1]) {
                     91:                case 'f':
                     92:                        noflush++;
                     93:                        continue;
                     94:                case 's':
                     95:                        scriptlogin = 1;
                     96:                case 'l':
                     97:                        serv[0] = '\0';
                     98:                        autologin = 0;
                     99:                        which_ld = dt_ld;
                    100:                        continue;
                    101:                case 'x':       /* deprecated */
                    102:                        strcpy(serv, ".dcon");
                    103:                        which_ld = dkp_ld;
                    104:                        autologin = 1;
                    105:                        break;
                    106:                case 't':
                    107:                        which_ld = dkp_ld;
                    108:                        strcpy(serv, ".tdcon");
                    109:                        break;
                    110:                case 'd':
                    111:                case 'b':
                    112:                        which_ld = dkp_ld;
                    113:                        break;
                    114:                case 'c':
                    115:                        which_ld = dt_ld;
                    116:                        break;
                    117:                case 'p':
                    118:                case 'g':
                    119:                        which_ld = pk_ld;
                    120:                        break;
                    121:                case 'v':
                    122:                        dkverbose++ ;
                    123:                        continue ;
                    124:                default:
                    125:                        goto Usage;
                    126:                }
                    127:        }
                    128:        if (i>=argc){
                    129:     Usage:
                    130:                /* don't use quit() because ioctl's aren't set up */
                    131:                printf("usage: dcon [-lvs] hostname\n");
                    132:                exit(1) ;
                    133:        }
                    134:        savint = signal(SIGINT, intcatch);
                    135:        savquit = signal(SIGQUIT, quitcatch);
                    136:        /*
                    137:         * request circuit to host.
                    138:         */
                    139:        strcpy(dialstr, argv[i]) ;
                    140:        if(index(dialstr, '.')){
                    141:                serv[0] = '\0';
                    142:        }
                    143:        if(scriptlogin)  {
                    144:                script = scriptopen(dialstr);
                    145:                if(script == NULL)
                    146:                        quit("bad script");
                    147:        }
                    148:        strcat(dialstr, serv);
                    149:        rem = tdkdial(dialstr, traffic);
                    150:        if (rem < 0) {
                    151:                char msg[64];
                    152:                extern char *dkerror;
                    153:                sprintf(msg, "%s; call failed", dkerror);
                    154:                quit(msg);
                    155:        }
                    156:        if(dkverbose) printf("cut through\n");
                    157:        rembit = 1<<rem;
                    158:        /*
                    159:         * turn on line discipline according to protocol.
                    160:         */
                    161:        if(dkverbose) printf("pushing %d...\n", which_ld);
                    162:        if(dkproto(rem, which_ld) < 0)
                    163:                quit("can't turn on datakit protocol");
                    164:        if (autologin){
                    165:                if (tdklogin(rem) < 0)
                    166:                        quit("can't log in") ;
                    167:                if(dkverbose) printf("logged in\n");
                    168:        } else if(scriptlogin) {
                    169:                if (dkscript(rem,script) < 0)
                    170:                        quit("can't log in") ;
                    171:                if(dkverbose) fprintf(stderr,"logged in\n");
                    172:        }
                    173:        if(strcmp(serv, ".tdcon") == 0){
                    174:                dotdcon(rem);
                    175:                if(dkverbose) printf("set terminal\n");
                    176:        }
                    177:        locvec.sg_flags &= ~(CRMOD|ECHO|XTABS);
                    178:        locvec.sg_flags |= CBREAK;
                    179:        ioctl(0, TIOCSETP, &locvec);
                    180:        ioctl(0, TIOCSLTC, &nlchars);
                    181: 
                    182: 
                    183:        /*
                    184:         * main loop.
                    185:         */
                    186:        ioctl(rem, DIOCSTREAM, (char *)0);
                    187:        do; while(scan() != -1);
                    188:        quit("select failed");
                    189:        /*NOTREACHED*/
                    190: }
                    191: scan()
                    192: {
                    193:        extern errno;
                    194:     Loop:
                    195:        rdfd_set.fds_bits[0] = 1|(1<<rem);
                    196:        if(select(NSELFD, &rdfd_set, (fd_set *)0, 2000) == -1)
                    197:                if(errno == EINTR)
                    198:                        goto Loop;
                    199:                else
                    200:                        return -1;
                    201:        if(rdfd_set.fds_bits[0] == 0)   /* timeout */
                    202:                goto Loop;
                    203:        if(rdfd_set.fds_bits[0] & 1)
                    204:                keyboard();
                    205:        if(rdfd_set.fds_bits[0] & rembit)
                    206:                remote();
                    207:        return 0;
                    208: }
                    209: 
                    210: quit(s)
                    211:        char *s;
                    212: {
                    213:        printf("dcon: %s\n", s);
                    214:        ioctl(0, TIOCSETP, &savloc);
                    215:        ioctl(0, TIOCSLTC, &lsavechars);
                    216:        signal(SIGINT, SIG_DFL);
                    217:        if (noflush==0) {
                    218:                ioctl(rem, TIOCFLUSH, 0);
                    219:                savloc.sg_ispeed = savloc.sg_ospeed = 0;        /* hangup */
                    220:                ioctl(rem, TIOCSETP, &savloc);
                    221:        }
                    222:        close(rem);
                    223:        exit(strcmp(s, "eof"));
                    224: }
                    225: 
                    226: /*
                    227:  * Scan data from keyboard, looking for escape lines.
                    228:  */
                    229: keyboard()
                    230: {
                    231:        register c;
                    232:        register cc;
                    233:        register char *bp;
                    234:        register char *be, *obp;
                    235:        char buf[1024];
                    236:        static char line[128];
                    237:        static char *linep = &line[0];
                    238:        static col = 0;
                    239:        long time();
                    240:        static long timev[2];
                    241: 
                    242:        cc = read(0, buf, sizeof buf);
                    243:        if(cc <0){
                    244:                if(errno == EINTR)
                    245:                        return;
                    246:        }
                    247:        if(cc <= 0)
                    248:                quit("read error on file descriptor 0");
                    249:        be = buf+cc;
                    250:        bp = obp = buf;
                    251:        while(bp < be) {
                    252:                c = *bp++;
                    253:                if (col==0 && c=='~') {
                    254:                        *linep++ = c;
                    255:                        col = 1;
                    256:                        locvec.sg_flags |= savloc.sg_flags&(CRMOD|ECHO);
                    257:                        ioctl(0, TIOCSETP, &locvec);
                    258:                        write(1, linep-1, 1);
                    259:                        continue;
                    260:                }
                    261:                col++;
                    262:                if (c=='\r')
                    263:                        c = '\n';
                    264:                if (linep>line) {
                    265:                        *linep++ = c;
                    266:                        if (c==savloc.sg_kill)
                    267:                                write(1, "\n", 1);
                    268:                        if (c==savloc.sg_erase)
                    269:                                linep -= 2;
                    270:                        if (c==savloc.sg_kill || linep<=line) {
                    271:                                linep = line;
                    272:                                locvec.sg_flags &= ~(CRMOD|ECHO);
                    273:                                ioctl(0, TIOCSETP, &locvec);
                    274:                                col = 0;
                    275:                                obp = bp;
                    276:                        }
                    277:                }
                    278:                if (c=='\n') {
                    279:                        col = 0;
                    280:                        if (linep > line) {
                    281:                                *linep = '\0';
                    282:                                if (escape(line+1, linep))
                    283:                                        write(rem, line+1, linep-line-1);
                    284:                                obp = bp;
                    285:                                linep = line;
                    286:                                locvec.sg_flags &= ~(CRMOD|ECHO);
                    287:                                ioctl(0, TIOCSETP, &locvec);
                    288:                        }
                    289:                }
                    290:        }
                    291:        if (bp>obp && linep==line)
                    292:                write(rem, obp, bp-obp);
                    293: }
                    294: 
                    295: /*
                    296:  * Send data from remote machine to standard output (trivial)
                    297:  */
                    298: remote(){
                    299:        char buf[1024];
                    300:        register n;
                    301: 
                    302:        n = read(rem, buf, sizeof buf);
                    303:        if(n < 0 && errno == EINTR)
                    304:                return;
                    305:        if(n <= 0){
                    306:                if(dkverbose) printf("EOF %d\r\n", neofs);
                    307:                if(neofs++ > 4){
                    308:                        quit("Eof\r");
                    309:                }
                    310:                return;
                    311:        }
                    312:        neofs = 0;
                    313:        write(1, buf, n);
                    314: }
                    315: 
                    316: escape(line, end)
                    317:        register char *line;
                    318: {
                    319:        int cc;
                    320: 
                    321:        switch(*line++) {
                    322:        case '!':
                    323:                cunix(line);
                    324:                return(0);
                    325: 
                    326:        case '.':
                    327:        case CEOT:
                    328:                quit("eof");
                    329: 
                    330:        case 'b':
                    331:                ioctl(rem, TIOCSBRK, 0);
                    332:                return(0);
                    333:        default:
                    334:                return(1);
                    335:        }
                    336: }
                    337: 
                    338: cunix(prog)
                    339: char *prog;
                    340: {
                    341:        register int upid;
                    342:        int retcode;
                    343: 
                    344:        if ((upid = fork()) == 0) {
                    345:                signal(SIGINT, savint);
                    346:                signal(SIGQUIT, savquit);
                    347:                ioctl(0, TIOCSETN, &savloc);
                    348:                ioctl(0, TIOCSLTC, &lsavechars);
                    349:                if (*prog == '\n')
                    350:                        execl("/bin/sh", "sh", "-i", 0);
                    351:                else
                    352:                        execl("/bin/sh","sh","-c",prog,0);
                    353:                exit(0100);
                    354:        }
                    355:        if (upid < 0) {
                    356:                printf("can't fork\n");
                    357:        } else {
                    358:                while((wait(&retcode) !=upid))
                    359:                        ;
                    360:        }
                    361:        signal(SIGINT, intcatch);
                    362:        signal(SIGQUIT, quitcatch);
                    363:        ioctl(0, TIOCSETN, &locvec);
                    364:        ioctl(0, TIOCSLTC, &nlchars);
                    365:        printf("!!\n");
                    366: }
                    367: 
                    368: int tfd;
                    369: 
                    370: dotdcon(fd)
                    371: {
                    372:        char *p, *getenv();
                    373:        char buf[3000];
                    374:        char c;
                    375: 
                    376:        tfd = fd;
                    377:        if((p = getenv("TERM")) != NULL && strlen(p) < (sizeof(buf) - 20)){
                    378:                sprintf(buf, "TERM=%s", p);
                    379:                tsend("env", buf);
                    380:        }
                    381: 
                    382:        qsend("erase", savloc.sg_erase, '\b');
                    383:        qsend("kill", savloc.sg_kill, '@');
                    384:        qsend("intrc", savechars.t_intrc, '\177');
                    385:        qsend("quitc", savechars.t_quitc, '\034');
                    386:        qsend("startc", savechars.t_startc, 'q' & 037);
                    387:        qsend("stopc", savechars.t_stopc, 's' & 037);
                    388:        qsend("eofc", savechars.t_eofc, '\004');
                    389:        qsend("brkc", savechars.t_brkc, '\377');
                    390: 
                    391:        if(savloc.sg_flags & XTABS) tsend("XTABS", "yes");
                    392:        if((savloc.sg_flags & CRMOD) == 0) tsend("CRMOD", "no");
                    393:        if((savloc.sg_flags & ECHO) == 0) tsend("ECHO", "no");
                    394:        if(savloc.sg_flags & CBREAK) tsend("CBREAK", "yes");
                    395:        if(savloc.sg_flags & LCASE) tsend("LCASE", "yes");
                    396: 
                    397:        tsend("env", "TDCON=YES");
                    398: 
                    399:        if((p = getenv("TDKBAG")) && strlen(p) < (sizeof(buf) - 20)){
                    400:                sprintf(buf, "TDKBAG=%s", p);
                    401:                tsend("env", buf);
                    402:        }
                    403:        /* TERMCAP is last because it might have messed up characters */
                    404:        if((p = getenv("TERMCAP")) != NULL){
                    405:                if(strlen(p) < (sizeof(buf) - 20)){
                    406:                        sprintf(buf, "TERMCAP=%s", p);
                    407:                        tsend("env", buf);
                    408:                }
                    409:        }
                    410: 
                    411:        write(fd, "\n", 1);
                    412: }
                    413: 
                    414: tsend(a, b)
                    415: char *a, *b;
                    416: {
                    417:        char *p;
                    418: 
                    419:        p = (char *) malloc(strlen(a) + strlen(b) + 10);
                    420:        if(p == NULL) return;
                    421:        sprintf(p, "%s=%s\n", a, b);
                    422:        write(tfd, p, strlen(p));
                    423:        if(dkverbose > 1) write(1, p, strlen(p));
                    424:        free(p);
                    425: }
                    426: 
                    427: ctsend(s, c)
                    428: char *s;
                    429: char c;
                    430: {
                    431:        char buf[50];
                    432: 
                    433:        sprintf(buf, "%o", (int) c);
                    434:        tsend(s, buf);
                    435: }
                    436: 
                    437: qsend(s, c, wc)
                    438: char *s;
                    439: char c, wc;
                    440: {
                    441:        if(c != wc)
                    442:                ctsend(s, c);
                    443: }
                    444: 
                    445: dkscript(rem,f)
                    446: FILE *f;
                    447: {
                    448:        char sline[LINSIZ];
                    449:        while(fgets(sline,100,f)) {
                    450:                if(rget(rem,strtok(sline,space)) < 0)
                    451:                        return(-1);
                    452:                if(fgets(sline,100,f)==0)
                    453:                        return(-1);
                    454:                if(dkverbose) fprintf(stderr,"sending %s",sline);
                    455:                write(rem,sline,strlen(sline));
                    456:        }
                    457:        return(1);
                    458: }
                    459: 
                    460: rget(rem,s)
                    461: char *s;
                    462: {
                    463:        int i;
                    464:        char buf[LINSIZ];
                    465:        int brkchr = s[strlen(s)-1];
                    466:        for(;;) {
                    467:                for(i=0; ; i++) {
                    468:                        if(i>=LINSIZ-2) {
                    469:                                buf[i] = 0;
                    470:                                strcpy(buf,&buf[LINSIZ/2]);
                    471:                                i = strlen(buf);
                    472:                        }
                    473:                        if(read(rem,&buf[i],1) <= 0)
                    474:                                return(-1);
                    475:                        buf[i] &= 0177;
                    476:                        if(buf[i] == brkchr)
                    477:                                break;
                    478:                }
                    479:                buf[i+1] = 0;
                    480:                while(i>=0 && buf[i] && !strchr(space,buf[i]))
                    481:                        i--;
                    482:                i++;
                    483:                if(dkverbose) fprintf(stderr,"check '%s' vs '%s'\n",s,&buf[i]);
                    484:                if(strcmp(s,&buf[i]) == 0)
                    485:                        return(1);
                    486:        }
                    487:        /*NOTREACHED*/
                    488: }
                    489: 
                    490: FILE *
                    491: scriptopen(s)
                    492: char *s;
                    493: {
                    494:        FILE *script = fopen(s, "r");
                    495:        if(script == NULL)
                    496:                return(NULL);
                    497:        if(fgets(s,LINSIZ,script) == NULL)
                    498:                return(NULL);
                    499:        if(dkverbose) fprintf(stderr,"calling %s\n",s);
                    500:        strtok(s,"\n");
                    501:        return script;
                    502: }

unix.superglobalmegacorp.com

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