/* (c) 1993 Julian Assage (proff@suburbia.apana.org.au)
 * All rights reserved, except that this program and its source code
 * maybe distrubuted freely and without profit in an unmodified form.
 */

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <termios.h>
  
struct termios term;
struct termios saveterm;
int out;

char catch[]="quitpassthru";

void hand()
{
	tcsetattr(0, TCSAFLUSH, &saveterm);
	close(out);
	exit(0);
}

main(int argc, char **argv)
{
  register int n;
  register int cn=0;
  unsigned char buf[2048];
  int cc;
	if (argc!=2) {
		fprintf(stderr, "Usage: %s output-file.\n\n\
Example: %s /dev/ttyS1  -  route all input to user on /dev/ttyS1.\n\n\
Quit Sequence = \"%s\".\n\
\n\
This program redirects all input to the specified output, passing any and\n\
all special characters (e.g ^c ^z ^q ^s), NULLS, and the 8th bit to the\n\
specified output, which may be a file or a tty. Typically the program is\n\
used to form a virtual 8bit rs232 connection between two users/ttys. This\n\
allows the users to use the virtual link for such things as direct zmodem\n\
transfers, multi-player serial games, term/slap connections, etc. Send \n\
bug reports to proff@suburbia.apana.org.au.\n",
			argv[0], argv[0], catch);
		exit(1);
	}
	if (!isatty(0)) {
		fprintf(stderr, "Must be executed from on a real tty\n");
		exit(1);
	}
	if ((out=open(argv[1], O_WRONLY|O_CREAT, 0777))<0) {
		perror(argv[1]);
		exit(1);
	}
	signal(SIGINT, hand);
	signal(SIGHUP, hand);
	tcgetattr(0, &term);
	tcgetattr(0, &saveterm);
	term.c_iflag&=~(INPCK|IXOFF|IXON);
	term.c_iflag|=BRKINT;
	term.c_oflag&=~OPOST;
	term.c_cflag&=~(PARENB|CSIZE);
	term.c_cflag|=CS8;
	term.c_lflag&=~(ICANON|ISIG|IEXTEN|TOSTOP|ECHO);
        term.c_cc[VMIN] = 1;
        term.c_cc[VTIME] = 2; /** 1/5 th of a second */
	tcsetattr(0, TCSAFLUSH, &term);

	cn = 0;

	while ((cc=read(0, buf, sizeof(buf)))>-1)
	{
		if (cc)
		{
			for (n=0;n<cc; n++)
			{
				if (buf[n]==catch[cn])
				{
					if (++cn==(sizeof(catch)-1)) hand();
                    		}
				else
					cn=0;
				}
			}
			write(out, buf, cc);
		}
	exit(1);
}
