/* fake-xterm
 * Behaves like xterm -S, but relays from the given fd to another pty
 * (written to redirect ski's console)
 */

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

void
relay(int fd1, int fd2)
{
	unsigned char buffer[1024];
	fd_set fds;
	int max, len;
	int nread;

	FD_ZERO(&fds);
	max = (fd1 > fd2) ? fd1 : fd2;

	while (1)
	{
		FD_SET(fd1, &fds);
		FD_SET(fd2, &fds);

		switch (select(max+1, &fds, NULL, NULL, NULL))
		{
			case -1:
				perror("select");
			case 0:
				return;
		}

		if (FD_ISSET(fd1, &fds))
		{
			switch (len = read(fd1, buffer, sizeof(buffer)))
			{
				case -1:
					perror("read");
				case 0:
					return;
			}

			if (write(fd2, buffer, len) == -1)
				perror("write");
		}

		if (FD_ISSET(fd2, &fds))
		{
			switch (len = read(fd2, buffer, sizeof(buffer)))
			{
				case -1:
					perror("read");
				case 0:
					return;
			}

			if (write(fd1, buffer, len) == -1)
				perror("write");
		}
	}
}


int
main(int argc, char *argv[])
{
	char *arg = NULL;
	char buffer[16];
	FILE *tty;
	int fd, ptyfd, logfd;
	int i;

	for (i = 0; i < argc; i++)
	{
		if ((argv[i][0] == '-') && (argv[i][1] == 'S'))
		{
			arg = &argv[i][2];
			break;
		}
	}

	if (arg == NULL)
	{
		fprintf(stderr, "fake-xterm: need -S argument\n");
		return 1;
	}

	fd = atoi(&arg[2]);
	if ((ptyfd = getpt()) == -1)
	{
		perror("getpt");
		return 1;
	}

	if ((grantpt(ptyfd) == -1) || (unlockpt(ptyfd) == -1))
	{
		perror("grantpt");
		return 1;
	}

	tty = fopen("/dev/tty", "w");
	if (tty != NULL)
	{
		fprintf(tty, "\r\nConnect to %s\r\n", ptsname(ptyfd));
		fclose(tty);
	}

	write(fd, "0\n", 2); /* ready */

	/* wait for remote end */
	if (read(ptyfd, buffer, sizeof(buffer)) == -1)
	{
		perror("read");
		return 1;
	}

	relay(fd, ptyfd);

	close(ptyfd);
	close(fd);
	return 0;
}
