GETTY replacement program "prtty"

John B. Milton jbm at uncle.UUCP
Wed May 3 12:41:39 AEST 1989


Well since people are starting to pass this around... I had several ideas in
mind, but haven't gotten around to them. I DID NOT WRITE THIS! This is my
hacked up version of the package named "modem-ctl". I use this to do bi-
directional access with HDB/Telebit.

John
---
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README UNIXpc.rdme TBregs prtty.1 Makefile prtty.h ring.h
#   exec.c extern.c io.c line.c lock.c misc.c prtty.c sendex.c sigs.c
#   uchange.c inst inst/Devices inst/Dialers inst/Systems
#   inst/gettydefs inst/inittab
# Wrapped by jbm at uncle on Mon Apr 17 22:13:15 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(2276 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XModem: A bi-directional uugetty replacement.
X
X"Modem" works just like "uugetty", and allows incoming and outgoing calls 
Xthrough the same port.
X
XIn addition, it allows provides additional facilities:
X
X1/.	Option to insert a uucp-style send-expect conversation to
Xinitialise the modem.
X
X2/.	Code to spawn getty at the correct speed, if you have a modem that
Xcan sense the speed of incoming calls.
X
X3/.	Autologout facility, if there is no activity on the modem for
Xa specified period of time.
X
X4/.	Log of all connected calls.
X
X5/.	Option to run "who" and "ps" on the port, when connected,
Xif you're really security-concious.
X
X6/.	Correct handling of DCD (carrier detect) signals from the modem.
X
X7/.	Works happily with "uucp", "cu", and "kermit", which are not aware
Xthat "modem" is running. [NB Slight change necessary to uucp dialer script
Xrequired]
X
X8/.	State-changing code, which allows you to set the modem in a state
Xrelated to the time of day. Useful if you want it only to auto-answer
Xwhen you're not there, and want to use it as a telephone otherwise.
X[Thanks to jack at swlabs.uucp for this code.]
X
X
XIt works fine on my modem, which talks too much for uugetty to be able to
Xhandle it!
X
X
XFor your local site, you have to do the following:
X
XPut this line in /etc/inittab
XXX:2:respawn:/usr/lib/modem ttyXX		where ttyXX is your modem line
X
XMake sure that your dialer script is prepared to:
X
X	a) sleep for > 1 sec BEFORE reading the first reply from the modem
X	b) accept that the first character sent by the modem will NOT get there
X
Xe.g. My Hayes dialer script is NORMALLY
X
X	... AT OK ATDP\T CONNECT
X
Xbut MUST be modified to
X
X	... AT\r\D OK ATDP\T CONNECT  		#( \D is a 2-sec pause )
X
X
XModify the included dialer script to talk to YOUR modem, if you have a non-
Xsupported modem type. Please let me have your scripts, so that I can include
Xthem in future releases.
X
XModify the speed-detection routine, if your modem is not a hayes-compatible
X
XModify "locked()" to read YOUR lock directory - but see the makefile options
Xfor various lockfile protocols.
X
XIf necessary, modify the wiring to the modem so that DCD is asserted
Xwhen the modem is online, but not asserted at other times.  This is
Xnecessary for the modem to generate a hangup signal when a remote site
Xdisconnects. 
X
END_OF_FILE
if test 2276 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'UNIXpc.rdme' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'UNIXpc.rdme'\"
else
echo shar: Extracting \"'UNIXpc.rdme'\" \(203 characters\)
sed "s/^X//" >'UNIXpc.rdme' <<'END_OF_FILE'
X
XNote that some UNIXpcs have trouble with the Telebit Trailblazer on tty000. The
Xsymptom is that, when on tty001-6, it will sometimes hang the system when it
Xdisconnects. If you can move it it to tty000
END_OF_FILE
if test 203 -ne `wc -c <'UNIXpc.rdme'`; then
    echo shar: \"'UNIXpc.rdme'\" unpacked with wrong size!
fi
# end of 'UNIXpc.rdme'
fi
if test -f 'TBregs' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'TBregs'\"
else
echo shar: Extracting \"'TBregs'\" \(437 characters\)
sed "s/^X//" >'TBregs' <<'END_OF_FILE'
XE0 F1 M1 Q0 T V1 X1     Version BA4.00
XS00=000 S01=000 S02=035 S03=013 S04=010 S05=008 S06=002 S07=060 S08=002 S09=006
XS10=007 S11=070 S12=050 
XS45=255 S47=004 S48=000 S49=000
XS50=000 S51=254 S52=002 S53=004 S54=003 S55=000 S56=017 S57=019 S58=002 S59=000
XS60=003 S61=045 S62=003 S63=001 S64=000 S65=000 S66=000 S67=000 S68=255 
XS90=000 S91=000 S92=001 S95=000 
XS100=000 S101=000 S102=000 S104=000 
XS110=001 S111=030 S112=001 
XS121=000 
END_OF_FILE
if test 437 -ne `wc -c <'TBregs'`; then
    echo shar: \"'TBregs'\" unpacked with wrong size!
fi
# end of 'TBregs'
fi
if test -f 'prtty.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'prtty.1'\"
else
echo shar: Extracting \"'prtty.1'\" \(2086 characters\)
sed "s/^X//" >'prtty.1' <<'END_OF_FILE'
X.TH prtty 1 local
X.SH NAME
Xprtty
X.SH SYNOPSIS
X.B "prtty tty [speed] [term]"
X.PP
X.SH DESCRIPTION
X.I prtty
Xis a functional replacement for \fIuugetty\fR, and allows a line connected
Xto a modem to be used for both incoming and outgoing uucp/cu calls.
X.PP
XIt has an initial conversation with the modem, so that it can be set
Xin the correct mode, and then waits for the modem to detect an incoming
Xcall. It then spawns \fIgetty(8)\fR to login the user, after making an
Xalteration in the file /etc/utmp, so that getty thinks it was spawned by
X\fIinit(8)\fR.
X.PP
XWhile the user remains logged on, \fIprtty\rB will periodically run
X\fIps\fR on the line, so that it can record what the user is doing.
XThis facility can be turned off (see WATCHIT) option, if not required.
X.PP
XIf, at any point prior to the incoming call, \fIprtty\fR detects an
X\fBoutgoing\fR call, then it exits. Just before the exit, it attempts
Xto set the line so that it can be used by outgoing callers.
X.PP
XIf \fIprtty\fR detects a LOCK file when it is invoked, then it will
Xwait until this file is removed before proceeding.
X.PP
X\fIprtty\fR also enforces an idle timeout, so that it the line appears
Xto be idle for too long, the user is logged out. This may cause problems
Xwith kermit, which doesn't update the times on the device, but uses
X\fI/dev/tty\fR instead.
X.PP
XThe optional \fBspeed\fR argument can be used to force \fIprtty\fR to talk
Xto the modem at the specified speed, otherwise it will talk at 1200 baud.
X.PP
XThe tty name should be of the form \fBtty44\fR.
X.SH EXAMPLES
X.PP
X44:2:respawn:/usr/lib/prtty tty44 vt100
X.PP
X1a:234:respawn:/usr/lib/modem 2400 tty1a vt100
X.PP
X.SH FILES
X/dev/\fI<tty>\fB
X.PP
X/usr/spool/uucp/prttyxx.log
X.SH SEE ALSO
Xgetty(8), uugetty(8), sh(1), ps(1), who(1), utmp(4)
X.SH BUGS
XThe code for hardware DCD detection support is new.
X.PP
XThere are still some unexplained diagnostics in my log file, mainly about
Xwrite(1) calls failing to write characters.
X.PP
XYou will have to modify some source code if your modem and/or system is
Xdifferent from mine (speed configuration and lock files).
END_OF_FILE
if test 2086 -ne `wc -c <'prtty.1'`; then
    echo shar: \"'prtty.1'\" unpacked with wrong size!
fi
# end of 'prtty.1'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(2647 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# /* vi:set ai sm ts=8 sw=8: */
XSHELL=/bin/sh
X#
X# This program was called "modem", I call it "prtty", pree tee tee why
X#
X# new makefile for prtty.
X#
X# if your lockfile is:
X# /usr/spool/uucp/LCK..<system>		No defines needed.
X# /usr/spool/locks/LCK..<system>	-DOL3B2
X# /usr/spool/locks/LCK.L.<system>	-DHDB
X#
X# New definitions:
X#	HDB:		If you have Honey-Danber UUCP (Thanks Rick) not on 3b1
X#	HAYES:		If you have a Hayes-type modem.
X#	JSET:		If you have an AT&T Aztec modem (Thanks Rick).
X#	OL3B2:		If you have an Olivetti 3B2
X#	SLOW:		Wait 1 sec between each character written to the modem. 
X#	SPEEDCONFIG:	If you have a modem that tells you the speed of incoming
X#			calls (In ASCII - 300(or \r), 1200, 2400, 1275, 7512)
X#			If your modem says different things, hack the code
X#	TELEBIT:	(not with HAYES) strings for telebit trailblazer
X#	UNIXPC:		UNIXpc needs EXTA for 19200
X#
X# check "prtty.h" for additional options on default modem speed and timezone.
X#
X# LIBS=-lg
X# DEFS=-DOL3B2 -DSPEEDCONFIG-DHAYES 
XDEFS=-DSPEEDCONFIG -DTELEBIT -DUNIXPC # UNIXpc
XSHLIB=/lib/shlib.ifile /lib/crt0s.o # UNIXpc
X# DEFS=-DSPEEDCONFIG -DHAYES # Sperry
X# LIBS=/lib.20/crt0.o -lc # Sperry
X
XCFLAGS=-O $(DEFS)
XPARTS=exec.o extern.o io.o line.o lock.o misc.o prtty.o sendex.o sigs.o uchange.o
X
X/etc/prtty: prtty
X	@echo "prtty ready to roll, 'make install' next"
X
Xprtty: ${PARTS}
X	ld -o prtty $(SHLIB) ${PARTS} $(NTSHLIB) ${LIBS}
X
Xinstall: prtty
X	strip prtty
X	chmod 700 prtty
X	chgrp root prtty
X	chown bin prtty
X	touch /etc/prtty
X	mv /etc/prtty /etc/oprtty
X	mv prtty /etc
X	
Xlint:
X	lint ${CFLAGS} ${PARTS:.o=.c}
X
Xman:
X	nroff -man prtty.1 > prtty.man
X
Xclean:
X	rm -f core *.o
X
Xclobber: clean
X	rm -f prtty
X	rm -rf inst
X
XTBregs: prtty.c ring.h
X	@echo "get the current telelbit registers into TBregs"
X	false
X
Xinst: clobber TBregs
X	mkdir inst
X	grep prtty /etc/inittab > inst/inittab
X	head -16 /usr/lib/uucp/Devices > inst/Devices
X	head -13 /usr/lib/uucp/Dialers > inst/Dialers
X	grep \^tb /usr/lib/uucp/Systems > inst/Systems
X	grep \^1200 /etc/gettydefs > inst/gettydefs
X	echo ""  >> inst/gettydefs
X	grep \^2400 /etc/gettydefs >> inst/gettydefs
X	echo ""  >> inst/gettydefs
X	grep \^19200 /etc/gettydefs >> inst/gettydefs
X	echo ""  >> inst/gettydefs
X	grep \^300 /etc/gettydefs >> inst/gettydefs
X	echo ""  >> inst/gettydefs
X
Xshar: inst
X	shar README UNIXpc.rdme TBregs prtty.1 Makefile prtty.h ring.h ${PARTS:.o=.c} inst inst/* > prtty.shar
X
Xexec.o: exec.c prtty.h
Xextern.o: extern.c
Xio.o: io.c prtty.h
Xline.o: line.c prtty.h
Xlock.o: line.c prtty.h
Xmisc.o: misc.c prtty.h
Xprtty.o: prtty.c prtty.h ring.h
Xsendex.o: sendex.c prtty.h
Xsigs.o: sigs.c prtty.h
Xuchange.o: uchange.c prtty.h
END_OF_FILE
if test 2647 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'prtty.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'prtty.h'\"
else
echo shar: Extracting \"'prtty.h'\" \(1141 characters\)
sed "s/^X//" >'prtty.h' <<'END_OF_FILE'
X/* vi:set ai sm ts=2 sw=2: */
X
X/*
X * some constants for your modem
X */
X
X#define TIMEZONE "TZ=EST5EDT"		/* time zone you operate in	*/
X#define DEFSPEED "1200"			/* speed your modem likes most	*/
X#define LOCKWAIT 10 /* seconds to wait between lockfile checks */
X#define PROCCHECK 5 /* how many LOCKWAITs go by until PID lock check */
X#define LOCKREUSE 10 /* secs to wait after lock file goes away to make sure */
X#define GETTYWAIT 10 /* seconds to hold device open while getty spins up */
X#define RESPWAIT 3 /* seconds to wait before exiting */
X#define DTRWAIT 3 /* seconds to leave B0 DTR dropped */
X
X#define WTIME 5				/* default wait time 		*/
X
X#define LOGFILE "/usr/spool/uucp/pr%s.log"	/* log file */
X
X#define max(a,b) ((a) > (b) ? (a) : (b))
X#define min(a,b) ((a) < (b) ? (a) : (b))
X
Xextern int errno;
X
Xlong time();
Xint dread(),dwrite(),myread();
Xvoid mywrite();
X
Xextern char *me; /* argv[0] */
Xextern int dev,mypid; /* device fd, our pid, and exit status */
Xextern int Debug,Hangup,Quiet,Timeout,Watchit;
Xextern char lockf[50];				/* argument lock file */
Xextern char dname[30];				/* device name in full - /dev/.... */
Xextern mylockf;
END_OF_FILE
if test 1141 -ne `wc -c <'prtty.h'`; then
    echo shar: \"'prtty.h'\" unpacked with wrong size!
fi
# end of 'prtty.h'
fi
if test -f 'ring.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ring.h'\"
else
echo shar: Extracting \"'ring.h'\" \(2897 characters\)
sed "s/^X//" >'ring.h' <<'END_OF_FILE'
X
X/*
X * The 'reset' sequence, if the modem doesn't behave as expected.
X * I still get problems with the modem not responding to 'AT'.
X */
X#ifdef HAYES
X/* #define RESET "\n\rAT\r\rAT\r\rAT\r\r" */
X#	define RESET "AT\rAT\rATZ\r"
X#else
X#	define RESET ""
X#endif
X
X/*
X * The 'conversation' necessary to get your modem into a 'listening' state.
X * The converasation should complete iff an incoming call is connected.
X * If using Jack's states, set up your states below. Each modem line
X * must have flags set to indicate in which state(s) it can be executed.
X * If you're not using the STATES stuff, leave them at zero.
X */
X#define SPK			0x0001	/* Speaker control */
X#define	AA			0x0002	/* Auto Answer Control */
X
Xstruct conv {
X	char *c_send;
X	char *c_expect;
X	int c_wait;		/* time to wait for c_expect */
X	int c_flags;		/* flags for matching with the state. */
X};
X
X/* The current setup here uses ATA to answer the phone, which means prtty
Xmust be running to tell the modem to answer, which probably means the system
Xis not crashed, which can be checked from a voice line and seen in the status
Xfiles of other calling systems
X
X--> Current telebit registers (atn?)
XE1 F1 M1 Q0 T V1 X1     Version BA4.00
XS00=000 S01=000 S02=035 S03=013 S04=010 S05=008 S06=002 S07=060 S08=002 S09=006
XS10=007 S11=070 S12=050 
XS45=255 S47=004 S48=000 S49=000
XS50=000 S51=254 S52=002 S53=004 S54=003 S55=000 S56=017 S57=019 S58=002 S59=000
XS60=003 S61=045 S62=003 S63=001 S64=000 S65=000 S66=000 S67=000 S68=255 
XS90=000 S91=000 S92=001 S95=000 
XS100=000 S101=000 S102=000 S104=000 
XS110=001 S111=030 S112=001 
XS121=000 
X
Xescapes:
X\\p 1 second
X\\d 2 seconds
X\\K break
X*/
Xstruct conv ring[] = {
X#	ifdef TELEBIT
X	{"\\d\\K\\dA\\pA\\pA\\pT\r","OK",WTIME,0},
X	{"ATM1\r","OK",WTIME,0},
X	{"ATX1Q0\r","OK",WTIME,0}, /* enable auto answer, norm msg, income stat */
X	{"","RING",0,0}, /* wait (indefinately) for first RING in */
X/*{"","RING",10,0}, /* add as many for as many rings as you want */
X	{"ATA\r","CONNECT",60,0}, /* answer phone, wait for connect (60 for pep) */
X	{NULL,NULL,0,0} /* finished */
X#	else /* not TELEBIT */
X#		ifdef HAYES
X	{"ATE0Q0\r","OK",WTIME,0},	/* wakeup, no echo, reply on */
X	{"AT\r","OK",WTIME,0},		/* test */
X	{"ATM1X1V1\r","OK",WTIME,0},		/* speaker on, response on, words */
X	{"ATS0=1\r","OK",WTIME,0},		/* enable auto answer */
X	{"","RING",0,0},		/* wait (indefinately) for RING in */
X	{"","CONNECT",20,0},		/* wait for call to be connected */
X	{NULL, NULL, 0, 0}			/* finished */
X#		else /* not HAYES */
X#			ifdef JSET /* AT&T Aztec Protocol */
X	{"\\d\r\\d", "MODEM: ", WTIME, 0 },	/* anyone there? */
X	{"", "DATA", 3600, 0},		/* wait (1 hour) for RING in */
X	{NULL, NULL, 0, 0}			/* Should be indefinite, but prevent
X					   problems if modem gets wedged */
X#			else /* not JSET */
X	{NULL, NULL, 0, 0}			/* no init conversation */
X#			endif /* JSET */
X#		endif /* HAYES */
X#	endif /* TELEBIT */
X};
END_OF_FILE
if test 2897 -ne `wc -c <'ring.h'`; then
    echo shar: \"'ring.h'\" unpacked with wrong size!
fi
# end of 'ring.h'
fi
if test -f 'exec.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'exec.c'\"
else
echo shar: Extracting \"'exec.c'\" \(1896 characters\)
sed "s/^X//" >'exec.c' <<'END_OF_FILE'
X/* vi:set ai sm ts=2 sw=2: */
X
X#include <signal.h>
X#include <stdio.h>
X#include "prtty.h"		/* variable definitions */
X
Xstatic int killgetty(sig)
Xint sig;
X{
X	kill(SIGKILL,mypid);
X}
X
Xvoid exgetty(line,connsp,term,ldisc,env)
Xchar *line,*connsp,*term,*ldisc,*env[];
X{
X	int i;
X	char *arg[8];
X	FILE *lock;
X
X	if (Debug>=9)
X		printf("Creating lock file");
X	mylockf=1; /* for unlink() in closedown */
X 	lock=fopen(lockf,"w");
X#ifdef OL3B2
X	fprintf(lock,"       %d\n",mypid);
X#else
X#	ifdef HDB
X	fprintf(lock,"%d\n",mypid);
X#	else
X	fwrite((char *) &mypid,sizeof(mypid),1,lock);
X#	endif
X#endif
X	fclose(lock);
X	if (Debug>=9)
X		printf(", done\n");
X
X	arg[0]="getty";
X 	arg[1]="-h";
X 	arg[2]="-t60";
X 	arg[3]=line;
X 	arg[4]=connsp;
X	arg[5]=term;
X	arg[6]=ldisc;
X	arg[7]=NULL;
X
X	if (Debug>=5) {
X		printf("/etc/getty");
X		for (i=0; arg[i]!=NULL; i++)
X			printf(" %s",arg[i]);
X		putchar('\n');
X	}
X	/* At this point, we also trap hangups, so that we can clean up after
X	 * any incoming calls. (Hangups are now detected by the hardware).
X	 * Note: must have no CLOCAL on either gettydefs section, use HUPCL
X	 * Re-do the termio settings, so that we can login. */
X	/* Close all the files we have open, getty expects none. */
X	fflush(stdout); /* avoid double printing buffers */
X	fflush(stderr);
X	if (fork()) { /* parent (PPID 1) */
X		uchange(mypid,1); /* change utmp entry */
X		login_term(findspeed(connsp));
X		if (Debug>=9)
X			printf("Close all files, exec getty...\n");
X		wait((int *)NULL); /* child returns, grand child holds */
X		for (i=0; i<20; i++)
X			close(i);
X		execve("/etc/getty",arg,env); /* polymorph self */
X		exit(99);
X	} else { /* child */
X		if (fork()) /* this avoids <defunct> entry */
X			exit(0);
X		/* grand child */
X		signal(SIGHUP,killgetty);
X		sleep(GETTYWAIT); /* child holds line while getty spins up */
X		if (Debug>=9)
X			printf("In grandchild, done holding line, good luck!\n");
X		exit(0);
X	}
X}
END_OF_FILE
if test 1896 -ne `wc -c <'exec.c'`; then
    echo shar: \"'exec.c'\" unpacked with wrong size!
fi
# end of 'exec.c'
fi
if test -f 'extern.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'extern.c'\"
else
echo shar: Extracting \"'extern.c'\" \(279 characters\)
sed "s/^X//" >'extern.c' <<'END_OF_FILE'
X/* vi:set ai sm ts=2 sw=2: */
X
Xchar *me; /* argv[0] */
Xint dev,mypid; /* device fd, our pid, and exit status */
Xint Debug=0,Hangup=1,Quiet=0,Timeout=0,Watchit=0;
Xchar lockf[50];				/* argument lock file */
Xchar dname[30];				/* device name in full - /dev/.... */
Xchar mylockf=0;
END_OF_FILE
if test 279 -ne `wc -c <'extern.c'`; then
    echo shar: \"'extern.c'\" unpacked with wrong size!
fi
# end of 'extern.c'
fi
if test -f 'io.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'io.c'\"
else
echo shar: Extracting \"'io.c'\" \(5258 characters\)
sed "s/^X//" >'io.c' <<'END_OF_FILE'
X/* vi:set ai sm ts=2 sw=2: */
X/*
X * Copyright (c) Dave Settle, March 1987
X * Permission is granted to do anything with this program, except remove
X * this copyright notice, or sell it for profit.
X *
X *
X * io.c: routines to talk to the device directly.
X *
X * dread and dwrite act like read(2) and write(2), execpt that they always
X * either succeed or exit, so the caller doesn't have to check.
X *
X * hangup drops the DTR line to the modem, so that it will (hopefully) hang up
X * the phone line. It keeps it this way for 5 seconds.
X *
X * findspeed takes an ascii speed, and returns the corresponing baud rate.
X *
X * uuexit is a dodgy routine to make UUCP happy.
X */
X
X#include <sys/errno.h>
X#include <termio.h>
X#include <fcntl.h>
X
X#include "prtty.h"
X
Xchar *sys_errlist[];		/* error list		*/
X#define RETRY 5			/* retry failed writes	*/
X
X/*
X * dwrite: write some characters to the modem. 
X * If your modem likes characters to be written s-l-o-w-l-y, define 'SLOW'	
X */
X
Xdwrite(s,n)
Xunsigned n;
Xchar *s;
X{
X	struct termio termio;
X	int r, retry=0, i=0;
X	static int error=0;		/* error occurred on last call */
X
X	while ((i<n) && (retry<RETRY)) {
X		if (locked())
X			uuexit(0);
X		errno=0;
X		if (*(s+i)=='\\') { /* escaped character */
X			i++; /* point at the character */
X			switch (*(s+i)) {
X				case 'p':
X					if (Debug>=9)
X						printf("<PAUSE>");
X					sleep(1);
X					i++;
X					continue;
X				case 'd':
X					if (Debug>=9)
X						printf("<DELAY>");
X					sleep(2);
X					i++;
X					continue;
X				case 'K':
X					if (Debug>=9)
X						printf("<BREAK>");
X					if (ioctl(dev,TCSBRK,0)==-1)
X						perror("sendex: \K: TCSBRK");
X					sleep(2);
X					i++;
X					continue;
X			}
X		}
X		if (r=write(dev,s+i,1)==1) {
X			if (Debug>=9)
X				show(*(s+i));
X			i++; /* Success! */
X		} else { /* 0 or -1 */
X			retry++;
X			fixline();
X		}
X#ifdef SLOW
X		sleep(1); /* Let the modem deal with it */
X#endif
X	} /* while (continue) */
X	if (i!=n) {
X		ioctl(dev,TCGETA,&termio);
X		if (Debug>=5) {
X			printf("Tried %d times, still got %d/%d written. [error=%s]\n", 
X				retry,i,n,sys_errlist[errno]);
X			printf("FAIL: dev %d, iflag %x, oflag %x, cflag %x, lflag %x, line %d\n",
X				dev,termio.c_iflag,termio.c_oflag,termio.c_cflag,
X				termio.c_lflag,termio.c_line);
X		}
X		error=1;
X	}
X	else
X		if (retry>1)
X			if (Debug>=6)
X				printf("Write problem: fixed on retry %d\n",retry-1);
X	if (error && i==n) {
X		ioctl(dev,TCGETA,&termio);
X		if (Debug>=7)
X			printf("OK: iflag %x, oflag %x, cflag %x, lflag %x, line %d\n",
X				termio.c_iflag,termio.c_oflag,termio.c_cflag,
X				termio.c_lflag, termio.c_line);
X	}
X	if (i==n)
X		error=0;
X	return(r);
X}
X
X/*
X * read one character at a time, checking before (and after) each read for
X * a lock file. If one exists, then exit.
X */
Xdread(s,n)
Xint n;
Xchar *s;
X{
X	int i,len;
X
X	for (i=0; i<n; i++,s++) {
X		if (locked())
X			uuexit(0);
X		while ((len=read(dev,s,1))<1) {
X			if (locked())
X				uuexit(0);
X			if (len==-1)
X				switch(errno) {
X					case EINTR: /* ignore */
X						break;
X					default:
X						perror("dread");
X				}
X		}
X	}
X}
X
X/*
X * hangup(): hangup the phone, and close the device.
X * I've had problems with indefinate echoes from the modem when a connection
X * has closed - my modem transmits crap. This ought to hangup the phone and
X * prevent this.
X *
X * Oct 87: This problem should now be fixed, with the introduction of the
X * DCD control from the modem - we should now receive a hangup signal when
X * the line drops.
X */
Xhangup()
X{
X	struct termio term;
X
X#if 0
X	if (ioctl(dev,TCXONC,1)==-1) /* let output go */
X		perror("hangup: TCXONC");
X	if (ioctl(dev,TCFLSH,2)==-1)
X		perror("hangup: TCFLSH 1");
X#endif
X	if (ioctl(dev,TCGETA,&term)==-1)
X		perror("hangup: TCGETA");
X	term.c_lflag &= ~(ECHO | ECHOE | ECHOK);
X	term.c_cflag &= ~CBAUD;
X	term.c_cflag |= B0;		/* hangup */
X#if 0
X	if (ioctl(dev,TCSBRK,0)==-1)
X		perror("hangup: TCSBRK");
X#endif
X	if (ioctl(dev,TCSETA,&term) == -1)
X		perror("hangup: TCSETA 1");
X	if (ioctl(dev,TCFLSH,2) == -1)
X		perror("hangup: TCFLSH 2");
X	sleep(DTRWAIT);
X#if 0
X	term.c_cflag &= ~CLOCAL; /* let line go back into normal state */
X	if (ioctl(dev,TCSETA,&term) == -1)
X		perror("hangup: TCSETA 2");
X#endif
X	return(0);
X}
X
X/*
X * uuexit: make line useable by UUCP.
X * Because UUCP is prtty determined about using a "modem", it clears CLOCAL
X * which means that it can't write any characters at this point (modem not
X * online, so DCD not asserted). Not suprisingly, it doesn't work.
X * Solution: turn it on again, while UUCP isn't looking; this seems to work
X * fine, although I'm a little puzzled about the timing: this is a 
X * definate "trial and error" solution.
X * This unfortunately also means that UUCP won't detect a line hangup, 
X * so we have to rely on it's timeout facilities ...
X */
X#define DIALTIME 5 /* time to continue to assert CLOCAL */
Xuuexit(code)
X{
X	struct termio term;
X	register int i;
X
X	for (i=0; i<DIALTIME; i++) {
X		close(open(dname,O_RDONLY | O_NDELAY)); /* vital magic */
X		if (ioctl(dev,TCGETA,&term) == -1)
X			perror("qx TCGETA");
X		term.c_cflag |= CLOCAL;
X		if (ioctl(dev,TCSETA,&term) == -1)
X			perror("qx TCSETA");
X		close(open(dname,O_RDONLY | O_NDELAY)); /* vital magic */
X		sleep(1);
X	}
X	exit(code);
X}
X
Xint myread()
X{
X	char c;
X
X	dread(&c,1);
X	return(c);
X}
X
Xvoid mywrite(s)
Xchar *s;
X{
X	dwrite(s,strlen(s));
X}
END_OF_FILE
if test 5258 -ne `wc -c <'io.c'`; then
    echo shar: \"'io.c'\" unpacked with wrong size!
fi
# end of 'io.c'
fi
if test -f 'line.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'line.c'\"
else
echo shar: Extracting \"'line.c'\" \(2883 characters\)
sed "s/^X//" >'line.c' <<'END_OF_FILE'
X/* vi:set ai sm ts=2 sw=2: */
X
X/* line.c: set up the various termio params for the line at various stages.
X * [What I would like for Christmas: System V tty driver code, so I could
X *  find out why it behaves so strangely ... ] */
X 
X#include <fcntl.h>
X#include <termio.h>
X#include "prtty.h"
X
Xstatic int speed; /* YUCK! */
X
Xinit_term(baud)
Xint baud;
X{
X	struct termio term;
X
X	if (Debug>=11) printf("init_term: flush");
X	ioctl(dev,TCFLSH,2); /* zap it! */
X	if (Debug>=11) printf(", xon restart");
X	ioctl(dev,TCXONC,1); /* then unlock it */
X	if (Debug>=11) printf(", TCGETA");
X	speed=baud; /* I did say yuck (read on) */
X	if (ioctl(dev,TCGETA,&term) == -1)
X		perror("TCGETA");
X	term.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL); /* ECHONL new */
X	term.c_iflag &= ~(ISTRIP | INPCK);
X	term.c_iflag &= ~(ICRNL | ISIG | IXON | IXOFF); /* these are new */
X	term.c_cflag &= ~(CBAUD | CSIZE);
X	term.c_cflag |= baud | CS8 | CLOCAL;
X	term.c_cc[VMIN] = 1; /* when ICANON is off */
X	term.c_cc[VTIME] = 0;
X	if (Debug>=11) printf(", TCSETA");
X	if (ioctl(dev,TCSETA,&term) == -1)
X		perror("TCSETA");
X/*
X * Since we opened the line with O_NDELAY, reads will return immediately if
X * no chars are ready. We don't really want this, 'cos "dread" will then
X * eat CPU time, so we turn it off.
X * It only seems to be really effective when the device is opened again -
X * otherwise we get strange diagnostics about "wrote 0 of 4". Thanks to
X * the C-KERMIT crew for this tip.
X *
X * The open() here seems to hang sometimes, so a timeout is implemented.
X * [since CLOCAL has been set above, this should never happen. We can't
X *  just open with O_NDELAY, because uucp won't work anyway.]
X */
X	if (Debug>=11) printf(", turn off NDELAY");
X 	fcntl(dev,F_SETFL,0);
X 	alarm(5);
X 	if (close(open(dname,O_RDONLY))==-1) {
X 		perror("ERROR: Couldn't reopen device after TCSETA");
X 		exit(1);
X 	}
X 	alarm(0);
X	if (Debug>=11) printf(", done\n");
X}
X
X/*
X * Strange things have been known to happen during "login" with incorrect 
X * settings - if it forgets to ask you for a password, check them carefully.
X * Oct 87: Disable CLOCAL, since DCD is now asserted, and we want to be told
X * about hangups.
X */
Xlogin_term(baud)
Xint baud;
X{
X	struct termio term;
X
X	ioctl(dev,TCGETA,&term);
X	term.c_cc[VEOF] = 04; /* cntrl-D, because of VMIN */
X	term.c_cc[VEOL] = '\n'; /* cntrl-J, because of VTIME */
X	term.c_iflag = BRKINT | IGNPAR | ISTRIP | ICRNL;
X	term.c_oflag = OPOST | ONLCR | TAB3;
X	term.c_cflag &= ~(CSIZE | CLOCAL | CBAUD);
X	term.c_cflag |= CS7 | HUPCL | CREAD | baud;
X	term.c_lflag = ISIG | ICANON;
X	ioctl(dev,TCSETAW,&term);
X}
X
X/* fixline: write failed - redo settings on line. */
Xfixline()
X{
X	ioctl(dev,TCFLSH,2); /* flush queues */
X	ioctl(dev,TCXONC,1); /* restart XON/XOFF */
X	fcntl(dev,F_SETFL,0); /* poke the flag */
X	close(open(dname,O_RDONLY | O_NDELAY));
X	init_term(dev,speed); /* I really meant it */
X}
END_OF_FILE
if test 2883 -ne `wc -c <'line.c'`; then
    echo shar: \"'line.c'\" unpacked with wrong size!
fi
# end of 'line.c'
fi
if test -f 'lock.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lock.c'\"
else
echo shar: Extracting \"'lock.c'\" \(2078 characters\)
sed "s/^X//" >'lock.c' <<'END_OF_FILE'
X/* vi:set ai sm ts=2 sw=2: */
X
X#include <sys/types.h>
X#include <stdio.h>
X
X#include "prtty.h"		/* variable definitions */
X
Xvoid mklockf(line,dnm)
Xchar *line,*dnm;
X{
X	sprintf(dnm,"/dev/%s",line);
X#ifdef OL3B2
X	sprintf(lockf,"/usr/spool/locks/LCK..%s",line);
X#else
X#	ifdef HDB
X	sprintf(lockf,"/usr/spool/locks/LCK.L.%s",line);
X#	else
X	sprintf(lockf,"/usr/spool/uucp/LCK..%s",line);
X#	endif
X#endif
X	if (Debug>=7)
X		printf("Lock file name is \"%s\"\n",lockf);
X}
X
Xstatic int killifdead()
X{
X	unsigned short int stat;
X	int lkpid;
X	FILE *lock;
X	char cmd[40];
X
X	if ((lock=fopen(lockf,"r"))==NULL)
X		return(1);
X#ifdef OL3B2
X	fscanf(lock,"%d",&lkpid);
X#else
X#ifdef HDB
X	fscanf(lock,"%d",&lkpid);
X#else
X	fread((char *) &lkpid,sizeof(lkpid),1,lock);
X#endif
X#endif
X	fclose(lock);
X	if (!lkpid) {
X		if (Debug>=5)
X			printf("PID in lock file is 0, lock file deleted\n");
X		return(unlink(lockf));
X	} else {
X		if (Debug>=9)
X			printf("Existing lockfile PID=%d\n",lkpid);
X		sprintf(cmd,"ps -p%d >/dev/null 2>&1",lkpid);
X		stat=system(cmd);
X		if (stat&0xff)
X			printf("Error doing ps, exit=%d\n",stat&0xff);
X		else
X			if ((stat>>8)==1) { /* ps failed, it's not there */
X				if (Debug>=9)
X					printf("Process not here, lock file deleted\n");
X				return(unlink(lockf));
X			} else
X				if (Debug>=9)
X					printf("Process still active, lock file not removed\n");
X		return(1);
X	}
X}
X
Xvoid wtlock()
X{
X	int i;
X	time_t now;
X
X	if (Debug>=5) {
X		now=time((long *)NULL);
X		printf("Startup, lock file%s: %s, now: %s",
X			locked()?"[present]":"",lockf,asctime(localtime(&now)));
X	}
X	if (Debug>=8)
X		printf("Dot is %d secs [",LOCKWAIT);
X	if (locked()) {
X		if (Debug>=8)
X			putchar('p');
X		killifdead();
X	}
X	while (locked()) {
X		for (i=0; i<PROCCHECK && locked(); i++) {
X			sleep(LOCKWAIT);
X			if (Debug>=8)
X				putchar('.');
X		}
X		if (i==PROCCHECK) {
X			if (Debug>=8)
X				putchar('p');
X			killifdead();
X		} else {
X			if (Debug>=8)
X				putchar('x');
X			sleep(LOCKREUSE);
X		}
X	}
X	if (Debug>=8)
X		puts("]");
X	if (Debug>=5) {
X		now=time((long *)NULL);
X		printf("Lock gone: %s, %s",lockf,asctime(localtime(&now)));
X	}
X}
END_OF_FILE
if test 2078 -ne `wc -c <'lock.c'`; then
    echo shar: \"'lock.c'\" unpacked with wrong size!
fi
# end of 'lock.c'
fi
if test -f 'misc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'misc.c'\"
else
echo shar: Extracting \"'misc.c'\" \(1443 characters\)
sed "s/^X//" >'misc.c' <<'END_OF_FILE'
X/* vi:set ai sm ts=2 sw=2: */
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <termio.h>
X#include <stdio.h>
X#include "prtty.h"
X
X/* haven't YOU always wanted this? */
Xvoid perrorf(format,a1,a2,a3,a4,a5,a6,a7,a8,a9)
Xchar *format,*a1,*a2,*a3,*a4,*a5,*a6,*a7,*a8,*a9;
X{
X	char line[200];
X
X	sprintf(line,format,a1,a2,a3,a4,a5,a6,a7,a8,a9);
X	perror(line);
X}
X
X/* check for presence of lock file return 1 if locked. */
Xint locked()
X{
X	int is;
X
X	is=access(lockf,0); /* is it there? */
X	if (Debug>=40) /* probably never want to set Debug this high! */
X		if (is==-1)
X			printf("||");
X		else
X			printf("==");
X	if (is==-1)
X		return(0);
X	return(1);
X}
X
Xint findspeed(s)
Xchar *s;
X{
X	int baud=atoi(s);
X
X	switch(baud) {
X		case 110: baud=B110;
X			break;
X		case 300: baud=B300;
X			break;
X		case 1200: baud=B1200;
X			break;
X		case 2400: baud=B2400;
X			break;
X		case 9600: baud=B9600;
X			break;
X		case 19200:
X#ifdef UNIXPC
X			baud=EXTA;
X#else
X			baud=B2400;
X#endif
X			break;
X		default:
X			printf("findspeed: unknown baud rate %s\n", s);
X			baud=B1200;
X	}
X	return(baud);
X}
X
X/* 0-31,127 as ^A, 32-126 normal, 128-255 as $FF */
Xvoid show(c)
Xchar c;
X{
X	if (c&0xe0) { /* not control */
X		if (c&0x80) /* 8th bit set */
X			printf("$02X",c);
X		else /* not control or 8th bit */
X			if (c==127) /* del */
X				fputs("^?",stdout);
X			else
X				putchar(c);
X	} else { /* control */
X		putchar('^');
X		putchar(c|'@');
X	}
X}
X
Xvoid sshow(s)
Xchar *s;
X{
X	while(*s)
X		show(*s++);
X}
END_OF_FILE
if test 1443 -ne `wc -c <'misc.c'`; then
    echo shar: \"'misc.c'\" unpacked with wrong size!
fi
# end of 'misc.c'
fi
if test -f 'prtty.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'prtty.c'\"
else
echo shar: Extracting \"'prtty.c'\" \(7620 characters\)
sed "s/^X//" >'prtty.c' <<'END_OF_FILE'
X/* vi:set ai sm ts=2 sw=2: */
X/*
X * Copyright (c) Dave Settle 1987
X * All rights reserved.
X * Permission is granted to do anything with this program, except remove
X * this copyright notice, or sell it for profit.
X *
X * Problems, suggestions, bug fixes etc, to:
X *
X * Dave Settle, SMB Business Software, Thorn EMI Datasolve
X * 
X * UUCP:
X * 	dave at smb.co.uk
X * 	...!mcvax!ukc!nott-cs!smb!dave	
X * 
X * SMAIL:					Voice:
X * 	SMB Business Software		     +44 623 651651
X * 	High Street
X * 	Mansfield			Telex:
X * 	Nottingham NG18 1ES		     37392 TECSMG
X * 	England	
X * 					Fax:
X * 					     +44 623 659947
X * 
X * prtty.c: a bi-directional "getty" to allow incoming calls AND outgoing 
X * uucico's
X *
X * name changed from "modem" to "prtty"
X *
X * Modified by Rick Richardson for HDB uucp and AT&T Aztec protocol
X *
X * Modified by Jack Bonn for state logic (allows autoanswer on/off at
X *                       a given time for each day of the week)
X *
X * Modified by Dave Settle:
X *
X * Code fixes:
X *	hangup routine added, to make sure phone is down before script, and
X *		after user disconnects.
X *	Parameterised send-expect routines.
X *	Minor bug fix to dread()
X *	Re-enable SIGALRM in wakeup()
X *	Catch all signals, to enable crashes to be detected.
X *	Chmod device back to 666, so that we can use it afterwards.
X *      Oct 87: fixup modem control with CLOCAL, so that remote disconnect
X *		can be detected and dealt with.
X *	Oct 87: fix autologout to send series of signals, not just SIGHUP
X *	Oct 87: Clean up code, and distribute to other source files.
X *	Nov 87: Fix lurking bug in 'expect'. Clean code for 'lint'.
X *	Nov 87: Ignore SIHGUP's generated by 'hangup'.
X *	Dec 87: Force getty NOT to hangup the line before login.
X *	Jan 87: Open stdio file descriptors.
X *
X *
X */
X#include <sys/types.h>
X#include <stdio.h>
X#include <signal.h>
X#include <errno.h>
X#include <fcntl.h>
X#include <sys/stat.h>
X#include <termio.h>
X#include <time.h>
X#include <string.h>
X
Xextern int optind;
Xextern char *optarg;
X
X#include "prtty.h"		/* variable definitions */
X#include "ring.h"		/* send expect strings */
Xextern int wakeup(),closedown(); /* sigs */
X
Xstatic void setlog(line)
Xchar *line;
X{
X	if (Quiet) {
X		close(0);
X		close(1);
X		close(2);
X		open("/dev/null",0); /* stdin */
X		open("/dev/null",1); /* stdout */
X		open("/dev/null",1); /* stderr */
X	} else { /* !Quiet */
X		int f;
X		char log[45];
X
X		/* Make sure we have stdxxx */
X		if ((f=open("/dev/null",0))==0) { /* first open got fd 0 */
X			open("/dev/null",1); /* stdout */
X			open("/dev/null",1); /* stderr */
X		} else /* assume stdout AND stderr were open */
X			close(f);
X		sprintf(log,LOGFILE,line); /* different log files for each line */
X		freopen(log,"a",stdout);
X		freopen(log,"a",stderr); /* because we use a lot of perror() */
X		chmod(log,0644);
X		setbuf(stdout,NULL);
X		setbuf(stderr,NULL);
X		if (Debug>=9) { /* not buffered this high */
X			printf("\n\nAhhh... log file ready to roll: stdout");
X			fprintf(stderr,", stderr\n");
X		}
X	}
X}
X
X/* partof: look for str in text. Has a bug if you look for ...xxx... */
Xstatic int partof(text,str)
Xchar *text,*str;
X{
X	char *needle, *p;
X
X	for (p=text,needle=str; *p ; p++) {
X		if (*p!=*needle)
X			needle=str;
X		if (*p==*needle)
X			needle++;
X		if (*needle=='\0')
X			return(1);
X	}
X	return(0);
X}
X
Xstatic void getmodem(chatsp)
Xchar *chatsp;
X{
X	long t;
X	int baud;
X	struct conv *p;
X
X /*
X  * set terminal parameters
X  * Additional argument (if present) can be used to force an initial speed
X  * (Thanks rick)
X  */
X	baud=findspeed(chatsp);
X	init_term(baud);
X	/* send-expect strings - at the end, someone has connected to the modem */
X	for (p=ring; p->c_send; p++) {
X		send(p->c_send,mywrite);
X		if (expect(p->c_expect,p->c_wait,myread)) {
X			t=time((long *) NULL);
X			if (Debug>=3)
X				if (p->c_wait)
X					printf("Modem chat script failed on %s",asctime(localtime(&t)));
X				else
X					printf("Timeout on %s",asctime(localtime(&t)));
X/*
X * We don't have to do anything special here, since no locks have been setup.
X * However, since the main problems appear to be non-responding modems, send
X * it some sort of 'un-wedging' sequence
X */
X 			send(RESET,mywrite);
X 			sleep(3);
X			hangup();
X			sleep(RESPWAIT);
X			ioctl(dev,TCFLSH,2);	/* Flush both queues */
X			exit(3);
X			/*NOTREACHED*/
X		}
X	}
X	if (Debug>=7)
X		printf("Send/expect completed, must be connected\n");
X}
X
Xstatic void getspeed(connsp)
Xchar **connsp;
X{
X#ifdef SPEEDCONFIG
X	char c,buff[8];
X
X	if (Debug>=7)
X		printf("SPEEDCONFIG: ");
X	dread(&c,1); /* space after CONNECT or \r */
X#	ifdef TELEBIT
X	dread(buff,4);
X	if (!strncmp(buff,"300\r",4)) *connsp="300";
X	else if (!strncmp(buff,"1200",4)) *connsp="1200";
X	else if (!strncmp(buff,"2400",4)) *connsp="2400";
X	else if (!strncmp(buff,"FAST",4)) *connsp="19200"; /* I hope so */
X#	else
X	if (c=='\r')
X		*connsp="300";
X	else {
X		dread(buff,4);
X		if (!strncmp(buff,"1200",4)) *connsp="1200";
X		else if (!strncmp(buff,"2400",4)) *connsp="2400";
X		else if (!strncmp(buff,"1275",4)) *connsp="1200";
X		else if (!strncmp(buff,"7512",4)) *connsp="1200";
X	}
X#	endif /* TELEBIT */
X	if (Debug>=7)
X		printf("string: \"%4.4s\", speed: %s\n",buff,*connsp);
X#endif /* SPEEDCONFIG */
X}
X
Xstatic void doit(line,chatsp,term,ldisc,env)
Xchar *line,*chatsp,*term,*ldisc,*env[];
X{
X	long t;
X	char *connsp;
X
X	dev=0; /* we are not using the device yet */
X	setsigs();
X	setlog(line);
X	if (Debug>=6) { /* now that the log file is available */
X		printf("line:%s speed:%s",line,chatsp);
X		if (term!=NULL) {
X			printf(" term:%s",term);
X			if (ldisc!=NULL)
X				printf(" ldisc:%s",ldisc);
X		}
X		putchar('\n');
X	}
X	mklockf(line,dname);
X	wtlock();
X
X	if (Debug>=9)
X		printf("Opening device ");
X	if ((dev=open(dname,O_RDWR|O_NDELAY))==-1) {
X		perror(dname);
X		sleep(RESPWAIT); /* don't go crazy with respawns */
X		exit(4);
X	}
X	if (Debug>=9)
X		printf(" device open\n");
X	getmodem(chatsp); /* do send/expect to beat on modem */
X	signal(SIGALRM,wakeup);
X 	signal(SIGHUP,closedown);
X	/* OK, incoming call connected. Find speed (if possible) */
X	connsp=chatsp; /* default */
X	getspeed(&connsp); /* build connsp from what modem tells us */
X
X	t=time((long *)NULL);
X	if (!Quiet)
X		printf("Call connected at %s baud, PID=%d on %s",
X			connsp,mypid,asctime(localtime(&t)));
X	exgetty(line,connsp,term,ldisc,env);
X}
X
Xchar *usage="Usage: %s <tty> [<speed> [<term> [<line discipline>]]]\n";
X
Xint main(argc,argv,envp)
Xint argc;
Xchar *argv[],*envp[];
X{
X	char opt;
X	char *line,*speed=NULL,*term=NULL,*ldisc=NULL;
X
X	if ((me=strrchr(argv[0],'/')+1)==NULL)
X		me=argv[0];
X	Debug=Hangup=Quiet=Timeout=Watchit=0;
X	Hangup=1;
X	while ((opt=getopt(argc,argv,"chqt:x:w?"))!=EOF)
X		switch (opt) {
X			case 'c':
X				fprintf(stderr,"Check what?\n");
X				break;
X			case 'h': /* same as getty */
X				Hangup=0; /* yes, it's backwards */
X				break;
X			case 'q':
X				Quiet=1;
X				break;
X			case 't': /* same as getty */
X				Timeout=atoi(optarg);
X				break;
X			case 'w':
X				Watchit=1;
X				break;
X			case 'x':
X				Debug=atoi(optarg);
X				if (!Debug)
X					Debug=1;
X				break;
X			case '?':
X			default:
X				fprintf(stderr,usage,me);
X				exit(1);
X		}
X	if (getppid()!=1) { /* wait until now so they get help */
X		fprintf(stderr,"%s: Parent PID is not 1 (init)\n",me);
X		sleep(RESPWAIT);
X		exit(1);
X	}
X	if (Quiet)
X		Debug=0; /* faster */
X	mypid=getpid();
X	putenv(TIMEZONE); /* before we use localtime() */
X	speed=DEFSPEED;
X	switch (argc-optind) {
X		case 4:
X			ldisc=argv[optind+3];
X		case 3:
X			term=argv[optind+2];
X		case 2:
X			speed=argv[optind+1];
X		case 1:
X			line=argv[optind+0];
X			break;
X		case 0:
X			fprintf(stderr,usage,me);
X			sleep(RESPWAIT);
X			exit(1);
X	}
X	doit(line,speed,term,ldisc,envp);
X	return(0);
X}
END_OF_FILE
if test 7620 -ne `wc -c <'prtty.c'`; then
    echo shar: \"'prtty.c'\" unpacked with wrong size!
fi
# end of 'prtty.c'
fi
if test -f 'sendex.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sendex.c'\"
else
echo shar: Extracting \"'sendex.c'\" \(1724 characters\)
sed "s/^X//" >'sendex.c' <<'END_OF_FILE'
X/* vi:set ai sm ts=2 sw=2: */
X/*
X * Copyright (c) Dave Settle, Mar 1987
X * Permission is granted to do anything with this program, except remove
X * this copyright notice, or sell it for profit.
X *
X *
X * sendex.c: contains the send-expect routines, beefed-up a little to
X * make them more useful.
X * Both "send" and "expect" now have a function, rather than
X * a file descriptor. This function gets called as follows:
X *
X *	(int) (*rdfunc)();		[send]
X *	(*wtfunc)((char *)s);		[expect]
X *
X */
X
X#include <setjmp.h>
X#include <signal.h>
X#include <stdio.h>
X#include "prtty.h"
X
Xvoid send(s,func)
Xchar *s;
Xvoid (*func)();
X{
X	if (Debug>=9)
X		printf("send(");
X	(*func)(s);
X	if (Debug>=9)
X		printf(")\n");
X	sleep(1);
X}
X
X/*
X * expect: expect a string. Return 0 on success, 1 on timeout.
X * chars are threaded on the needle as they match the expect string
X * if one fails to match, all chars are unthreaded. 
X * expect succeeds if all chars on expect string are threaded.
X */
X
Xjmp_buf env;
X
Xstatic void timeout()
X{
X	longjmp(env,1);
X}
X
Xint expect(s,t,func)
Xchar *s;
Xint (*func)();
X{
X	char *needle=s,c;
X	int (*handler)();
X
X	alarm(0);
X	handler=signal(SIGALRM,timeout);
X	if (setjmp(env)) {
X		if (t)
X			if (Debug>=5) /* should be rare */
X				printf("\nTimeout expecting %s\n",s);
X			else if (Debug>=7) /* may happen continuously */
X				printf("\nTimeout (-t%d) expecting %s\n",Timeout,s);
X		return(1);
X	}
X	if (t)
X		alarm(t);
X	else
X		alarm(Timeout); /* if zero, no timeout */
X	if (Debug>=9)
X		printf("expect(%s) [",s);
X	while (*needle) {
X		c=(*func)();
X		if (Debug>=9)
X			show(c);
X		if (*needle != c)
X			needle = s;
X		if (*needle == c)
X			needle++;
X	}
X	if (Debug>=9)
X		printf("] got it\n");
X	alarm(0);
X	signal(SIGALRM,handler);
X	return(0);
X}
END_OF_FILE
if test 1724 -ne `wc -c <'sendex.c'`; then
    echo shar: \"'sendex.c'\" unpacked with wrong size!
fi
# end of 'sendex.c'
fi
if test -f 'sigs.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sigs.c'\"
else
echo shar: Extracting \"'sigs.c'\" \(1519 characters\)
sed "s/^X//" >'sigs.c' <<'END_OF_FILE'
X/* vi:set ai sm ts=2 sw=2: */
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <signal.h>
X/*#include <time.h>*/
X#include "prtty.h"		/* variable definitions */
X
Xint wakeup(sig)
Xint sig;
X{
X	signal(SIGALRM,wakeup); /* Hmm */
X}
X
Xint closedown(sig)
Xint sig;
X{
X	time_t now;
X
X	now=time((long *) NULL);
X	signal(SIGHUP,SIG_IGN);
X	if (Debug>=3)
X		printf("\nClosedown, signal %d at %s",sig,asctime(localtime(&now)));
X	/* change the value in utmp back to our pid. */		
X	uchange(mypid,0); /* back to normal */
X	/* clear modem line, should also hangup the phone (if it wasn't already). */	
X	if (dev) {
X		hangup();
X		close(dev); /* drop it */
X		dev=0;
X	}
X	/*
X	 * chmod the device back to 666, so that uucico and cu can access it.
X	 * NOTE: I prefer this to chown(uucp), which does not allow "cu" access.
X	 */
X	if (mylockf) {
X		chmod(dname,0666); /* uucp access */
X		unlink(lockf);
X		if (Debug>=5)
X			printf("Our lock file removed.\n");
X	}
X	fclose(stdout);
X	fclose(stderr);
X	exit(sig);
X}
X
Xstatic int fault(sig)
Xint sig;
X{
X	printf("\nCrashed with signal %d\n",sig);
X	exit(sig);
X}
X
Xvoid setsigs()
X{
X	int i;
X
X	/*
X	 * catch and report all signals, but apply special treatment to legal signals
X	 * Any program bugs get reported this way. You can get a core dump by sending
X	 * it SIGFPE.
X	 */
X 	for (i=1; i<SIGUSR1; i++)
X		signal(i,fault);
X 	signal(SIGHUP,SIG_IGN);
X 	signal(SIGINT,SIG_IGN);
X 	signal(SIGQUIT,SIG_IGN);
X 	signal(SIGFPE,SIG_DFL);	/* you can get a core dump here */
X 	signal(SIGALRM,wakeup);
X 	signal(SIGTERM,closedown);
X}
END_OF_FILE
if test 1519 -ne `wc -c <'sigs.c'`; then
    echo shar: \"'sigs.c'\" unpacked with wrong size!
fi
# end of 'sigs.c'
fi
if test -f 'uchange.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'uchange.c'\"
else
echo shar: Extracting \"'uchange.c'\" \(1457 characters\)
sed "s/^X//" >'uchange.c' <<'END_OF_FILE'
X/* vi:set ai sm ts=2 sw=2: */
X/*
X * Copyright (c) Dave Settle, Mar 1987
X * Permission is granted to do anything with this program, except remove
X * this copyright notice, or sell it for profit.
X *
X *
X * change the ut_pid value from "old" to "new".
X * Attempts to do all the things that "getty" appears to do.
X */
X 
X#include <sys/types.h>
X#include <utmp.h>
X#include "prtty.h"
X
Xstruct utmp *utmp, *getutent();
X
Xuchange(pid,getty)
Xint pid,getty;
X{
X	int ent=0;
X
X	setutent();
X	if (Debug>=20)
X		printf("/etc/utmp open, scanning for pid=%d\n",mypid);
X	while (utmp=getutent()) {
X		if (Debug>=20)
X			printf("ent: %2d, pid:%d, user %s, type %d\n",
X				ent,utmp->ut_pid,utmp->ut_user,utmp->ut_type);
X		if (utmp->ut_pid==pid) {
X			/* utmp->ut_type=INIT_PROCESS; */
X			if (getty)
X				strcpy(utmp->ut_user,"getty");
X			else
X				strcpy(utmp->ut_user,me);
X			if (Debug>=20)
X				printf("Found! Changed name to \"%s\"",utmp->ut_user);
X			pututline(utmp);
X			if (Debug>=20)
X				printf(", writing");
X			endutent();
X			if (Debug>=20)
X				printf(", closed.\n");
X			return(1);
X		}
X		ent++;
X	}
X	printf("ERROR: Can't find utmp entry\n");
X	endutent();
X	return(1);
X}
X
X#if 0
X#define	EMPTY		0
X#define	RUN_LVL		1
X#define	BOOT_TIME	2
X#define	OLD_TIME	3
X#define	NEW_TIME	4
X#define	INIT_PROCESS	5	/* Process spawned by "init" */
X#define	LOGIN_PROCESS	6	/* A "getty" process waiting for login */
X#define	USER_PROCESS	7	/* A user process */
X#define	DEAD_PROCESS	8
X#define	ACCOUNTING	9
X#endif
END_OF_FILE
if test 1457 -ne `wc -c <'uchange.c'`; then
    echo shar: \"'uchange.c'\" unpacked with wrong size!
fi
# end of 'uchange.c'
fi
if test ! -d 'inst' ; then
    echo shar: Creating directory \"'inst'\"
    mkdir 'inst'
fi
if test -f 'inst/Devices' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'inst/Devices'\"
else
echo shar: Extracting \"'inst/Devices'\" \(499 characters\)
sed "s/^X//" >'inst/Devices' <<'END_OF_FILE'
Xtbdir tty000,M - Any tbcu
Xwake tty000,M - Any tbwake
X103 tty000,M - 300 tbdial
X212 tty000,M - 1200 tbdial
Xv22 tty000,M - 2400 tbdial
Xpep tty000,M - 19200 tbdipep
XACU ph1 ph1 1200 PC7300 \T
XDirect tty000 - Any direct
XDirect tty002 - Any direct
X#
X# UNDOCUMENTED FEATURE:
X# tty000,M
X# The ",M" opens the line O_NDELAY. The first token in the Dialers file must
X# start with "\M" in order to hold the line. Because of this, the ",M" does no
X# good on "Direct" lines: it drops after the device is open.
X#
END_OF_FILE
if test 499 -ne `wc -c <'inst/Devices'`; then
    echo shar: \"'inst/Devices'\" unpacked with wrong size!
fi
# end of 'inst/Devices'
fi
if test -f 'inst/Dialers' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'inst/Dialers'\"
else
echo shar: Extracting \"'inst/Dialers'\" \(783 characters\)
sed "s/^X//" >'inst/Dialers' <<'END_OF_FILE'
Xdirect
Xtbcu	=W-,	"" \M\K\dA\pA\pA\pT\r\c OK-\rAT\r\c-OK ATS???????????????\r\c OK ATE1\r\c
Xtbdial	=W-,	"" \M\K\dA\pA\pA\pT\r\c OK-\rAT\r\c-OK ATS???????????????\r\c OK ATS66=1DT\T\r\c CONNECT-\c-CONNECT \m\c 00
Xtbwake	=W-,	"" \M\K\dA\pA\pA\pT\r\c OK-\rAT\r\c-OK ATS???????????????\r\c OK ATS8=1S11=200DT\T,,,,,,9515999,555,999,9515999955951\r\c ""
Xtbdipep	=W-,	"" \M\K\dA\pA\pA\pT\r\c OK-\rAT\r\c-OK ATS???????????????\r\c OK ATSS50=255S66=1DT\T\r\c CONNECT-\c-CONNECT-\c-CONNECT \m\c FAST
X#
X# My escape code is ### right now
X#
X# Each caller type that appears in the Devices file (5th field)
X# should appear in this file except for the built in callers.
X# Each line consists of three parts:
X# - the name of the caller
X# - the translation table for the phone number to translate from
END_OF_FILE
if test 783 -ne `wc -c <'inst/Dialers'`; then
    echo shar: \"'inst/Dialers'\" unpacked with wrong size!
fi
# end of 'inst/Dialers'
fi
if test -f 'inst/Systems' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'inst/Systems'\"
else
echo shar: Extracting \"'inst/Systems'\" \(100 characters\)
sed "s/^X//" >'inst/Systems' <<'END_OF_FILE'
Xtb300 Any tbdir 300 OUT
Xtb212 Any tbdir 1200 OUT
Xtbv22 Any tbdir 2400 OUT
Xtbpep Any tbdir 19200 OUT
END_OF_FILE
if test 100 -ne `wc -c <'inst/Systems'`; then
    echo shar: \"'inst/Systems'\" unpacked with wrong size!
fi
# end of 'inst/Systems'
fi
if test -f 'inst/gettydefs' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'inst/gettydefs'\"
else
echo shar: Extracting \"'inst/gettydefs'\" \(686 characters\)
sed "s/^X//" >'inst/gettydefs' <<'END_OF_FILE'
X1200# B1200 HUPCL BRKINT IGNPAR ISTRIP ECHO OPOST ONLCR # B1200 HUPCL BRKINT ISTRIP ICRNL IXON OPOST ONLCR CS8 CREAD ISIG ICANON ECHO ECHOE ECHOK TAB3 #1200 login: #1200
X
X2400# B2400 HUPCL BRKINT IGNPAR ISTRIP ECHO OPOST ONLCR # B2400 HUPCL BRKINT ISTRIP ICRNL IXON OPOST ONLCR CS8 CREAD ISIG ICANON ECHO ECHOE ECHOK TAB3 #2400 login: #2400
X
X19200# EXTA HUPCL BRKINT IGNPAR ISTRIP ECHO OPOST ONLCR # EXTA HUPCL BRKINT ISTRIP ICRNL IXON OPOST ONLCR CS8 CREAD ISIG ICANON ECHO ECHOE ECHOK TAB3 #19200 login: #19200
X
X300# B300 HUPCL BRKINT IGNPAR ISTRIP ECHO OPOST ONLCR # B300 HUPCL BRKINT ISTRIP ICRNL IXON OPOST ONLCR CS8 CREAD ISIG ICANON ECHO ECHOE ECHOK TAB3 #Yuck! 300 login: #300
X
END_OF_FILE
if test 686 -ne `wc -c <'inst/gettydefs'`; then
    echo shar: \"'inst/gettydefs'\" unpacked with wrong size!
fi
# end of 'inst/gettydefs'
fi
if test -f 'inst/inittab' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'inst/inittab'\"
else
echo shar: Extracting \"'inst/inittab'\" \(74 characters\)
sed "s/^X//" >'inst/inittab' <<'END_OF_FILE'
X 000:2:respawn:/etc/prtty -x1 -t1800 tty000 19200 # TrailBlazer, 294-0819
END_OF_FILE
if test 74 -ne `wc -c <'inst/inittab'`; then
    echo shar: \"'inst/inittab'\" unpacked with wrong size!
fi
# end of 'inst/inittab'
fi
echo shar: End of shell archive.
exit 0
-- 
John Bly Milton IV, jbm at uncle.UUCP, n8emr!uncle!jbm at osu-cis.cis.ohio-state.edu
(614) h:294-4823, w:764-2933; AMPR: 44.70.0.52;  Don't FLAME, inform!



More information about the Unix-pc.sources mailing list