|
|
1.1 ! root 1: #include <getflags.h> ! 2: #include <sys/types.h> ! 3: #include <sys/filio.h> ! 4: #include <sys/ttyio.h> ! 5: #include <ctype.h> ! 6: ! 7: int logfd; ! 8: int verbose; ! 9: int vswfd; ! 10: int row, col; ! 11: int mode; ! 12: int didoutput; ! 13: ! 14: main(argc, argv) ! 15: char **argv; ! 16: { ! 17: int i, n, in, out; ! 18: char buf[256]; ! 19: struct sgttyb vvec; ! 20: extern int tty_ld; ! 21: ! 22: if((argc = getflags(argc, argv, "vsfi:1", 0)) < 0) ! 23: usage(""); ! 24: verbose = flag['v'] != 0; ! 25: logfd = creat("vswconlog", 0666); ! 26: if(flag['i']){ ! 27: if((vswfd = open(flag['i'][0], 0)) < 0){ ! 28: perror(flag['i'][0]); ! 29: exit(1); ! 30: } ! 31: } else { ! 32: sprint(buf, "/cs/dk!vswcon"); ! 33: vswfd = ipcopen(buf, "light"); ! 34: if(vswfd < 0){ ! 35: perror(buf); ! 36: exit(1); ! 37: } ! 38: if(ioctl(vswfd, FIOLOOKLD, 0) != tty_ld){ ! 39: if(ioctl(vswfd, FIOPUSHLD, &tty_ld) < 0){ ! 40: perror("tty_ld"); ! 41: exit(1); ! 42: } ! 43: } ! 44: vvec.sg_flags = RAW; ! 45: vvec.sg_erase = 0; ! 46: vvec.sg_kill = 0; ! 47: if(ioctl(vswfd, TIOCSETP, &vvec) < 0){ ! 48: perror("ioctl"); ! 49: exit(1); ! 50: } ! 51: } ! 52: if(flag['f']) ! 53: fileinput(); ! 54: else ! 55: interactive(); ! 56: } ! 57: ! 58: fileinput() ! 59: { ! 60: int i, n, in, out; ! 61: long t0; ! 62: char buf[256]; ! 63: fd_set fds; ! 64: ! 65: FD_ZERO(fds); ! 66: for(;;){ ! 67: t0 = time((long *)0)+2; ! 68: didoutput = 0; ! 69: for(;;){ ! 70: FD_SET(vswfd, fds); ! 71: if((select(vswfd+1, &fds, (fd_set *)0, 2000) > 0) && FD_ISSET(vswfd, fds)){ ! 72: if(read(vswfd, buf, 1) == 1){ ! 73: Fputc(logfd, buf[0]); ! 74: vt100(buf[0]); ! 75: } ! 76: } ! 77: if(time((long *)0) >= t0){ ! 78: if(didoutput) ! 79: didoutput = 0, t0 = time((long *)0)+2; ! 80: else ! 81: break; ! 82: } ! 83: } ! 84: if(read(0, buf, 1) <= 0) ! 85: break; ! 86: if(0)fprint(2, "<%c>", buf[0]); ! 87: if(buf[0] == '_'){ ! 88: while(read(0, buf, 1) == 1) ! 89: if(buf[0] == '\n') ! 90: break; ! 91: } else ! 92: kbd(buf[0]); ! 93: } ! 94: } ! 95: ! 96: interactive() ! 97: { ! 98: int i, n, in, out; ! 99: char buf[256]; ! 100: struct sgttyb vvec; ! 101: fd_set fds; ! 102: ! 103: FD_ZERO(fds); ! 104: for(;;){ ! 105: FD_SET(0, fds); ! 106: FD_SET(vswfd, fds); ! 107: if(select(vswfd+1, &fds, (fd_set *)0, 1000*3600) < 0){ ! 108: perror("select"); ! 109: exit(1); ! 110: } ! 111: if(FD_ISSET(vswfd, fds)){ ! 112: if(read(vswfd, buf, 1) == 1){ ! 113: Fputc(logfd, buf[0]); ! 114: vt100(buf[0]); ! 115: continue; ! 116: } ! 117: } ! 118: if(FD_ISSET(0, fds)){ ! 119: read(0, buf, 1); ! 120: kbd(buf[0]); ! 121: } ! 122: } ! 123: } ! 124: ! 125: typedef enum { IDLE, ESC, NUM1, NUM2 } State; ! 126: ! 127: vt100(c) ! 128: { ! 129: static State state = IDLE; ! 130: static prchar = 0; ! 131: static char buf[256]; ! 132: static next = 0; ! 133: static num; ! 134: ! 135: switch(state) ! 136: { ! 137: case IDLE: ! 138: if(c == 033){ ! 139: state = ESC; ! 140: flush: ! 141: if(next && !flag['s']) ! 142: next = screen(buf, next); ! 143: if(next){ ! 144: buf[next] = 0; ! 145: if(mode) ! 146: print("[%d,%d]: *%s*\n", row, col, buf); ! 147: else ! 148: print("[%d,%d]: %s\n", row, col, buf); ! 149: didoutput = 1; ! 150: next = 0; ! 151: } ! 152: } else { ! 153: buf[next++] = c; ! 154: if(next+1 == sizeof buf) ! 155: goto flush; ! 156: } ! 157: break; ! 158: case ESC: ! 159: switch(c) ! 160: { ! 161: case '[': ! 162: state = NUM1; ! 163: num = 0; ! 164: break; ! 165: case '=': ! 166: state = IDLE; ! 167: break; ! 168: default: ! 169: fprint(2, "*************ESC %c\n", c); ! 170: state = IDLE; ! 171: break; ! 172: } ! 173: break; ! 174: case NUM1: ! 175: switch(c) ! 176: { ! 177: case '0': case '1': case '2': case '3': case '4': ! 178: case '5': case '6': case '7': case '8': case '9': ! 179: num = 10*num+c-'0'; ! 180: break; ! 181: case ';': ! 182: row = num; ! 183: num = 0; ! 184: state = NUM2; ! 185: break; ! 186: case 'H': /* short address? */ ! 187: row = num; ! 188: state = IDLE; ! 189: break; ! 190: case 'm': /* mode select */ ! 191: mode = num; ! 192: state = IDLE; ! 193: break; ! 194: case 'K': /* line erase */ ! 195: case 'J': /* screen erase */ ! 196: state = IDLE; ! 197: break; ! 198: default: ! 199: fprint(2, "***********NUM1 error 0%o '%c'\n", c, c); ! 200: state = IDLE; ! 201: } ! 202: break; ! 203: case NUM2: ! 204: switch(c) ! 205: { ! 206: case '0': case '1': case '2': case '3': case '4': ! 207: case '5': case '6': case '7': case '8': case '9': ! 208: num = 10*num+c-'0'; ! 209: break; ! 210: case 'H': ! 211: col = num; ! 212: state = IDLE; ! 213: break; ! 214: default: ! 215: fprint(2, "**********NUM2 error 0%o '%c'\n", c, c); ! 216: state = IDLE; ! 217: } ! 218: break; ! 219: } ! 220: } ! 221: ! 222: screen(buf, n) ! 223: char *buf; ! 224: { ! 225: if(n == 8){ ! 226: if((buf[2] == ':') && (buf[5] == ':')) ! 227: return(0); ! 228: } ! 229: return(n); ! 230: } ! 231: ! 232: kbd(c) ! 233: { ! 234: switch(c) ! 235: { ! 236: case '*': ! 237: while(read(0, &c, 1) == 1) ! 238: if(c == '\n') break; ! 239: exit(0); ! 240: case '\\': ! 241: c = '\r'; ! 242: default: ! 243: fprint(vswfd, "%c", c); ! 244: break; ! 245: } ! 246: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.