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