home *** CD-ROM | disk | FTP | other *** search
- /*
- * Filename: TRFIFO.C
- * Author: Douglas Thomson, MUCG, Churchill, Victoria, AUSTRALIA
- * Status: Public Domain
- * History: 02-Dec-91 prepared source code for release
- */
-
- /*
- * trfifo: link two users via UNIX FIFO files
- *
- * Instructions:
- * 1. run trfifo on the HOST PC:
- * trfifo host
- * 2. enter any name, say "test" at the prompt
- * 3. exit to DOS, but KEEP connection
- * 4. run TRHOST
- * 5. run trfifo on the REPLICA PC:
- * trfifo
- * 6. enter the SAME name ("test") at the prompt
- * 7. exit to DOS, but KEEP connection (if not using TR to log in)
- * 8. run TR (if not using TR to log in)
- * 9. when finished, exit TR with F10/3 (host PC will reboot)
- * 10. normally host will keep running trfifo ready for next login. To
- * stop trfifo on host, send DEL from host PC.
- */
- #include <stdio.h>
- #include <fcntl.h>
- #include <signal.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <termio.h>
- #include <sys/ioctl.h>
-
- #define TRUE 1
- #define FALSE 0
- #define OK 0
- #define ERROR (-1)
- #define FIFO ( S_IFIFO | 0666 )
- #define IN 0
- #define OUT 1
-
- #define BUFF_SIZE 128
-
- struct termio oldtty, tty; /* used for setting RAW I/O */
- int iofd = 0; /* file descriptor for setting RAW I/O */
- char readfile[BUFF_SIZE]; /* name of host input FIFO */
- char writefile[BUFF_SIZE]; /* name of host output FIFO */
-
- /*
- * restore tty to its original state
- */
- void terminate(status)
- int status;
- {
- /*
- * go back to normal I/O - borrowed from rbsb.c from the zmodem
- * package.
- */
- (void) ioctl(iofd, TCSBRK, 1); /* wait for output to drain */
- (void) ioctl(iofd, TCFLSH, 1); /* flush input queue */
- (void) ioctl(iofd, TCSETAW, &oldtty); /* restore original modes */
- (void) ioctl(iofd, TCXONC,1); /* restart output */
-
- /*
- * don't leave inactive pipes around
- */
- unlink(readfile);
- unlink(writefile);
-
- exit(status);
- }
-
- /*
- * trap interrupts so that tty state can be restored
- */
- void int_handler()
- {
- terminate(0);
- }
-
- void main(argc, argv)
- int argc;
- char *argv[];
- {
- char sys_name[256]; /* base name of FIFO link */
- unsigned char buff[BUFF_SIZE]; /* buffer for transferred characters */
- int n; /* number of characters read */
- unsigned char c; /* a general purpose character! */
- int readfd; /* file descriptor for reading FIFO */
- int writefd; /* file descriptor for writing FIFO */
- int child; /* PID for child process */
- int host; /* is this the host end? */
- static struct sigaction act; /* used for catching BREAK */
- int first = TRUE; /* first time around? */
-
- /*
- * store settings for later
- */
- (void) ioctl(iofd, TCGETA, &oldtty);
-
- restart: /* come back here after each session */
-
- /*
- * ignore BREAK for a bit
- */
- tty = oldtty; /* save original settings for later */
- tty.c_iflag &= ~BRKINT; /* DO NOT allow BREAK to kill */
- tty.c_iflag |= IGNBRK; /* ignore BREAK */
- (void) ioctl(iofd, TCSETAW, &tty);
-
-
- if (first) {
- if (argc > 3 || (argc == 3 && strcmp(argv[1], "host") != 0)) {
- fprintf(stderr, "Usage: trfifo [host] [<FIFO name>]\n");
- terminate(1);
- }
-
- if (argc > 1 && strcmp(argv[1], "host") == 0) {
- host = TRUE;
- }
- else {
- host = FALSE;
- }
-
- if (argc != 3) { /* no output for command line version of host */
- printf("TRFifo PC linking utility\n");
- }
-
- if (argc == host + 1) {
- printf("Enter system name (e.g. as1): ");
- fflush(stdout);
- gets(sys_name);
- }
- else {
- strcpy(sys_name, argv[host+1]);
- }
-
- if (argc != 3) { /* no output for command line version of host */
- printf("Setting up %s '%s'\n", host ? "host" : "replica", sys_name);
- }
-
- /*
- * Name the FIFOs - the host gets sensible names, the replica gets
- * reversed names!
- */
- if (host) {
- sprintf(readfile, "/tmp/in_%s", sys_name);
- sprintf(writefile, "/tmp/out_%s", sys_name);
- }
- else {
- sprintf(readfile, "/tmp/out_%s", sys_name);
- sprintf(writefile, "/tmp/in_%s", sys_name);
- }
- }
-
- /*
- * Create the FIFOs
- */
- if (host) {
- umask(0); /* let anyone into the FIFO */
- unlink(readfile); /* kill old FIFO from last crash? */
- if (mknod(readfile, FIFO) == ERROR) {
- perror(readfile);
- terminate(1);
- }
- unlink(writefile);
- if (mknod(writefile, FIFO) == ERROR) {
- perror(writefile);
- unlink(readfile);
- terminate(1);
- }
- }
-
- if (host && first) {
- printf("Return to DOS (keeping connection) and run TRHOST\n");
- fflush(stdout);
- }
-
- /*
- * catch interrupt
- */
- act.sa_handler = int_handler;
- sigaction(SIGINT, &act, NULL);
-
- /*
- * pipes are opened in the opposite order, so that deadlock does
- * not occur waiting to open pipes...
- */
- if (host) {
- if ((readfd = open(readfile, O_RDONLY)) == ERROR) {
- perror("can't open FIFO for reading");
- unlink(readfile);
- unlink(writefile);
- terminate(1);
- }
- if ((writefd = open(writefile, O_WRONLY)) == ERROR) {
- perror("can't open FIFO for writing");
- unlink(readfile);
- unlink(writefile);
- terminate(1);
- }
- }
- else {
- if ((writefd = open(writefile, O_WRONLY)) == ERROR) {
- /*
- * This probably means the host is not running or is in use
- * by someone else...
- */
- fprintf(stderr, "Sorry, '%s' is not currently available\n",
- sys_name);
- terminate(1);
- }
- if ((readfd = open(readfile, O_RDONLY)) == ERROR) {
- perror("can't open FIFO for reading");
- terminate(1);
- }
- }
-
- /*
- * have established the FIFO, remove the files so no-one else can
- * interfere...
- */
- unlink(readfile);
- unlink(writefile);
-
- if (!host) {
- printf("Return to DOS (keeping connection) and run TR\n");
- fflush(stdout);
- }
-
- first = FALSE;
-
- /*
- * go into transparent 8-bit raw I/O etc etc - largely inspired by the
- * rbsb.c file in the zmodem package. See this file for ideas if you
- * have an incompatible flavor of UNIX...
- */
- tty = oldtty; /* save original settings for later */
- tty.c_iflag = BRKINT; /* DO allow BREAK to kill */
- tty.c_lflag &= ~(ECHO | ICANON | ISIG); /* no echo etc etc*/
- tty.c_oflag = 0; /* no output processing */
- tty.c_cflag &= ~PARENB; /* disable parity */
- tty.c_cflag |= CS8; /* set character size to 8 bits */
- tty.c_cc[VMIN] = BUFF_SIZE; /* try to read a decent block */
- tty.c_cc[VTIME] = 1; /* give up after 0.1 seconds */
- (void) ioctl(iofd, TCSETAW, &tty);
-
- /*
- * One process reads the input FIFO and copies it to STDOUT; the other
- * reads STDIN and copies it to the output FIFO.
- */
- switch (child = fork()) {
- case ERROR:
- perror("fork");
- terminate(1);
- case 0:
- for (;;) {
- n = read(0, buff, BUFF_SIZE);
- if (n > 0) {
- write(writefd, buff, n);
- }
- }
- default:
- for (;;) {
- if ((n = read(readfd, buff, BUFF_SIZE)) <= 0) {
- break;
- }
- write(1, buff, n);
- }
- if (host) {
- /*
- * the replica has just terminated, so send a reboot command
- * to the host
- */
-
- /*
- * ensure BREAK is ignored before rebooting PC
- */
- tty = oldtty; /* save original settings for later */
- tty.c_iflag &= ~BRKINT; /* DO NOT allow BREAK to kill */
- tty.c_iflag |= IGNBRK; /* ignore BREAK */
- (void) ioctl(iofd, TCSETAW, &tty);
-
- c = 0;
- write(1, &c, 1);
- write(1, &c, 1);
- c = 3;
- write(1, &c, 1);
- sleep(1);
- c = 0;
- write(1, &c, 1);
- write(1, &c, 1);
- c = 3;
- write(1, &c, 1);
-
- kill(child, SIGINT); /* don't leave orphan */
- wait(NULL);
-
- goto restart;
- }
-
- /*
- * don't leave orphan processes...
- */
- kill(child, SIGINT);
- wait(NULL);
- }
-
- terminate(0);
- }
-
-