[alt.sources] A binary transparent passthru program for use with tip

jimb@faatcrl.UUCP (Jim Burwell) (01/04/91)

Here's a little program I hacked up to allow me to call a system, dial out
on that system (using tip) to another host, then start up a raw binary 
connection between the remote host and the local machine THROUGH the system
I called with my local machine.  i.e.:


 System                        System                 System
   A(JR-Comm Zmodem Receive) <-> B(tip w/ passthru) <-> C(sz Zmodem send)


Binary data flows either way THROUGH system B, even though the connection
is made with tip.

The program is called passthru, and it does exactly that.  See the man page
and readme for more info.

Have Fun!


---- Cut Here and unpack ----
#!/bin/sh
# This is a shell archive (shar 3.32)
# made 01/03/1991 23:24 UTC by jimb@faatcrl
# Source directory /home/nssf/jimb/hack
#
# existing files WILL be overwritten
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#    111 -rw-r--r-- passthru/Makefile
#   1464 -rw-r--r-- passthru/README
#   1431 -rw-r--r-- passthru/man/passthru.l
#   3995 -rw-r--r-- passthru/passthru.c
#
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= passthru/Makefile ==============
if test ! -d 'passthru'; then
    echo "x - creating directory passthru"
    mkdir 'passthru'
fi
echo "x - extracting passthru/Makefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > passthru/Makefile &&
X#
X# Makefile for passthru
X#
X
XCC = cc
XCFLAGS = -O
X
Xpassthru: passthru.c
X	$(CC) $(CFLAGS) -o passthru passthru.c
SHAR_EOF
$TOUCH -am 1218231190 passthru/Makefile &&
chmod 0644 passthru/Makefile ||
echo "restore of passthru/Makefile failed"
set `wc -c passthru/Makefile`;Wc_c=$1
if test "$Wc_c" != "111"; then
	echo original size 111, current size $Wc_c
fi
# ============= passthru/README ==============
echo "x - extracting passthru/README (Text)"
sed 's/^X//' << 'SHAR_EOF' > passthru/README &&
XFirst, the legal stuff:
X**********************************************************************
XDISCLAIMER:
X
XThis program has been put into the Public Domain.  This is Freeware.  The
XAuthor, and his employers disclaim any responsibility for any damages caused
Xby or though the use of this program.
X
X**********************************************************************
X
XPassthru starts up a raw 8-bit copy of data between a remote
Xtty that has been connected to with tip, and the tty tip was
Xinvoked on.  This facilitates the use of 8-bit file transfer
Xprotocols  such  as  Zmodem  with the data going through the
Xhost tip and passthru were invoked on.  This allows  a  user
Xto  dial-up  a  system,  connect  to another using tip, then
Xafter invoking passthru, send and  recieve  raw  8-bit  data
Xbetween  the  far  remote  end  and local ends.  Passthru is
Xinvoked by using the tip command "~C", "connect remote  host
Xto program".
X
XTo compile, just type "make".  This has been tested and works on Suns, but I 
Xdon't know what else it will work on.  I'm not doing anything especially 
Xexotic in the code (reading from stderr ? :-), so it should be very portable.
X
XFeel free to mail me if you find any bugs, or have suggestions, etc.
XNO FLAMES.
X
XFor more details on the programs operation, see the manual page in the 
X./man directory.
X
X---
XJames S. Burwell, CTA Inc.  NASPAC (ACD-340), Faa Technical Center, Pomona NJ
XEMAIL:  jimb@faatcrl.uucp
XPHONE:  609/484-6700
SHAR_EOF
$TOUCH -am 0103175791 passthru/README &&
chmod 0644 passthru/README ||
echo "restore of passthru/README failed"
set `wc -c passthru/README`;Wc_c=$1
if test "$Wc_c" != "1464"; then
	echo original size 1464, current size $Wc_c
fi
# ============= passthru/man/passthru.l ==============
if test ! -d 'passthru/man'; then
    echo "x - creating directory passthru/man"
    mkdir 'passthru/man'
fi
echo "x - extracting passthru/man/passthru.l (Text)"
sed 's/^X//' << 'SHAR_EOF' > passthru/man/passthru.l &&
X.TH PASSTHRU 1 local
X.SH NAME
Xpassthru \- enable an 8\-bit binary transparent connection through tip(1)
X.SH SYNOPSIS
X.B "connect with tip(1), ~C, local command? passthru"
X.SH DESCRIPTION
X.I Passthru
Xstarts up a raw 8\-bit copy of data between a remote tty that has been
Xconnected to with tip, and the tty tip was invoked on.  This facilitates
Xthe use of 8\-bit file transfer protocols such as Zmodem with the data
Xgoing 
X.I through 
Xthe host tip and passthru were invoked on.  This allows
Xa user to dial\-up a system, connect to another using tip, then after
Xinvoking passthru, send and recieve raw 8\-bit data between the far remote
Xend and local ends.  Passthru is invoked by using the tip command "~C",
X"connect remote host to program".  
X
XTo exit passthru, you must issue this escape sequence:
X
X   1. Wait three seconds without transmitting any data
X   2. Transmit at least three minus signs ('-') in quick 
X      succession
X   3. Wait another three seconds without transmitting data
X
X.RE
XThis type of "guard\-time" escape sequence should be familiar to those
Xfamiliar with Hayes compatible modems.
X
X.SH "SEE ALSO"
X.BR tip (1)
X.SH WARNINGS
XPassthrough expects these file descriptors to be as follows:
X   0 <\-> input from remote tty
X   1 <\-> output to remote tty
X   2 <\-> output to local tty (stderr)
X.SH DIAGNOSTICS
X.IP "Can't fork!"
XPassthru couldn't fork its child process
X
X.SH AUTHOR
X James S. Burwell
X jimb@faatcrl.uucp
SHAR_EOF
$TOUCH -am 1219232790 passthru/man/passthru.l &&
chmod 0644 passthru/man/passthru.l ||
echo "restore of passthru/man/passthru.l failed"
set `wc -c passthru/man/passthru.l`;Wc_c=$1
if test "$Wc_c" != "1431"; then
	echo original size 1431, current size $Wc_c
fi
# ============= passthru/passthru.c ==============
echo "x - extracting passthru/passthru.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > passthru/passthru.c &&
X/*
X * passthru.c
X *
X * This program sets up an 8 bit raw data path between a remote host
X * connected to with tip(1), and the tty tip was invoked on.  It accomplishes
X * this by making use of tip's "~C" command.  In order for this program to
X * work, "~C" must connect the following file descriptors like so:
X * 
X *  0 (stdin)  <-> input from remote host
X *  1 (stdout) <-> output to remote host
X *  2 (stderr) <-> output to tty tip was invoked on
X *
X * This program takes input from the tty tip was invoked on by making a copy
X * of file descriptor 2 (stderr), and using that with read(2).  I don't know
X * if this is legal, but it works Suns (tested running SunOS 4.0.3).
X * To invoke, use the "~C" command, and enter the name of this program at the
X * prompt.
X *
X * To shut-down passthru, you must issue the escape sequence:
X *
X *      1. Wait three seconds without transmitting any data
X *      2. Transmit at least three minus signs (-) in
X *         quick succession
X *      3. Wait another three seconds without transmitting data
X *
X *   This type of "guard-time" escape sequence should be familiar
X *   to those familiar with Hayes compatible modems.
X *
X */
X
X
X#include <stdio.h>
X#include <signal.h>
X#include <termios.h>
X
Xint nbytes, cpid;
Xchar buf[256];
Xstruct termios tio[3], ntio;
X
X/* sigf:
X *
X * Escape-sequence validator.  Uses a "state-machine" to determine whether
X * the escape-sequence has been issued, and shuts down the program if it has.
X *
X */
X
Xint sflag = 0;  /* state variable */
X
X#define TIMEOUT 3
X#define ESCCHAR '-'
X
X/* state machine states */
X#define WAITPRE 0  /* waiting for pre-sequence guard time */
X#define WAITESC 1  /* waiting for esc-sequence string */
X#define WAITPST 2  /* waiting for post-sequence guard time  */
X
Xsigf() {
X
X	int i;
X
X	switch(sflag) {
X		case WAITPRE: /* Our pre-escape guard time is satisfied */
X			sflag = WAITESC; /* state = waiting-for-escape-string */
X			/* nuke the first three chars of the buffer.  After TIMEOUT
X			 * seconds, the contents of buf should have been copied by the write
X          * system call.
X			 */
X			buf[0] = '\0'; buf[1] = '\0'; buf[2] = '\0';
X			break;
X		case WAITESC: /* Check to see if we have our escape string */
X			/* is the escape string in the buffer ? */
X			if((buf[0] == ESCCHAR) && (buf[1] == ESCCHAR) && (buf[2] == ESCCHAR)) {
X				sflag = WAITPST;  /* yes.  state = wait for post-esc guard time */
X			} else {
X				sflag = WAITPRE;  /* no.  state = wait-for-pre-esc guard time */
X			}
X			break;
X		case WAITPST: /* post-escape guard time satisfied.  exit */
X			fprintf(stderr,"\n\n\rDetected escape sequence ... exiting.\n\n");
X			/* reset descriptor settings to initial values */
X			for(i=0; i < 3; i++) 
X				ioctl(i,TCSETS,&tio[i]);
X			close(3); /* close our dup2()ed descriptor */
X			kill(cpid,SIGHUP); /* kill child process */
X			exit(0);  /* exit program */
X			break;
X	}
X	alarm(TIMEOUT);  /* reset alarm */
X}
X
X
Xmain() {
X
X	int i;
X
X	/* set all of our descriptors to 8/n/1 raw */
X	for(i=0;i < 3; i++) {
X		ioctl(i,TCGETS,&ntio);
X		ioctl(i,TCGETS,&tio[i]); /* save copies of each descriptor's settings */
X		
X		ntio.c_iflag = 0;
X		ntio.c_oflag = 0;
X		ntio.c_cflag = ntio.c_cflag & (~(PARENB));
X		ntio.c_cflag = ntio.c_cflag | CS8;
X		ntio.c_lflag = 0;
X
X		ioctl(i,TCSETS,&ntio);
X	}
X
X	dup2(2,3); /* make a copy of our file descriptor */
X
X	if((cpid = fork()) < 0) {
X		fprintf(stderr,"Couldn't fork!\n");
X	} else {
X		/* Parent process.  Copies from the tty tip & passthru were invoked on  
X		 * to the remote host.  3 -> 1
X       */
X		if(cpid) {
X			signal(SIGALRM, sigf);  /* set up alarm service routine */
X			alarm(TIMEOUT);  /* set alarm */
X			while(1) {
X				nbytes = read(3,buf,256);
X
X				if(sflag != WAITESC) {
X					sflag = WAITPRE;
X					alarm(TIMEOUT);
X				}
X
X				write(1,buf,nbytes);
X			}
X		} else {
X			/* Child process.  Copies from remote host to the tty tip & passthru
X          * were invoked on.  0 -> 2
X          */
X			while(1) {
X				nbytes = read(0,buf,256);
X				write(2,buf,nbytes);
X			}
X		}
X	}
X}
SHAR_EOF
$TOUCH -am 1219232690 passthru/passthru.c &&
chmod 0644 passthru/passthru.c ||
echo "restore of passthru/passthru.c failed"
set `wc -c passthru/passthru.c`;Wc_c=$1
if test "$Wc_c" != "3995"; then
	echo original size 3995, current size $Wc_c
fi
exit 0
-- 
UUCP:  ...!rutgers!faatcrl!jimb              Internet:  jimb@faatcrl.UUCP
		Under brooding skys and watchful eyes
		On convulsive seas of false urgency
		We walk empty corridors in vain - "No Exit", Fate's Warning