[unix-pc.sources] tstmodem, Part 2 of 4

vern@zebra.UUCP (Vernon C. Hoxie) (09/09/89)

This is a continuation of the 'tstmodem' program.  Additional parts will
be posted tomorrow.

-------------------------------- cut here -----------------------------

#! /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 archive 2 (of 4)."
# Contents:  tb.hints/karl tb.hints/vern.hdb tstmodem.1.c utils.c
# Wrapped by vern@zebra on Mon Aug 21 22:11:16 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f tb.hints/karl -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"tb.hints/karl\"
else
echo shar: Extracting \"tb.hints/karl\" \(12132 characters\)
sed "s/^X//" >tb.hints/karl <<'END_OF_tb.hints/karl'
XNewsgroups: unix-pc.uucp,comp.mail.uucp,comp.dcom.modems,biz.comp.telebit
XSubject: TrailBlazer Plus (and PC Pursuit) configuration with HDB
XKeywords: Telebit, TrailBlazer, PC Pursuit, UNIX PC, HDB, HoneyDanBer
XMessage-ID: <437@ditka.UUCP>
XDate: 4 Nov 88 09:19:35 GMT
XReply-To: kls@ditka.UUCP (Karl Swartz)
XOrganization: Inaction Central, Los Alamos, New Mexico
XLines: 262
X
XThis article describes the configuration I have been successfully using
Xon ditka with HoneyDanBer (HDB) uucp, a Telebit TrailBlazer Plus, and PC
XPursuit.  While most of the TB stuff is specific to the AT&T UNIX PC,
Xthere may be some neat tricks for other systems; the PC Pursuit scripts
Xshould be useful to anybody running the HDB (aka BNU) breed of uucp.
X
XIn setting up the TrailBlazer, I had several seemingly contradictory re-
Xquirements.  First, I wanted to list the desired speed in the Systems
Xentries, precluding a locked outgoing interface.  This was motivated by
Xthese considerations:
X
X -- The 1200 baud on-board modem (OBM) on ditka has a phone line, and I
X    didn't want to have separate Systems entries for each modem at 1200
X    baud.  The software *should* be able to select whatever modem match-
X    es the speed criterion.
X
X -- Some TrailBlazers that I call answer with PEP tones last, and there-
X    fore need a special chat script to connect.  This rightfully belongs
X    in the Dialers script, and that's where I wanted it to be.
X
XOn the other hand, I did not want callers to have to send BREAKs to
Xchange the baud rate when calling the TrailBlazer.  For one thing, this
Xseems ugly and unnecessary since the modem and the computer can both use
Xhardware flow control (HFC) and just leave the connection at 19200 baud.
XMore importantly, when my modem arrived I was running the 3.51 release
Xkernel, which wouldn't pass BREAKs correctly, and while the 3.51a kernel
Xfixed this it broke things if you dialed in with a vt100, which I need
Xto do.
X
XSo, what I wanted was a locked interface speed while still having an un-
Xlocked interface on dialout.  After puzzling over Telebit's manual, it
Xseemed that nothing said you couldn't do it; I tried a few experiments
Xand discovered that it worked.  A call to Telebit the next day confirmed
Xthat this was indeed legal; they hadn't documented it because it seemed
Xpretty bizarre, and more likely to confuse people than anything else.
X
XHere are the settings that are different from the factory defaults:
X
X    Q6		Return result codes only on outgoing calls.
X    X1		Return extended result codes.
X    S51=254	Autobaud outgoing calls, assume 19200 on incoming.
X    S52=2	Reset to EEPROM values on DTR drop.
X    S54=3	Pass BREAKs transparently.
X    S58=2	Use hardware (RTS/CTS) flow control.
X    S66=1	Lock interface speed.
X    S110=0	Disable data compression.
X    S111=30	Enable UUCP "g" protocol support.
X
XThe weird looking part is S66=1 and S51=254, but it works.
X
XHere's the full procedure for getting a brand-new TrailBlazer working
Xwith your UNIX PC.  I assume it's connected to the built-in serial port
X(tty000) but it should work on expansion ports as well.
X
X    1.  Append the following line to /usr/lib/uucp/Devices:
X
X	    Direct tty000 - Any direct
X
X    2.	From Install's "Main Menu", select "Administration", within that
X	select "Hardware Setup", then select "RS232 Setup".  Select the
X	"MODEM/SWITCH" device, 9600 baud rate, and enable hardware flow
X	control.  (Yes, you can do this without resorting to the stupid
X	User Agent, but this was the simplest for me to figure out.)
X
X    3.	Connect to the modem using cu:
X
X	    cu -l tty000 -s 9600
X
X	and configure the modem:
X
X	    AT &F Q6 X1 S51=254 S52=002 S54=003 S58=002 S66=001
X		S110=000 S111=030 &W
X
X	That's all on one line; I wrapped it for readability.  Note that
X	you may need to hit 'A' several times at the beginning of the
X	line.
X
XNow that your modem is configured, there are a bunch of files that need
Xto be modified:
X
X    /etc/gettydefs
X
X	If you don't have an entry beginning with "19200#" you need to
X	add one--just copy the "9600#" line and change all occurences
X	of 9600 in the copy to 19200.  (If your gettydefs was stock
X	there should be four changes required in the line.)
X
X    /etc/inittab
X
X	Change the line beginning with " 000:" to read as follows:
X
X	     000:2:respawn:/usr/lib/uucp/uugetty -r -t60 tty000 19200
X
X	Note that there must be exactly *one* space at the beginning of
X	this line.  You'll need to say "telinit q" for this to take
X	effect.
X
X    /usr/lib/uucp/modemcap
X
X	Add the following entries (for dial() and maybe other stuff):
X
X	    # Telebit trailblazer modem
X	    # same as hayes, but send a couple of "A"s first to get autobaud right
X	    # Name=telebit9600
X	    t9|telebit96|telebit 9600:tr=\r:wp=\r:wk=K:wt=T:\
X	                             :ta=AT\r:ph=ATDT:\
X	                             :eh=\r:\
X	                             :d1#1:d5#5:ti=A:wi=A:\
X	                             :d2#30:\
X	                             :pl=tid1tid1tiwid1tad1wpwpwkwpphd2wpwpwttr:
X	    #
X	    # Name=telebit2400
X	    t2|telebit24|telebit 2400:tr=\r:wp=\r:wk=K:wt=T:\
X	                             :ta=AT\r:ph=ATDT:\
X	                             :tp=ATS50=3\r:\
X	                             :eh=\r:\
X	                             :d1#1:d5#5:ti=A:wi=A:\
X	                             :d2#20:\
X	                             :pl=tid1tid1tid1tiwid1tad1wpwpwkwptpwkphd2wpwpwttr:
X	    #
X	    # Name=telebit1200
X	    t1|telebit12|telebit 1200:tr=\r:wp=\r:wk=OK:wt=ECT:\
X	                             :ta=AT\r:ph=DT:\
X	                             :tp=ATS50=2:\
X	                             :eh=\r:\
X	                             :d1#1:d5#5:ti=A:wi=A:\
X	                             :d2#20:\
X	                             :pl=titid1titid1titiwitad1wktpphd2wt:
X
X	(These are slightly hacked from some I saw posted on the net; I
X	regret not being able to find the information to properly credit
X	their original source.)
X
X    /usr/lib/uucp/Devices
X
X	Make sure something like the following lines are present:
X
X	    #
X	    # UNIX PC's on-board modem
X	    #
X	    ACU ph1 ph1 1200 PC7300 \T
X	    ACU ph1 ph1 obm.1200 PC7300 \T
X
X	Add entries for the TrailBlazer:
X
X	    #
X	    # TrailBlazer
X	    #
X	    Direct tty000 - Any direct
X	    Direct tty000 - 9600 direct
X	    ACU tty000 - 19200 tbfast \D
X	    ACU tty000 - 9600 tbfast \D
X	    ACU tty000 - 2400 tb2400 \D
X	    ACU tty000 - 1200 tb1200 \D
X	    ACU tty000 - mnp.2400 tbmnp24 \D
X	    ACU tty000 - mnp.1200 tbmnp12 \D
X	    ACU tty000 - tb.19200 tbfast \D
X	    ACU tty000 - tb.9600 tbfast \D
X	    ACU tty000 - tb.2400 tb2400 \D
X	    ACU tty000 - tb.1200 tb1200 \D
X
X	Assuming you want 1200 baud dialouts to use the TrailBlazer only
X	if the OBM is busy, make sure the TrailBlazer entries are after
X	the PC7300 entries.
X
X	In addition, if you use PC Pursuit via the OBM, add these lines
X	(suitably tailored with your local Telenet access number and the
X	names of the outdial ports you are interested in):
X
X	    #
X	    # PC Pursuit via OBM
X	    #
X	    ACU ph1 ph1 CASFA.1200 PC7300 5551212 pcp1200 CASFA pcpdial \D
X	    ACU ph1 ph1 ILCHI.1200 PC7300 5551212 pcp1200 ILCHI pcpdial \D
X	    ACU ph1 ph1 NYNYO.1200 PC7300 5551212 pcp1200 NYNYO pcpdial \D
X
X	Or if you really want to use your TrailBlazer for PC Pursuit:
X
X	    #
X	    # PC Pursuit via TrailBlazer
X	    #
X	    ACU tty000 - CASFA.1200 tb1200 5551212 pcp1200 CASFA pcpdial \D
X	    ACU tty000 - ILCHI.1200 tb1200 5551212 pcp1200 ILCHI pcpdial \D
X	    ACU tty000 - NYNYO.1200 tb1200 5551212 pcp1200 NYNYO pcpdial \D
X
X	    ACU tty000 - ILCHI.2400 tb2400 5551212 pcp2400 ILCHI pcpdial \D
X	    ACU tty000 - NYNYO.2400 tb2400 5551212 pcp2400 NYNYO pcpdial \D
X
X    /usr/lib/uucp/Dialers
X
X	Add the following lines for the TrailBlazer:
X
X	    # Telebit TrailBlazer
X	    tbfast	=W-/	"" A\pA\pA\pAT OK ATS64=1S92=0S50=255S7=60DWT\T FAST-\c-FAST
X	    tb2400	=W-/	"" A\pA\pA\pAT OK ATS64=1S92=0S50=3S95=0DWT\T CONNECT\s2400
X	    tb1200	=W-/	"" A\pA\pA\pAT OK ATS64=1S92=0S50=2S95=0DWT\T CONNECT\s1200
X	    tbmnp24	=W-/	"" A\pA\pA\pAT OK ATS64=1S92=0S50=3S95=1DWT\T CONNECT\s2400
X	    tbmnp12	=W-/	"" A\pA\pA\pAT OK ATS64=1S92=0S50=2S95=1DWT\T CONNECT\s1200
X
X	In the "tbfast" entry "S7=60" and "FAST-\c-FAST" are to handle
X	the long connect times that may be necessary if you are making a
X	long-distance call to TrailBlazer configured to answer with PEP
X	tones last (i.e. S92=1).
X
X	The "S64=1 S92=0" stuff seems to be necessary to work with the
X	"locked but not really" operating mode.  Telebit's support staff
X	helped a great deal to make this all work; it appears there is a
X	slight bug in the ROM here.  (Note that the S92=0 isn't needed
X	unless you normally have S92=1.  I used to have it that way and
X	was too lazy to change the scripts when I changed the modem.)
X
X	If you're using PC Pursuit, add these lines too (again, after
X	suitable customization):
X
X	    # PC Pursuit
X	    pcp2400 =W-/	"" \d\r@D\r\c INAL= D1\r\c @ C\sD/\D/24,USERID,PASSWD\r\c ECTED-\rC\sD/\D/24,USERID,PASSWD\r\c-ECTED
X	    pcp1200 =W-/	"" \d\rD\r\c  INAL= D1\r\c @ C\sD/\D/12,USERID,PASSWD\r\c ECTED-\rC\sD/\D/12,USERID,PASSWD\r\c-ECTED
X	    pcpdial =W-/	"" \r@\r\c @ SET\s1:0,7:0,4:2\r\c @ CONT\r\pI\r\dATZ\r\c OK-I\r\dATZ\r\c-OK ATDT\T ECT-ATDT\T-ECT
X
X    /usr/lib/uucp/Systems
X
X	These are just a few examples; tailor to your requirements:
X
X	    # PC Pursuit when available, TrailBlazer at other times
X	    chicago Wk1805-0630,SaSu;5 ACU ILCHI.2400   5551212 ogin: nuucp
X	    chicago Wk1805-0630,SaSu;5 ACU ILCHI.1200   5551212 ogin: nuucp
X	    chicago Wk0630-1800        ACU tb.19200 13125551212 ogin: nuucp
X
X	    # PC Pursuit only
X	    sanfran Wk1805-0630,SaSu;5 ACU CASFA.1200 5551212 ogin: nuucp
X
X	    # Local 1200, try OBM then TB
X	    local12 Any ACU 1200 5551212 ogin: nuucp
X
X	    # UNIX PC, sometimes gets confused by TB so only use OBM
X	    unix-pc Any ACU obm.1200 5551212 ogin: nuucp
X
X    /usr/lib/uucp/uucico
X
X	If you receive much data via PC Pursuit (whether you place the
X	call or the remote calls you), you'll want to patch your uucico
X	to run with WINDOWS=7 instead of 3.  Change the 31188'th byte
X	of uucico from a 3 to a 7; a "cmp -l" of the old and new files
X	should give this result:
X
X	     31188   3   7
X
X	How do you do this?  That, as they say, is left as an exercise
X	for the reader.  (In other words, somebody sent me a patched
X	copy and I'm too lazy to figure out how to patch it myself.)
X
XWell, that's pretty long-winded, but it took even longer to get it all
Xworking.  (All the pieces have been working reliably on ditka for months
Xnow.)  Many, many thanks to a variety of people around the net and in
XCustomer Support at Telebit for help with various bits and pieces--all
XI did was put them together.
X
X-- 
XKarl Swartz		|UUCP	{ames!hc!rt1,uunet!dasys1}!ditka!kls
X1-505/667-7777 (work)	|ARPA	rt1!ditka!kls@hc.dspo.gov
X1-505/672-3113 (home)	|BIX	kswartz
X"I never let my schooling get in the way of my education."  (Twain)
X
X----------------------------------------------------------------------
XKarl later made some revisions to his files and asked that this addendum
Xbe added.   -- Received by vch 8/12/89
X----------------------------------------------------------------------
X
X*******
XDialers
X*******
X
X#
X# PC Pursuit
X#
Xpcp2400 ==--	"" \d\r@D INAL= D1 @ C\sD/\D/24,USERID,PASSWD ECTED
Xpcp1200 ==--	"" \d\rD  INAL= D1 @ C\sD/\D/12,USERID,PASSWD ECTED
Xpcp1224 ==--	"" \d\rD  INAL= D1 @ C\sD/\D/24,USERID,PASSWD ECTED
Xpcpdial ==--	"" I\r@ @ SET\s1:0,7:0,4:2\rCONT\r\pATZ OK ATDT\T ECT
X
X*******
XDevices
X*******
X
X#
X# PC Pursuit
X#
XACU ph1 ph1 CASAN.1200 PC7300 4733403 pcp1200 CASAN pcpdial \D
XACU ph1 ph1 CODEN.1200 PC7300 4733403 pcp1200 CODEN pcpdial \D
XACU ph1 ph1 ILCHI.1200 PC7300 4733403 pcp1200 ILCHI pcpdial \D
X
XACU tty000 - ILCHI.1200 tb1200 4733403 pcp1200 ILCHI pcpdial \D
XACU tty000 - ILCHI.2400 tb2400 4733403 pcp2400 ILCHI pcpdial \D
X
XACU ph1 ph1 ILCHIx1200 PC7300 4733403 pcp1224 ILCHI pcpdial \D
X
X****************
X-- 
XKarl Swartz		|UUCP	{ames!hc!rt1,uunet!dasys1}!ditka!kls
X1-505/667-7777 (work)	|ARPA	rt1!ditka!kls@hc.dspo.gov
X1-505/672-3113 (home)	|BIX	kswartz
X"I never let my schooling get in the way of my education."  (Twain)
X
END_OF_tb.hints/karl
if test 12132 -ne `wc -c <tb.hints/karl`; then
    echo shar: \"tb.hints/karl\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f tb.hints/vern.hdb -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"tb.hints/vern.hdb\"
else
echo shar: Extracting \"tb.hints/vern.hdb\" \(10868 characters\)
sed "s/^X//" >tb.hints/vern.hdb <<'END_OF_tb.hints/vern.hdb'
X	Before going into a discussion about setting the various
Xoptions to HDB, I suggest that you acquire ( purchase if you aren't
Xinto thievery ) the Nutshell Handbook, 'Managing uucp and Usenet',
Xpublished by O'Reilly and Associates.  This is a big help in setting
Xup the various files which support the 'uucp' process.
X
X---------------------------- /etc/gettydefs ------------------------------
X
X	From the GETTYDEFS(4) manual page, each entry is one line with
Xfive fields delimited by '#'s.  The first field is the 'label' and is
Xthe term that is referenced by entries in '/etc/inittabs',
X'/usr/lib/uucp/Systems', and  the fourth field of '/usr/lib/uucp/Devices'.
XIt can be any name you give it.
X
X	The second field has the initial flags.  By default, all the
Xlabels for the 'c_iflag' are ignored.  ( Yes, the example supplied with
Xthe system set some of these bits.  Who said the AT&T programmers for
Xthe 7300/3B1 knew what they were doing? ).  The OPOST and ONLCR should
Xbe set for the benefit of the TrailBlazer modem, it needs the CR to for
Xend of message.
X
X	Use the BEXTA form for a computer/modem speed of 19200 and
Xinclude HUPCL and CLOCAL.  ICANON should not appear in this field.
X
X	The third field defines the final flags.  It is just as well to
Xcopy this field from the standard entries.  You need ECHO at least if
Xyou expect anyone to call in using 'cu'.  With ECHO off, they don't get
Xa display of the characters they send.
X
X	The fourth field has the login-prompt.  It can say anything as
Xlong as it ends with "ogin:" for the benefit of calling scripts.
X
X	The fifth field is the next label.  It searchs '/etc/gettydefs'
Xfor an entry with whatever is here.  Because the TrailBlazer will search
Xtoward lesser speeds, it is best to reference this back to itself so
Xthat the interface speed will remain at 19200 for incoming calls and
Xlet the hardware controls keep track of the data flow.  I included a
Xsecond 19200 entry called N19200 so that a circular sequence could be
Xused during a search for speed.  I don't know if this is necessary, but
Xit doesn't hurt.
X
X	After setting up '/etc/gettydefs', run "/etc/getty -c
X/etc/gettydefs" to test for errors ( see GETTY(1) ).  Pay particular
Xattention to the length of your login message.
X
XHere are the 'gettydefs' I am using:
X
XNOTE: These should be continuous lines with no carriage returns.  I have
Xbroken these into separate lines for readability.  Backslashes ( \ )
Xdon't work in this file!!
X
XT19200# OPOST ONLCR EXTA CS8 CREAD HUPCL CLOCAL # BRKINT IGNPAR OPOST ONLCR
XEXTA CS8 CREAD HUPCL ISIG ICANON ECHO ECHOE ECHOK #\nWelcome to 'zebra',
XI am an AT&T 3B1.\n\nPlease login: #T19200
X                                     ^^^^^^
X	NOTE: This will not break out of 19200.
X
XN19200# OPOST ONLCR EXTA CS8 CREAD HUPCL CLOCAL # BRKINT IGNPAR ICRNL IXON
XIXOFF IXANY OPOST ONLCR EXTA CS8 CREAD HUPCL ISIG ICANON ECHO ECHOE ECHOK
X#a\nRunning at 19200 baud.\n\nPlease login: #T9600
X                                             ^^^^^
X	NOTE: This will go to 9600 baud after a break.
X
XT9600# OPOST ONLCR B9600 CS8 CREAD HUPCL CLOCAL # BRKINT IGNPAR ICRNL IXON
XIXOFF IXANY OPOST ONLCR B9600 CS8 CREAD HUPCL ISIG ICANON ECHO ECHOE ECHOK
X#a\nRunning at 9600 baud.\n\nPlease login: #T2400
X
XT2400# OPOST ONLCR B2400 CS8 CREAD HUPCL CLOCAL # BRKINT IGNPAR ICRNL IXON
XIXOFF IXANY OPOST ONLCR B2400 CS8 CREAD HUPCL ISIG ICANON ECHO ECHOE ECHOK
X#a\nRunning at 2400 baud.\n\nPlease login: #T1200
X
XT1200# OPOST ONLCR B1200 CS8 CREAD HUPCL CLOCAL # BRKINT IGNPAR ICRNL IXON
XIXOFF IXANY OPOST ONLCR B1200 CS8 CREAD HUPCL ISIG ICANON ECHO ECHOE ECHOK
X#a\nRunning at 1200 baud.\n\nPlease login: #B300
X
XT300# OPOST ONLCR B300 CS8 CREAD HUPCL CLOCAL # BRKINT IGNPAR ICRNL IXON
XIXOFF IXANY OPOST ONLCR B300 CS8 CREAD HUPCL ISIG ICANON ECHO ECHOE ECHOK
X#a\nRunning at 300 baud.\n\nPlease login: #N19200
X
X-------------------------- /usr/lib/uucp/Devices* -------------------------
X
X	In the 'Devices' file, the first field can be anything you want
Xbut must be referenced in 'Systems' by the same name.  The second field
Xmust be a device from the '/dev' directory.  The third field ( - ) is a
Xplace holder ( used when separate dialers are installed ).  The fourth
Xfield must be a reference to an entry in '/etc/gettydefs'.  The fifth
Xfield is any name you want but must be an entry in 'Dialers*'.  The '\D'
Xtells 'uucico' to look into a 'Dialers*' for further information.
X
X	Actually, this information may be in any file defined in the
X'Sysfiles' file.  I use 'Devices.hop' since it isn't munged by the UA
Xwhen I make changes to the Communications Window of Install.
X
XHere are my entries for the /usr/lib/uucp/Devices.hop file:
X
XACU3 tty000 - T300 tb300 \D
XACU3M tty000 - T300 tbm300 \D
XACU12 tty000 - T1200 tb1200 \D
XACU12M tty000 - T1200 tbm1200 \D	< Used for calling MNP sites
XACU24 tty000 - T2400 tb2400 \D
XACU24K tty000 - T2400 tbk2400 \D	< Used for sending break
XACU24M tty000 - T2400 tbm2400 \D	< Used for calling MNP sites
XACUTB tty000 - T19200 tbfast \D
X
X---------------------------- /usr/lib/uucp/Dialers* ---------------------
X
X	The 'Dialers' file ( or any variation defined in 'Permissions' )
Xinitiates the connection to the modem.  The first field must correspond
Xto a name in 'Devices'.  The second field ( =W-, ) translates the obscure
XHDB symbols for delay ( = ) and pause ( - ) to symbols understood by the
Xmodem.  From there on is the setup "chat" script, each field is
Xalternately 'expect'ed or 'send'.  The first of these ( "" )
Xmeans 'expect nothing'.  Following are a series of 'A pause' followed by
X'AT'. This is to get the attention of the modem in the speed you
Xselected when you called the 'uugetty' in '/etc/inittab'.  The 'OK' is
Xthe response from the the modem that is running at the same speed.
X
X	Next are the commands to change the modem from the answer mode
Xyou have set into the registers to the configuration to place the call
Xusing specific speeds and MNP or not. Now wait for the modem to
Xsend 'OK' indicating that the computer and the modem have changed speeds
Xand are once again talking.  'ATDTW\T' first tell the modem to connect
Xfor tone dialing while the '\T' tells 'uucico' to find the number in
Xthe 'Systems file.  Finally the response from the modem when it
Xcompletes the connection.  Note the '\s' to indicate a space without
Xchanging from 'expect' to 'send' as would a real space.
X
X	These are the entries in my 'Dialers.ACU' file.  Again, these
Xcan be in any file defined in 'Sysfiles' and the UA screws up 'Devices'.
XAlso note that each entry must be one continuous line, I have broken them for
Xeasier reading.
X
Xtb300	=W-,	"" A\dA\dA\dAT OK ATS50=1S51=0S95=0 OK
X	ATDTW\T CONNECT\s300
Xtbm300	=W-,	"" A\dA\dA\dAT OK ATS50=1S51=0S95=1 OK
X	ATDTW\T CONNECT\s300/REL
Xtb1200	=W-,	"" A\pA\pA\pAT OK ATS50=2S51=1S95=0 OK
X	ATDTW\T CONNECT\s1200
Xtbm1200	=W-,	"" A\pA\pA\pAT OK ATS50=2S51=1S95=1 OK
X	ATDTW\T CONNECT\s1200/REL
Xtb2400	=W-,	"" A\pA\pA\pAT OK ATS50=3S51=2S95=0 OK
X	ATDTW\T CONNECT\s2400
Xtbm2400	=W-,	"" A\pA\pA\pAT OK ATS50=3S51=2S95=1 OK
X	ATDTW\T CONNECT\s2400/REL
Xtbk2400	=W-,	"" A\pA\pA\pAT OK ATS50=3S51=2S54=2S95=0 OK
X	ATDTW\T CONNECT \K\c
Xtbfast	=W-,	"" A\pA\pA\pAT OK ATSS50=255S51=5S95=0S111=30 OK
X	ATDTW\T\r\n\d\d\d\d\d\d\c CONNECT\sFAST--CONNECT\sFAST
X
X
X	Note the series of delays ( \d ) following the dial command.
XThis is one method suggested from the net for keeping HDB from timing
Xout while waiting for the modems to go through their dance to get into
XPEP.  Both Lenny and Karl show that their Dialers script for PEP mode
Xend with 'CONNECT\sFAST--CONNECT\sFAST'.  I use both just to be safe.
XNote the '\r' following the '\T'.
X
X---------------------------- /usr/lib/uucp/Systems ---------------------
X
X	The first filed of the 'Systems' file is the name of the machine
Xyou are calling.  The leading '#' is the standard shell symbol
Xfor 'comment' and tell 'uucico' to ignore that entry.  The second field
Xgives the times that you may call, see a manual for a full description
Xof options.  The third field is an entry in a 'Devices' file.  The
Xfourth is an entry in the 'gettydefs' file.  The fifth is the telephone
Xnumber.
X
X	Next are another series of 'expect' and 'send' fields.  ( "" )
Xmeans 'expect nothing'.  The series of '\r\d' or '\r\p' are carriage
Xreturns to your 'uugetty' to get off the line.  Next, you expect to
Xreceive "Please Login:" but don't know if the senders will all use
Xuppercase so look for just the lower case part of "Login:".  The ( -- )
Xmeans that if you don't receive the first part in the allotted time,
Xsend the part between the hyphens ( in this case a carriage return )
Xthen expect whatever follows the second hyphen.  If either of
Xthese 'expect's are successful, send the next field ( 'mama' ) here.
XFinally, expect 'sword:' ( last part of "Password:" ) and answer with
X'mama's password ( 'baby' here ).
X
XNOTE: These must be continuous lines for each entry.  These example have
Xbeen folded for easier reading.
X
X#quagga Any ACU 1200 5551234 "" \r\d\r ogin:--ogin: mama
X	sword:--sword: baby
X#quagga Any ACU3 T300 5551234 "" \r\d\r\d\r\d ogin:--ogin: mama
X	sword:--sword: baby
X#quagga Any ACU3M T300 5551234 "" \r\d\r\d\r\d ogin:--ogin: mama
X	sword:--sword: baby
X#quagga Any ACU12 T1200 5551234 "" \r\p\r\p\r ogin:--ogin: mama
X	sword:--sword: baby
X#quagga Any ACU12M T1200 5551234 "" \r\d\r ogin:--ogin: mama
X	sword:--sword: baby
Xquagga Any ACU24 T2400 5551234 "" \r\d\r ogin:--ogin: mama
X	sword:--sword: baby
X#quagga Any ACU24M T2400 5551234 "" \r\d\r ogin:--ogin: mama
X	sword:--sword: baby
X#quagga Any ACUTB T19200 5551234 "" \r\d\r ogin:--ogin: mama
X	sword:--sword: baby
X
X------------------------- /usr/lib/uucp/Permissions ----------------------
X
XNOTE: These must be continuous lines but may be broken with the back
Xslash.  Believe me -- omitting a back slash can create problems.
X
XLOGNAME=uucp:nuucp \
X	REQUEST=no SENDFILES=no \
X	READ=/usr/spool WRITE=/usr/spool \
X	COMMANDS=/bin/rmail
X
XMACHINE=OTHER REQUEST=no READ=/usr/spool/uucppublic \
X	WRITE=/usr/spool/uucppublic SENDFILES=no \
X	COMMANDS=rmail \
X	COMMANDS=ALL	< NOTE: This says that when I call OTHER
X				machines, I want to use ALL the
X				commands.  Its up to them to restrict
X				me with the LOGNAME entry if I am
X				using 'uucp' or 'nuucp'.
X
XLOGNAME=daddy \		< This is the login name 'quagga' uses to call
XMACHINE=quagga \	  'zebra'
X	VALIDATE=quagga \
X	REQUEST=yes SENDFILES=yes \
X	READ=/ WRITE=/ \
X
X-------------------------- /usr/lib/uucp/Sysfiles ---------------------
X
Xservice=uucico	devices=Devices.hop:Devices \
X		dialers=Dialers:Dialers.SW:Dialers.ACU
Xservice=cu	devices=Devices.hop:Devices \
X		dialers=Dialers:Dialers.SW:Dialers.ACU
X
X--------------------------- /etc/inittab ------------------------------
X
X 000:2:respawn:/usr/lib/uucp/uugetty -r -t60 tty000 T19200
X:001:2:respawn:/usr/lib/uucp/uugetty -r -t60 tty001 T19200
X:002:2:respawn:/usr/lib/uucp/uugetty -r -t60 tty002 T19200
END_OF_tb.hints/vern.hdb
if test 10868 -ne `wc -c <tb.hints/vern.hdb`; then
    echo shar: \"tb.hints/vern.hdb\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f tstmodem.1.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"tstmodem.1.c\"
else
echo shar: Extracting \"tstmodem.1.c\" \(11026 characters\)
sed "s/^X//" >tstmodem.1.c <<'END_OF_tstmodem.1.c'
X/* Version 1.0		Aug 21, 1989 */
X
X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
X *									 *
X *		Copyright (c) Aug 21, 1989 by Vernon C. Hoxie		 *
X *									 *
X *	This source code may be freely distributed as long as this	 *
X *	copyright notice is included.  No monetary charges should	 *
X *	be made in excess of the cost of copying and distribution.	 *
X *									 *
X *	Any profits which might be derived from the sale of this	 *
X *	work must be shared with me.  Other monetary contributions	 *
X *	will be gratefully accepted.					 *
X *									 *
X *		Vernon C. Hoxie						 *
X *									 *
X * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
X
X/* This is the start-up section.  It checks for LCK.. files and opens */
X/* the data port.  It also contains the communtator which tracks */
X/* selection of subroutines. */
X
X#include "tstmodem.h"
X
XWINDOW *w1;
XWINDOW *p1;
X
Xextern void sho_help();
Xextern int sig_int();
Xextern void do_err();
X
Xstatic int hasLock;
Xstatic char devname[10];
Xstatic char devfile[13];
Xstatic char *suffix;
Xstatic char lockfile[30];
Xstatic char lockdir[] = "/usr/spool/uucp";	/* for unix-pc */
Xstatic int had_getty;
X
Xvoid help_setup()
X
X{
X	FILE *hlp;
X	char *ptmp, *ptest;
X	char temp[85];
X	char *test = "tst.hlp";
X	int i, j;
X
X	hlp = fopen( "help.txt", "r" );
X	for( j = 0; j < 20; hlp_ray[ j++ ] = 0 );
X	rewind( hlp );
X	j = 0;
X	while( fgets( temp, sizeof( temp ), hlp ) != NULL )
X	{    /* We need to test only the first 8 chars of each string */
X		for( i = 8, ptmp = temp, ptest = test; *ptmp, i ;
X							ptmp++, i-- )
X			if ( *ptmp == *ptest ) ptest++;
X		if ( !*ptest ) hlp_ray[ ++j ] = ftell( hlp );
X	}
X	fclose( hlp );
X	if (( hfd = open( "help.txt", O_RDONLY )) == NULL )
X	{
X		do_err("Unable to open 'help.txt'." );
X		return;
X	}
X}
X
Xint lockit()
X
X{
X	int lfd;
X	int k;
X	int oldpid = 0;
X	char buf[ 40 ];
X
X	strcat( strcat( strcpy( lockfile, lockdir), "/LCK.." ), devname );
X	if (( k = access( lockfile, 06 )) == 0 )
X	{		/* We have an existing LCK.. file */
X		lfd = open ( lockfile, O_RDWR | O_NDELAY );
X		read( lfd, &oldpid, sizeof( int ));
X		if ( kill( oldpid, 0 ) == 0 )
X		{	/* We can't kill() it if it is use! */
X			sprintf( buf,"%s is in use by pid %d ",
X					 devname, oldpid );
X			do_err( buf );
X			return( -1 );
X		}
X	}
X	else
X	{
X		if ( errno != ENOENT )
X		{	/* Quit except for "file doesn't exist" */
X			do_err( "Open lockfile" );
X			return( -1 );
X		}
X		if (( lfd = open ( lockfile, O_RDWR | O_CREAT, 0666)) < 0)
X		{
X			do_err("Creation of lockfile");
X			return(-1);
X		}
X			/* 'open(2)' trims the mode according to */
X			/* 'umask', this gets around that. 	 */
X		if (( chmod ( lockfile, 0666 )) < 0)
X		{
X			do_err("Changing mode");
X			return(-1);
X		}
X	}
X	k = getpid();
X
X/* If a file alresdy exists and we did the 'read(2)' then we need to */
X/* reposition the pointer, otherwise no harm done. */
X
X	if (( lseek( lfd, 0, 0 )) < 0 )
X	{
X		do_err( "Seeking lockfile" );
X		return( -1 );
X	}
X	if (( k = write ( lfd, &k, sizeof( int ))) < 0 )
X	{
X		do_err( "Writing pid to lockfile" );
X		return( -1 );
X	}
X	close( lfd );
X	hasLock = TRUE;
X	return(0);
X}
X
X#ifdef DUMPGETTY
X	/* This routine was suggested by a similar procedure */
X	/* posted to the net by John B. Milton.		     */
X
Xint do_getty( dev, new )
Xchar *dev, new;
X
X{
X	int j;
X	int ifd;
X	int this;
X	int last;
X	
X	char old;
X	char test[6];
X	char buf[85];
X	char *pscan;
X	char *ptarg;
X	char *anch;
X	
X	if ( new == ' ') old = ':';
X	else if ( new = ':' ) old = ' ';
X  	if ( getuid( ) )
X	{
X		mvwprintw( w1, 8, 10, 
X		   "You must be running as 'su' to dump a 'uugetty'." );
X		return( -1 );
X	}
X
X	if (( ifd = open( INITTAB, O_RDWR ) ) < 0 )
X	{
X		do_err( "Can't open '/etc/inittab'");
X		return( -1 );
X	}
X	
X	anch = dev;
X	while ( *++anch );
X	anch -= 3;			/* get last three characters */
X
X	this = 0;
X	ptarg = test;
X	*ptarg++ = '\n';
X	*ptarg++ = old;
X	while ( *ptarg++ = *anch++);
X	ptarg = test;
X	while ( *ptarg )
X	{
X		if (( j = read( ifd, buf, sizeof(buf) - 1 )) < 0 )
X		{
X			do_err( "Can't read '/etc/inittab'");
X			close( ifd );
X			return( -1 );
X		}
X		if ( j == 0 )
X		{
X			had_getty = old;
X			close( ifd );
X			return( 0 );
X		}
X		last = this;
X		this += j;
X		for ( pscan = buf; j && *ptarg; pscan++, j-- )
X		{
X			if ( *pscan == *ptarg ) ptarg++;
X			else ptarg = test;
X		}
X	}
X	*(pscan - 4) = new;
X	lseek( ifd, last, 0 );
X	write( ifd, buf, this - last);
X	had_getty = new;
X	close( ifd );
X		/* A sloppy 'telinit(1) q' */
X	j = kill( 1, 1 );
X	sleep( 1 );			/* Give the modem time to reset */
X	return( j );
X}	/* do_getty() */
X#endif		/* DUPGETTY */
X
Xint openttymodes()
X
X{
X	int i, j;
X	if ((j = open(devfile, O_RDWR | O_NDELAY)) == -1)
X	{
X		do_err("Opening port");
X		return(-1);
X	}
X	if ((ioctl(j, TCGETA, &oldgetty)) == -1)
X	{
X		do_err("TCGETA oldgetty");
X		return(-1);
X	}
X/* You can read these settings as 'newgetty' in 'TERMIO' mode */
X
X	newgetty.c_iflag = 014206;
X	newgetty.c_oflag = 05;
X	newgetty.c_cflag = 016275;
X	newgetty.c_lflag = 01;
X	newgetty.c_line  = oldgetty.c_line;
X/* Copy in the old settings of 'c_cc[]' */
X	for (i = 0; i < NCC; i++)
X		newgetty.c_cc[i] = oldgetty.c_cc[i];
X/* Change the value of VMIN to at least one character */
X	newgetty.c_cc[6] = 1;
X	if ((ioctl(j, TCSETA, &newgetty)) == -1)
X	{
X		do_err("TCSETA newgetty");
X		return(-1);
X	}
X	if ((ioctl(j, TCFLSH, 2)) == -1)
X	{
X		do_err("TCFLSH flushing I/O queues");
X		return(-1);
X	}
X	return(j);
X}
X
Xint readline( wx, wye, ex, p, num, buf )
XWINDOW *wx;
Xint wye, ex, p, num;
Xchar *buf;
X
X/* We want to enter a string from line 'wye', space 'ex' with a max   */
X/* of 'num' characters.  The length is displayed with underscores.    */
X
X{
X	unsigned short rch;
X	int i;
X	for ( i = strlen(buf); i < num; buf[ i++ ] = '_');
X	do
X	{
X		mvwprintw( wx, wye, ex, buf );
X		rch = mvwgetch( wx, wye, ex + p );
X		if ( p == num )
X		{
X			wmove( w1, wye, ex + p );
X			wclrtoeol( w1 );
X		}
X		switch ( rch )
X		{
X			case '\b': if ( p > 0 ) p--; /* backspace */
X			case KEY_DC: 	/* and/or delete */
X				if ( p >= 0 && p < num )
X				{
X					for ( i =  p; i < num; i++)
X						buf[ i ] = buf[ i+1 ];
X					buf[ --i ] = '_';
X				}
X				break;
X			case KEY_LEFT: 	/* move the cursor */
X				if ( p > 0 ) --p;
X				break;
X			case KEY_RIGHT:
X				if ( p < num ) ++p;
X				break;
X			case KEY_HELP: sho_help( 1 ); break;
X			case KEY_EXIT: return( -1 );
X			default:	/* Enter characters */
X	/* Change from curses unsigned short to standard type char */
X				rch = rch & 0xff;
X				if ( isgraph( rch ) && p < num )
X				{
X					for ( i = num - 1; i > p; i-- )
X						buf[ i ] = buf[ i-1 ];
X					buf[ p ] = rch;
X					p++;
X				}
X		}
X	} while ( rch != '\n' );
X		/* Remove the underscores from the display */
X	for ( i = num - 1; buf[ i ] == '_' && i >= 0; buf[ i-- ] = '\0');
X	return( 0 );
X}		/* readline() */
X
Xint namestrgs( sample )
Xchar *sample;
X
X/* This was part of the hook to use 'tstmodem' with other than TB's. */
X/* If you need more than one set of prompts in MODEM mode, clean     */
X/* this up and remove the patch for 'modname' in 'open_up()'.	     */
X
X/* Try to compare the name entered as modem name with the list of  */
X/* names in 'smanes[]' for a .strgs file to provide prompts in the */
X/* modem display routine. */
X
X/* If you generate another .strgs file, make an entry here       */
X/* then recompile.  I'm sorry but I didn't generate a function   */
X/* to read the directory and check out file names.  Be my guest! */
X
X{
X	static char *snames[] = { "blazer" };
X	int i;
X	char *p, *q, *r;
X	int num = 1;		/* Number of entries in snames[] */
X	int el = strlen(sample);
X	if (el <= 0) return(-1);
X	for (i = 0; i < num; i++)
X	{
X		r = snames[i];
X		for (q = sample, p = r; *q != '\0' && *p != '\0'; q++)
X		{
X			if (*q == *p) p++;
X			else p = r;
X		}
X		if (*p == '\0')
X		{
X			strcat( strcpy( modprmpt, r ), ".strgs");
X			if (( access( modprmpt, 04 )) == 0 ) return( 0 );
X			else do_err( "No '.strgs' file by name given:" );
X		}
X	}
X	return(-1);
X}
X
Xint open_up()
X
X{
X	unsigned short ich;
X	unsigned short modname[15];
X	char buf[80];
X
X	int k;
X	char ch, mode[2];
X	help_setup();
X	wattron( w1, A_UNDERLINE );
X	mvwprintw( w1, 20, 10, "Tstmodem" );
X	wattroff( w1, A_UNDERLINE );
X	mvwprintw( w1, 20, 18,
X		" - an interactive tool for testing \"smart\" modems." );
X	mvwprintw( w1, 22, 10, "Version %s", VERS );
X	mvwprintw( w1, 22, 49, "By Vernon C. Hoxie" );
X	do
X	{
X		mvwprintw( w1, 5, 20,
X			 "A)ppend to existing log?, N)ew log? " );
X		ich = wgetch( w1 );
X		if ( ich == KEY_HELP )
X		{
X			sho_help( 2 );
X			touchwin( w1 );
X		}
X		else if ( ich == 10 || ich == ' ' ) ch = 'N';
X		else if ( ich == KEY_EXIT ) return( 0 );
X		else ch = ich & 0x005f;
X	} while( ch != 'A' && ch != 'N' );
X	if ( ch == 'A' ) mode[ 0 ] = 'a';
X		else if ( ch == 'N' ) mode[ 0 ] = 'w';
X	mode[1] = '\0';
X	wmove( w1, 6, 20 );
X	wrefresh( w1 );
X 	if (( log = fopen( "tst.log", mode )) == 0 ) return( -6 );
X	do
X	{
X		mvwprintw( w1, 6, 20, "Name of port /dev/");
X		wclrtoeol( w1 );
X		wmove( w1, 7, 0 );
X		wclrtoeol( w1 );
X		strcpy( devname, DEF_TTY );
X		if ( readline( w1, 6, 38, 6, 8, devname ) < 0 )
X				return( 0 );
X		strcat( strcpy( devfile, "/dev/" ), devname );
X		touchwin( w1 );
X		if (( k = access( devfile, 0 )) < 0 )
X		{
X			mvwprintw( w1, 6, 20,
X				"%s doesn't exist! ", devfile );
X			wclrtoeol( w1 );
X			mvwprintw( w1, 7, 20,
X				" <sp> to continue, Exit to leave. " );
X			while (( ich = wgetch( w1 )) == 0xffff );
X			if ( ich == KEY_EXIT ) return( 0 );
X		}
X	} while ( k < 0 );
X	wmove( w1, 7, 20 );
X	wrefresh( w1 );
X
X	if ( lockit() < 0 ) return( -2 );
X	mvwprintw( w1, 7, 20, "%s is inplace.", lockfile );
X	wrefresh( w1 );
X	wclrtoeol( w1 );
X	sleep( 1 );			/* Give the user time to read */
X
X#ifdef DUMPGETTY
X	if ( do_getty( devname, ':' ) < 0 )
X	{
X		wrefresh( w1 );
X			while (( ich = wgetch( w1 )) == 0xffff );
X		return( -3 );
X	}
X	else if ( had_getty == ' ' )
X		 mvwprintw( w1, 8, 20, "There was no 'getty' running." );
X	else mvwprintw( w1, 8, 20, "The 'getty' has been removed." );
X	wrefresh( w1 );
X#endif		/* DUMPGETTY */
X
X	strcpy( modname, DEF_MOD );
X	if ( namestrgs( modname ) < 0 ) return( -4 );
X	mvwprintw( w1, 9, 20, "Using the '%s' prompt file.", modprmpt );
X	wrefresh( w1 );
X	sleep( 1 );			/* Give the user time to read */
X
X	if (( tiofd = openttymodes() ) < 0) return( -5 );
X	mvwprintw( w1, 10, 20, "Port %s is now open.", devfile );
X	wrefresh( w1 );
X	sleep( 1 );			/* Give the user time to read */
X
X	mvwprintw( w1, 11, 20, "<sp> to continue, <Exit> to leave. " );
X	while (( ich = wgetch( w1 )) == 0xffff );
X	if ( ich != KEY_EXIT ) cmd_disp();
X	return( 0 );
X}
X
Xvoid main()
X{
X	int i;
X	char buf[ 40 ];
X	initscr();			/* a required curses routine */
X	w1 = newwin( 0, 0, 0, 0 );
X	keypad( w1, TRUE );
X	halfdelay( 1 );
X	if ((i = open_up()) < 0)
X	{
X		sprintf( buf, "Something goofed! <sp> %d  ", i);
X		do_err( buf );
X	}
X	fclose(log);
X 	if (hasLock) unlink( lockfile );
X	if ((ioctl(tiofd, TCSETA, &oldgetty)) == -1)
X	{
X		do_err("TCSETA oldgetty");
X	}
X#ifdef DUMPGETTY
X	if ( had_getty == ':' ) do_getty( devname, ' ' );
X#endif		/* DUMPGETTY */
X
X	keypad(w1, FALSE);
X	nocbreak();
X	wclear(w1);
X	wrefresh(w1);
X	delwin(w1);
X	refresh();
X	endwin();
X	exit(0);
X}
END_OF_tstmodem.1.c
if test 11026 -ne `wc -c <tstmodem.1.c`; then
    echo shar: \"tstmodem.1.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f utils.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"utils.c\"
else
echo shar: Extracting \"utils.c\" \(9178 characters\)
sed "s/^X//" >utils.c <<'END_OF_utils.c'
X/* Version 1.0		Aug 21, 1989 */
X
X/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
X *									 *
X *		Copyright (c) Aug 21, 1989 by Vernon C. Hoxie		 *
X *									 *
X *	This source code may be freely distributed as long as this	 *
X *	copyright notice is included.  No monetary charges should	 *
X *	be made in excess of the cost of copying and distribution.	 *
X *									 *
X *	Any profits which might be derived from the sale of this	 *
X *	work must be shared with me.  Other monetary contributions	 *
X *	will be gratefully accepted.					 *
X *									 *
X *		Vernon C. Hoxie						 *
X *									 *
X * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
X
X#include "tstmodem.h"
X
X/* These are the labels to be displayed near the bottome of the screen */
X/* w5 is used by the help screen */
X
Xstatic char *labtable[][8] = {
X/* This first set of labels was used in routine which has been      */
X/* discarded.  It is available for use elsewhere as labels( wX, 0 ) */
X	{"        ", "        ", "        ", "        ", /* 0 */
X	 "        ", "        ", "        ", "        "},
X	{"OLD I/O ", "NEW I/O ", "        ", "        ", /* 1 */
X	 "        ", "        ", " RETURN ", "        "},
X	{"  READ  ", "  SEND  ", " WRITE  ", " EEPROM ", /* 2 */
X	 " FACTORY", "        ", " TERMIO ", " RETURN "},
X	{"  RAW   ", "  CHAT  ", "  SYNC  ", "  STATS ", /* 3 */
X	 " CONTROL", " RETURN ", " TERMIO ", " MODEM  "},
X	{"  XON   ", "  XOFF  ", "  ACK   ", "  NAK   ", /* 4 */
X	 " Other  ", " Break  ", " RESET  ", " ESCAPE "},
X	{"TX RATE ", "TX BITS ", "RX RATE ", "RX BITS ", /* 5 */
X	 " PACKS  ", " NOISE  ", "FREQ OFF", " LINE Q "}
X};
X
Xlabels(wx, num)
XWINDOW *wx;
Xint num;
X
X{
X	int i;
X	static char *labptr[8];
X	static int was = 99;
X	int bot = NUMLINES;
X/* Change the pointers in labptr[] only if the screen has changed */
X	if (num != was)
X	{
X		for (i = 0; i < 8; i++)
X			labptr[i] = labtable[num][i];
X		was = num;
X	}
X	wattron(wx,A_REVERSE);
X	mvwprintw(wx,bot,0,  "%s", labptr[0]);
X	mvwprintw(wx,bot,9,  "%s", labptr[1]);
X	mvwprintw(wx,bot,18, "%s", labptr[2]);
X	mvwprintw(wx,bot,31, "%s", labptr[3]);
X	mvwprintw(wx,bot,40, "%s", labptr[4]);
X	mvwprintw(wx,bot,53, "%s", labptr[5]);
X	mvwprintw(wx,bot,62, "%s", labptr[6]);
X	mvwprintw(wx,bot,71, "%s", labptr[7]);
X	wattroff(wx,A_REVERSE);
X}
X
X
Xvoid do_err( msg )
Xchar *msg;
X
X/* This routine should reference the *sys_errlist as described in */
X/* perror(3), but it doesn't work on my machine.  There is some   */
X/* magic needed which I haven't found -- vch                      */
X
X{
X	void what();
X	void logit();
X	WINDOW *w7;
X	
X	char ebuf[80];
X	unsigned short ich;
X	sprintf( ebuf, "%s: %d ", msg, errno );
X	what( 8 );
X	logit( ebuf );
X	w7 = newwin( 4, 40, 1, 20 );	/* set window */
X	keypad( w7, TRUE );
X	mvwprintw( w7, 0, 2, ebuf );
X/* 	mvwprintw( w7, 1, 2, "%s", sys_errlist[ errno ] ); */
X	mvwprintw( w7, 2, 5, " <sp> to continue." );
X	wrefresh(w7);
X	while (( ich = wgetch( w7 )) == 0xffff );
X	keypad( w7, FALSE );
X	clear( w7 );
X	wrefresh( w7 );
X	delwin( w7 );
X	return;
X}
X
Xint sig_int( )
X
X{
X	signal( SIGINT, sig_int );
X	longjmp( place2, 1 );
X}
X
Xvoid sig_pause()
X
X{
X	signal(SIGALRM, sig_pause);
X	return;
X}
X
Xvoid sig_timeout( sig )
Xint sig;
X
X{
X	void what();
X	
X	signal( SIGALRM, sig_timeout );
X	what( 5 );
X	longjmp( place, 1 );
X	return;
X}					/* sig_timeout() */
X
X#define CLOCK_TICK 1000/HZ		/* HZ = 60 for unix-pc */
X
X/* This routine "borrowed" from kermit.  Its a handy little routine */
X/* and if you are building your own library of pets, consider this  */
X/* for inclusion - vch */
X
Xint mpause(m)
Xint m;
X
X{
X	extern long times();
X	long t1, t2, tarray[4];
X	int t3;
X
X	if (m <= 0) return(0);
X 	if ((t1 = times(tarray)) < 0) return(-1);
X	while (1)
X	{
X		if ((t2 = times(tarray)) < 0) return(-1);
X		t3 = ((int)(t2 - t1)) * CLOCK_TICK;
X		if (t3 > m) return(t3);
X 	}
X}					/* mpause() */
X
X/* This routine will log all the comunication between the computer and */
X/* the modem.  The log is read from the COMMANDS mode.		       */
X
Xvoid logit(strg)
Xchar *strg;
X
X{
X	fseek( log, 0, 2 );		/* goto EOF */
X	fputs( strg, log );
X	fflush( log );
X	while ( *strg ) if ( *strg++ == '\n' ) new_nls++;
X	return;
X}					/* logit() */
X
Xvoid what( from ) 
Xint from;
X
X{
X	char *p;
X	char wrds[15];
X	static was = 0;
X	for ( p = wrds; p < wrds + sizeof(wrds); *p++ = '\0');
X	if (from != was)
X	{			/* Insert discriptors in log */
X		switch (from)
X		{
X			case 1: strcpy(wrds, "Send:   " ); break;
X			case 2: strcpy(wrds, "Expect: " ); break;
X			case 3: strcpy(wrds, "Modem:  " ); break;
X			case 4: strcpy(wrds, "Got it: " ); break;
X			case 5: strcpy(wrds, "Timed out:\n" ); break;
X			case 6: strcpy(wrds, "Termio:\n" ); break;
X			case 7: strcpy(wrds, "Speed:" ); break;
X			case 8: strcpy(wrds, "Error: " ); break;
X		}
X		was = from;
X		logit( wrds );
X	}
X}					/* *what() */
X
X/* This generates a separate window for the Help information. */
X/* When editing the 'help.txt' file, you will find the separators */
X/* as 'tst.hlp <00\n'.  These separators must have the 'tst.hlp' */
X/* characters and be exactly 12 characters in length, including the */
X/* trailing newline. */
X
Xvoid sho_help( which )
Xint which;
X{
X	WINDOW *w5;
X
X	int msize;
X	int a, b, i, n;
X	int jump;
X	char *beg, *bot, *top, *wrk;
X	char msg[50];
X	unsigned short ich;
X
X	w5 = newwin( 0, 0, 0, 0 );
X	keypad( w5, TRUE );
X	halfdelay( 1 );
X
X	if ( hlp_ray[ which ] == 0 && which > 0 ) return;
X	msize = hlp_ray[ which + 1 ] - hlp_ray[ which ];
X	beg = malloc( msize );
X	lseek( hfd, hlp_ray[ which ], 0 );
X	if (( n = read( hfd, beg, msize )) != msize)
X	{
X		sprintf( msg, "Error in reading help information");
X		do_err( msg );
X		sprintf( msg,
X			"Requested msize = %d, Returned msize = %d",
X			 msize, n);
X		do_err( msg );
X		return;
X	}
X	scrollok( w5, FALSE );
X	bot = beg + msize - 12;
X	jump = -80;
X	do
X	{
X		if ( jump == -80 )
X		{			/* Home */
X			top = beg;
X			jump = 0;
X		}
X		else if ( jump == 80 )
X		{			/* <sh> Home */
X			top = bot;
X			jump = -1;
X		}
X		else if ( jump > 0 )
X		{			/* Down or Page */
X			while ( jump > 0 )
X			{
X				while( *top++ != '\n' );
X				jump--;
X				if ( top >= bot ) break;
X			}
X		}
XLOOP:		if ( jump < 0 )
X		{			/* Up or <sh> Page */
X			--top;
X			do
X			{
X				if ( top < beg ) break;
X				while( *--top != '\n' );
X				jump++;
X			} while ( jump < 0 );
X			if ( top < beg ) top = beg;
X			else top++;
X		}
X		wrk = top;
X		for( i = HELPSZ; i; i-- )
X		{
X			while( *wrk != '\n' ) *wrk++ ;
X			*wrk++ ;
X			if ( wrk >= bot ) break;
X		}
X 		if ( i > 1 && top > beg )
X		{
X			jump = -i;
X			goto LOOP;
X		}
X		a = b = 0;
X		wmove( w5, 0, 0 );
X		wrk = top;
X		for( i = HELPSZ + 1; i; i-- )
X		{
X			while( *wrk != '\n' ) waddch( w5, *wrk++ );
X			waddch( w5, *wrk++ );
X			if ( wrk >= bot ) break;
X		}
X		if ( top == beg )
X		{
X			wattron( w5, A_REVERSE );
X			mvwprintw( w5, 0, 75, " BEG " );
X			wattroff( w5, A_REVERSE );
X			a = -1;
X		}
X		if ( wrk >= bot )
X		{
X			wattron( w5, A_REVERSE );
X			mvwprintw( w5, HELPSZ, 75, " END " );
X			wattroff( w5, A_REVERSE );
X			b = 1;
X		}
X		wrefresh( w5 );
X		while (( ich = wgetch( w5 )) == 0xffff );
X		switch ( ich )
X		{
X			case KEY_UP:	jump = -1; break;
X			case KEY_DOWN:	jump = 1; break;
X			case KEY_HOME:	jump = -80; break;
X			case KEY_SHOME: jump = 80; break;
X			case KEY_NPAGE:	jump = HELPSZ + 1; break;
X			case KEY_PPAGE: jump = -( HELPSZ + 1 ); break;
X			case KEY_HELP:	if ( which ) sho_help( 0 );
X					touchwin( w5 );
X					jump = 0;
X					break;
X			case KEY_EXIT:  break;
X			default: jump = 0; beep();
X		}
X		if ( b > 0 && jump > 0 ) jump = 0;
X
X		if ( a < 0 && jump < 0 ) jump = 0;
X	} while ( ich != KEY_EXIT );
X	free( beg );
X	wclear(w5);
X	if ( !which ) return;
X	keypad(w5, FALSE);
X	wrefresh(w5);
X	delwin(w5);
X	refresh();
X}
X
X/* load the prompts in "blazer.strgs" or "termio.strgs into buffer */
X
Xchar *load_prompts( file_name, pntrs, size_pntrs )
Xchar *file_name;
Xchar *pntrs[];
Xint size_pntrs;
X#include <stdio.h>
X#include <sys/stat.h>
X
X{
X	struct stat sbuf, *psbuf;
X	char msg[50];
X	int k, n, bfd;
X	off_t t;		/* type off_t defined <sys/types.h> */
X	unsigned bsize;
X	char *wptr, *bbuf;
X	if ( access( file_name, 0 ) < 0 )
X	{
X		sprintf( msg,
X			"%s doesn't exist! <sp> ", file_name );
X		do_err( msg );
X		return( 0 );
X	}
X	if (( bfd = open( file_name, O_RDONLY )) < 0 )
X	{
X		sprintf( msg,
X			"Unable to open '%s' file.", file_name );
X		do_err( msg );
X		return( 0 );
X	}
X	psbuf = &sbuf;
X
X		/* Read the size of the file from the 'struct stat' */
X	if (( t = fstat( bfd, &sbuf )) < 0 )
X	{
X		sprintf( msg, "Unable to get file stats." );
X		do_err( msg );
X		sprintf( msg,
X			"t = %d, bfd = %x, sbuf = %x", t, bfd, sbuf );
X		do_err( msg );
X		return( 0 );
X	}
X	bsize = psbuf->st_size;
X	bbuf = malloc( bsize );
X
X		/* Read the entire file into 'malloc'ed area of memory */
X	if (( k = read( bfd, bbuf, bsize )) != bsize )
X	{
X		sprintf( msg, "Error in reading prompt information");
X		do_err( msg );
X		sprintf( msg,
X			"Requested size = %d, Returned size = %d",
X			 bsize, k );
X		do_err( msg );
X		return( 0 );
X	}
X
X		/* Fill the bbuf array with addresses of the \0's */
X	for ( k = 0, n = 0, wptr = bbuf;
X		( k < size_pntrs ) && ( n < bsize); k++ )
X	{		/* initialize pointer array */
X		pntrs[ k ] = wptr;
X		while ( *wptr++ != '\0' ) n++;
X	}
X	return( bbuf );
X}	/* load_prompts */
X
END_OF_utils.c
if test 9178 -ne `wc -c <utils.c`; then
    echo shar: \"utils.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 2 \(of 4\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 4 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Vernon C. Hoxie		       {ncar,nbires,boulder,isis}!scicom!zebra!vern
3975 W. 29th Ave.					voice: 303-477-1780
Denver, Colo., 80212				  TB+	 uucp: 303-455-2670