wok rev 5711
busybox: add conspy
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Wed Jun 23 21:48:13 2010 +0200 (2010-06-23) |
parents | 932522d70bdb |
children | 386214f606f5 |
files | busybox/receipt busybox/stuff/busybox-1.16.1-modinfo.u busybox/stuff/busybox-1.16.1-modprobe.u busybox/stuff/busybox-1.16.1-stat.u busybox/stuff/busybox-1.16.1-vcsa2txt.u |
line diff
1.1 --- a/busybox/receipt Wed Jun 23 16:11:06 2010 +0200 1.2 +++ b/busybox/receipt Wed Jun 23 21:48:13 2010 +0200 1.3 @@ -36,8 +36,13 @@ 1.4 EOT 1.5 cp ../stuff/$PACKAGE-$VERSION.config .config 1.6 make oldconfig 1.7 - # "CFLAGS=-O0" is a workaround for GCC 4.5.0 1.8 - make -j 4 "CFLAGS=-O0" && make "CFLAGS=-O0" install 1.9 + if [ "$(gcc --version | awk '{ print $3; exit }')" == "4.5.0" ]; then 1.10 + # "CFLAGS=-O0" is a workaround for GCC 4.5.0 (sed crach) 1.11 + # "CFLAGS=-fno-tree-pta" may be a workaround for GCC 4.5.0 (sed garbage) 1.12 + make -j 4 "CFLAGS=-O0" && make "CFLAGS=-O0" install 1.13 + else 1.14 + make -j 4 && make install 1.15 + fi 1.16 echo "Chmod 4755 on busybox binary..." 1.17 chmod 4755 _install/bin/busybox 1.18 } 1.19 @@ -88,10 +93,10 @@ 1.20 [ -e $ROOT$i ] || continue 1.21 if [ -z "$answer" ]; then 1.22 echo -n "Keep installed GNU utilities ? " 1.23 - read answer 1.24 + read -t 30 answer # by default: keep 1.25 case "$answer" in 1.26 - y*|Y*|o*|O*);; 1.27 - *) break;; 1.28 + n*|N*) break;; 1.29 + *) ;; 1.30 esac 1.31 fi 1.32 mv $ROOT$i $ROOT$i-busybox-install
2.1 --- a/busybox/stuff/busybox-1.16.1-modinfo.u Wed Jun 23 16:11:06 2010 +0200 2.2 +++ b/busybox/stuff/busybox-1.16.1-modinfo.u Wed Jun 23 21:48:13 2010 +0200 2.3 @@ -1,6 +1,6 @@ 2.4 --- busybox-1.16.1/include/applets.h 2.5 +++ busybox-1.16.1/include/applets.h 2.6 -@@ -272,6 +272,7 @@ 2.7 +@@ -273,6 +273,7 @@ 2.8 IF_CRYPTPW(APPLET_ODDNAME(mkpasswd, cryptpw, _BB_DIR_USR_BIN, _BB_SUID_DROP, mkpasswd)) 2.9 IF_MKSWAP(APPLET(mkswap, _BB_DIR_SBIN, _BB_SUID_DROP)) 2.10 IF_MKTEMP(APPLET(mktemp, _BB_DIR_BIN, _BB_SUID_DROP)) 2.11 @@ -11,7 +11,7 @@ 2.12 2.13 --- busybox-1.16.1/include/usage.h 2.14 +++ busybox-1.16.1/include/usage.h 2.15 -@@ -2967,6 +2967,20 @@ 2.16 +@@ -2984,6 +2984,20 @@ 2.17 " which are the default for alias 'tulip2' overridden by the options 'irq=2 io=0x210'\n\n" \ 2.18 " from the command line\n" 2.19
3.1 --- a/busybox/stuff/busybox-1.16.1-modprobe.u Wed Jun 23 16:11:06 2010 +0200 3.2 +++ b/busybox/stuff/busybox-1.16.1-modprobe.u Wed Jun 23 21:48:13 2010 +0200 3.3 @@ -1,6 +1,6 @@ 3.4 --- busybox-1.16.1/include/usage.h 3.5 +++ busybox-1.16.1/include/usage.h 3.6 -@@ -2881,7 +2881,7 @@ 3.7 +@@ -2898,7 +2898,7 @@ 3.8 #define modprobe_trivial_usage \ 3.9 IF_MODPROBE_SMALL("[-qfwrsv] MODULE [symbol=value]...") \ 3.10 IF_NOT_MODPROBE_SMALL("[-" \ 3.11 @@ -9,7 +9,7 @@ 3.12 IF_FEATURE_MODPROBE_BLACKLIST("b")"] MODULE [symbol=value]...") 3.13 #define modprobe_full_usage "\n\n" \ 3.14 "Options:" \ 3.15 -@@ -2898,6 +2898,7 @@ 3.16 +@@ -2915,6 +2915,7 @@ 3.17 "\n -k Make module autoclean-able" \ 3.18 ) \ 3.19 "\n -n Dry run" \
4.1 --- a/busybox/stuff/busybox-1.16.1-stat.u Wed Jun 23 16:11:06 2010 +0200 4.2 +++ b/busybox/stuff/busybox-1.16.1-stat.u Wed Jun 23 21:48:13 2010 +0200 4.3 @@ -65,7 +65,7 @@ 4.4 4.5 --- busybox-1.16.1/include/usage.h 4.6 +++ busybox-1.16.1/include/usage.h 4.7 -@@ -4184,6 +4184,7 @@ 4.8 +@@ -4201,6 +4201,7 @@ 4.9 "\n -f Display filesystem status" \ 4.10 "\n -L Follow links" \ 4.11 "\n -t Display info in terse form" \
5.1 --- a/busybox/stuff/busybox-1.16.1-vcsa2txt.u Wed Jun 23 16:11:06 2010 +0200 5.2 +++ b/busybox/stuff/busybox-1.16.1-vcsa2txt.u Wed Jun 23 21:48:13 2010 +0200 5.3 @@ -1,6 +1,14 @@ 5.4 --- busybox-1.16.1/include/applets.h 5.5 +++ busybox-1.16.1/include/applets.h 5.6 -@@ -420,6 +420,7 @@ 5.7 +@@ -105,6 +105,7 @@ 5.8 + IF_CLEAR(APPLET(clear, _BB_DIR_USR_BIN, _BB_SUID_DROP)) 5.9 + IF_CMP(APPLET(cmp, _BB_DIR_USR_BIN, _BB_SUID_DROP)) 5.10 + IF_COMM(APPLET(comm, _BB_DIR_USR_BIN, _BB_SUID_DROP)) 5.11 ++IF_VCSA2TXT(APPLET(conspy, _BB_DIR_USR_BIN, _BB_SUID_DROP)) 5.12 + IF_CP(APPLET_NOEXEC(cp, cp, _BB_DIR_BIN, _BB_SUID_DROP, cp)) 5.13 + IF_CPIO(APPLET(cpio, _BB_DIR_BIN, _BB_SUID_DROP)) 5.14 + IF_CROND(APPLET(crond, _BB_DIR_USR_SBIN, _BB_SUID_DROP)) 5.15 +@@ -420,6 +421,7 @@ 5.16 IF_UUDECODE(APPLET(uudecode, _BB_DIR_USR_BIN, _BB_SUID_DROP)) 5.17 IF_UUENCODE(APPLET(uuencode, _BB_DIR_USR_BIN, _BB_SUID_DROP)) 5.18 IF_VCONFIG(APPLET(vconfig, _BB_DIR_SBIN, _BB_SUID_DROP)) 5.19 @@ -11,14 +19,38 @@ 5.20 5.21 --- busybox-1.16.1/include/usage.h 5.22 +++ busybox-1.16.1/include/usage.h 5.23 -@@ -5011,6 +5011,13 @@ 5.24 +@@ -440,6 +440,23 @@ 5.25 + "\n -1 Close stdout" \ 5.26 + "\n -2 Close stderr" \ 5.27 + 5.28 ++#define conspy_trivial_usage \ 5.29 ++ "[-vcsnd] [-x rows] [-y lines] [virtual_console]" 5.30 ++#define conspy_full_usage "\n\n" \ 5.31 ++ "A text-mode VNC like program for Linux virtual terminals.\n" \ 5.32 ++ "\nTo exit, quickly press escape 3 times.\n" \ 5.33 ++ "\nvirtual_console:\n" \ 5.34 ++ " omitted Track the current console.\n" \ 5.35 ++ " 1..63 Virtual console N.\n" \ 5.36 ++ "\nOptions:" \ 5.37 ++ "\n -v Don't send keystrokes to the console." \ 5.38 ++ "\n -c May create device in /dev." \ 5.39 ++ "\n -s Open a SHELL session." \ 5.40 ++ "\n -n No colors. Black & white only." \ 5.41 ++ "\n -d Dump console to stdout."\ 5.42 ++ "\n -x r Skip the r first rows."\ 5.43 ++ "\n -y l Skip the l first lines."\ 5.44 ++ 5.45 + #define setuidgid_trivial_usage \ 5.46 + "USER PROG ARGS" 5.47 + #define setuidgid_full_usage "\n\n" \ 5.48 +@@ -5011,6 +5028,13 @@ 5.49 "\n set_ingress_map [vlan-name] [skb_priority] [vlan_qos]" \ 5.50 "\n set_name_type [name-type]" \ 5.51 5.52 +#define vcsa2txt_trivial_usage \ 5.53 + "stdin" 5.54 +#define vcsa2txt_full_usage \ 5.55 -+ "Filter /dev/vcsa* to ansi escape sequences" 5.56 ++ " Filter /dev/vcsa* to ansi escape sequences" 5.57 +#define vcsa2txt_example_usage \ 5.58 + "# vcsa2txt < /dev/vcsa1\n" 5.59 + 5.60 @@ -33,7 +65,7 @@ 5.61 Write a message to all users that are logged in. 5.62 5.63 +config VCSA2TXT 5.64 -+ bool "vcsa2txt" 5.65 ++ bool "vcsa2txt/conspy" 5.66 + default n 5.67 + help 5.68 + Filter /dev/vcsa* output to ansi escape sequences. 5.69 @@ -52,83 +84,493 @@ 5.70 5.71 --- busybox-1.16.1/util-linux/vcsa2txt.c 5.72 +++ busybox-1.16.1/util-linux/vcsa2txt.c 5.73 -@@ -0,0 +1,79 @@ 5.74 +@@ -0,0 +1,489 @@ 5.75 +/* vi: set sw=4 ts=4: */ 5.76 +/* 5.77 -+ * /dev/vcsa* filter for busybox 5.78 ++ * A text-mode VNC like program for Linux virtual terminals. 5.79 + * 5.80 + * pascal.bellard@ads-lu.com 5.81 + * 5.82 ++ * Based on Russell Stuart's conspy.c 5.83 ++ * http://ace-host.stuart.id.au/russell/files/conspy.c 5.84 ++ * 5.85 + * Licensed under GPLv2 or later, see file License in this tarball for details. 5.86 ++ * 5.87 ++ * example : conspy num shared access to console num 5.88 ++ * or conspy -d num screenshot of console num 5.89 ++ * or conspy -cs num poor man's GNU screen like 5.90 + */ 5.91 -+ 5.92 ++ 5.93 ++//applet:IF_CONSPY(APPLET(conspy, _BB_DIR_BIN, _BB_SUID_DROP)) 5.94 ++ 5.95 ++//kbuild:lib-$(CONFIG_CONSPY) += conspy.o 5.96 ++ 5.97 ++//config:config CONSPY 5.98 ++//config: bool "conspy" 5.99 ++//config: default n 5.100 ++//config: help 5.101 ++//config: A text-mode VNC like program for Linux virtual terminals. 5.102 ++//config: example : conspy num shared access to console num 5.103 ++//config: or conspy -d num screenshot of console num 5.104 ++//config: or conspy -cs num poor man's GNU screen like 5.105 ++ 5.106 ++//usage:#define conspy_trivial_usage 5.107 ++//usage: "[-vcsndf] [-x ROW] [-y LINE] [CONSOLE_NO]" 5.108 ++//usage:#define conspy_full_usage "\n\n" 5.109 ++//usage: "A text-mode VNC like program for Linux virtual consoles." 5.110 ++//usage: "\nTo exit, quickly press ESC 3 times." 5.111 ++//usage: "\n" 5.112 ++//usage: "\nOptions:" 5.113 ++//usage: "\n -v Don't send keystrokes to the console" 5.114 ++//usage: "\n -c Create missing devices in /dev" 5.115 ++//usage: "\n -s Open a SHELL session" 5.116 ++//usage: "\n -n Black & white" 5.117 ++//usage: "\n -d Dump console to stdout" 5.118 ++//usage: "\n -f Follow cursor" 5.119 ++//usage: "\n -x ROW Starting row" 5.120 ++//usage: "\n -y LINE Starting line" 5.121 ++ 5.122 +#include "libbb.h" 5.123 ++#include <sys/kd.h> 5.124 ++ 5.125 ++struct screen_info { 5.126 ++ unsigned char lines, rows, cursor_x, cursor_y; 5.127 ++}; 5.128 ++ 5.129 ++#define CHAR(x) ((x)[0]) 5.130 ++#define ATTR(x) ((x)[1]) 5.131 ++#define NEXT(x) ((x)+=2) 5.132 ++#define DATA(x) (* (short *) (x)) 5.133 ++ 5.134 ++struct globals { 5.135 ++ char* data; 5.136 ++ int size; 5.137 ++ int x, y; 5.138 ++ int kbd_fd; 5.139 ++ unsigned width; 5.140 ++ unsigned height; 5.141 ++ char last_attr; 5.142 ++ int ioerror_count; 5.143 ++ int key_count; 5.144 ++ int escape_count; 5.145 ++ int nokeys; 5.146 ++ int current; 5.147 ++ int vcsa_fd; 5.148 ++ struct screen_info info; 5.149 ++ struct termios term_orig; 5.150 ++}; 5.151 ++ 5.152 ++#define G (*ptr_to_globals) 5.153 ++#define INIT_G() do { \ 5.154 ++ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 5.155 ++} while (0) 5.156 ++ 5.157 ++enum { 5.158 ++ FLAG_v, // view only 5.159 ++ FLAG_c, // create device if need 5.160 ++ FLAG_s, // session 5.161 ++ FLAG_n, // no colors 5.162 ++ FLAG_d, // dump screen 5.163 ++ FLAG_f, // follow cursor 5.164 ++}; 5.165 ++#define FLAG(x) (1 << FLAG_##x) 5.166 ++#define BW (option_mask32 & FLAG(n)) 5.167 ++ 5.168 ++static void screen_read_close(void) 5.169 ++{ 5.170 ++ unsigned i, j; 5.171 ++ char *data = G.data + G.current; 5.172 ++ 5.173 ++ xread(G.vcsa_fd, data, G.size); 5.174 ++ G.last_attr = 0; 5.175 ++ for (i = 0; i < G.info.lines; i++) { 5.176 ++ for (j = 0; j < G.info.rows; j++, NEXT(data)) { 5.177 ++ unsigned x = j - G.x; // if will catch j < G.x too 5.178 ++ unsigned y = i - G.y; // if will catch i < G.y too 5.179 ++ 5.180 ++ if (CHAR(data) < ' ') 5.181 ++ CHAR(data) = ' '; 5.182 ++ if (y >= G.height || x >= G.width) 5.183 ++ DATA(data) = 0; 5.184 ++ } 5.185 ++ } 5.186 ++ close(G.vcsa_fd); 5.187 ++} 5.188 ++ 5.189 ++static void screen_char(char *data) 5.190 ++{ 5.191 ++ if (!BW && G.last_attr != ATTR(data)) { 5.192 ++ // BLGCRMOW 5.193 ++ static const char color[8] = "04261537"; 5.194 ++ 5.195 ++ printf("\033[%c;4%c;3%cm", 5.196 ++ (ATTR(data) & 8) ? '1' // bold 5.197 ++ : '0', // defaults 5.198 ++ color[(ATTR(data) >> 4) & 7], color[ATTR(data) & 7]); 5.199 ++ G.last_attr = ATTR(data); 5.200 ++ } 5.201 ++ bb_putchar(CHAR(data)); 5.202 ++} 5.203 ++ 5.204 ++#define clrscr() printf("\033[1;1H" "\033[0J") 5.205 ++#define curoff() printf("\033[?25l") 5.206 ++ 5.207 ++static void curon(void) 5.208 ++{ 5.209 ++ printf("\033[?25h"); 5.210 ++} 5.211 ++ 5.212 ++static void gotoxy(int row, int line) 5.213 ++{ 5.214 ++ printf("\033[%u;%uH", line + 1, row + 1); 5.215 ++} 5.216 ++ 5.217 ++static void screen_dump(void) 5.218 ++{ 5.219 ++ int linefeed_cnt; 5.220 ++ int line, row; 5.221 ++ int linecnt = G.info.lines - G.y; 5.222 ++ char *data = G.data + G.current + (2 * G.y * G.info.rows); 5.223 ++ 5.224 ++ linefeed_cnt = 0; 5.225 ++ for (line = 0; line < linecnt && line < G.height; line++) { 5.226 ++ int space_cnt = 0; 5.227 ++ for (row = 0; row < G.info.rows; row++, NEXT(data)) { 5.228 ++ unsigned tty_row = row - G.x; // if will catch row < G.x too 5.229 ++ 5.230 ++ if (tty_row >= G.width) 5.231 ++ continue; 5.232 ++ space_cnt++; 5.233 ++ if (BW && (CHAR(data) | ' ') == ' ') 5.234 ++ continue; 5.235 ++ while (linefeed_cnt != 0) { 5.236 ++ bb_putchar('\r'); 5.237 ++ bb_putchar('\n'); 5.238 ++ linefeed_cnt--; 5.239 ++ } 5.240 ++ while (--space_cnt) 5.241 ++ bb_putchar(' '); 5.242 ++ screen_char(data); 5.243 ++ } 5.244 ++ linefeed_cnt++; 5.245 ++ } 5.246 ++} 5.247 ++ 5.248 ++static void curmove(void) 5.249 ++{ 5.250 ++ unsigned cx = G.info.cursor_x - G.x; 5.251 ++ unsigned cy = G.info.cursor_y - G.y; 5.252 ++ 5.253 ++ if (cx >= G.width || cy >= G.height) { 5.254 ++ curoff(); 5.255 ++ } else { 5.256 ++ curon(); 5.257 ++ gotoxy(cx, cy); 5.258 ++ } 5.259 ++ fflush_all(); 5.260 ++} 5.261 ++ 5.262 ++static void cleanup(int code) 5.263 ++{ 5.264 ++ curon(); 5.265 ++ fflush_all(); 5.266 ++ tcsetattr(G.kbd_fd, TCSANOW, &G.term_orig); 5.267 ++ if (ENABLE_FEATURE_CLEAN_UP) { 5.268 ++ free(ptr_to_globals); 5.269 ++ close(G.kbd_fd); 5.270 ++ } 5.271 ++ // Reset attributes 5.272 ++ if (!BW) 5.273 ++ printf("\033[0m"); 5.274 ++ bb_putchar('\n'); 5.275 ++ if (code > 1) 5.276 ++ kill_myself_with_sig(code); // does not return 5.277 ++ exit(code); 5.278 ++} 5.279 ++ 5.280 ++static void get_initial_data(const char* vcsa_name) 5.281 ++{ 5.282 ++ G.vcsa_fd = xopen(vcsa_name, O_RDONLY); 5.283 ++ xread(G.vcsa_fd, &G.info, 4); 5.284 ++ G.size = G.info.rows * G.info.lines * 2; 5.285 ++ G.width = G.height = UINT_MAX; 5.286 ++ G.data = xzalloc(2 * G.size); 5.287 ++ screen_read_close(); 5.288 ++} 5.289 ++ 5.290 ++static void create_cdev_if_doesnt_exist(const char* name, dev_t dev) 5.291 ++{ 5.292 ++ int fd = open(name, O_RDONLY); 5.293 ++ if (fd != -1) 5.294 ++ close(fd); 5.295 ++ else if (errno == ENOENT) 5.296 ++ mknod(name, S_IFCHR | 0660, dev); 5.297 ++} 5.298 ++ 5.299 ++static NOINLINE void start_shell_in_child(const char* tty_name) 5.300 ++{ 5.301 ++ int pid = vfork(); 5.302 ++ if (pid < 0) { 5.303 ++ bb_perror_msg_and_die("vfork"); 5.304 ++ } 5.305 ++ if (pid == 0) { 5.306 ++ struct termios termchild; 5.307 ++ char *shell = getenv("SHELL"); 5.308 ++ 5.309 ++ if (!shell) 5.310 ++ shell = (char *) DEFAULT_SHELL; 5.311 ++ signal(SIGHUP, SIG_IGN); 5.312 ++ // set tty as a controlling tty 5.313 ++ setsid(); 5.314 ++ // make tty to be input, output, error 5.315 ++ close(0); 5.316 ++ xopen(tty_name, O_RDWR); // uses fd 0 5.317 ++ xdup2(0, 1); 5.318 ++ xdup2(0, 2); 5.319 ++ ioctl(0, TIOCSCTTY, 1); 5.320 ++ tcsetpgrp(0, getpid()); 5.321 ++ tcgetattr(0, &termchild); 5.322 ++ termchild.c_lflag |= ECHO; 5.323 ++ termchild.c_oflag |= ONLCR | XTABS; 5.324 ++ termchild.c_iflag |= ICRNL; 5.325 ++ termchild.c_iflag &= ~IXOFF; 5.326 ++ tcsetattr_stdin_TCSANOW(&termchild); 5.327 ++ execl(shell, shell, "-i", (char *) NULL); 5.328 ++ bb_simple_perror_msg_and_die(shell); 5.329 ++ } 5.330 ++} 5.331 + 5.332 +int vcsa2txt_main(int argc) MAIN_EXTERNALLY_VISIBLE; 5.333 +int vcsa2txt_main(int argc) 5.334 +{ 5.335 -+ struct { 5.336 -+ unsigned char l, c, x, y; // man 4 console_codes 5.337 -+ } scrn; 5.338 -+ unsigned char last = 0, ch[2]; // BLGCRMOW 5.339 -+ static unsigned char end[5] = "\e[0m\n", color[8] = "04261537"; 5.340 -+ int sp, lf, x; 5.341 -+ 5.342 -+ if (safe_read(0, &scrn, 4) < 0) return 1; 5.343 -+ for (lf = 0; scrn.l; lf++, scrn.l--) { 5.344 -+ for (sp = x = 0; ++x <= scrn.c;) { 5.345 -+ if (safe_read(0, &ch[0], 2) < 0) return 1; 5.346 -+ if (argc > 1) ch[1] = 0; 5.347 -+ sp++; 5.348 -+ if (last == ch[1] && ch[0] == ' ') continue; 5.349 -+ for (lf++; --lf;) bb_putchar('\n'); 5.350 -+ while (--sp) bb_putchar(' '); 5.351 -+#define ENABLE_VCSA_PACKED 1 5.352 -+#if ENABLE_VCSA_PACKED 5.353 -+ if (last ^= ch[1]) { 5.354 -+ char esc[16],*s; 5.355 -+ struct offsets { 5.356 -+ char mask, type, shr; 5.357 -+ } *p; 5.358 -+ static struct offsets offset[3] = { 5.359 -+ {8,0,1}, {0x70,'4',4}, {7,'3',0} 5.360 -+ }; 5.361 -+ static char init = 0x7F; 5.362 ++ INIT_G(); 5.363 ++ option_mask32 = FLAG(n); 5.364 ++ if (argc < 2) option_mask32 = 0; 5.365 ++ xread(0, &G.info, 4); 5.366 ++ G.size = G.info.rows * G.info.lines * 2; 5.367 ++ G.width = G.height = UINT_MAX; 5.368 ++ G.data = xzalloc(G.size); 5.369 ++ screen_read_close(); 5.370 ++ screen_dump(); 5.371 ++ bb_putchar('\n'); 5.372 ++ if (ENABLE_FEATURE_CLEAN_UP) { 5.373 ++ free(ptr_to_globals); 5.374 ++ close(G.kbd_fd); 5.375 ++ } 5.376 ++ return 0; 5.377 ++} 5.378 ++ 5.379 ++int conspy_main(int argc UNUSED_PARAM, char **argv) MAIN_EXTERNALLY_VISIBLE; 5.380 ++int conspy_main(int argc UNUSED_PARAM, char **argv) 5.381 ++{ 5.382 ++ char vcsa_name[sizeof("/dev/vcsa") + 2]; 5.383 ++ char tty_name[sizeof("/dev/tty") + 2]; 5.384 ++#define keybuf bb_common_bufsiz1 5.385 ++ struct termios termbuf; 5.386 ++ unsigned opts; 5.387 ++ unsigned ttynum; 5.388 ++ int poll_timeout_ms; 5.389 ++#if ENABLE_LONG_OPTS 5.390 ++ static const char getopt_longopts[] ALIGN1 = 5.391 ++ "viewonly\0" No_argument "v" 5.392 ++ "createdevice\0" No_argument "c" 5.393 ++ "session\0" No_argument "s" 5.394 ++ "nocolors\0" No_argument "n" 5.395 ++ "dump\0" No_argument "d" 5.396 ++ "follow\0" No_argument "f" 5.397 ++ ; 5.398 ++ 5.399 ++ applet_long_options = getopt_longopts; 5.400 ++#endif 5.401 ++ INIT_G(); 5.402 ++ 5.403 ++ opt_complementary = "x+:y+"; // numeric params 5.404 ++ opts = getopt32(argv, "vcsndfx:y:", &G.x, &G.y); 5.405 ++ argv += optind; 5.406 ++ ttynum = 0; 5.407 ++ if (argv[0]) { 5.408 ++ ttynum = xatou_range(argv[0], 0, 63); 5.409 ++ } 5.410 ++ sprintf(vcsa_name, "/dev/vcsa%u", ttynum); 5.411 ++ sprintf(tty_name, "%s%u", "/dev/tty", ttynum); 5.412 ++ if (opts & FLAG(c)) { 5.413 ++ if ((opts & (FLAG(s)|FLAG(v))) != FLAG(v)) 5.414 ++ create_cdev_if_doesnt_exist(tty_name, makedev(4, ttynum)); 5.415 ++ create_cdev_if_doesnt_exist(vcsa_name, makedev(7, 128 + ttynum)); 5.416 ++ } 5.417 ++ if ((opts & FLAG(s)) && ttynum) { 5.418 ++ start_shell_in_child(tty_name); 5.419 ++ } 5.420 ++ 5.421 ++ get_initial_data(vcsa_name); 5.422 ++ G.kbd_fd = xopen(CURRENT_TTY, O_RDONLY); 5.423 ++ if (opts & FLAG(d)) { 5.424 ++ screen_dump(); 5.425 ++ bb_putchar('\n'); 5.426 ++ if (ENABLE_FEATURE_CLEAN_UP) { 5.427 ++ free(ptr_to_globals); 5.428 ++ close(G.kbd_fd); 5.429 ++ } 5.430 ++ return 0; 5.431 ++ } 5.432 ++ 5.433 ++ bb_signals(BB_FATAL_SIGS, cleanup); 5.434 ++ // All characters must be passed through to us unaltered 5.435 ++ tcgetattr(G.kbd_fd, &G.term_orig); 5.436 ++ termbuf = G.term_orig; 5.437 ++ termbuf.c_iflag &= ~(BRKINT|INLCR|ICRNL|IXON|IXOFF|IUCLC|IXANY|IMAXBEL); 5.438 ++ termbuf.c_oflag &= ~(OPOST); 5.439 ++ termbuf.c_lflag &= ~(ISIG|ICANON|ECHO); 5.440 ++ termbuf.c_cc[VMIN] = 1; 5.441 ++ termbuf.c_cc[VTIME] = 0; 5.442 ++ tcsetattr(G.kbd_fd, TCSANOW, &termbuf); 5.443 ++ poll_timeout_ms = 250; 5.444 ++ while (1) { 5.445 ++ struct pollfd pfd; 5.446 ++ int bytes_read; 5.447 ++ int i, j; 5.448 ++ char *data, *old; 5.449 ++ 5.450 ++ old = G.data + G.current; 5.451 ++ G.current = G.size - G.current; 5.452 ++ data = G.data + G.current; 5.453 + 5.454 -+ s = esc+2; 5.455 -+ *(short *)esc = ntohs(256*'\e'+'['); 5.456 -+ p = offset; 5.457 -+ do { 5.458 -+ if ((init|last) & p->mask) { 5.459 -+ int c = (ch[1] & p->mask) >> p->shr; 5.460 -+ 5.461 -+ if ((*s = p->type) != 0) s++; 5.462 -+ else if (c == 0) { 5.463 -+ c = 2; 5.464 -+ *s++ = '2'; /* normal */ 5.465 ++ // Close & re-open vcsa in case they have 5.466 ++ // swapped virtual consoles 5.467 ++ G.vcsa_fd = xopen(vcsa_name, O_RDONLY); 5.468 ++ xread(G.vcsa_fd, &G.info, 4); 5.469 ++ if (G.size != (G.info.rows * G.info.lines * 2)) { 5.470 ++ cleanup(1); 5.471 ++ } 5.472 ++ i = G.width; 5.473 ++ j = G.height; 5.474 ++ get_terminal_width_height(G.kbd_fd, &G.width, &G.height); 5.475 ++ if ((option_mask32 & FLAG(f))) { 5.476 ++ int nx = G.info.cursor_x - G.width + 1; 5.477 ++ int ny = G.info.cursor_y - G.height + 1; 5.478 ++ 5.479 ++ if (G.info.cursor_x < G.x) { 5.480 ++ G.x = G.info.cursor_x; 5.481 ++ i = 0; // force refresh 5.482 + } 5.483 -+ *s++ = color[c]; 5.484 -+ *s++ = ';'; 5.485 -+ } 5.486 -+ } while (p++->shr); 5.487 -+ s[-1] = 'm'; 5.488 -+ init = 0; 5.489 -+ fwrite(esc,s-esc,1,stdout); 5.490 -+ } 5.491 -+ last = ch[1]; 5.492 -+#else 5.493 -+ if (last != ch[1]) { 5.494 -+ static char esc[10] = "\e[0;47;37m"; 5.495 -+ 5.496 -+ esc[2] = ((last = ch[1]) & 8) ? '1' /* bold */ : '0' /* defaults */; 5.497 -+ esc[sizeof(esc)-5] = color[(ch[1] >> 4) & 7]; 5.498 -+ esc[sizeof(esc)-2] = color[ch[1] & 7]; 5.499 -+ fwrite(esc,sizeof(esc),1,stdout); 5.500 -+ } 5.501 -+#endif 5.502 -+ bb_putchar(ch[0]); 5.503 ++ if (nx > G.x) { 5.504 ++ G.x = nx; 5.505 ++ i = 0; // force refresh 5.506 ++ } 5.507 ++ if (G.info.cursor_y < G.y) { 5.508 ++ G.y = G.info.cursor_y; 5.509 ++ i = 0; // force refresh 5.510 ++ } 5.511 ++ if (ny > G.y) { 5.512 ++ G.y = ny; 5.513 ++ i = 0; // force refresh 5.514 ++ } 5.515 ++ } 5.516 ++ 5.517 ++ // Scan console data and redraw our tty where needed 5.518 ++ screen_read_close(); 5.519 ++ if (i != G.width || j != G.height) { 5.520 ++ clrscr(); 5.521 ++ screen_dump(); 5.522 ++ } 5.523 ++ else for (i = 0; i < G.info.lines; i++) { 5.524 ++ char *last = last; 5.525 ++ char *first = NULL; 5.526 ++ int iy = i - G.y; 5.527 ++ 5.528 ++ if (iy >= (int) G.height) 5.529 ++ break; 5.530 ++ for (j = 0; j < G.info.rows; j++) { 5.531 ++ last = data; 5.532 ++ if (DATA(data) != DATA(old) && iy >= 0) { 5.533 ++ unsigned jx = j - G.x; 5.534 ++ 5.535 ++ last = NULL; 5.536 ++ if (first == NULL && jx < G.width) { 5.537 ++ first = data; 5.538 ++ gotoxy(jx, iy); 5.539 ++ } 5.540 ++ } 5.541 ++ NEXT(old); 5.542 ++ NEXT(data); 5.543 ++ } 5.544 ++ if (first == NULL) 5.545 ++ continue; 5.546 ++ if (last == NULL) 5.547 ++ last = data; 5.548 ++ 5.549 ++ // Write the data to the screen 5.550 ++ for (; first < last; NEXT(first)) 5.551 ++ screen_char(first); 5.552 ++ } 5.553 ++ curmove(); 5.554 ++ 5.555 ++ // Wait for local user keypresses 5.556 ++ pfd.fd = G.kbd_fd; 5.557 ++ pfd.events = POLLIN; 5.558 ++ bytes_read = 0; 5.559 ++ switch (poll(&pfd, 1, poll_timeout_ms)) { 5.560 ++ char *k; 5.561 ++ case -1: 5.562 ++ if (errno != EINTR) 5.563 ++ cleanup(1); 5.564 ++ break; 5.565 ++ case 0: 5.566 ++ if (++G.nokeys >= 4) 5.567 ++ G.nokeys = G.escape_count = 0; 5.568 ++ break; 5.569 ++ default: 5.570 ++ // Read the keys pressed 5.571 ++ k = keybuf + G.key_count; 5.572 ++ bytes_read = read(G.kbd_fd, k, sizeof(keybuf) - G.key_count); 5.573 ++ if (bytes_read < 0) 5.574 ++ cleanup(1); 5.575 ++ 5.576 ++ // Do exit processing 5.577 ++ for (i = 0; i < bytes_read; i++) { 5.578 ++ if (k[i] != '\033') G.escape_count = 0; 5.579 ++ else if (++G.escape_count >= 3) 5.580 ++ cleanup(0); 5.581 ++ } 5.582 ++ } 5.583 ++ poll_timeout_ms = 250; 5.584 ++ 5.585 ++ // Insert all keys pressed into the virtual console's input 5.586 ++ // buffer. Don't do this if the virtual console is in scan 5.587 ++ // code mode - giving ASCII characters to a program expecting 5.588 ++ // scan codes will confuse it. 5.589 ++ if (!(option_mask32 & FLAG(v)) && G.escape_count == 0) { 5.590 ++ int handle, result; 5.591 ++ long kbd_mode; 5.592 ++ 5.593 ++ G.key_count += bytes_read; 5.594 ++ handle = xopen(tty_name, O_WRONLY); 5.595 ++ result = ioctl(handle, KDGKBMODE, &kbd_mode); 5.596 ++ if (result == -1) 5.597 ++ /* nothing */; 5.598 ++ else if (kbd_mode != K_XLATE && kbd_mode != K_UNICODE) 5.599 ++ G.key_count = 0; // scan code mode 5.600 ++ else { 5.601 ++ for (i = 0; i < G.key_count && result != -1; i++) 5.602 ++ result = ioctl(handle, TIOCSTI, keybuf + i); 5.603 ++ G.key_count -= i; 5.604 ++ if (G.key_count) 5.605 ++ memmove(keybuf, keybuf + i, G.key_count); 5.606 ++ // If there is an application on console which reacts 5.607 ++ // to keypresses, we need to make our first sleep 5.608 ++ // shorter to quickly redraw whatever it printed there. 5.609 ++ poll_timeout_ms = 20; 5.610 ++ } 5.611 ++ // Close & re-open tty in case they have 5.612 ++ // swapped virtual consoles 5.613 ++ close(handle); 5.614 ++ 5.615 ++ // We sometimes get spurious IO errors on the TTY 5.616 ++ // as programs close and re-open it 5.617 ++ if (result != -1) 5.618 ++ G.ioerror_count = 0; 5.619 ++ else if (errno != EIO || ++G.ioerror_count > 4) 5.620 ++ cleanup(1); 5.621 ++ } 5.622 + } 5.623 -+ } 5.624 -+ fwrite(end,sizeof(end),1,stdout); 5.625 -+ return 0; 5.626 +}