/* vi: set sw=4 ts=4: */
/*
 * A text-mode VNC like program for Linux virtual terminals.
 *
 * pascal.bellard@ads-lu.com
 *
 * Based on Russell Stuart's conspy.c
 *   http://ace-host.stuart.id.au/russell/files/conspy.c
 *
 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
 */

//applet:IF_CONSPY(APPLET(conspy, BB_DIR_BIN, BB_SUID_DROP))

//kbuild:lib-$(CONFIG_CONSPY) += conspy.o

//config:config CONSPY
//config:	bool "conspy"
//config:	default n
//config:	select PLATFORM_LINUX
//config:	help
//config:	  A text-mode VNC like program for Linux virtual terminals.
//config:	  example:  conspy NUM      shared access to console num
//config:	  or        conspy -nd NUM  screenshot of console num
//config:	  or        conspy -cs NUM  poor man's GNU screen like

//usage:#define conspy_trivial_usage
//usage:	"[-vcsndf] [-x COL] [-y LINE] [CONSOLE_NO]"
//usage:#define conspy_full_usage "\n\n"
//usage:     "A text-mode VNC like program for Linux virtual consoles."
//usage:     "\nTo exit, quickly press ESC 3 times."
//usage:     "\n"
//usage:     "\n	-v	Don't send keystrokes to the console"
//usage:     "\n	-c	Create missing devices in /dev"
//usage:     "\n	-s	Open a SHELL session"
//usage:     "\n	-n	Black & white"
//usage:     "\n	-d	Dump console to stdout"
//usage:     "\n	-f	Follow cursor"
//usage:     "\n	-x COL	Starting column"
//usage:     "\n	-y LINE	Starting line"

#include "libbb.h"
#include <sys/kd.h>


#define ESC "\033"

struct screen_info {
	unsigned char lines, cols, cursor_x, cursor_y;
};

#define CHAR(x) (*(uint8_t*)(x))
#define ATTR(x) (((uint8_t*)(x))[1])
#define NEXT(x) ((x) += 2)
#define DATA(x) (*(uint16_t*)(x))

struct globals {
	char* data;
	int size;
	int x, y;
	int kbd_fd;
	int ioerror_count;
	int key_count;
	int escape_count;
	int nokeys;
	int current;
	int first_line_offset;
	int last_attr;
	// cached local tty parameters
	unsigned width;
	unsigned height;
	unsigned col;
	unsigned line;
	smallint curoff; // unknown:0 cursor on:-1 cursor off:1
	char attrbuf[sizeof(ESC"[0;1;5;30;40m")];
	// remote console
	struct screen_info remote;
	// saved local tty terminfo
	struct termios term_orig;
	char vcsa_name[sizeof("/dev/vcsaNN")];
};

#define G (*ptr_to_globals)
#define INIT_G() do { \
	SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
	G.attrbuf[0] = '\033'; \
	G.attrbuf[1] = '['; \
	G.width = G.height = UINT_MAX; \
	G.last_attr--; \
} while (0)

enum {
	FLAG_v,  // view only
	FLAG_c,  // create device if need
	FLAG_s,  // session
	FLAG_n,  // no colors
	FLAG_d,  // dump screen
	FLAG_f,  // follow cursor
};
#define FLAG(x) (1 << FLAG_##x)
#define BW (option_mask32 & FLAG(n))

static void clrscr(void)
{
	// Home, clear till end of screen
	fputs(ESC"[1;1H" ESC"[J", stdout);
	G.col = G.line = 0;
}

static void set_cursor(int state)
{
	if (G.curoff != state) {
		G.curoff = state;
		fputs(ESC"[?25", stdout);
		bb_putchar("h?l"[1 + state]);
	}
}

static void gotoxy(int col, int line)
{
	if (G.col != col || G.line != line) {
		G.col = col;
		G.line = line;
		printf(ESC"[%u;%uH", line + 1, col + 1);
	}
}

static void cleanup(int code)
{
	set_cursor(-1); // cursor on
	tcsetattr(G.kbd_fd, TCSANOW, &G.term_orig);
	if (ENABLE_FEATURE_CLEAN_UP) {
		close(G.kbd_fd);
	}
	// Reset attributes
	if (!BW)
		fputs(ESC"[0m", stdout);
	bb_putchar('\n');
	if (code > 1)
		kill_myself_with_sig(code);
	exit(code);
}

static void screen_read_close(void)
{
	unsigned i, j;
	int vcsa_fd;
	char *data;

	// Close & re-open vcsa in case they have swapped virtual consoles
	vcsa_fd = xopen(G.vcsa_name, O_RDONLY);
	xread(vcsa_fd, &G.remote, 4);
	i = G.remote.cols * 2;
	G.first_line_offset = G.y * i;
	i *= G.remote.lines;
	if (G.data == NULL) {
		G.size = i;
		G.data = xzalloc(2 * i);
	}
	else if (G.size != i) {
		cleanup(1);
	}
	data = G.data + G.current;
	xread(vcsa_fd, data, G.size);
	close(vcsa_fd);
	for (i = 0; i < G.remote.lines; i++) {
		for (j = 0; j < G.remote.cols; j++, NEXT(data)) {
			unsigned x = j - G.x; // if will catch j < G.x too
			unsigned y = i - G.y; // if will catch i < G.y too

			if (CHAR(data) < ' ')
				CHAR(data) = ' ';
			if (y >= G.height || x >= G.width)
				DATA(data) = 0;
		}
	}
}

static void screen_char(char *data)
{
	if (!BW) {
		uint8_t attr = ATTR(data);
		//uint8_t attr = ATTR(data) >> 1; // for framebuffer console
		uint8_t attr_diff = G.last_attr ^ attr;

		if (attr_diff) {
// Attribute layout for VGA compatible text videobuffer:
// blinking text
// |red bkgd
// ||green bkgd
// |||blue bkgd
// vvvv
// 00000000 <- lsb bit on the right
//     bold text / text 8th bit
//      red text
//       green text
//        blue text
// TODO: apparently framebuffer-based console uses different layout
// (bug? attempt to get 8th text bit in better position?)
// red bkgd
// |green bkgd
// ||blue bkgd
// vvv
// 00000000 <- lsb bit on the right
//    bold text
//     red text
//      green text
//       blue text
//        text 8th bit
			// converting RGB color bit triad to BGR:
			static const char color[8] = "04261537";
			const uint8_t fg_mask = 0x07, bold_mask  = 0x08;
			const uint8_t bg_mask = 0x70, blink_mask = 0x80;
			char *ptr;

			ptr = G.attrbuf + 2; // skip "ESC ["

			// (G.last_attr & ~attr) has 1 only where
			// G.last_attr has 1 but attr has 0.
			// Here we check whether we have transition
			// bold->non-bold or blink->non-blink:
			if (G.last_attr < 0  // initial value
			 || ((G.last_attr & ~attr) & (bold_mask | blink_mask)) != 0
			) {
				*ptr++ = '0'; // "reset all attrs"
				*ptr++ = ';';
				// must set fg & bg, maybe need to set bold or blink:
				attr_diff = attr | ~(bold_mask | blink_mask);
			}
			G.last_attr = attr;
			if (attr_diff & bold_mask) {
				*ptr++ = '1';
				*ptr++ = ';';
			}
			if (attr_diff & blink_mask) {
				*ptr++ = '5';
				*ptr++ = ';';
			}
			if (attr_diff & fg_mask) {
				*ptr++ = '3';
				*ptr++ = color[attr & fg_mask];
				*ptr++ = ';';
			}
			if (attr_diff & bg_mask) {
				*ptr++ = '4';
				*ptr++ = color[(attr & bg_mask) >> 4];
				*ptr++ = ';';
			}
			if (ptr != G.attrbuf + 2) {
				ptr[-1] = 'm';
				*ptr = '\0';
				fputs(G.attrbuf, stdout);
			}
		}
	}
	putchar(CHAR(data));
	G.col++;
}

static void screen_dump(void)
{
	int linefeed_cnt;
	int line, col;
	int linecnt = G.remote.lines - G.y;
	char *data = G.data + G.current + G.first_line_offset;

	linefeed_cnt = 0;
	for (line = 0; line < linecnt && line < G.height; line++) {
		int space_cnt = 0;
		for (col = 0; col < G.remote.cols; col++, NEXT(data)) {
			unsigned tty_col = col - G.x; // if will catch col < G.x too

			if (tty_col >= G.width)
				continue;
			space_cnt++;
			if (BW && CHAR(data) == ' ')
				continue;
			while (linefeed_cnt != 0) {
				//bb_putchar('\r'); - tty driver does it for us
				bb_putchar('\n');
				linefeed_cnt--;
			}
			while (--space_cnt)
				bb_putchar(' ');
			screen_char(data);
		}
		linefeed_cnt++;
	}
}

static void curmove(void)
{
	unsigned cx = G.remote.cursor_x - G.x;
	unsigned cy = G.remote.cursor_y - G.y;
	int cursor = 1;

	if (cx < G.width && cy < G.height) {
		gotoxy(cx, cy);
		cursor = -1;
	}
	set_cursor(cursor);
}

static void create_cdev_if_doesnt_exist(const char* name, dev_t dev)
{
	int fd = open(name, O_RDONLY);
	if (fd != -1)
		close(fd);
	else if (errno == ENOENT)
		mknod(name, S_IFCHR | 0660, dev);
}

static NOINLINE void start_shell_in_child(const char* tty_name)
{
	int pid = xvfork();
	if (pid == 0) {
		struct termios termchild;
		const char *shell = get_shell_name();

		signal(SIGHUP, SIG_IGN);
		// set tty as a controlling tty
		setsid();
		// make tty to be input, output, error
		close(0);
		xopen(tty_name, O_RDWR); // uses fd 0
		xdup2(0, 1);
		xdup2(0, 2);
		ioctl(0, TIOCSCTTY, 1);
		tcsetpgrp(0, getpid());
		tcgetattr(0, &termchild);
		termchild.c_lflag |= ECHO;
		termchild.c_oflag |= ONLCR | XTABS;
		termchild.c_iflag |= ICRNL;
		termchild.c_iflag &= ~IXOFF;
		tcsetattr_stdin_TCSANOW(&termchild);
		execl(shell, shell, "-i", (char *) NULL);
		bb_simple_perror_msg_and_die(shell);
	}
}

int conspy_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int conspy_main(int argc UNUSED_PARAM, char **argv)
{
	char tty_name[sizeof("/dev/ttyNN")];
#define keybuf bb_common_bufsiz1
	struct termios termbuf;
	unsigned opts;
	unsigned ttynum;
	int poll_timeout_ms;
#if ENABLE_LONG_OPTS
	static const char getopt_longopts[] ALIGN1 =
		"viewonly\0"     No_argument "v"
		"createdevice\0" No_argument "c"
		"session\0"      No_argument "s"
		"nocolors\0"     No_argument "n"
		"dump\0"         No_argument "d"
		"follow\0"       No_argument "f"
		;

	applet_long_options = getopt_longopts;
#endif
	INIT_G();
	strcpy(G.vcsa_name, "/dev/vcsa");

	opt_complementary = "x+:y+"; // numeric params
	opts = getopt32(argv, "vcsndfx:y:", &G.x, &G.y);
	argv += optind;
	ttynum = 0;
	if (argv[0]) {
		ttynum = xatou_range(argv[0], 0, 63);
		sprintf(G.vcsa_name + sizeof("/dev/vcsa")-1, "%u", ttynum);
	}
	sprintf(tty_name, "%s%u", "/dev/tty", ttynum);
	if (opts & FLAG(c)) {
		if ((opts & (FLAG(s)|FLAG(v))) != FLAG(v))
			create_cdev_if_doesnt_exist(tty_name, makedev(4, ttynum));
		create_cdev_if_doesnt_exist(G.vcsa_name, makedev(7, 128 + ttynum));
	}
	if ((opts & FLAG(s)) && ttynum) {
		start_shell_in_child(tty_name);
	}

	screen_read_close();
	if (opts & FLAG(d)) {
		screen_dump();
		bb_putchar('\n');
		return 0;
	}

	bb_signals(BB_FATAL_SIGS, cleanup);

	// All characters must be passed through to us unaltered
	G.kbd_fd = xopen(CURRENT_TTY, O_RDONLY);
	tcgetattr(G.kbd_fd, &G.term_orig);
	termbuf = G.term_orig;
	termbuf.c_iflag &= ~(BRKINT|INLCR|ICRNL|IXON|IXOFF|IUCLC|IXANY|IMAXBEL);
	//termbuf.c_oflag &= ~(OPOST); - no, we still want \n -> \r\n
	termbuf.c_lflag &= ~(ISIG|ICANON|ECHO);
	termbuf.c_cc[VMIN] = 1;
	termbuf.c_cc[VTIME] = 0;
	tcsetattr(G.kbd_fd, TCSANOW, &termbuf);

	poll_timeout_ms = 250;
	while (1) {
		struct pollfd pfd;
		int bytes_read;
		int i, j;
		char *data, *old;

		// in the first loop G.width = G.height = 0: refresh
		i = G.width;
		j = G.height;
		get_terminal_width_height(G.kbd_fd, &G.width, &G.height);
		if (option_mask32 & FLAG(f)) {
			int nx = G.remote.cursor_x - G.width + 1;
			int ny = G.remote.cursor_y - G.height + 1;

			if (G.remote.cursor_x < G.x) {
				G.x = G.remote.cursor_x;
				i = 0; // force refresh
			}
			if (nx > G.x) {
				G.x = nx;
				i = 0; // force refresh
			}
			if (G.remote.cursor_y < G.y) {
				G.y = G.remote.cursor_y;
				i = 0; // force refresh
			}
			if (ny > G.y) {
				G.y = ny;
				i = 0; // force refresh
			}
		}

		// Scan console data and redraw our tty where needed
		old = G.data + G.current;
		G.current = G.size - G.current;
		data = G.data + G.current;
		screen_read_close();
		if (i != G.width || j != G.height) {
			clrscr();
			screen_dump();
		} else {
			// For each remote line
			old += G.first_line_offset;
			data += G.first_line_offset;
			for (i = G.y; i < G.remote.lines; i++) {
				char *first = NULL; // first char which needs updating
				char *last = last;  // last char which needs updating
				unsigned iy = i - G.y;

				if (iy >= G.height)
					break;
				for (j = 0; j < G.remote.cols; j++, NEXT(old), NEXT(data)) {
					unsigned jx = j - G.x; // if will catch j >= G.x too

					if (jx < G.width && DATA(data) != DATA(old)) {
						last = data;
						if (!first) {
							first = data;
							gotoxy(jx, iy);
						}
					}
				}
				if (first) {
					// Rewrite updated data on the local screen
					for (; first <= last; NEXT(first))
						screen_char(first);
				}
			}
		}
		curmove();

		// Wait for local user keypresses
		fflush_all();
		pfd.fd = G.kbd_fd;
		pfd.events = POLLIN;
		bytes_read = 0;
		switch (poll(&pfd, 1, poll_timeout_ms)) {
			char *k;
		case -1:
			if (errno != EINTR)
				cleanup(1);
			break;
		case 0:
			if (++G.nokeys >= 4)
				G.nokeys = G.escape_count = 0;
			break;
		default:
			// Read the keys pressed
			k = keybuf + G.key_count;
			bytes_read = read(G.kbd_fd, k, sizeof(keybuf) - G.key_count);
			if (bytes_read < 0)
				cleanup(1);

			// Do exit processing
			for (i = 0; i < bytes_read; i++) {
				if (k[i] != '\033')
					G.escape_count = 0;
				else if (++G.escape_count >= 3)
					cleanup(0);
			}
		}
		poll_timeout_ms = 250;
		if (option_mask32 & FLAG(v)) continue;

		// Insert all keys pressed into the virtual console's input
		// buffer.  Don't do this if the virtual console is in scan
		// code mode - giving ASCII characters to a program expecting
		// scan codes will confuse it.
		G.key_count += bytes_read;
		if (G.escape_count == 0) {
			int handle, result;
			long kbd_mode;

			handle = xopen(tty_name, O_WRONLY);
			result = ioctl(handle, KDGKBMODE, &kbd_mode);
			if (result >= 0) {
				char *p = keybuf;

				if (kbd_mode != K_XLATE && kbd_mode != K_UNICODE) {
					G.key_count = 0; // scan code mode
				}
				for (; G.key_count != 0; p++, G.key_count--) {
					result = ioctl(handle, TIOCSTI, p);
					if (result < 0) {
						memmove(keybuf, p, G.key_count);
						break;
					}
					// If there is an application on console which reacts
					// to keypresses, we need to make our first sleep
					// shorter to quickly redraw whatever it printed there.
					poll_timeout_ms = 20;
				}
			}
			// Close & re-open tty in case they have
			// swapped virtual consoles
			close(handle);

			// We sometimes get spurious IO errors on the TTY
			// as programs close and re-open it
			if (result >= 0)
				G.ioerror_count = 0;
			else if (errno != EIO || ++G.ioerror_count > 4)
				cleanup(1);
		}
	} /* while (1) */
}
