|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.