Annotation of researchv10no/dk/cmd/dcon.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 <sys/ioctl.h>
                     10: #include <signal.h>
                     11: #include <dk.h>
                     12: #include <errno.h>
                     13: 
                     14: #define        CEOT    04
                     15: 
                     16: struct sgttyb  savloc;
                     17: struct tchars savechars;
                     18: struct ltchars lsavechars;
                     19: struct ltchars nlchars = { -1, -1, -1, -1, -1, -1 };
                     20: char   intrchar = 0177;
                     21: char   quitchar = '\\'&037;
                     22: 
                     23: int    rem;    /* remote descriptor */
                     24: extern int dkp_ld, cdkp_ld;
                     25: #define        NOLD    (-1)    /* no line discipline */
                     26: int    which_ld = NOLD;
                     27: char   serv[32];               /* .login, .dcon, etc. */
                     28: int    autologin;
                     29: int    noflush;
                     30: #define LINSIZ 128
                     31: char *space = " \r\t\n";
                     32: int    neofs = 0;              /* die when greater than N */
                     33: int    sigint();
                     34: extern int     dkverbose ;
                     35: extern char *strtok();
                     36: extern char *strchr();
                     37: extern char *strcpy();
                     38: extern char *strcat();
                     39: extern char *malloc();
                     40: extern FILE *scriptopen();
                     41: extern char *strchr();
                     42: SIG_TYP savint, savquit;
                     43: 
                     44: intcatch(){    /* catch interrupts, turn them into rubouts */
                     45:        signal(SIGINT, intcatch);
                     46:        ioctl(rem, TIOCFLUSH, 0);
                     47:        write(rem, &intrchar, 1);
                     48:        ioctl(rem, TIOCFLUSH, 0);
                     49:        ioctl(0, TIOCFLUSH, 0);
                     50: }
                     51: 
                     52: quitcatch(){   /* catch quits, turn them into FS's */
                     53:        ioctl(0, TIOCFLUSH, 0);
                     54:        signal(SIGQUIT, quitcatch);
                     55:        write(rem, &quitchar, 1);
                     56: }
                     57: 
                     58: main(argc,argv)
                     59:        char **argv;
                     60: {
                     61:        int     i, traffic;
                     62:        char dialstr[64] ;
                     63:        int scriptlogin;
                     64:        FILE *script;
                     65: 
                     66:        savetty();
                     67:        which_ld = dkp_ld;
                     68:        strcpy(serv, ".dcon");
                     69:        traffic = 0;
                     70:        autologin = 1;
                     71:        scriptlogin = 0;
                     72:        for(i=1; i<argc && argv[i][0]=='-'; i++) {
                     73:                switch(argv[i][1]) {
                     74:                case 'u':
                     75:                        which_ld = NOLD;
                     76:                        continue;
                     77:                case 'f':
                     78:                        noflush++;
                     79:                        continue;
                     80:                case 's':
                     81:                        scriptlogin = 1;
                     82:                        continue;
                     83:                case 'l':
                     84:                        serv[0] = '\0';
                     85:                        autologin = 0;
                     86:                        continue;
                     87:                case 'd':
                     88:                case 'b':
                     89:                        which_ld = dkp_ld;
                     90:                        continue;
                     91:                case 'c':
                     92:                        which_ld = cdkp_ld;
                     93:                        continue;
                     94:                case 'v':
                     95:                        dkverbose++ ;
                     96:                        continue ;
                     97:                default:
                     98:                        goto Usage;
                     99:                }
                    100:        }
                    101:        if (i>=argc){
                    102:     Usage:
                    103:                quit("usage: dcon [-lvs] hostname");
                    104:        }
                    105:        savint = signal(SIGINT, intcatch);
                    106:        savquit = signal(SIGQUIT, quitcatch);
                    107:        /*
                    108:         * request circuit to host.
                    109:         */
                    110:        strcpy(dialstr, argv[i]) ;
                    111:        if(strchr(dialstr, '.'))
                    112:                serv[0] = '\0';
                    113:        if(scriptlogin) {
                    114:                script = scriptopen(dialstr);
                    115:                if(script == NULL)
                    116:                        quit("bad script");
                    117:        }
                    118:        strcat(dialstr, serv);
                    119:        rem = tdkdial(dialstr, traffic);
                    120:        if (rem < 0) {
                    121:                char msg[64];
                    122:                extern char *dkerror;
                    123:                sprintf(msg, "%s; call failed", dkerror);
                    124:                quit(msg);
                    125:        }
                    126:        /*
                    127:         * turn on line discipline according to protocol.
                    128:         */
                    129:        if(dkverbose) printf("pushing %d...\n", which_ld);
                    130:        if (which_ld != NOLD
                    131:        &&  dkproto(rem, which_ld) < 0)
                    132:                quit("can't turn on datakit protocol");
                    133:        if (autologin){
                    134:                if (tdklogin(rem) < 0)
                    135:                        quit("can't log in") ;
                    136:                if(dkverbose) printf("logged in\n");
                    137:        }
                    138:        if(scriptlogin) {
                    139:                if (dkscript(rem,script) < 0)
                    140:                        quit("can't log in") ;
                    141:                if(dkverbose) fprintf(stderr,"logged in\n");
                    142:        }
                    143:        settty();
                    144:        scan(rem);
                    145:        /*NOTREACHED*/
                    146: }
                    147: 
                    148: scan(f)
                    149: int f;
                    150: {
                    151:        extern errno;
                    152:        fd_set rd;
                    153: 
                    154:        ioctl(f, DIOCSTREAM, (char *)0);
                    155:        FD_ZERO(rd);
                    156:        for (;;) {
                    157:                FD_SET(f, rd);
                    158:                FD_SET(0, rd);
                    159:                if (select(f+1, &rd, (fd_set *)0, 2000) == -1) {
                    160:                        if(errno == EINTR)
                    161:                                continue;
                    162:                        quit("select failed");
                    163:                }
                    164:                if (FD_ISSET(0, rd))
                    165:                        keyboard();
                    166:                if (FD_ISSET(f, rd))
                    167:                        remote();
                    168:        }
                    169: }
                    170: 
                    171: quit(s)
                    172:        char *s;
                    173: {
                    174:        printf("dcon: %s\n", s);
                    175:        signal(SIGINT, SIG_DFL);
                    176:        resettty();
                    177:        if (noflush==0)
                    178:                ioctl(rem, TIOCFLUSH, 0);
                    179:        close(rem);
                    180:        exit(strcmp(s, "eof"));
                    181: }
                    182: 
                    183: /*
                    184:  * Scan data from keyboard, looking for escape lines.
                    185:  */
                    186: keyboard()
                    187: {
                    188:        register c;
                    189:        register cc;
                    190:        register char *bp;
                    191:        register char *be, *obp;
                    192:        char buf[1024];
                    193:        static char line[128];
                    194:        static char *linep = &line[0];
                    195:        static col = 0;
                    196: 
                    197:        cc = read(0, buf, sizeof buf);
                    198:        if (cc == 0)
                    199:                quit("eof");
                    200:        if (cc < 0) {
                    201:                if (errno == EINTR)
                    202:                        return;
                    203:                quit("read error on file descriptor 0");
                    204:        }
                    205:        be = buf+cc;
                    206:        bp = obp = buf;
                    207:        while(bp < be) {
                    208:                c = *bp++;
                    209:                if (col==0 && c=='~') {
                    210:                        *linep++ = c;
                    211:                        col = 1;
                    212:                        resettty();
                    213:                        write(1, linep-1, 1);
                    214:                        continue;
                    215:                }
                    216:                col++;
                    217:                if (c=='\r')
                    218:                        c = '\n';
                    219:                if (linep>line) {
                    220:                        *linep++ = c;
                    221:                        if (c==savloc.sg_kill)
                    222:                                write(1, "\n", 1);
                    223:                        if (c==savloc.sg_erase)
                    224:                                linep -= 2;
                    225:                        if (c==savloc.sg_kill || linep<=line) {
                    226:                                linep = line;
                    227:                                settty();
                    228:                                col = 0;
                    229:                                obp = bp;
                    230:                        }
                    231:                }
                    232:                if (c=='\n') {
                    233:                        col = 0;
                    234:                        if (linep > line) {
                    235:                                *linep = '\0';
                    236:                                if (escape(line+1))
                    237:                                        write(rem, line+1, linep-line-1);
                    238:                                obp = bp;
                    239:                                linep = line;
                    240:                                settty();
                    241:                        }
                    242:                }
                    243:        }
                    244:        if (bp>obp && linep==line)
                    245:                write(rem, obp, bp-obp);
                    246: }
                    247: 
                    248: /*
                    249:  * Send data from remote machine to standard output (trivial)
                    250:  */
                    251: remote(){
                    252:        char buf[1024];
                    253:        register n;
                    254: 
                    255:        n = read(rem, buf, sizeof buf);
                    256:        if(n < 0 && errno == EINTR)
                    257:                return;
                    258:        if(n <= 0){
                    259:                if(dkverbose) printf("EOF %d\r\n", neofs);
                    260:                if(neofs++ > 4){
                    261:                        quit("Eof\r");
                    262:                }
                    263:                return;
                    264:        }
                    265:        neofs = 0;
                    266:        write(1, buf, n);
                    267: }
                    268: 
                    269: escape(line)
                    270:        register char *line;
                    271: {
                    272: 
                    273:        switch(*line++) {
                    274:        case '!':
                    275:                cunix(line);
                    276:                return(0);
                    277: 
                    278:        case '.':
                    279:        case CEOT:
                    280:                quit("eof");
                    281: 
                    282:        case 'b':
                    283:                ioctl(rem, TIOCSBRK, 0);
                    284:                return(0);
                    285:        default:
                    286:                return(1);
                    287:        }
                    288: }
                    289: 
                    290: cunix(prog)
                    291: char *prog;
                    292: {
                    293:        register int upid;
                    294:        int retcode;
                    295: 
                    296:        if ((upid = fork()) == 0) {
                    297:                signal(SIGINT, savint);
                    298:                signal(SIGQUIT, savquit);
                    299:                resettty();
                    300:                if (*prog == '\n')
                    301:                        execl("/bin/sh", "sh", "-i", 0);
                    302:                else
                    303:                        execl("/bin/sh","sh","-c",prog,0);
                    304:                exit(0100);
                    305:        }
                    306:        if (upid < 0)
                    307:                printf("can't fork\n");
                    308:        else {
                    309:                signal(SIGINT, SIG_IGN);
                    310:                signal(SIGQUIT, SIG_IGN);
                    311:                while((wait(&retcode) !=upid))
                    312:                        ;
                    313:        }
                    314:        signal(SIGINT, intcatch);
                    315:        signal(SIGQUIT, quitcatch);
                    316:        settty();
                    317:        printf("!!\n");
                    318: }
                    319: 
                    320: dkscript(r,f)
                    321: FILE *f;
                    322: {
                    323:        char sline[LINSIZ];
                    324:        while(fgets(sline,100,f)) {
                    325:                if(rget(r,strtok(sline,space)) < 0)
                    326:                        return(-1);
                    327:                if(fgets(sline,100,f)==0)
                    328:                        return(-1);
                    329:                if(dkverbose) fprintf(stderr,"sending %s",sline);
                    330:                write(r,sline,strlen(sline));
                    331:        }
                    332:        return(1);
                    333: }
                    334: 
                    335: rget(r,s)
                    336: char *s;
                    337: {
                    338:        int i;
                    339:        char buf[LINSIZ];
                    340:        int brkchr = s[strlen(s)-1];
                    341:        for(;;) {
                    342:                for(i=0; ; i++) {
                    343:                        if(i>=LINSIZ-2) {
                    344:                                buf[i] = 0;
                    345:                                strcpy(buf,&buf[LINSIZ/2]);
                    346:                                i = strlen(buf);
                    347:                        }
                    348:                        if(read(r,&buf[i],1) <= 0)
                    349:                                return(-1);
                    350:                        buf[i] &= 0177;
                    351:                        if(buf[i] == brkchr)
                    352:                                break;
                    353:                }
                    354:                buf[i+1] = 0;
                    355:                while(i>=0 && buf[i] && !strchr(space,buf[i]))
                    356:                        i--;
                    357:                i++;
                    358:                if(dkverbose) fprintf(stderr,"check '%s' vs '%s'\n",s,&buf[i]);
                    359:                if(strcmp(s,&buf[i]) == 0)
                    360:                        return(1);
                    361:        }
                    362:        /*NOTREACHED*/
                    363: }
                    364: 
                    365: FILE *
                    366: scriptopen(s)
                    367: char *s;
                    368: {
                    369:        FILE *script = fopen(s, "r");
                    370:        if(script == NULL)
                    371:                return(NULL);
                    372:        if(fgets(s,LINSIZ,script) == NULL)
                    373:                return(NULL);
                    374:        if(dkverbose) fprintf(stderr,"calling %s\n",s);
                    375:        strtok(s,"\n");
                    376:        return script;
                    377: }
                    378: 
                    379: savetty()
                    380: {
                    381:        if (ioctl(0, TIOCGETC, &savechars) >= 0) {
                    382:                intrchar = savechars.t_intrc;
                    383:                quitchar = savechars.t_quitc;
                    384:        }
                    385:        ioctl(0, TIOCGLTC, &lsavechars);
                    386:        ioctl(0, TIOCGETP, &savloc);
                    387: }
                    388: 
                    389: settty()
                    390: {
                    391:        struct sgttyb s;
                    392: 
                    393:        s = savloc;
                    394:        s.sg_flags &=~ (CRMOD|ECHO|XTABS);
                    395:        s.sg_flags |= CBREAK;
                    396:        ioctl(0, TIOCSETP, &s);
                    397:        ioctl(0, TIOCSLTC, &nlchars);
                    398: }
                    399: 
                    400: resettty()
                    401: {
                    402:        ioctl(0, TIOCSETP, &savloc);
                    403:        ioctl(0, TIOCSLTC, &lsavechars);
                    404: }

unix.superglobalmegacorp.com

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