// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
 */

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <termios.h>
#include "chan_user.h"
#include <os.h>
#include <um_malloc.h>
#include "xterm.h"

struct xterm_chan {
	int pid;
	int helper_pid;
	int chan_fd;
	char *title;
	int device;
	int raw;
	struct termios tt;
};

static void *xterm_init(char *str, int device, const struct chan_opts *opts)
{
	struct xterm_chan *data;

	data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
	if (data == NULL)
		return NULL;
	*data = ((struct xterm_chan) { .pid 		= -1,
				       .helper_pid 	= -1,
				       .chan_fd		= -1,
				       .device 		= device,
				       .title 		= opts->xterm_title,
				       .raw  		= opts->raw } );
	return data;
}

/* Only changed by xterm_setup, which is a setup */
static char *terminal_emulator = CONFIG_XTERM_CHAN_DEFAULT_EMULATOR;
static char *title_switch = "-T";
static char *exec_switch = "-e";

static int __init xterm_setup(char *line, int *add)
{
	*add = 0;
	terminal_emulator = line;

	line = strchr(line, ',');
	if (line == NULL)
		return 0;

	*line++ = '\0';
	if (*line)
		title_switch = line;

	line = strchr(line, ',');
	if (line == NULL)
		return 0;

	*line++ = '\0';
	if (*line)
		exec_switch = line;

	return 0;
}

__uml_setup("xterm=", xterm_setup,
"xterm=<terminal emulator>,<title switch>,<exec switch>\n"
"    Specifies an alternate terminal emulator to use for the debugger,\n"
"    consoles, and serial lines when they are attached to the xterm channel.\n"
"    The values are the terminal emulator binary, the switch it uses to set\n"
"    its title, and the switch it uses to execute a subprocess,\n"
"    respectively.  The title switch must have the form '<switch> title',\n"
"    not '<switch>=title'.  Similarly, the exec switch must have the form\n"
"    '<switch> command arg1 arg2 ...'.\n"
"    The default values are 'xterm=" CONFIG_XTERM_CHAN_DEFAULT_EMULATOR
     ",-T,-e'.\n"
"    Values for gnome-terminal are 'xterm=gnome-terminal,-t,--'.\n\n"
);

static int xterm_open(int input, int output, int primary, void *d,
		      char **dev_out)
{
	struct xterm_chan *data = d;
	int pid, fd, new, err;
	char title[256], file[] = "/tmp/xterm-pipeXXXXXX";
	char *argv[] = { terminal_emulator, title_switch, title, exec_switch,
			 OS_LIB_PATH "/uml/port-helper", "-uml-socket",
			 file, NULL };

	if (access(argv[4], X_OK) < 0)
		argv[4] = "port-helper";

	/* Ensure we are running on Xorg or Wayland. */
	if (!getenv("DISPLAY") && !getenv("WAYLAND_DISPLAY")) {
		printk(UM_KERN_ERR "xterm_open : neither $DISPLAY nor $WAYLAND_DISPLAY is set.\n");
		return -ENODEV;
	}

	/*
	 * This business of getting a descriptor to a temp file,
	 * deleting the file and closing the descriptor is just to get
	 * a known-unused name for the Unix socket that we really
	 * want.
	 */
	fd = mkstemp(file);
	if (fd < 0) {
		err = -errno;
		printk(UM_KERN_ERR "xterm_open : mkstemp failed, errno = %d\n",
		       errno);
		return err;
	}

	if (unlink(file)) {
		err = -errno;
		printk(UM_KERN_ERR "xterm_open : unlink failed, errno = %d\n",
		       errno);
		close(fd);
		return err;
	}
	close(fd);

	fd = os_create_unix_socket(file, sizeof(file), 1);
	if (fd < 0) {
		printk(UM_KERN_ERR "xterm_open : create_unix_socket failed, "
		       "errno = %d\n", -fd);
		return fd;
	}

	sprintf(title, data->title, data->device);
	pid = run_helper(NULL, NULL, argv);
	if (pid < 0) {
		err = pid;
		printk(UM_KERN_ERR "xterm_open : run_helper failed, "
		       "errno = %d\n", -err);
		goto out_close1;
	}

	err = os_set_fd_block(fd, 0);
	if (err < 0) {
		printk(UM_KERN_ERR "xterm_open : failed to set descriptor "
		       "non-blocking, err = %d\n", -err);
		goto out_kill;
	}

	data->chan_fd = fd;
	new = xterm_fd(fd, &data->helper_pid);
	if (new < 0) {
		err = new;
		printk(UM_KERN_ERR "xterm_open : xterm_fd failed, err = %d\n",
		       -err);
		goto out_kill;
	}

	err = os_set_fd_block(new, 0);
	if (err) {
		printk(UM_KERN_ERR "xterm_open : failed to set xterm "
		       "descriptor non-blocking, err = %d\n", -err);
		goto out_close2;
	}

	CATCH_EINTR(err = tcgetattr(new, &data->tt));
	if (err) {
		new = err;
		goto out_close2;
	}

	if (data->raw) {
		err = raw(new);
		if (err) {
			new = err;
			goto out_close2;
		}
	}

	unlink(file);
	data->pid = pid;
	*dev_out = NULL;

	return new;

 out_close2:
	close(new);
 out_kill:
	os_kill_process(pid, 1);
 out_close1:
	close(fd);

	return err;
}

static void xterm_close(int fd, void *d)
{
	struct xterm_chan *data = d;

	if (data->pid != -1)
		os_kill_process(data->pid, 1);
	data->pid = -1;

	if (data->helper_pid != -1)
		os_kill_process(data->helper_pid, 0);
	data->helper_pid = -1;

	if (data->chan_fd != -1)
		os_close_file(data->chan_fd);
	os_close_file(fd);
}

const struct chan_ops xterm_ops = {
	.type		= "xterm",
	.init		= xterm_init,
	.open		= xterm_open,
	.close		= xterm_close,
	.read		= generic_read,
	.write		= generic_write,
	.console_write	= generic_console_write,
	.window_size	= generic_window_size,
	.free		= generic_free,
	.winch		= 1,
};
