/* 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.
 */
//config:config CONSPY
//config:	bool "conspy (10 kb)"
//config:	default y
//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

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

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

//usage:#define conspy_trivial_usage
//usage:	"[-vcsndfFQ] [-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 /dev/{tty,vcsa}N"
//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	-F	Assume console is on a framebuffer device"
//usage:     "\n	-Q	Disable exit on ESC-ESC-ESC"
//usage:     "\n	-x COL	Starting column"
//usage:     "\n	-y LINE	Starting line"

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

#define ESC "\033"
#define CURSOR_ON	-1
#define CURSOR_OFF	1

#define DEV_TTY		"/dev/tty"
#define DEV_VCSA	"/dev/vcsa"

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("0;1;5;30;40m")];
	// remote console
	struct screen_info remote;
	// saved local tty terminfo
	struct termios term_orig;
	char vcsa_name[sizeof(DEV_VCSA "NN")];
};

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

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

static void putcsi(const char *s)
{
	fputs(ESC"[", stdout);
	fputs(s, stdout);
}

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

static void set_cursor(int state)
{
	if (G.curoff != state) {
		G.curoff = state;
		putcsi("?25");
		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) NORETURN;
static void cleanup(int code)
{
	set_cursor(CURSOR_ON);
	tcsetattr(G.kbd_fd, TCSANOW, &G.term_orig);
	if (ENABLE_FEATURE_CLEAN_UP) {
		close(G.kbd_fd);
	}
	// Reset attributes
	if (!BW)
		putcsi("0m");
	bb_putchar('\n');
	if (code > EXIT_FAILURE)
		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);
	}
	if (G.size != i) {
		cleanup(EXIT_FAILURE);
	}
	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 (y >= G.height || x >= G.width)
				DATA(data) = 0;
			else {
				uint8_t ch = CHAR(data);
				if (ch < ' ')
					CHAR(data) = ch | 0x40;
				else if (ch > 0x7e)
					CHAR(data) = '?';
			}
		}
	}
}

static void screen_char(char *data)
{
	if (!BW) {
		uint8_t attr_diff;
		uint8_t attr = ATTR(data);

		if (option_mask32 & FLAG(F)) {
			attr >>= 1;
		}
		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;

			// (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++; // last attribute
			}
			if (ptr != G.attrbuf) {
				ptr[-1] = 'm';
				*ptr = '\0';
				putcsi(G.attrbuf);
			}
		}
	}
	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 = CURSOR_OFF;

	if (cx < G.width && cy < G.height) {
		gotoxy(cx, cy);
		cursor = CURSOR_ON;
	}
	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_TTY "NN")];
	unsigned opts;
	unsigned ttynum;
	int poll_timeout_ms;
#if ENABLE_LONG_OPTS
	static const char conspy_longopts[] ALIGN1 =
		"viewonly\0"     No_argument "v"
		"createdevice\0" No_argument "c"
		"neverquit\0"    No_argument "Q"
		"session\0"      No_argument "s"
		"nocolors\0"     No_argument "n"
		"dump\0"         No_argument "d"
		"follow\0"       No_argument "f"
		"framebuffer\0"  No_argument "F"
		;
#endif
#define keybuf bb_common_bufsiz1
	setup_common_bufsiz();

	INIT_G();
	strcpy(G.vcsa_name, DEV_VCSA);

	// numeric params
	opts = getopt32long(argv, "vcQsndfFx:+y:+", conspy_longopts, &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);

	G.kbd_fd = xopen(CURRENT_TTY, O_RDONLY);

	// All characters must be passed through to us unaltered
	set_termios_to_raw(G.kbd_fd, &G.term_orig, 0
		| TERMIOS_CLEAR_ISIG // no signals on ^C ^Z etc
		| TERMIOS_RAW_INPUT  // turn off all input conversions
	);
	//Note: termios.c_oflag &= ~(OPOST); - no, we still want \n -> \r\n

	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)
				goto abort;
			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, COMMON_BUFSIZE - G.key_count);
			if (bytes_read < 0)
				goto abort;

			// Do exit processing
			if (!(option_mask32 & FLAG(Q))) {
				for (i = 0; i < bytes_read; i++) {
					if (k[i] != '\033')
						G.escape_count = -1;
					if (++G.escape_count >= 3)
						cleanup(EXIT_SUCCESS);
				}
			}
		}
		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;

				G.ioerror_count = 0;
				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;
				}
			}
			// We sometimes get spurious IO errors on the TTY
			// as programs close and re-open it
			else if (errno != EIO || ++G.ioerror_count > 4) {
				if (ENABLE_FEATURE_CLEAN_UP)
					close(handle);
				goto abort;
			}
			// Close & re-open tty in case they have
			// swapped virtual consoles
			close(handle);
		}
	} /* while (1) */
  abort:
	cleanup(EXIT_FAILURE);
}
