Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/miscutils/conspy.c
- Timestamp:
- Jan 1, 2014, 12:47:38 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.2/mindi-busybox/miscutils/conspy.c
r2725 r3232 11 11 */ 12 12 13 //applet:IF_CONSPY(APPLET(conspy, _BB_DIR_BIN, _BB_SUID_DROP))13 //applet:IF_CONSPY(APPLET(conspy, BB_DIR_BIN, BB_SUID_DROP)) 14 14 15 15 //kbuild:lib-$(CONFIG_CONSPY) += conspy.o … … 17 17 //config:config CONSPY 18 18 //config: bool "conspy" 19 //config: default n20 //config: depends onPLATFORM_LINUX19 //config: default y 20 //config: select PLATFORM_LINUX 21 21 //config: help 22 22 //config: A text-mode VNC like program for Linux virtual terminals. … … 26 26 27 27 //usage:#define conspy_trivial_usage 28 //usage: "[-vcsndf ] [-x COL] [-y LINE] [CONSOLE_NO]"28 //usage: "[-vcsndfFQ] [-x COL] [-y LINE] [CONSOLE_NO]" 29 29 //usage:#define conspy_full_usage "\n\n" 30 30 //usage: "A text-mode VNC like program for Linux virtual consoles." 31 31 //usage: "\nTo exit, quickly press ESC 3 times." 32 32 //usage: "\n" 33 //usage: "\nOptions:"34 33 //usage: "\n -v Don't send keystrokes to the console" 35 //usage: "\n -c Create missing devices in /dev"34 //usage: "\n -c Create missing /dev/{tty,vcsa}N" 36 35 //usage: "\n -s Open a SHELL session" 37 36 //usage: "\n -n Black & white" 38 37 //usage: "\n -d Dump console to stdout" 39 38 //usage: "\n -f Follow cursor" 39 //usage: "\n -F Assume console is on a framebuffer device" 40 //usage: "\n -Q Disable exit on ESC-ESC-ESC" 40 41 //usage: "\n -x COL Starting column" 41 42 //usage: "\n -y LINE Starting line" … … 44 45 #include <sys/kd.h> 45 46 46 47 47 #define ESC "\033" 48 #define CURSOR_ON -1 49 #define CURSOR_OFF 1 50 51 #define DEV_TTY "/dev/tty" 52 #define DEV_VCSA "/dev/vcsa" 48 53 49 54 struct screen_info { … … 74 79 unsigned line; 75 80 smallint curoff; // unknown:0 cursor on:-1 cursor off:1 76 char attrbuf[sizeof( ESC"[0;1;5;30;40m")];81 char attrbuf[sizeof("0;1;5;30;40m")]; 77 82 // remote console 78 83 struct screen_info remote; 79 84 // saved local tty terminfo 80 85 struct termios term_orig; 81 char vcsa_name[sizeof( "/dev/vcsaNN")];86 char vcsa_name[sizeof(DEV_VCSA "NN")]; 82 87 }; 83 88 … … 85 90 #define INIT_G() do { \ 86 91 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 87 G.attrbuf[0] = '\033'; \88 G.attrbuf[1] = '['; \89 92 G.width = G.height = UINT_MAX; \ 90 93 G.last_attr--; \ … … 94 97 FLAG_v, // view only 95 98 FLAG_c, // create device if need 99 FLAG_Q, // never exit 96 100 FLAG_s, // session 97 101 FLAG_n, // no colors 98 102 FLAG_d, // dump screen 99 103 FLAG_f, // follow cursor 104 FLAG_F, // framebuffer 100 105 }; 101 106 #define FLAG(x) (1 << FLAG_##x) 102 107 #define BW (option_mask32 & FLAG(n)) 103 108 109 static void putcsi(const char *s) 110 { 111 fputs(ESC"[", stdout); 112 fputs(s, stdout); 113 } 114 104 115 static void clrscr(void) 105 116 { 106 117 // Home, clear till end of screen 107 fputs(ESC"[1;1H" ESC"[J", stdout);118 putcsi("1;1H" ESC"[J"); 108 119 G.col = G.line = 0; 109 120 } … … 113 124 if (G.curoff != state) { 114 125 G.curoff = state; 115 fputs(ESC"[?25", stdout);126 putcsi("?25"); 116 127 bb_putchar("h?l"[1 + state]); 117 128 } … … 127 138 } 128 139 140 static void cleanup(int code) NORETURN; 129 141 static void cleanup(int code) 130 142 { 131 set_cursor( -1); // cursor on143 set_cursor(CURSOR_ON); 132 144 tcsetattr(G.kbd_fd, TCSANOW, &G.term_orig); 133 145 if (ENABLE_FEATURE_CLEAN_UP) { … … 136 148 // Reset attributes 137 149 if (!BW) 138 fputs(ESC"[0m", stdout);150 putcsi("0m"); 139 151 bb_putchar('\n'); 140 if (code > 1)152 if (code > EXIT_FAILURE) 141 153 kill_myself_with_sig(code); 142 154 exit(code); … … 159 171 G.data = xzalloc(2 * i); 160 172 } 161 elseif (G.size != i) {162 cleanup( 1);173 if (G.size != i) { 174 cleanup(EXIT_FAILURE); 163 175 } 164 176 data = G.data + G.current; … … 170 182 unsigned y = i - G.y; // if will catch i < G.y too 171 183 172 if (CHAR(data) < ' ')173 CHAR(data) = ' ';174 184 if (y >= G.height || x >= G.width) 175 185 DATA(data) = 0; 186 else { 187 uint8_t ch = CHAR(data); 188 if (ch < ' ') 189 CHAR(data) = ch | 0x40; 190 else if (ch > 0x7e) 191 CHAR(data) = '?'; 192 } 176 193 } 177 194 } … … 181 198 { 182 199 if (!BW) { 200 uint8_t attr_diff; 183 201 uint8_t attr = ATTR(data); 184 //uint8_t attr = ATTR(data) >> 1; // for framebuffer console 185 uint8_t attr_diff = G.last_attr ^ attr; 186 202 203 if (option_mask32 & FLAG(F)) { 204 attr >>= 1; 205 } 206 attr_diff = G.last_attr ^ attr; 187 207 if (attr_diff) { 188 208 // Attribute layout for VGA compatible text videobuffer: … … 215 235 char *ptr; 216 236 217 ptr = G.attrbuf + 2; // skip "ESC ["237 ptr = G.attrbuf; 218 238 219 239 // (G.last_attr & ~attr) has 1 only where … … 246 266 *ptr++ = '4'; 247 267 *ptr++ = color[(attr & bg_mask) >> 4]; 248 *ptr++ = ';';249 } 250 if (ptr != G.attrbuf + 2) {268 ptr++; // last attribute 269 } 270 if (ptr != G.attrbuf) { 251 271 ptr[-1] = 'm'; 252 272 *ptr = '\0'; 253 fputs(G.attrbuf, stdout);273 putcsi(G.attrbuf); 254 274 } 255 275 } … … 294 314 unsigned cx = G.remote.cursor_x - G.x; 295 315 unsigned cy = G.remote.cursor_y - G.y; 296 int cursor = 1;316 int cursor = CURSOR_OFF; 297 317 298 318 if (cx < G.width && cy < G.height) { 299 319 gotoxy(cx, cy); 300 cursor = -1;320 cursor = CURSOR_ON; 301 321 } 302 322 set_cursor(cursor); … … 317 337 if (pid == 0) { 318 338 struct termios termchild; 319 char *shell = getenv("SHELL"); 320 321 if (!shell) 322 shell = (char *) DEFAULT_SHELL; 339 const char *shell = get_shell_name(); 340 323 341 signal(SIGHUP, SIG_IGN); 324 342 // set tty as a controlling tty … … 345 363 int conspy_main(int argc UNUSED_PARAM, char **argv) 346 364 { 347 char tty_name[sizeof( "/dev/ttyNN")];365 char tty_name[sizeof(DEV_TTY "NN")]; 348 366 #define keybuf bb_common_bufsiz1 349 367 struct termios termbuf; … … 355 373 "viewonly\0" No_argument "v" 356 374 "createdevice\0" No_argument "c" 375 "neverquit\0" No_argument "Q" 357 376 "session\0" No_argument "s" 358 377 "nocolors\0" No_argument "n" 359 378 "dump\0" No_argument "d" 360 379 "follow\0" No_argument "f" 380 "framebuffer\0" No_argument "F" 361 381 ; 362 382 … … 364 384 #endif 365 385 INIT_G(); 366 strcpy(G.vcsa_name, "/dev/vcsa");386 strcpy(G.vcsa_name, DEV_VCSA); 367 387 368 388 opt_complementary = "x+:y+"; // numeric params 369 opts = getopt32(argv, "vc sndfx:y:", &G.x, &G.y);389 opts = getopt32(argv, "vcQsndfFx:y:", &G.x, &G.y); 370 390 argv += optind; 371 391 ttynum = 0; 372 392 if (argv[0]) { 373 393 ttynum = xatou_range(argv[0], 0, 63); 374 sprintf(G.vcsa_name + sizeof( "/dev/vcsa")-1, "%u", ttynum);375 } 376 sprintf(tty_name, "%s%u", "/dev/tty", ttynum);394 sprintf(G.vcsa_name + sizeof(DEV_VCSA)-1, "%u", ttynum); 395 } 396 sprintf(tty_name, "%s%u", DEV_TTY, ttynum); 377 397 if (opts & FLAG(c)) { 378 398 if ((opts & (FLAG(s)|FLAG(v))) != FLAG(v)) … … 485 505 case -1: 486 506 if (errno != EINTR) 487 cleanup(1);507 goto abort; 488 508 break; 489 509 case 0: … … 496 516 bytes_read = read(G.kbd_fd, k, sizeof(keybuf) - G.key_count); 497 517 if (bytes_read < 0) 498 cleanup(1);518 goto abort; 499 519 500 520 // Do exit processing 501 for (i = 0; i < bytes_read; i++) { 502 if (k[i] != '\033') 503 G.escape_count = 0; 504 else if (++G.escape_count >= 3) 505 cleanup(0); 521 if (!(option_mask32 & FLAG(Q))) { 522 for (i = 0; i < bytes_read; i++) { 523 if (k[i] != '\033') 524 G.escape_count = -1; 525 if (++G.escape_count >= 3) 526 cleanup(EXIT_SUCCESS); 527 } 506 528 } 507 529 } 508 530 poll_timeout_ms = 250; 531 if (option_mask32 & FLAG(v)) continue; 509 532 510 533 // Insert all keys pressed into the virtual console's input … … 512 535 // code mode - giving ASCII characters to a program expecting 513 536 // scan codes will confuse it. 514 if (!(option_mask32 & FLAG(v)) && G.escape_count == 0) { 537 G.key_count += bytes_read; 538 if (G.escape_count == 0) { 515 539 int handle, result; 516 540 long kbd_mode; 517 541 518 G.key_count += bytes_read;519 542 handle = xopen(tty_name, O_WRONLY); 520 543 result = ioctl(handle, KDGKBMODE, &kbd_mode); … … 522 545 char *p = keybuf; 523 546 547 G.ioerror_count = 0; 524 548 if (kbd_mode != K_XLATE && kbd_mode != K_UNICODE) { 525 549 G.key_count = 0; // scan code mode … … 537 561 } 538 562 } 563 // We sometimes get spurious IO errors on the TTY 564 // as programs close and re-open it 565 else if (errno != EIO || ++G.ioerror_count > 4) { 566 if (ENABLE_FEATURE_CLEAN_UP) 567 close(handle); 568 goto abort; 569 } 539 570 // Close & re-open tty in case they have 540 571 // swapped virtual consoles 541 572 close(handle); 542 543 // We sometimes get spurious IO errors on the TTY544 // as programs close and re-open it545 if (result >= 0)546 G.ioerror_count = 0;547 else if (errno != EIO || ++G.ioerror_count > 4)548 cleanup(1);549 573 } 550 574 } /* while (1) */ 551 } 575 abort: 576 cleanup(EXIT_FAILURE); 577 }
Note:
See TracChangeset
for help on using the changeset viewer.