/* vi: set sw=4 ts=4: */
/*
 *  openvt.c - open a vt to run a command.
 *
 *  busyboxed by Quy Tonthat <quy@signal3.com>
 *  hacked by Tito <farmatito@tiscali.it>
 *
 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
 */

#include <linux/vt.h>
#include "libbb.h"

/* "Standard" openvt's man page (we do not support all of this):

openvt [-c NUM] [-fsulv] [--] [command [args]]

Find the first available VT, and run command on it. Stdio is directed
to that VT. If no command is specified then $SHELL is used.

-c NUM
    Use the given VT number, not the first free one.
-f
    Force opening a VT: don't try to check if VT is already in use.
-s
    Switch to the new VT when starting the command.
    The VT of the new command will be made the new current VT.
-u
    Figure out the owner of the current VT, and run login as that user.
    Suitable to be called by init. Shouldn't be used with -c or -l.
-l
    Make the command a login shell: a "-" is prepended to the argv[0]
    when command is executed.
-v
    Verbose.
-w
    Wait for command to complete. If -w and -s are used together,
    switch back to the controlling terminal when the command completes.

bbox:
-u: not implemented
-f: always in effect
-l: not implemented, ignored
-v: ignored
-ws: does NOT switch back
*/

/* Helper: does this fd understand VT_xxx? */
static int not_vt_fd(int fd)
{
	struct vt_stat vtstat;
	return ioctl(fd, VT_GETSTATE, &vtstat); /* !0: error, it's not VT fd */
}

/* Helper: get a fd suitable for VT_xxx */
static int get_vt_fd(void)
{
	int fd;

	/* Do we, by chance, already have it? */
	for (fd = 0; fd < 3; fd++)
		if (!not_vt_fd(fd))
    			return fd;
	/* _only_ O_NONBLOCK: ask for neither read not write perms */
	fd = open(DEV_CONSOLE, O_NONBLOCK);
	if (fd >= 0 && !not_vt_fd(fd))
		return fd;
	bb_error_msg_and_die("can't find open VT");
}

static int find_free_vtno(void)
{
	int vtno;
	int fd = get_vt_fd();

 	errno = 0;
	/*xfunc_error_retval = 3; - do we need compat? */
	if (ioctl(fd, VT_OPENQRY, &vtno) != 0 || vtno <= 0)
		bb_perror_msg_and_die("can't find open VT");
// Not really needed, grep for DAEMON_ONLY_SANITIZE
//	if (fd > 2)
//		close(fd);
	return vtno;
}

/* vfork scares gcc, it generates bigger code.
 * Keep it away from main program.
 * TODO: move to libbb; or adapt existing libbb's spawn().
 */
static NOINLINE void vfork_child(char **argv)
{
	if (vfork() == 0) {
		/* CHILD */
		/* Try to make this VT our controlling tty */
		setsid(); /* lose old ctty */
		ioctl(0, TIOCSCTTY, 0 /* 0: don't forcibly steal */);
		//bb_error_msg("our sid %d", getsid(0));
		//bb_error_msg("our pgrp %d", getpgrp());
		//bb_error_msg("VT's sid %d", tcgetsid(0));
		//bb_error_msg("VT's pgrp %d", tcgetpgrp(0));
		BB_EXECVP(argv[0], argv);
		bb_perror_msg_and_die("exec %s", argv[0]);
	}
}

int openvt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int openvt_main(int argc ATTRIBUTE_UNUSED, char **argv)
{
	char vtname[sizeof(VC_FORMAT) + sizeof(int)*3];
	struct vt_stat vtstat;
	char *str_c;
	int vtno;
	int flags;
	enum {
		OPT_c = (1 << 0),
		OPT_w = (1 << 1),
		OPT_s = (1 << 2),
		OPT_l = (1 << 3),
		OPT_f = (1 << 4),
		OPT_v = (1 << 5),
	};

	/* "+" - stop on first non-option */
	flags = getopt32(argv, "+c:wslfv", &str_c);
	argv += optind;

	if (flags & OPT_c) {
		/* Check for illegal vt number: < 1 or > 63 */
		vtno = xatou_range(str_c, 1, 63);
	} else {
		vtno = find_free_vtno();
	}

	/* Grab new VT */
	sprintf(vtname, VC_FORMAT, vtno);
	/* (Try to) clean up stray open fds above fd 2 */
	bb_daemonize_or_rexec(DAEMON_CLOSE_EXTRA_FDS | DAEMON_ONLY_SANITIZE, NULL);
	close(0);
	/*setsid(); - BAD IDEA: after we exit, child is SIGHUPed... */
	xopen(vtname, O_RDWR);
	xioctl(0, VT_GETSTATE, &vtstat);	

	if (flags & OPT_s) {
		xioctl(0, VT_ACTIVATE, (void*)(ptrdiff_t)vtno);
		xioctl(0, VT_WAITACTIVE, (void*)(ptrdiff_t)vtno);
	}

	if (!argv[0]) {
		argv--;
		argv[0] = getenv("SHELL");
		if (!argv[0])
			argv[0] = (char *) DEFAULT_SHELL;
		/*argv[1] = NULL; - already is */
	}

	xdup2(0, STDOUT_FILENO);
	xdup2(0, STDERR_FILENO);

#ifdef BLOAT
	/* Handle -l (login shell) option */
	const char *prog = argv[0];
	if (flags & OPT_l)
		argv[0] = xasprintf("-%s", argv[0]);
#endif

	vfork_child(argv);
	if (flags & OPT_w) {
		/* We have only one child, wait for it */
		safe_waitpid(-1, NULL, 0); /* loops on EINTR */
		if (flags & OPT_s) {
			xioctl(0, VT_ACTIVATE, (void*)(ptrdiff_t)(vtstat.v_active));
			xioctl(0, VT_WAITACTIVE, (void*)(ptrdiff_t)(vtstat.v_active));
			// Compat: even with -c N (try to) disallocate:
			// # /usr/app/kbd-1.12/bin/openvt -f -c 9 -ws sleep 5
			// openvt: could not deallocate console 9
			xioctl(0, VT_DISALLOCATE, (void*)(ptrdiff_t)vtno);
		}
	}
	return EXIT_SUCCESS;
}
