// 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 = "xterm";
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=xterm,-T,-e'.  Values for gnome-terminal\n"
"    are 'xterm=gnome-terminal,-t,-x'.\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";

	/*
	 * Check that DISPLAY is set, this doesn't guarantee the xterm
	 * will work but w/o it we can be pretty sure it won't.
	 */
	if (getenv("DISPLAY") == NULL) {
		printk(UM_KERN_ERR "xterm_open: $DISPLAY not 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 : os_rcv_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,
};
