[comp.sources.amiga] vt100 version 2.8

ahh@j.cc.purdue.edu (Brent L. Woods) (02/25/88)

Program Name:  vt100 (version 2.8)
Submitted By:  acs@uts.amdahl.com (Tony Sumrall)
Summary:  vt100 terminal emulator.
Poster Boy:  Brent Woods  (ahh@j.cc.purdue.edu)
Tested.  Part 1 of 4.

NOTES:  This program was tested by our Guest Moderator, Robert Tillotson.
He had a couple of problems with the program at first (a couple of Guru
errors, and we think that the vt100 task hung around instead of exiting
properly; not certain, though), but when we (Rob, Pat, and I) tested it
a few hours ago, none of us had any problems.  I dunno.  It seems to work
okay now.  Probably some fluke or other.



Brent Woods, Co-Moderator, comp.{sources,binaries}.amiga

USENET:  ...!j.cc.purdue.edu!ahh     ARPANET:  ahh@j.cc.purdue.edu
BITNET:  PODUM@PURCCVM               PHONE:  +1 (317) 743-8421
USNAIL:  320 Brown St., #406  /  West Lafayette, IN  47906

================================================================
#! /bin/sh
#
# This is a shell archive.  Save this into a file, edit it
# and delete all lines above this comment.  Then give this
# file to sh by executing the command "sh file".  The files
# will be extracted into the current directory owned by
# you with default permissions.
#
# The files contained herein are:
#
# -rw-r--r--   1 acs      other      15758 Feb  1 18:52 README
# -rw-r--r--   1 acs      other      24525 Feb  1 18:52 vt100.doc
# -rw-r--r--   1 acs      other        860 Feb  1 18:52 Logon
# -rw-r--r--   1 acs      other       1461 Feb  1 18:53 Makefile
#
echo 'x - README'
if test -f README; then echo 'shar: not overwriting README'; else
sed 's/^X//' << '________This_Is_The_END________' > README
XThis archive contains a vt100 emulator with KERMIT and XMODEM file
Xtransfer protocols.  Original work by Dave Wecker, V2.7-V2.8 by Tony Sumrall.
X
XThanks:
X-------
X	To everyone who sent in code, suggestions and fixes!
X
XReleases:
X---------
X	v2.8 880117 ACS - See Release Notes.
X	v2.7 870825 ACS - See Release Notes.
X	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
X	v2.5 870214 DBW - more additions (see readme file)
X	v2.4 861214 DBW - lots of fixes/additions
X	v2.3 861101 DBW - minor bug fixes
X	v2.2 861012 DBW - more of the same
X 	v2.1 860915 DBW - new features (see README)
X	v2.0 860823 DBW - Major rewrite
X	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
X	v1.0 860712 DBW	- First version released
X
XUsage:
X------
X	Please read VT100.DOC for usage information and examples.
X
XRelease Notes:
X--------------
Xv2.8 880117 ACS - Info/Status window automatically deselected.
X	- 1st menu item re-worked.  Now the user need only choose Send,
X	  Receive, Kermit Get, Kermit Bye and Capture.  Protocol to send or
X	  receive is selected via the 1st sub-menu from the 1st menu item.
X	- New command: XPROTO XMODEM | XMODEMCRC | ASCII | KERMIT to select
X	  transfer protocol via scripts.
X	- User may capture simultaneously with sending or receiving via
X	  a different protocol by using the Capture menu item.  This item
X	  changes to Capturing when capture is in effect.
X	- Kermit will transfer long packets (up to 1000 bytes).  New cmd:
X	  "KMAXPACK n" sets maximum packet length to n bytes.  Remember to
X	  increase your send and/or receive timeouts on your host!!!
X	- Added insert/delete character to the recognized escape sequences.
X	  ESC [ n @ inserts n characters, ESC [ n P deletes n characters
X	  (thanks to John Wang (jwang@ATRP.MEDIA.MIT.EDU)).  He suggests 
X	  using the following termcap:
X	  CA|vt100|amiga|Amiga termcap:al=\E[L:AL=\E[%dL:am:bl=^G:bs:cd=\E[J:\
X	    :ce=\E[K:cl=\E[;H\E[2J:cm=\E[%i%d;%dH:co#80:cr=^M:cs=\E[%i%d;%dr:\
X	    :dc=\E[P:DC=\E[%dP:dl=\E[M:DL=\E[%dM:do=^J:ho=\E[H:\
X	    :is=\E[1;24r\E[24;1H:ic=\E[@:IC=\E[%d@:kb=^H:kd=\E[B:\
X	    :ke=\E[?1l\E>:kl=\E[D:kr=\E[C:ks=\E[?1h\E=:ku=\E[A:k1=\EOP:\
X	    :k2=\EOQ:k3=\EOR:k4=\EOS:le=^H:li#24:mb=\E[5m:md=\E[1m:me=\E[m:\
X	    :mr=\E[7m:nd=\E[C:pt:rc=\E8:rf=/usr/lib/tabset/vt100:\
X	    :rs=\E>\E[?3l\E[?4l\E[?5l\E[?7h\E[?8h:sc=\E7:se=\E[m:\
X	    :sf=^J:so=\E[7m:sr=\EM:ta=^I:ue=\E[m:up=\E[A:us=\E[4m:vc#16:vt#3:xn:
X	- Fixed scroll regions.  Now will not wrap-around out of a scroll
X	  region. (thanks to Tad Guy (ames!xanth.cs.odu.edu!tadguy))
X	- Fixed the FileLock() problem (thanks to many!).
X	- The "nagging requester" bug was a bug in *my* code (gasp!).  Thanks
X	  to Joel Swank (joels@tekred.TEK.COM) for finding and squashing it!
X	- Fixed overzealous xmodem chopping.  It now strips contiguous
X	  strings of nulls OR Ctrl-Z (not a mixture) and will avoid writing
X	  anything if they were all chopped.  Thanks to Wayne Davison
X	  (drivax!davison--I only had to modify it a little, Wayne).  Also,
X	  when sending, it now sends a stream of nulls OR Ctrl-Zs, whichever
X	  is NOT the last character.
X	- Removed an extraneous continue in readchar().  Thanks to someone!
X	  (Sorry, I lost your name and address.)
X	- Now uses the default keymap.  All of the old mappings have been
X	  retained (e.g. Ctrl-2 generates Ctrl-@, Ctrl-6 generates Ctrl-^,
X	  ALT acts as META key (i.e. sets the high-order bit)).  Note,
X	  however, that your keymap may preclude the use of the ALT key if
X	  dead keys are defined.  A future version will support specification
X	  of a keymap different from the system map.
X	- New commands: SENDF file-spec and REC file which will send/receive
X	  via the default XPROTO setting.  You still have XS, KR, etc.
X	- New command: FONT font-name.  Allows the user to specify which
X	  8-point font to use.  If you want to use your new whippy-font, sau
X	  FONT whippy-font.  These must be 8-point fonts for now!
X	- Saying LINES 0 will use all available lines on the screen (useful
X	  to you MoreRows groupies).
X	- P_unit may be changed in vt100.c to specify a different unit of
X	  the serial.device to use (for expansion serial ports).  As of this
X	  writing there are no expansion serial devices...this is just in
X	  preparation for the future.  Also provided a new INIT command:
X	  UNIT which accomplishes the same result.
Xv2.7 870825 ACS - Requester is only used for input.  A new window (the
X	  Info/Xfer Status window) now shows what used to go there and the
X	  requester now comes up in this window.  The window is sizable,
X	  draggable, closeable and front-to-backable; when re-opened it
X	  will appear in its last location with its last dimensions.  The
X	  window ignores input but will become active when it's first
X	  displayed as well as when a requester is put up in it.  To
X	  cancel a transfer request, first ensure that the mail VT100
X	  windiw is active then hit ESC in it.
X	- KERMIT mode has been hardened and wildcarded files can be sent
X	  to a KERMIT that is *not* in server mode.  E.g. you may say
X	  RECEIVE to your host's KERMIT then send Foo* -- all files
X	  starting with Foo in the current directory will be sent.
X	- New command line switches -i and +i.  -I says don't use an init
X	  file, +i file says use "file".  User may also specify script
X	  files on the command line which will be executed in sequence.
X	- New init file command SHORTCUT.  See vt100.doc.
X	- I've included the font code.  It looks for an env variable named
X	  "font" (yes, lowercase) and, if found, uses that font for its
X	  test.  If you don't like it you may wanna remove it.  I was gonna
X	  ifdef it but I ran out of time.  Remember that there's a PD set
X	  cmd to allow Lattice users to set env vars.
X	- Nagging bug: On 2nd and subsequent uses of the requester, the
X	  1st character of the last use is redisplayed.  Intuition bug?
Xv2.6 870227 DBW - bug fixes for all the stuff in v2.5
X	- Input requestors are now self selecting (ignore comment in 2.5)
X	- Added a BS<->DEL menu item and startup option (SWAP ON/OFF)
X	- Renamed dopen/dnext/dclose to diropen/dirnext/dirclose for LATTICE
X	- Added a CONVERT option that tells whether KERMIT should downcase
X	- MAJOR CHANGE: re write the INPUT/SCRIPT commands, see VT100.DOC
X	- Fixed a major problem with Set Directory causing LOCK conflicts
X	- Moved the Title up 1 pixel so that it doesn't get cut off anymore
Xv2.5 870214 DBW - more additions (see readme file)
X	- All prompting now done through a string requester/gadget.
X	  NOTE: YOU MUST SELECT THE INPUT STRING OF THE REQUESTER BEFORE
X		YOU CAN TYPE A RESPONSE.
X	- Local echo mode added (half duplex for Carolyn)
X	- BEEP command added to SCRIPT
X	- New menu/init/script items:
X		CLEAR SCREEN	- clears the screen
X	 	ECHO		- turns on/off half duplex mode
X		WRAP		- turns on/off autowrap on long lines
X		NUMKEY		- turns on/off numeric keypad mode
X		APPCUR		- turns on/off application cursor mode
X	- Rewrote toasc() to use qualifier field (no more getting the
X	  keyboard "stuck")
X	- Fixed locking of directories (should now run under workbench ok)
X	- Cleaned up VT100.H to really check includes on compile
X	- Setting font explicitly to TOPAZ 8 (no more dumb assumptions)
X
Xv2.4 861214 DBW - lots of fixes/additions
X	- Beep should now work under Lattice
X	- CreatePort now passes longs (as it should always have)
X	- Nested comments in KERMIT.C removed
X	- Beep volume of 0 (DisplayBeep) now works
X	- snum[] declaration in KERMIT.C fixed
X	- multi_xfer is now void and return fixed (in kermit)
X	- "." can no longer get "stuck" as the break key
X
X	- RIGHT-AMIGA-keys have been added for most menu items
X	- The ALT key is now an EIGHTth bit shifter
X	- Control-@, Control-2, Control-space send the NULL character
X	- Control-6 now sends Control-^
X	- Control-- and Control-? now sends Control-_
X	- Cursor application mode (<esc>[?1h and <esc>[?1l) now work
X	- XMODEM now masks the eighth bit if parity is other than NONE
X
Xv2.3 861101 DBW - minor bug fixes:
X	- added p_wbcolors to allow workbench colors on custom screen
X	  (In the init file you can specify WBCOLORS to be NO (use color
X	   definitions in INIT FILE or VT100.H) or YES (use WORKBENCH
X	   colors for everything)).
X	- "$" now sends a kermit-bye (like it says in VT100.DOC).
X	- made window/screen heights more reasonable
X	- Added ANSI insert line and delete line (<csi><num>L and
X	  <csi><num>M) to speed up various editors (like emacs).
X	  NOTE: This is NOT a VT100 sequence (new extension).
X	- ctrl-space now also sends a null (along with ^@ and ^`)
X	- RAWKEY fixed in WINDOW.C
X	- p_wrap fixed in WINDOW.C
X	- removed WRDMAX from VT100.H
X	- fixed exit with no params in SCRIPT.C
X	- fixed parity comparisons in KERMIT.C
X	- init file [n+1] changed to [nplus1] to make Lattice happy.
X	- cursoron(), cursoroff() changed to one routine cursorflip().
X	- long lines shortened to less than 80 characters (for gateways).
X	- blanks following exit (or comments) now work in scripts.
X
Xv2.2 861012 DBW - more of the same:
X	- The INIT file "exit" can now chain to a script
X	- The SCRIPT command "exit" can now chain to another script
X	- Hangup menu item now works.
X	- Autowrap can now be set from VT100.H, VT100.INIT (<esc>[?7h l)
X	- Control-G is now handled with an audible beep
X	- Script now used "^chr" to send control characters
X	- The graphics "box" character (a) was added
X	- Control-@ and Control-` now send the NULL character
X	- Alternate color for BOLD has been re-instated by popular demand
X	- Menus have been cleaned up.
X	- Lattice compilation cleaned up.
X	- No more wordsize parameter since PARITY takes care of all cases
X	- Function keys can now call scripts
X	- Double shift keys are now handled correctly.
X	- Version has been added to the title bar (for bug reports).
X
Xv2.1 860915 DBW - new features / bug fixes
X	- Now identifies as a VT100 (including the response to <esc>Z)
X	- Cursor color now gets read in as hex (instead of decimal)
X	- REPORTMOUSE taken out of definitions (not needed)
X	- XON/XOFF now being handled by the device driver instead of me
X	- Literal escape characters have been replaced with \033
X	- At init time the user can now specify the input BUFFER size
X	  (typically between 512 and 2048 bytes) depending on baud rate
X	- Script files are now case insensitive for commands
X	- XMODEM now turns off the driver XON/XOFF during transfers
X	- Graphic rendition now done by the OS instead of me.
X	- Initialization files are now searched for in S: instead of C:
X	- Forward GOTO bug fixed in the script package.
X	- Keypad can now be used in both numeric and application mode
X	- General purpose cleanup() routine added for all exits.
X	- Utility menu added (sendbreak, hangup, change directory).
X	  NOTE: hangup is not implemented yet.
X	- Full wild card support in file transfers (see vt100.doc).
X	- Kermit cleaned up with better filename handling (from host).
X	- Script now has CD (changed directory) and SB (send break) commands
X	- Added Parity and Wordsize choices in VT100.H, VT100.INIT, menu
X	  and scripts. (Generates parity from a table).
X	- Added 8th bit quoting in KERMIT when using 7 bit words (ODD or
X	  EVEN parity).
X	- Break time can be set from VT100.H, VT100.INIT or a script file.
X	- Transfer mode (image or CRLF) can now be set from a script file.
X	- Control characters in escape sequences now act like a true VT100.
X	- F10 now works from init files.
X	- Right (or Left) AMIGA with period (".") sends a BREAK to the host
X	  from the keyboard.
X	- XMODEM status kept down to one line for a file transfer.
X
Xv2.0 860823 DBW	- Major rewrite:
X	- Emulator now compiles under either MANX or LATTICE by defining
X	  the appropriate compiler type in VT100.H.
X	- Sped up code to an effective baud rate of (about) 8k. This means
X	  that clear text at 4800 baud should be no problem.
X	- Added XON/XOFF generation so that characters should not get lost
X	  any more at 9600 baud (when receiving clear text).
X	- Got rid of all command line switches and environment variables.
X	  Instead upon invocation the program searches first for any file
X	  named on the command line, then looks for VT100.INIT in the
X	  current directory and finally searches for C:VT100.INIT.
X	  All parameters can be set in the init file, and a sample VT100.INIT
X	  is provided in VT100.DOC that shows all possible options.
X	- All parameters that are set by VT100.INIT are defined in VT100.H
X	  (variables starting with "p_"). This allows you to compile your
X	  own defaults into the code.
X	- You can now set the number of lines (for all you EMACS freaks :-).
X	  On an interlaced screen this gives you upto a 48 line terminal.
X	- WORKBENCH colors are NEVER touched.
X	- In an attempt to keep the size down, the color palette menu item
X	  has been removed (current). Code is about 36K in size with a
X	  run time image (using workbench screen) of about 88k.
X	- Many bugs fixed including reverse scrolling with descenders,
X	  reverse video at end of line, clearing with scrolling regions,
X		... and 20 or more others.
X	- File capture now no longer sends the filename to the host.
X	- BOLD (<esc>[1m) has now been added by using an additional color
X	  when you specify a depth of 2 (instead of 1) bitplane.
X	- UNDERLINE (<esc>[4m) has now been added.
X	- The handling of remote (host) escape sequences has been completly
X	  re-written (thanks to Dawn Banks for all the work).
X	- Function keys (and shifted function keys) can now be bound to
X	  arbitrary strings (Jim Ravan gets his macros). See VT100.DOC
X	  for details.
X	- Cursor has no been reduced to the size of a normal character for
X	  easier readability.
X	- XMODEM has been improved (by Steve Drew) to use a timer device
X	  (for timeouts) and to abort immediately if the user types <ESC>.
X	- KERMIT has been completely re-written and appears to work fine,
X	  thanks to the efforts of Steve Drew.
X	- New menu item allows script file support. Module written by
X	  Steve Drew. See VT100.DOC for details.
X
XKnown problems:
X---------------
X	none
X
XSuggestions/bug fixes not implemented (as of yet):
X--------------------------------------------------
X	- Custom screen should use a borderless backdrop window
X	- Quit from keyboard should be supported (for above)
X	- Automatic maximum sizing of window should happen
X	- Screen should be resizable
X	- AT TIME should be implemented in scripts (besides DELAY)
X	- Kermit should create sub directories (when necessary)
X	- Use a disk font for graphic character set
X	- Allow the mouse to be sent to the host (for various EMACSs)
X	- Kermit VM/CMS (IBM) protocol support (it works for me, how about
X	  you?)
X	- Allow the user to use a keymap different from the default one.
X	- Allow use of an "external" transfer protocol.
X	- Allow use of other than 8-point fonts.
X
XInstallation:
X-------------
X	The files in this archive may be extracted by the bourne shell
X	(/bin/sh) or the shar program using the "unshar switch (-u)",
X	contact me if you need a copy of this version of shar.
X
X	REMEMBER: Set the correct compiler definition in VT100.H
X
XFiles:
X------
X	README		- this file
X	vt100.doc	- documentation for the terminal emulator
X	makefile	- make file for the emulator (under MANX AZTEC-C)
X	vt100.h		- include file used by all other modules
X	window.c	- manager for window and keyboard
X	vt100.c		- main module, handles menus
X	remote.c	- handle remote characters (vt100 emulation)
X	kermit.c	- kermit protocol (to transfer text files on VMS
X			  select the CRLF option on the transfer mode menu,
X			  otherwise use image mode).
X	init.c		- startup code
X	xmodem.c	- xmodem protocol that understands AMIGA binary and
X			  text file formats (automatically).
X	script.c	- script control package
X	expand.c	- filename expansion (wildcards) and dir setting
X
XContact:
X--------
XPlease send bugs/comments/suggestions/praise for V2.8 to:
X
X	Tony Sumrall at USENET: acs@amdahl.com
________This_Is_The_END________
if test `wc -l < README` -ne 314; then
	echo 'shar: README was damaged during transit (should have been 314 bytes)'
fi
fi		; : end of overwriting check
echo 'x - vt100.doc'
if test -f vt100.doc; then echo 'shar: not overwriting vt100.doc'; else
sed 's/^X//' << '________This_Is_The_END________' > vt100.doc
XThis is the documentation file for the VT100 terminal emulator originally
Xby Dave Wecker.  Versions 2.7-2.8 are by Tony Sumrall.  I can be reached
Xon USENET => acs@amdahl.com
X
XDave can be reached via:
X
X	Dave Wecker at	ENET:	COOKIE::WECKER
X			ARPA:	wecker%cookie.dec.com@decwrl.dec.com
X			USENET:	{decvax|decwrl}!cookie.dec.com!wecker
X			SNAIL:	Dave Wecker
X				115 Palm Springs Drive
X				Colorado Springs, CO  80908
X
XNote that Dave had NOTHING to do with this release.  Don't bother him with
Xproblem in my code.
X
X
XMANY pieces of code/suggestions have been sent in..
X
X	thanks to all!
X
XIn particular, I'd like to thank Kim DeVaughn (kim@amdahl.com) for his
Xhelp in testing this release.  We went through a lot together.
X
XProgram startup:
X----------------
X	1> vt100 [-i | +i initfile] [ scriptfile ... ]
X
X                - -i option means don't look for an init file; +i means
X                  look for an init file of this name.  The search for the
X                  init file will be the current directory then S:.  Of
X                  course you can always override this by saying C:file if
X                  you like.  The format for the init file is described
X                  later in this document.
X
X		- The init file controls the setting of initial defaults
X		  and screen and macro definitions.
X
X		- If none of the files (listed above) are found, the
X		  built-in defaults (defined in VT100.C as variables,
X		  beginning with "p_") are used.
X
X		- All commands are either menu or script based. Scripts
X		  are described below.
X
XMenus (Commands in parenthesis are default keyboard bindings: Right-Amiga-chr):
X-----------------------------------------------------------------------
XFile 	  			- file transfers
X	Protocol		- Sets the protocol to be used for send/rec.
X		ASCII		- use uncontrolled protocol
X		Xmodem	(A-X)	- use the ever-popular Xmodem Checksum
X		XmodemCRC	- use the in demand Xmodem CRC
X		Kermit	(A-K)	- my favorite protocol
X	Send		(A-^)	- Send a file using the selected protocol
X	Receive		(A-V)	- Receive a file as above
X	Kermit Get	(A-G)	- Get files from a kermit server
X	Kermit Bye	(A-B)	- Finish with the kermit server.
X	Capture			- Log received text to a file.  Changes to
X				  Capturing when in progress
XComm Setup			- Setup communications
X	Baud Rate		- Set the terminal baud rate
X		300
X		1200	(A-L)
X		2400	(A-H)
X		4800
X		9600
X	Parity			- Type of parity
X		NONE 	(A-X)
X		MARK
X		SPACE
X		EVEN	(A-E)
X		ODD	(A-O)
X	Xfer Mode
X		Image	(A-I)	- Send files verbatim (for UNIX hosts or
X				  binary files)
X		Text	(A-T)	- Send CR LF as line terminator and strip
X				  CR on received files (VMS text).
X		Convert		- Should KERMIT convert fnames to lower case
XScript				- Script commands
X	Execute Macro	(A-M)	- Start up an asynchronous script file
X	Abort Execution	(A-A)	- Terminate a script file
XUtility   			- Utility commands
X	Send Break	(A-.)	- send a break to the host
X	Hang Up			- close line (not implemented yet)
X	Change Dir	(A-D)	- change the local directory (for transfers)
X	Clear Scrn		- clear the screen (initial state)
X	Echo			- turn on/off half duplex mode
X	Wrap		(A-W)	- turn on/off long line wrapping mode
X	Num Key		(A-K)	- turn on/off numeric keypad mode
X	App Cur		(A-C)	- turn on/off application cursor mode
X	BS<->DEL		- swap backspace and delete keys
X
XKeypad mapping (in application keypad mode):
X--------------------------------------------
X
X		AMIGA		VT100		comments
X		-------		-------		---------------------------
X		0-9	==	0-9
X		.	==	.
X		ENTER	==	ENTER		(basically, flip the bottom
X		-	==	,		 2 keys up to get a VT100)
X		HELP	==	-		(only free key around)
X		f1-f4	==	PF1-PF4		(or any rebinding you do)
X		arrows	==	arrows
X
XNote:	Right AMIGA key in conjunction with a period (".")
X	will send a break to the host.
X
X	CTRL in conjunction with an at-sign ("@") a two ("2") or a
X	space (" ") will send a NULL to the host.
X
X	CTRL in conjunction with a six  ("6") will send a CTRL-^
X	CTRL in conjunction with a dash ("-") or question mark ("?")
X		will send a CTRL-_ to the host.
X
XMulti file Xfers:
X-----------------
XThe VT100 emulator supports multiple file transfers. This is
Xspecified by using a comma (",") between file names when using XMODEM
Xor KERMIT. (NOTE: host XMODEM's normally CANNOT support multiple file
Xtransfers).
X
XWhen specifying a file name to recieve by default the directory path
Xis stripped off of the filename when sent to the host but is kept for the
Xlocal file spec. eg:
X
X        receive file: ram:file.txt,df1:newfile.bin,$
X
Xwill ask the server for file.txt and put it in ram:, and get
Xnewfile.bin and put it on df1: (see explanation of "$" below). If you
Xdo a single file transfer you will get another prompt for the remote
Xname e.g.:
X
X        receive file: ram:file.txt
X        remote file name [file.txt]:  userdisk1:wantfile.txt
X
XThe same rules apply to sending multiple files therefore if you are
Xdoing multi file transfers make sure the host server is connected to
Xthe desired directory.
X
XIn addition KERMIT supports wildcards:
X    * = any number of characters
X    ? = any single character
XExamples:
X	send:	*.c,*.h,*.doc
X	get:	*.c,*.h,$
X
XNote that in this release, wilcarded files may be sent to a KERMIT that is
X*not* in server mode (e.g. you can say "RECEIVE" to the host KERMIT and
Xsend *.c files successfully).
X
XKERMIT receive is now smart enough to use the host filename so no
Xfilename needs to be specified on the AMIGA's side (see the CONVERT option).
X
XIf your host is capable of sending or receiving long packets (packets in
Xexcess of 94 bytes) you may set p_kmaxpack to some number <= 1000.  The script
Xcommand KMAXPACK can accomplish the same result.
X
XInitialization and Script file operation:
X-----------------------------------------
XAn initialization file (as described in the "Program Startup" section)
Xmay contain any of the commands shown below that have the word INIT in
Xtheir description below. Commands that are available from scripts have
Xthe word SCRIPT in the descriptions below. All commands may be abbreviated
Xto 3 letters and are case insensitive.
X
XThe script file can be invoked by selecting 'execute file' from the
Xscript menu. At any time you can abort the script file by selecting
X'Abort Execution'. You may also invoke a script from a function key if
Xthe first character of the function key definition is the KEYSCRIPT
Xcharacter (e.g., define F5 as "~df1:foo.script").
X
XDuring the time script file is running the terminal emulation is still
Xactive and you may type simulataneous to the script file. This may be
Xdesired if your script file is WAITing for a string or is DELAYing for
Xa period of time etc.
X
XInitialization and Script file Commands:
X----------------------------------------
X#	Commented line					(INIT,SCRIPT)
X   Format:
X	# This line is a comment
X------------------------------------------------------------
XAPPCUR	Set the application cursor mode			(INIT,SCRIPT)
X   Format:
X	APPCUR	ON/OFF or YES/NO
X------------------------------------------------------------
XASCII_SEND Send an ascii file to the host.		(SCRIPT)
X   Format:
X	(same format as CAPTURE)
X------------------------------------------------------------
XBACKGROUND Define a background color			(INIT)
X   Format:
X	BACKGROUND hex		three digit hex number
X   Example:
X	BACKGROUND F00		bright red background
X------------------------------------------------------------
XBAUD 	Set baud rate					(INIT,SCRIPT)
X   Format:
X	BAUD rate		Sets the baud rate for send/receive
X   Example:
X	BAUD 2400		Sets the baud rate at 2400 baud
X------------------------------------------------------------
XBEEP	Beep at the console				(SCRIPT)
X   Format:
X	BEEP
X------------------------------------------------------------
XBOLD 	Define a color for bold				(INIT)
X   Format:
X	(same as BACKGROUND)
X------------------------------------------------------------
XBREAK	Set the break time (for an SB command)		(INIT,SCRIPT)
X   Format:
X	BREAK value		Value is in micro-seconds
X   Example:
X	BREAK 750000
X------------------------------------------------------------
XBUFFER 	Set transmission buffer size			(INIT)
X   Format:
X	BUFFER n		Number of bytes to buffer
X   Example:
X	BUFFER 512
X------------------------------------------------------------
XCAPTURE	To start/stop ascii file capture.		(SCRIPT)
X   Format:
X	CAPTURE	file		Start ascii capturing
X	CAPTURE			End ascii capturing
X------------------------------------------------------------
XCD 	To change the local directory			(SCRIPT)
X   Format:
X	CD	newdir		set a new directory for file transfers
X   Example:
X	CD	DF1:foo/bar	set the directory as specified
X------------------------------------------------------------
XCONVERT	Tell KERMIT whether or not to convert filenames	(INIT,SCRIPT)
X   Format:
X	CONVERT	ON/OFF or YES/NO
X   Example:
X	CONVERT	ON		Filenames will be down cased
X------------------------------------------------------------
XCURSOR 	Define a color for the cursor			(INIT)
X   Format:
X	(same as BACKGROUND)
X------------------------------------------------------------
XDELAY 	Suspends script file for a specified time	(SCRIPT)
X   Format:        
X        DELAY 	n		Suspends execution for n seconds
X   Example:
X	DELAY	2		Suspends for 2 seconds
X------------------------------------------------------------
XDEPTH 	Define the depth of the window/screen		(INIT)
X   Format:
X	DEPTH n		Number of planes in window/screen
X   Example:
X	DEPTH 1		Minimum depth
X	DEPTH 2		Same as Workbench
X------------------------------------------------------------
XECHO	Turn on/off local echo				(INIT,SCRIPT)
X   Format:
X	ECHO	ON/OFF or YES/NO
X   Example:
X	ECHO	ON		Half duplex mode
X------------------------------------------------------------
XEXIT	Ends execution of the current script file.	(INIT,SCRIPT)
X   Format:
X	EXIT			Exit the current script/init file
X	EXIT VT100		Exit vt100 program (from SCRIPT only)
X	EXIT newscript		Exit this file and start up newscript
X   Example:
X	EXIT DF1:FOO.BAR	Exit the current file and start FOO.BAR
X------------------------------------------------------------
XF	Define a function key				(INIT,SCRIPT)
X   Format:
X	F n string		Define Function key n to be string
X   Example:				(see SEND for string format)
X	F 1 "dir^M"		Define F1 is the string dir<cr>
X	F 11 "help"		Define Shifted F1 as the string help
X	F 20 ^C			Define Shifted F10 as a control-C
X------------------------------------------------------------
XFONT Specify font to use				(INIT)
X   Format:
X	FONT 8-point-font-name
X   Example:
X	FONT whippy-8-point-font
X------------------------------------------------------------
XFOREGROUND Define a color for the foreground		(INIT)
X   Format:
X	(same as BACKGROUND)
X------------------------------------------------------------
XGOTO	Jumps to a different part of the script file.	(SCRIPT)
X   Format:
X	GOTO label		Jumps to a line beginning with label:
X				Jumps may be forward or backward.
X   Example:
X	FOO:			Sets up a label
X	...
X	GOTO FOO		Jumps to FOO
X------------------------------------------------------------
XINTERLACE Turn on/off interlace				(INIT)
X   Format:
X	INTERLACE ON/OFF or YES/NO
X   Example:
X	INTERLACE ON		Use interlacing
X------------------------------------------------------------
XKB  	Send a BYE packet to a host KERMIT server.	(SCRIPT)
X   Format:
X	KB 			Shut down server.
X------------------------------------------------------------
XKEYSCRIPT Define a new keyscript character		(INIT,SCRIPT)
X   Format:
X	KEYSCRIPT hex		New character in hex
X   Example:
X	KEYSCRIPT 7E		Use "~" as the new character
X------------------------------------------------------------
XKG  	Gets files from host.				(SCRIPT)
X   Format:
X	(same format as KS)	 Get from server
X------------------------------------------------------------
XKMAXPACK Set maximum packet size for kermit transfers	(INIT,SCRIPT)
X   Format:
X	KMAXPACK n		Set maximum packet size to n
X   Example:
X	KMAXPACK 1000		Use long packets if possible.  Don't forget
X				to increase the send/receive timeout values
X				on your host!!!
X------------------------------------------------------------
XKR  	Receives a file from kermit host.		(SCRIPT)
X   Format:
X	(same format as KS)	 Not from a server
X------------------------------------------------------------
XKS  	Sends files via kermit to the host.		(SCRIPT)
X   Format:
X	KS file			Send one file
X	KS file1,file2,...	Send multiple files
X	KS file1,file2,...,$	Send multiple files and shut down server
X   Example:
X	KS foo.bar		sends foo.bar (note no quoting is used)
X	KS foo1,foo2,foo3	sends three files
X	KS foo1,foo2,foo3,$	sends three files and shuts down server
X------------------------------------------------------------
XLINES	Define number of lines in the window		(INIT)
X   Format:
X	LINES n
X   Example:
X	LINES 24		Maximum for non-interlace
X	LINES 48		Maximum for interlaced
X	LINES 0			Determine the maximum number of lines
X				available and use it
X------------------------------------------------------------
XMODE	Set a transfer mode for KERMIT to use		(INIT,SCRIPT)
X   Format:
X	MODE type		type of transfers to perform
X   Example:
X	MODE IMAGE		image mode transfers
X	MODE CRLF		<CR><LF> text transfers (VMS Kermit).
X------------------------------------------------------------
XNUMKEY	Numeric keypad mode				(INIT,SCRIPT)
X   Format:
X	NUMKEY	ON/OFF or YES/NO
X   Example:
X	NUMKEY	ON		Keypad is pure numbers
X------------------------------------------------------------
XON	Peforms a command every time string is received	(SCRIPT)
X   Format:
X        ON      "string"  cmd	Execute cmd when string is received.
X				Only one ON string may be installed at a
X				time.
X
X  				If cmd is a GOTO and we were previously
X				WAITing for a string the WAIT is aborted and
X				execution resumes at the new label.
X
X              			If cmd is not SEND and we were previously
X				DELAYing, then the DELAY is aborted and the
X				cmd is executed, followed by the next command
X				after the DELAY.
X
X				If cmd is a SEND and we were previously
X				DELAYing, then the DELAY is continued.
X   Example:
X        ON  "LOSS CARRIER" GOTO RESTART
X				If modem drops carrier, try to redial
X        ON  "--more--" SEND " "
X				Send a space every time --more-- is received
X------------------------------------------------------------
XPARITY	Sets the parity					(INIT,SCRIPT)
X   Format:
X	PARITY	type		Set the parity type
X   Example:
X	PARITY	NONE		no parity
X	PARITY	MARK		mark parity
X	PARITY	SPACE		space parity
X	PARITY	ODD		odd parity
X	PARITY	EVEN		even parity
X------------------------------------------------------------
XRECF Receive a file using the protocol specified in XPROTO	(SCRIPT)
X   Format:
X	RECF file-spec
X   Example:
X	XPROTO XMODEMCRC	Select XMODEM CRC protocol
X	RECF Foo		Receive Foo using XMODEM CRC
X------------------------------------------------------------
XSB	Sends a break character to the host		(SCRIPT)
X   Format:			Note that any pending character to send
X	SB				is aborted by this call
X------------------------------------------------------------
XSCREEN	Define the screen type				(INIT)
X   Format:
X	SCREEN type		type of screen to use
X   Example:
X	SCREEN WORKBENCH	use the workbench screen
X	SCREEN CUSTOM		use a custom screen
X------------------------------------------------------------
XSEND 	Sends a string or character to the host.	(SCRIPT)
X   Format:
X	SEND    "string"	Sends a string to the host. Beginning and
X				ending double quotes (") are required. A
X				carat (^) may be used to send control chars.
X				Two carats transmits a carat character.
X        SEND    chr           	Sends a single character.
X        SEND    ^chr   	    	Sends a single control character. The chr
X				is NOT case sensitve
X   Example:
X	SEND	"mail"		Send the string mail
X	SEND    "dir^M"		Send the string dir followed by a <CR>
X	SEND	a		Send the letter a
X	SEND	^C		Send a control C
X	SEND	"abc^^def"	Send the string abc^def
X	SEND	^^		Send a control-uparrow
X	SEND	"		Send the '"' character
X------------------------------------------------------------
XSENDF Send a file using the protocol specified in XPROTO	(SCRIPT)
X   Format:
X	SENDF file-spec
X   Example:
X	XPROTO XMODEMCRC	Select XMODEM CRC protocol
X	SENDF Foo		Send Foo using XMODEM CRC
X------------------------------------------------------------
XSHORTCUT set a new shortcut command key          (INIT)
X   Format:
X	SHORTCUT cmd key        Sets key "key" to be the shortcut key for
X                                script command "cmd".  A null key will
X                                cause no shortcut to be available for this
X                                command (menu-option).  Cmd may be one of
X                                the following:
X			  >> File items:   <<
X    SE	- Send file using XPROTO	RE	- Receive file using XPROTO
X    KG	- kermit get file		KB	- kermit bye (for server)
X    CAP	- ascii capture on/off
X			  >> Mode (XPROTO) items: <<
X    ASC - ASCII "protocol"		XM	- XMODEM protocol
X    XMC	- XMODEM CRC protocol		KE	- Kermit protocol
X			  >> Comm items:   <<
X    300     - Set Baud 300             1200	- Set Baud 1200
X    2400    - Set Baud 2400            4800	- Set Baud 4800
X    9600    - Set Baud 9600            NONE	- Set Parity none
X    MARK    - Set Parity mark          SPACE	- Set Parity space
X    EVEN    - Set Parity even          ODD	- Set Parity odd
X    IMAGE   - KERMIT transfer mode     TEXT	- KERMIT transfer mode
X    CONVERT - KERMIT transfer mode
X			  >> Script items: <<
X    EXECUTE - execute macro		ABORT	- abort macro
X			  >> Util items:   <<
X    SB      - send break		HANG	- hang up
X    CD      - change directory		CLEAR	- clear screen
X    ECH     - turn echo on or off	WRAP	- turn wrap on or off
X    NUMKEY  - turn numeric kpad on/off	APP	- turn app. cursor on/off
X    CON     - convert bs to del		SWAP	- Swap BS and DEL
X
X   Example:
X	SHORTCUT ASC Q          set Right-Amiga-Q to be the shortcut for
X                                ASCII_SEND.
X	SHORTCUT XS             removes the shortcut key for sending via
X                                XMODEM protocol
X------------------------------------------------------------
XSWAP 	Swap the meanings of backspace and delete keys	(INIT,SCRIPT)
X   Format:
X	SWAP ON/OFF or YES/NO
X   Example:
X	SWAP NO		Use standard definitions
X------------------------------------------------------------
XUNIT	Set unit of serial device to use		(INIT)
X   Format:
X	UNIT n
X   Example:
X	UNIT 1		Open unit 1 of serial.device.  Generally the user
X			will want to specify unit 0.  When multi-port serial
X			cards become available specify as necessary.
X------------------------------------------------------------
XVOLUME	Set the BELL volume				(INIT)
X   Format:
X	VOLUME n
X   Example:
X	VOLUME 0		Use a visual bell
X	VOLUME 64		Use a loud audible bell
X------------------------------------------------------------
XWAIT 	Suspends until a certain string is received.	(SCRIPT)
X   Format:
X	WAIT	"string"	Same rules for string as SEND
X	WAIT			Enter an endless wait. Usually used after
X				some "ON" commands have been set up. Can
X				still be aborted via the script menu.
X   Example:
X        WAIT    "User:"    	Waits for the string User:
X------------------------------------------------------------
XWBCOLORS Force usage of workbench colors		(INIT)
X   Format:
X	WBCOLORS ON/OFF or YES/NO
X   Example:
X	WBCOLORS YES		Workbebch colors will be used for all
X------------------------------------------------------------
XWRAP	Set long line wrapping				(INIT,SCRIPT)
X   Format:
X	WRAP	ON/OFF or YES/NO
X   Example:
X	WRAP	ON		Long lines will wrap
X------------------------------------------------------------
XXBEEP	Beep at end of xfer				(INIT,SCRIPT)
X   Format:
X	XBEEP	ON/OFF or YES/NO
X   Example:
X	XBEEP	ON		Beep when xfers are finished
X------------------------------------------------------------
XXPROTO	Set default transfer protocol			(INIT,SCRIPT)
X   Format:
X	XPROTO	XMODEM or XMODEMCRC or KERMIT
X   Example:
X	XPROTO	KERMIT		Sets transfer protocol to Kermit
X------------------------------------------------------------
XXR  	Receives a file via XMODEM.			(SCRIPT)
X   Format:
X	(same format as KS)
X------------------------------------------------------------
XXS  	Sends a file via XMODEM.			(SCRIPT)
X   Format:
X	(same format as KS)
X------------------------------------------------------------
X
X
X----------------------------
XInitialization file example:
X----------------------------
X
X#####################################################################
X#
X#	VT100 sample initialization file
X#       v2.8 880117 ACS
X#
X# Hash mark at the beginning of a line denotes a comment.
X# White space (space(s) or tab(s)) delimit fields.
X# Case ignored except for function key bindings.
X#
X# All items in this file overide variables of the same name in VT100.C
X# (all variables in vt100.c have a "p_" prepended to them)
X#
X#####################################################################
X#
XAPPCUR		ON		# Application keypad mode is being used
XBACKGROUND	000		# Colors are in hex RGB from 000 to FFF
XBAUD		2400		# Anything after required fields is ignored
XBOLD		a00		# Color for bold highlighting (in custom)
XBREAK		750000		# Break time in micro-seconds
XBUFFER		512		# 512 <= Input buffer size <= 2048
XCONVERT		ON		# KERMIT should downcase host names
XCURSOR		00a		# Color for cursor (in custom screen)
XDEPTH		1		# number of bit planes to use (1 or 2)
XECHO		OFF		# Full duplex mode in use
XFONT		MyFont		# Use my own special 8-point font
XFOREGROUND	950		# Colors are only used on the custom screen
XINTERLACE	ON		# ON for CUSTOM or interlaced workbench
XKEYSCRIPT	7E		# Hex value for script introducer
XLINES		0		# normal <= 24 interlaced <= 48 or 0
XMODE		CRLF		# IMAGE or CRLF (for KERMIT transfers)
XNUMKEY		ON		# The keypad should be numeric
XPARITY		NONE		# NONE (= 8 bit), MARK, SPACE, ODD or EVEN
XSCREEN		CUSTOM		# may be CUSTOM or WORKBENCH
XSWAP		OFF		# Don't Swap the Back-space and Delete keys
XVOLUME		64		# Beep Volume (0 = Visual Beep)
XWBCOLORS	YES		# ignore custom colors and use defaults
XWRAP		OFF		# Auto wrap ON or OFF
XXBEEP		ON		# Beep when xfer is done
XXPROTO		XMODEMCRC	# Send/Receive will use Xmodem CRC.
X#   Remove the shortcut key for the CD command.  No comment on next line
X# as it will be taken as the shortcut key.
XSHORTCUT        CD
X#
X# Function bindings (strings to type when any of F1 - F10 are pressed)
X#	f <num>		= function key
X#	f <num>+10	= shifted function key
X#
X# The string specified must be the same format as the SEND command:
X#	^	= control next character
X#	^^	= up arrow
X#
X# Sample control characters:
X#	^[	= escape	^M	= carriage return
X#	^J	= line feed	^L	= form feed
X#
X# If the first character of the string is a script introducer
X# (KEYSCRIPT) then the string is interpreted as a script filename
X# to be executed when the key is pressed.
X#
X# Examples of bindings:
X#
Xf 1	"^[OP"			# f1-f4 = PF1 - PF4 on a VT100
Xf 2	"^[OQ"
Xf 3	"^[OR"
Xf 4	"^[OS"
X#
X# f5,6,7 = scripts to execute (assuming that KEYSCRIPT = '~' = 0x7E)
X#
Xf 5	"~df1:vt100_source/dialwork.script"
Xf 6	"~df1:vt100_source/sendvt100.script"
Xf 7	"~df1:vt100_source/getpics.script"
X#
Xf 8	"MAIL^M"		# Reads my mail (note embedded <CR>)
Xf 9	"NOTE^M"		# Reads conferences
Xf 11    "ATdt415-595-2479^M"    # dials the FAUG BBS
X#
X# all done with init, now execute script as startup sequence
X#
Xexit df1:vt100_source/dialwork.script
X
X--------------------
XScript file example:
X--------------------
X
X###################################################################
X# Script to dial work (dialwork.script)
X#	v2.6	870222	DBW
X###################################################################
X#
X# Make sure that we have all the parameters we want
X#
X	DELAY	2
X	BAUD	2400
X	PARITY	NONE
X	MODE	CRLF
X	BREAK	750000
X	SB
X#
X# First get the modem's attention:
X#
XStart:
X	DELAY 1
X	ON "Ready" GOTO Dial
X	SEND ^B
X	DELAY 2
X	GOTO Start
X#
X# Now dial the 2400 baud line to work:
X#
XDial:
X	ON "Attached" GOTO Login
X	SEND "$2400!"
X	DELAY 30
X	GOTO Start
X#
X# We got attached, so keep hitting return until the Gandalf terminal
X# handler wakes up:
X#
XLogin:
X	ON "enter" GOTO Gandalf
X	DELAY 1
X	SEND ^M
X	GOTO Login
X#
X# Now connect from the Gandalf to the terminal server (ts2):
X# (when it asks for a password I need to type the password 
X# manually here)
X#
XGandalf:
X	DELAY 2
X	SEND "ts2^M"
X	WAIT "class start"
X#
X# Keep sending <CR>'s until the LAT prompts for a username:
X#
XWaitLat:
X	DELAY 2
X	ON "username>" GOTO Lat
X	SEND ^M
X	GOTO WaitLat
X#
X# Tell the LAT that it's me, and connect to the "cookie cluster"
X# (my host systems). Tell the cluster my user name.
X# (when it asks for a password I need to type the password
X# manually here)
X#
XLat:
X	SEND "wecker^M"
X	DELAY 1
X	SEND "connect cookie^M"
X	WAIT "Username:"
X	SEND "WECKER^M"
X	WAIT "at home"
X	SEND "^M^Mn^M"
X#
X# Got through all the LOGIN garbage, so let's do some work.
X#
X	WAIT "$ "
X#
X# All done so stop:
X#
X	EXIT
________This_Is_The_END________
if test `wc -l < vt100.doc` -ne 705; then
	echo 'shar: vt100.doc was damaged during transit (should have been 705 bytes)'
fi
fi		; : end of overwriting check
echo 'x - Logon'
if test -f Logon; then echo 'shar: not overwriting Logon'; else
sed 's/^X//' << '________This_Is_The_END________' > Logon
XDIAL:
X	DELAY 3
X	SEND "ATdt555-1221^M"
X	ON "CONNECT" GOTO CONN
X	DELAY 20
X	SEND " "
X	DELAY 1
X#
X	SEND "ATdt555-1222^M"
X	ON "CONNECT" GOTO CONN
X	DELAY 20
X	SEND " "
X	DELAY 1
X#
X	SEND "ATdt555-1223^M"
X	ON "CONNECT" GOTO CONN
X	DELAY 20
X	SEND " "
X	DELAY 1
X#
X	SEND "ATdt555-1224^M"
X	ON "CONNECT" GOTO CONN
X	DELAY 20
X	SEND " "
X	DELAY 1
X	GOTO DIAL
X#
XCONN:
X#   Send CRs till I get a login: prompt.
X	SEND ^M
X	ON "login:" GOTO LOGIN
X	DELAY 3
X	GOTO CONN
XLOGIN:
X#  Send my username and my "password", reply to first prompt.
X	SEND "acs^M"
X	WAIT "assword:"
X	SEND "mypass^M"
X	WAIT "#?"
X	SEND "1^M"
X	WAIT "=> "
X#  Go to the source directory and send EVERYTHING then get off.
X	SEND "cd vt100src/rel2.8^M"
X	WAIT "=> "
X	SEND "wermit^M"
X	WAIT "mit>"
X	SEND "send *^M"
X	XPROTO KERMIT
X	RECF
X	DELAY 5
X	SEND "ex^M"
X	WAIT "=> "
X	SEND "logoff^M"
X	WAIT "NO CARRIER"
X	SEND "ATH^M"
X	EXIT VT100
X
________This_Is_The_END________
if test `wc -l < Logon` -ne 57; then
	echo 'shar: Logon was damaged during transit (should have been 57 bytes)'
fi
fi		; : end of overwriting check
echo 'x - Makefile'
if test -f Makefile; then echo 'shar: not overwriting Makefile'; else
sed 's/^X//' << '________This_Is_The_END________' > Makefile
X######################################################################
X#
X# Makefile to build vt100 terminal emulator
X#
X#	v2.8 880117 ACS - See the README file
X#	v2.7 870825 ACS - See the README file
X#	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
X#	v2.5 870214 DBW - more additions (see readme file)
X#	v2.4 861214 DBW - lots of fixes/additions (see readme file)
X#	v2.3 861101 DBW - minor bug fixes
X#	v2.2 861012 DBW	- more of the same
X#	v2.1 860915 DBW - new features (see README)
X#	     860823 DBW - Integrated and rewrote lots of code
X#	v2.0 860809 DBW	- Major release.. LOTS of changes
X# 	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
X# 	v1.0 860712 DBW	- First version released
X#
X#
X# Don't forget to define the right compiler (MANX or LATTICE) in VT100.H
X#
X######################################################################
X
XOBJS	= vt100.o init.o window.o xmodem.o remote.o \
X	  kermit.o script.o expand.o
X
Xvt100	: vt100.syms $(OBJS)
X	ln -o vt100 $(OBJS) -lc
X
Xvt100-w	: vt100.syms $(OBJS)
X	ln -w -o vt100-w $(OBJS) -lc
X
Xvt100.syms : vt100.h
X	cc -A +Hvt100.syms vt100.h
X
Xvt100.o	: vt100.c
X	cc +Ivt100.syms vt100.c
X
Xinit.o	: init.c
X	cc +Ivt100.syms init.c
X
Xwindow.o : window.c
X	cc +Ivt100.syms window.c
X
Xxmodem.o : xmodem.c
X	cc +Ivt100.syms xmodem.c
X
Xremote.o : remote.c
X	cc +Ivt100.syms remote.c
X
Xkermit.o : kermit.c
X	cc +Ivt100.syms kermit.c
X
Xscript.o : script.c
X	cc +Ivt100.syms script.c
X
Xexpand.o : expand.c
X	cc +Ivt100.syms expand.c
________This_Is_The_END________
if test `wc -l < Makefile` -ne 57; then
	echo 'shar: Makefile was damaged during transit (should have been 57 bytes)'
fi
fi		; : end of overwriting check
exit 0

ahh@j.cc.purdue.edu (Brent L. Woods) (02/25/88)

Program Name:  vt100 (version 2.8)
Submitted By:  acs@uts.amdahl.com (Tony Sumrall)
Summary:  vt100 terminal emulator.
Poster Boy:  Brent Woods  (ahh@j.cc.purdue.edu)
Tested.  Part 2 of 4

NOTES:  This program was tested by our Guest Moderator, Robert Tillotson.
He had a couple of problems with the program at first (a couple of Guru
errors, and we think that the vt100 task hung around instead of exiting
properly; not certain, though), but when we (Rob, Pat, and I) tested it
a few hours ago, none of us had any problems.  I dunno.  It seems to work
okay now.  Probably some fluke or other.



Brent Woods, Co-Moderator, comp.{sources,binaries}.amiga

USENET:  ...!j.cc.purdue.edu!ahh     ARPANET:  ahh@j.cc.purdue.edu
BITNET:  PODUM@PURCCVM               PHONE:  +1 (317) 743-8421
USNAIL:  320 Brown St., #406  /  West Lafayette, IN  47906

================================================================
#! /bin/sh
#
# This is a shell archive.  Save this into a file, edit it
# and delete all lines above this comment.  Then give this
# file to sh by executing the command "sh file".  The files
# will be extracted into the current directory owned by
# you with default permissions.
#
# The files contained herein are:
#
# -rw-r--r--   1 acs      other       7980 Feb  1 18:53 expand.c
# -rw-r--r--   1 acs      other      19521 Feb  1 18:53 init.c
# -rw-r--r--   1 acs      other      25220 Feb  1 18:54 kermit.c
#
echo 'x - expand.c'
if test -f expand.c; then echo 'shar: not overwriting expand.c'; else
sed 's/^X//' << '________This_Is_The_END________' > expand.c
X/*************************************************************
X * vt100 terminal emulator - Wild card and Directory support
X *
X *	v2.8 880117 ACS - See the README file
X *	v2.7 870825 ACS - Use the *InfoMsg*() routines in window.c rather
X *			  than req().
X *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
X *	v2.5 870214 DBW - more additions (see readme file)
X *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
X *	v2.3 861101 DBW - minor bug fixes
X *	v2.2 861012 DBW - more of the same
X *	v2.1 860915 DBW	- new features (see README)
X *           860830 Steve Drew Added Wild card support,
X *		    features(expand.c)
X *	v2.0 860809 DBW - Major rewrite
X *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
X *	v1.0 860712 DBW	- First version released
X *
X *      Much of the code from this module extracted from
X *      Matt Dillons Shell program. (Thanxs Matt.)
X *************************************************************/
X
X#include "vt100.h"
X
Xstruct DPTR {                    /* Format of directory fetch ptr */
X   struct FileLock *lock;        /* lock on directory   */
X   struct FileInfoBlock *fib;    /* mod'd fib for entry */
X};
X
X/*
X * Disk directory routines
X *
X *
X * diropen() returns a struct DPTR, or NULL if the given file does not
X * exist.  stat will be set to 1 if the file is a directory.  If the
X * name is "", then the current directory is openned.
X *
X * dirnext() returns 1 until there are no more entries.  The **name and
X * *stat are set.  *stat = 1 if the file is a directory.
X *
X * dirclose() closes a directory channel.
X *
X */
X
Xstruct DPTR *
Xdiropen(name, stat)
Xchar *name;
Xint *stat;
X{
X   struct DPTR *dp;
X   int namelen, endslash = 0;
X   struct FileLock *MyLock;
X
X   MyLock = (struct FileLock *)( (ULONG) ((struct Process *)
X				 (FindTask(NULL)))->pr_CurrentDir);
X   namelen = strlen(name);
X   if (namelen && name[namelen - 1] == '/') {
X      name[namelen - 1] = '\0';
X      endslash = 1;
X   }
X   *stat = 0;
X   dp = (struct DPTR *)malloc(sizeof(struct DPTR));
X   if (*name == '\0')
X      dp->lock = (struct FileLock *)DupLock (MyLock);
X   else
X      dp->lock = (struct FileLock *)Lock (name, ACCESS_READ);
X   if (endslash)
X      name[namelen - 1] = '/';
X   if (dp->lock == NULL) {
X      free (dp);
X      return (NULL);
X   }
X   dp->fib = (struct FileInfoBlock *)
X	 AllocMem((long)sizeof(struct FileInfoBlock), MEMF_PUBLIC);
X   if (!Examine (dp->lock, dp->fib)) {
X      dirclose (dp);
X      return (NULL);
X   }
X   if (dp->fib->fib_DirEntryType >= 0)
X      *stat = 1;
X   return (dp);
X}
X
Xdirnext(dp, pname, stat)
Xstruct DPTR *dp;
Xchar **pname;
Xint *stat;
X{
X   if (dp == NULL)
X      return (0);
X   if (ExNext (dp->lock, dp->fib)) {
X      *stat = (dp->fib->fib_DirEntryType < 0) ? 0 : 1;
X      *pname = dp->fib->fib_FileName;
X      return (1);
X   }
X   return (0);
X}
X
X
Xdirclose(dp)
Xstruct DPTR *dp;
X{
X   if (dp == NULL)
X      return (1);
X   if (dp->fib)
X      FreeMem (dp->fib, (long)sizeof(*dp->fib));
X   if (dp->lock)
X      UnLock (dp->lock);
X   free (dp);
X   return (1);
X}
X
Xfree_expand(av)
Xchar **av;
X{
X   char **base = av;
X
X   if (av) {
X      while (*av) {
X	 free (*av);
X	 ++av;
X      }
X      free (base);
X   }
X}
X
X/*
X * EXPAND(wild_name, pac)
X *    wild_name      - char * (example: "df0:*.c")
X *    pac            - int  *  will be set to # of arguments.
X *
X */
X
X
Xchar **
Xexpand(base, pac)
Xchar *base;
Xint *pac;
X{
X   char **eav = (char **)malloc (sizeof(char *));
X   int  eleft, eac;
X
X   char *ptr, *name;
X   char *bname, *ename, *tail;
X   int stat, scr;
X   struct DPTR *dp;
X
X   *pac = eleft = eac = 0;
X   base = strcpy(malloc(strlen(base)+1), base);
X   for (ptr = base; *ptr && *ptr != '?' && *ptr != '*'; ++ptr);
X   for (; ptr >= base && !(*ptr == '/' || *ptr == ':'); --ptr);
X   if (ptr < base) {
X      bname = strcpy (malloc(1), "");
X   } else {
X      scr = ptr[1];
X      ptr[1] = '\0';
X      bname = strcpy (malloc(strlen(base)+1), base);
X      ptr[1] = scr;
X   }
X   ename = ptr + 1;
X   for (ptr = ename; *ptr && *ptr != '/'; ++ptr);
X   scr = *ptr;
X   *ptr = '\0';
X   tail = (scr) ? ptr + 1 : NULL;
X
X   if ((dp = diropen (bname, &stat)) == NULL  ||  stat == 0) {
X      free (bname);
X      free (base);
X      free (eav);
X      InfoMsg1Line("Could not open directory");
X      return (NULL);
X   }
X   while (dirnext (dp, &name, &stat)) {
X      if (compare_ok(ename, name)) {
X	 if (tail) {
X	    int alt_ac;
X	    char *search, **alt_av, **scrav;
X	    struct FileLock *lock;
X
X	    if (!stat)      /* expect more dirs, but this not a dir */
X	       continue;
X	    lock = (struct FileLock *)CurrentDir (dp->lock);
X	    search = malloc(strlen(name)+strlen(tail)+2);
X	    strcpy (search, name);
X	    strcat (search, "/");
X	    strcat (search, tail);
X	    scrav = alt_av = expand (search, &alt_ac);
X	    CurrentDir (lock);
X	    if (scrav) {
X	       while (*scrav) {
X		  if (eleft < 2) {
X		     char **scrav = (char **)
X			malloc(sizeof(char *) * (eac + 10));
X		     movmem (eav, scrav, sizeof(char *) * (eac + 1));
X		     free (eav);
X		     eav = scrav;
X		     eleft = 10;
X		  }
X		  eav[eac] = malloc(strlen(bname)+strlen(*scrav)+1);
X		  strcpy(eav[eac], bname);
X		  strcat(eav[eac], *scrav);
X		  free (*scrav);
X		  ++scrav;
X		  --eleft, ++eac;
X	       }
X	       free (alt_av);
X	    }
X	 } else {
X	    if (eleft < 2) {
X	       char **scrav = (char **)
X		    malloc(sizeof(char *) * (eac + 10));
X	       movmem (eav, scrav, sizeof(char *) * (eac + 1));
X	       free (eav);
X	       eav = scrav;
X	       eleft = 10;
X	    }
X	    eav[eac] = malloc (strlen(bname)+strlen(name)+1);
X	    eav[eac] = strcpy(eav[eac], bname);
X	    strcat(eav[eac], name);
X	    --eleft, ++eac;
X	 }
X      }
X   }
X   dirclose (dp);
X   *pac = eac;
X   eav[eac] = NULL;
X   free (bname);
X   free (base);
X   if (eac)
X      return (eav);
X   free (eav);
X   return (NULL);
X}
X
X/*
X * Compare a wild card name with a normal name
X */
X
X#define MAXB   8
X
Xcompare_ok(wild, name)
Xchar *wild, *name;
X{
X   char *w = wild;
X   char *n = name;
X   char *back[MAXB][2];
X   int  bi = 0;
X
X   while (*n || *w) {
X      switch (*w) {
X      case '*':
X	 if (bi == MAXB) {
X	    InfoMsg1Line("Too many levels of '*'");
X	    return (0);
X	 }
X	 back[bi][0] = w;
X	 back[bi][1] = n;
X	 ++bi;
X	 ++w;
X	 continue;
Xgoback:
X	 --bi;
X	 while (bi >= 0 && *back[bi][1] == '\0')
X	    --bi;
X	 if (bi < 0)
X	    return (0);
X	 w = back[bi][0] + 1;
X	 n = ++back[bi][1];
X	 ++bi;
X	 continue;
X      case '?':
X	 if (!*n) {
X	    if (bi)
X	       goto goback;
X	    return (0);
X	 }
X	 break;
X      default:
X	 if (toupper(*n) != toupper(*w)) {
X	    if (bi)
X	       goto goback;
X	    return (0);
X	 }
X	 break;
X      }
X      if (*n)  ++n;
X      if (*w)  ++w;
X   }
X   return (1);
X}
X
Xset_dir(new)
Xchar *new;
X{
X   register 	char 		*s;
X   int   			i;
X   struct 	FileLock 	*lock;
X   char 			temp[60];
X   struct       FileInfoBlock   *fib;
X
X   if (*new != '\000') {
X      strcpy(temp, MyDir);
X      s = new;
X      if (*s == '/') {
X	 s++;
X	 for (i=strlen(MyDir);
X	      MyDir[i] != '/' && MyDir[i] != ':';
X	      i--);
X	 MyDir[i+1] = '\0';
X	 strcat(MyDir, s);
X	 }
X      else if (exists(s, ':') == 0) {
X	 if (MyDir[strlen(MyDir)-1] != ':')
X	    strcat(MyDir, "/");
X	 strcat(MyDir, s);
X	 }
X      else
X	 strcpy(MyDir, s);
X
X      if ((lock = (struct FileLock *)Lock(MyDir, (long)ACCESS_READ)) == 0) {
X	 InfoMsg2Line("Directory not found:",MyDir);
X	 strcpy(MyDir, temp);
X	 }
X      else {
X	 fib = (struct FileInfoBlock *)AllocMem(
X		(long)sizeof(struct FileInfoBlock), MEMF_PUBLIC);
X	 if (fib) {
X	    if (Examine(lock, fib)) {
X		if (fib->fib_DirEntryType > 0) {
X		    UnLock(CurrentDir(lock));
X		    if (MyDir[strlen(MyDir)-1] == '/')
X			MyDir[strlen(MyDir)-1] = '\000';
X		    }
X		else {
X		    InfoMsg2Line("Not a Directory:",MyDir);
X		    strcpy(MyDir,temp);
X		    }
X		}
X	    FreeMem(fib, (long)sizeof(struct FileInfoBlock));
X	    }
X	else {
X	    InfoMsg1Line("Can't change directory...No free memory!");
X	    strcpy(MyDir,temp);
X	    }
X	}
X    }
X}
X
Xexists(s,c)
Xchar *s,c;
X    {
X    while (*s != '\000')
X	if (*s++ == c) return(1);
X    return(0);
X    }
________This_Is_The_END________
if test `wc -l < expand.c` -ne 355; then
	echo 'shar: expand.c was damaged during transit (should have been 355 bytes)'
fi
fi		; : end of overwriting check
echo 'x - init.c'
if test -f init.c; then echo 'shar: not overwriting init.c'; else
sed 's/^X//' << '________This_Is_The_END________' > init.c
X/***************************************************************
X * vt100 - terminal emulator - initialization
X *
X *	v2.8 880117 ACS - See the README file
X *	v2.7 870825 ACS - Allow execution of all script files specified on
X *			  command line (companion to changes in script.c).
X *			  Rolled menu init into one routine (do_menu_init()).
X *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
X *	v2.5 870214 DBW - more additions (see readme file)
X *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
X *	v2.3 861101 DBW - minor bug fixes
X *	v2.2 861012 DBW - more of the same
X *	v2.1 860915 DBW - new features (see README)
X *	     860901 ACS - Added Parity and Word Length and support code
X *	     860823 DBW - Integrated and rewrote lots of code
X *	v2.0 860809 DBW - Major rewrite
X *	v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes
X *	v1.0 860712 DBW - First version released
X *
X ***************************************************************/
X
X#include "vt100.h"
X
Xstruct Device *ConsoleDevice = NULL;
Xstruct IOStdReq ConReq;
Xextern APTR OrigWindowPtr;
Xextern int capture;		/* in vt100.c */
X
X/*   Used by script.c for script file chaining. */
Xint script_files_todo = 0;
Xchar **script_files = NULL;
X
Xchar line[256];
X
X/* Command key equivalences per menu.  Manipulated by script.c */
X
X/*   Equivalences for the File menu... */
Xstruct filecmd {
X    char mo;	/* Mode			*/
X    char se;	/* Send			*/
X    char re;	/* Receive		*/
X    char kg;	/* Kermit Get		*/
X    char kb;	/* Kermit Bye		*/
X    char ca;	/* Capture or Capturing */
X    char nl;
X} filecmd_chars = { ' ', '^', 'V', 'G', 'B', ' ', '\0' };
X
X/*   Equivalences for Mode sub-menu... */
Xstruct mode_cmd {
X    char as;	/* ascii mode		*/
X    char xm;	/* xmodem mode		*/
X    char xmc;	/* xmodemcrc mode	*/
X    char ke;	/* kermit mode		*/
X    char nl;
X} modecmd_chars = { ' ', 'X', ' ', 'K', '\0' };
X
X/*   Equivalences for the Baud Rate sub-menu... */
Xstruct baudcmd {
X    char b03;	/* 0300			*/
X    char b12;	/* 1200			*/
X    char b24;	/* 2400			*/
X    char b48;	/* 4800			*/
X    char b96;	/* 9600			*/
X    char bnl;
X} baudcmd_chars = { ' ', 'L', 'H', ' ', ' ', '\0' };
X
X/*   Equivalences for the Parity sub-menu... */
Xstruct parcmd {
X    char no;	/* NOne			*/
X    char ma;	/* MArk			*/
X    char sp;	/* SPace		*/
X    char ev;	/* EVen			*/
X    char od;	/* ODd			*/
X    char nl;
X} parcmd_chars = { 'N', ' ', ' ', 'E', 'O', '\0' };
X
X/*   Equivalences for the Xfer Mode sub-menu... */
Xstruct modcmd {
X    char im;	/* IMage		*/
X    char tx;	/* TeXt			*/
X    char cn;	/* CoNvert		*/
X    char nl;
X} modcmd_chars = { 'I', 'T', ' ', '\0' };
X
X/*   Equivalences for the Script menu... */
Xstruct scrcmd {
X    char em;	/* Execute Macro	*/
X    char ab;	/* Abort Macro		*/
X    char nl;
X} scrcmd_chars = { 'M', 'A', '\0' };
X
X/*   Equivalences for the Utility menu... */
Xstruct utilcmd {
X    char sb;	/* Send Break	*/
X    char hu;	/* Hang Up	*/
X    char cd;	/* Change Dir	*/
X    char cs;	/* Clear Screen	*/
X    char ec;	/* ECho		*/
X    char wr;	/* WRap		*/
X    char nk;	/* Num Key	*/
X    char ac;	/* App Cur	*/
X    char bs;	/* BS<->DEL	*/
X    char xb;	/* Xfer beep	*/
X    char nl;
X} utilcmd_chars = { '.', ' ', 'D', ' ', ' ', 'W', 'K', 'C', ' ', ' ', '\0' };
X
Xextern char myfontname[];
X
Xstatic char *filetext[] = {
X    "Protocol",
X    "Send",
X    "Receive",
X    "Kermit Get",
X    "Kermit BYE",
X    "Capture"
X};
X
Xstatic char *modetext[] = {
X    "  Ascii",
X    "  Xmodem",
X    "  XmodemCRC",
X    "  Kermit"
X};
X
Xstatic char *commtext[] = {
X    "Baud Rate",
X    "Parity   ",
X    "Xfer Mode"
X};
X
Xstatic char *baudtext[] = {
X    "   300",
X    "  1200",
X    "  2400",
X    "  4800",
X    "  9600"
X};
X
Xstatic char *partext[] = {
X    "  None ",
X    "  Mark ",
X    "  Space",
X    "  Even ",
X    "  Odd  "
X};
X
Xstatic char *modtext[] = {
X    "  Image  ",
X    "  Text   ",
X    "  Convert"
X};
X
Xstatic char *scrtext[] = {
X    "Execute Macro",
X    "Abort Execution"
X};
X
Xstatic char *utiltext[] = {
X    "Send Break",
X    "Hang Up",
X    "Change Dir",
X    "Clear Scrn",
X    "  Echo",
X    "  Wrap",
X    "  Num Key",
X    "  App Cur",
X    "  BS<->DEL",
X    "  Xfer Beep"
X};
X
Xstruct HowToInit {
X    int LeftEdge;
X    int Width;
X    ULONG Flags;
X    char **text;
X    char *cmdkeys;
X};
X
Xstatic struct HowToInit menu_init[] = {
X	{ 0, 120+40, ITEMTEXT | ITEMENABLED | HIGHCOMP,
X	     filetext, (char *)(&filecmd_chars) },
X	{75, 92+40, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT,
X	     modetext, (char *)(&modecmd_chars) },
X	{ 0, 88, ITEMTEXT | ITEMENABLED | HIGHCOMP,
X	     commtext, NULL },
X	{ 75, 56+40, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT,
X	       baudtext, (char *)(&baudcmd_chars) },
X	{ 75, 56+40, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT,
X	      partext, (char *)(&parcmd_chars) },
X	{ 75, 80+40, ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT,
X	      modtext, (char *)(&modcmd_chars) },
X	{ 0, 160, ITEMTEXT | ITEMENABLED | HIGHCOMP,
X	     scrtext, (char *)(&scrcmd_chars) },
X	{ 0, 88+40, ITEMTEXT | ITEMENABLED | HIGHCOMP,
X	     utiltext, (char *)(&utilcmd_chars) }
X};
X
X#define FILE_INIT_ENTRY	(&(menu_init[0]))
X#define MODE_INIT_ENTRY (&(menu_init[1]))
X#define COMM_INIT_ENTRY	(&(menu_init[2]))
X#define RS_INIT_ENTRY	(&(menu_init[3]))
X#define PAR_INIT_ENTRY	(&(menu_init[4]))
X#define XF_INIT_ENTRY	(&(menu_init[5]))
X#define SCRIPT_INIT_ENTRY	(&(menu_init[6]))
X#define UTIL_INIT_ENTRY	(&(menu_init[7]))
X
Xvoid do_menu_init();
X
Xchar *InitDefaults(argc,argv)
Xint	argc;
Xchar	**argv;
X    {
X    FILE    *fd = NULL;
X    char    *p, *t, *ifile;
X    int     l, dont_init = 0;
X
X    doing_init = 1;	/* make sure we only allow INIT script commands */
X    if (argc > 1) {
X	int start_of_script_files = 1;
X
X	if(strcmp(argv[1], "-i") == 0) {	/* No init file */
X	    dont_init = 1;
X	    start_of_script_files = 2;
X	}
X	else if(strcmp(argv[1], "+i") == 0) {	/* Use specified init file */
X	    start_of_script_files = 3;
X    	    if((fd=fopen(argv[2],"r")) == NULL) {
X		ifile = AllocMem((LONG)(strlen(argv[2])+3), MEMF_PUBLIC|MEMF_CLEAR);
X		strcpy(ifile, "S:");
X		strcat(ifile, argv[2]);
X		fd = fopen(ifile, "r");
X		FreeMem(ifile, (LONG)(strlen(argv[2])+3));
X		ifile = NULL;
X	    }
X	}
X	if(start_of_script_files > argc)
X	    script_files_todo = 0;
X	else
X	    script_files_todo = argc - start_of_script_files; /* # of cmdline script files left */
X	script_files = &(argv[start_of_script_files]);	  /* Ptr to first of 'em */
X    }
X
X    if((p_font == NULL) || (p_font[0] == '\0'))
X	strcpy(myfontname, "topaz");
X    else
X	strcpy(myfontname, p_font);	/* Init font name */
X    strcat(myfontname, ".font");
X
X    if(!dont_init)
X	if((fd == NULL) && ((fd=fopen("vt100.init","r")) == NULL))
X	    fd=fopen("s:vt100.init","r");
X
X    if(fd != NULL) {
X	while (fgets(line,256,fd) != 0) {
X	    line[strlen(line)-1] = '\000';
X	    p = next_wrd(&line[0],&l);
X	    if (*p) {
X		*p |= ' ';
X		if (p[1]) p[1] |= ' ';
X		if (*p == '#') continue;
X		if (*p == 'e' && p[1] == 'x') break;
X		exe_cmd(p,l);
X		}
X	}
X	fclose(fd);
X    }
X    doing_init = 0;
X
X    IntuitionBase = (struct IntuitionBase *)
X	OpenLibrary("intuition.library", INTUITION_REV);
X    if( IntuitionBase == NULL )
X	cleanup("can't open intuition",1);
X
X    GfxBase = (struct GfxBase *)
X	OpenLibrary("graphics.library",GRAPHICS_REV);
X    if( GfxBase == NULL )
X	cleanup("can't open graphics library",2);
X
X    /* Now set up all the screen info as necessary */
X    if(p_lines == 0)	/* Wants to use everything available */
X	    if(p_interlace)
X		p_lines = ((GfxBase->NormalDisplayRows*2) - 6) / 8;
X	    else
X		p_lines = ((GfxBase->NormalDisplayRows - 6) / 8);
X
X    if (p_interlace == 0) {
X	if (p_lines > 24) p_lines = 24;
X	MINY = 14;
X	NewWindow.Height    = (long)((p_lines*8)+8);
X	}
X    else {
X	if (p_lines > 48) p_lines = 48;
X	MINY = 16;
X	NewScreen.ViewModes |= LACE;
X	NewWindow.Height    = (long)((p_lines*8)+10);
X	}
X    NewWindow.MinHeight = NewWindow.Height;
X    NewWindow.MaxHeight = NewWindow.Height;
X    NewWindow.TopEdge	= 0L;
X    MAXY = ((p_lines-1)*8) + MINY;
X    top  = MINY;
X    bot  = MAXY;
X    savx = MINX;
X    savy = MINY;
X    if (p_screen == 1) {
X	if (p_depth > 2) p_depth = 2;
X	if (p_depth < 1) p_depth = 1;
X	NewScreen.Depth     = (long)p_depth;
X
X	NewScreen.Height    = (long)((p_lines*8)+16);
X
X	if (p_interlace == 1)
X	    NewScreen.TopEdge	= (long)(400 - NewScreen.Height);
X	else
X	    NewScreen.TopEdge	= (long)(208 - NewScreen.Height);
X	}
X    else {
X	p_depth			= 2L;
X	NewWindow.TopEdge	= 0L;
X	NewWindow.Screen	= NULL;
X	NewReqWindow.Screen	= NULL;
X	NewWindow.Type		= WBENCHSCREEN;
X	NewReqWindow.Type	= WBENCHSCREEN;
X	}
X
X    /* see if we exit with a startup script */
X    if (*p == 'e') {
X	p = next_wrd(p+l+1,&l);
X	if (*p) return(p);
X    }
X    if (script_files_todo > 0) {
X    	script_files_todo--;
X    	return(*(script_files++));
X    }
X    return(NULL);
X    }
X
Xvoid InitDevs()
X{
XUSHORT	colors[4];
Xint	i;
XBYTE	*b,*c;
Xstruct Process *mproc;
Xchar temp[80];
X
Xif (p_screen == 1) {
X    if ((myscreen = (struct Screen *)OpenScreen(&NewScreen)) == NULL)
X	cleanup("can't open screen",3);
X    NewWindow.Screen = myscreen;
X    NewReqWindow.Screen = myscreen;
X    }
X
Xif ((mywindow = (struct Window *)OpenWindow(&NewWindow)) == NULL)
X    cleanup("can't open window",4);
X
Xif(OpenDevice("console.device", -1L, &ConReq, 0L))
X    cleanup("can't open console", 4);
XConsoleDevice = ConReq.io_Device;
X
Xif(p_screen == 1) {	/* Cause system reqs to come to this screen */
X    mproc = (struct Process *)FindTask(0L);
X    OrigWindowPtr = mproc->pr_WindowPtr;
X    mproc->pr_WindowPtr = (APTR)mywindow;
X}
Xif ((myfont = (struct TextFont *)OpenFont(&myattr)) == NULL) {
X    sprintf(temp, "Can't open font %s", myfontname);
X    cleanup(temp, 4);
X}
X
Xmyviewport   = (struct ViewPort *)ViewPortAddress(mywindow);
Xmyrastport   = (struct RastPort *)mywindow->RPort;
X
XSetFont(myrastport,myfont);
X
Xif (p_depth > 1) myrequest.BackFill = 2;
Xif (p_screen != 0 && p_wbcolors == 0) {
X    colors[0] = p_background;
X    colors[1] = p_foreground;
X    colors[2] = p_bold;
X    colors[3] = p_cursor;
X    if (p_depth == 1)
X	LoadRGB4(myviewport,(struct ColorMap *)colors,2L);
X    else
X	LoadRGB4(myviewport,(struct ColorMap *)colors,4L);
X    }
X
XRead_Request = (struct IOExtSer *)
X    AllocMem((long)sizeof(*Read_Request),MEMF_PUBLIC|MEMF_CLEAR);
XRead_Request->io_SerFlags = 0L;
XRead_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L);
Xif(OpenDevice(SERIALNAME,(LONG)p_unit,Read_Request,NULL))
X    cleanup("Cant open Read device",5);
Xrs_in = malloc(p_buffer+1);
XRead_Request->io_SerFlags = 0L;
XRead_Request->io_Baud	  = p_baud;
XRead_Request->io_ReadLen  = 8L;
XRead_Request->io_WriteLen = 8L;
XRead_Request->io_CtlChar  = 0x11130000L;
XRead_Request->io_RBufLen  = p_buffer;
XRead_Request->io_BrkTime  = p_break;
XRead_Request->IOSer.io_Command = SDCMD_SETPARAMS;
XDoIO(Read_Request);
XRead_Request->IOSer.io_Command = CMD_READ;
XRead_Request->IOSer.io_Length  = 1;
XRead_Request->IOSer.io_Data    = (APTR) &rs_in[0];
X
XWrite_Request = (struct IOExtSer *)
X    AllocMem((long)sizeof(*Write_Request),MEMF_PUBLIC|MEMF_CLEAR);
Xb = (BYTE *)Read_Request;
Xc = (BYTE *)Write_Request;
Xfor (i=0;i<sizeof(struct IOExtSer);i++) *c++ = *b++;
XWrite_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L);
XWrite_Request->IOSer.io_Command = CMD_WRITE;
XWrite_Request->IOSer.io_Length	= 1;
XWrite_Request->IOSer.io_Data	= (APTR) &rs_out[0];
X
XTimer_Port = CreatePort("Timer Port",0L);
XScript_Timer_Port = CreatePort("Timer Port",0L);
X
Xif (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Timer, 0) ||
X    OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Script_Timer, 0))
X	cleanup("can't open timer device",7);
X
XTimer.tr_node.io_Message.mn_ReplyPort = Timer_Port;
XTimer.tr_node.io_Command = TR_ADDREQUEST;
XTimer.tr_node.io_Flags = 0;
XTimer.tr_node.io_Error = 0;
X
XScript_Timer.tr_node.io_Message.mn_ReplyPort = Script_Timer_Port;
XScript_Timer.tr_node.io_Command = TR_ADDREQUEST;
XScript_Timer.tr_node.io_Flags = 0;
XScript_Timer.tr_node.io_Error = 0;
X
XBeepWave   = (UBYTE *)AllocMem(BEEPSIZE,(long)(MEMF_CHIP|MEMF_CLEAR));
Xif (BeepWave != 0) BeepWave[0] = 100;
X
XAudio_Port = CreatePort("Audio Port",0L);
X
XAudio_Request.ioa_Request.io_Message.mn_ReplyPort   = Audio_Port;
XAudio_Request.ioa_Request.io_Message.mn_Node.ln_Pri = 85;
XAudio_Request.ioa_Data		    = Audio_AllocMap;
XAudio_Request.ioa_Length	    = (ULONG) sizeof(Audio_AllocMap);
X
Xif (OpenDevice(AUDIONAME, NULL, (char *) &Audio_Request, NULL))
X	cleanup("can't open audio device",8);
X
XAudio_Request.ioa_Request.io_Command	= CMD_WRITE;
XAudio_Request.ioa_Request.io_Flags	= ADIOF_PERVOL;
XAudio_Request.ioa_Data		= BeepWave;
XAudio_Request.ioa_Length	= BEEPSIZE;
XAudio_Request.ioa_Period	= COLORCLOCK / (BEEPSIZE * BEEPFREQ);
XAudio_Request.ioa_Volume	= p_volume;
XAudio_Request.ioa_Cycles	= 100;
X}
X
X/*****************************************************************/
X/*    The following function initializes the structure arrays	 */
X/*   needed to provide the File menu topic.			 */
X/*****************************************************************/
Xvoid InitFileItems()
X{
X    int n;
X
X    if(capture == TRUE)
X	filetext[FILEMAX-1] = "Capturing";
X    else
X	filetext[FILEMAX-1] = "Capture";
X    do_menu_init(FileItem, FileText, FILE_INIT_ENTRY, FILEMAX);
X    FileItem[0].SubItem = ModeItem;
X    do_menu_init(ModeItem, ModeText, MODE_INIT_ENTRY, MODEMAX);
X    for( n=0; n<MODEMAX; n++ ) {
X	ModeItem[n].MutualExclude = (~(1 << n));
X    }
X    if(p_xproto > MODEMAX)
X	p_xproto = MODEMAX-1;
X    ModeItem[p_xproto].Flags |= CHECKED;
X}
X
X/******************************************************************
X/*			Main Comm menu
X/*		set up for Baud & Parity submenus
X/******************************************************************/
Xvoid InitCommItems()
X{
X    int n;
X
X    do_menu_init(CommItem, CommText, COMM_INIT_ENTRY, COMMAX);
X    CommItem[0].SubItem = RSItem;
X    CommItem[1].SubItem = ParItem;
X    CommItem[2].SubItem = XFItem;
X
X/*****************************************************************/
X/*    The following initializes the structure arrays		 */
X/*   needed to provide the BaudRate Submenu topic.		 */
X/*****************************************************************/
X
X    do_menu_init(RSItem, RSText, RS_INIT_ENTRY, RSMAX);
X    for( n=0; n<RSMAX; n++ ) {
X	RSItem[n].MutualExclude = (~(1 << n));
X    }
X
X    /* select baud item chekced */
X    switch (p_baud) {
X	case 300:	n = 0; break;
X	case 1200:	n = 1; break;
X	case 2400:	n = 2; break;
X	case 4800:	n = 3; break;
X	case 9600:	n = 4; break;
X	default:	n = 2; p_baud = 2400;
X    }
X    RSItem[n].Flags |= CHECKED;
X
X/* initialize text for specific menu items */
X
X/*****************************************************************/
X/*    The following initializes the structure arrays		 */
X/*   needed to provide the Parity   Submenu topic.		 */
X/*****************************************************************/
X
X    do_menu_init(ParItem, ParText, PAR_INIT_ENTRY, PARMAX);
X    for( n=0; n<PARMAX; n++ ) {
X	ParItem[n].MutualExclude = (~(1 << n));
X    }
X
X    /* select parity item chekced */
X    ParItem[p_parity].Flags |= CHECKED;
X
X/*****************************************************************/
X/*    The following initializes the structure arrays		 */
X/* initialize text for specific menu items */
X/*    needed to provide the Transfer Mode menu topic.		 */
X/*****************************************************************/
X
X    do_menu_init(XFItem, XFText, XF_INIT_ENTRY, XFMAX);
X    
X    /* initialize each menu item and IntuiText with loop */
X    for( n=0; n<XFMAX; n++ ) {
X	if (n < 2)	XFItem[n].MutualExclude = 2 - n;
X    }
X    /* mode checked */
X    XFItem[p_mode].Flags |= CHECKED;
X    if (p_convert)	XFItem[2].Flags |= CHECKED;
X
X/* initialize text for specific menu items */
X
X} /* end of InitCommItems() */
X
X
X/*****************************************************************/
X/*    The following function initializes the structure arrays	 */
X/*   needed to provide the Script menu topic.			 */
X/*****************************************************************/
Xvoid InitScriptItems()
X{
X    do_menu_init(ScriptItem, ScriptText, SCRIPT_INIT_ENTRY, SCRIPTMAX);
X}
X
X/*****************************************************************/
X/*    The following function initializes the structure arrays	 */
X/*   needed to provide the Util menu topic.		       */
X/*****************************************************************/
Xvoid InitUtilItems()
X    {
X    int	n;
X
X    do_menu_init(UtilItem, UtilText, UTIL_INIT_ENTRY, UTILMAX);
X/* initialize each menu item and IntuiText with loop */
X    for( n=0; n<UTILMAX; n++ ) {
X	if (n > 3) UtilItem[n].Flags |= CHECKIT;
X    }
X
X    if (p_echo)		UtilItem[4].Flags |= CHECKED;
X    if (p_wrap)		UtilItem[5].Flags |= CHECKED;
X    if (p_keyapp == 0)	UtilItem[6].Flags |= CHECKED;
X    if (p_curapp)	UtilItem[7].Flags |= CHECKED;
X    if (p_bs_del)	UtilItem[8].Flags |= CHECKED;
X    if (p_xbeep)	UtilItem[9].Flags |= CHECKED;
X    swap_bs_del();	/* Setup keys[] properly... */
X    swap_bs_del();	/* ...for mode		    */
X}
X
X/****************************************************************/
X/*   The following function inits the Menu structure array with */
X/*  appropriate values for our simple menu.  Review the manual	*/
X/*  if you need to know what each value means.			*/
X/****************************************************************/
Xvoid InitMenu()
X{
Xmenu[0].NextMenu = &menu[1];
Xmenu[0].LeftEdge = 5;
Xmenu[0].TopEdge = 0;
Xmenu[0].Width = 40;
Xmenu[0].Height = 10;
Xmenu[0].Flags = MENUENABLED;
Xmenu[0].MenuName = "File";	  /* text for menu-bar display */
Xmenu[0].FirstItem = &FileItem[0]; /* pointer to first item in list */
X
Xmenu[1].NextMenu = &menu[2];
Xmenu[1].LeftEdge = 55;
Xmenu[1].TopEdge = 0;
Xmenu[1].Width = 88;
Xmenu[1].Height = 10;
Xmenu[1].Flags = MENUENABLED;
Xmenu[1].MenuName = "Comm Setup";   /* text for menu-bar display */
Xmenu[1].FirstItem = &CommItem[0];  /* pointer to first item in list */
X
Xmenu[2].NextMenu = &menu[3];
Xmenu[2].LeftEdge = 153;
Xmenu[2].TopEdge = 0;
Xmenu[2].Width = 56;
Xmenu[2].Height = 10;
Xmenu[2].Flags = MENUENABLED;
Xmenu[2].MenuName = "Script";	    /* text for menu-bar display */
Xmenu[2].FirstItem = &ScriptItem[0]; /* pointer to first item in list*/
X
Xmenu[3].NextMenu = NULL;
Xmenu[3].LeftEdge = 225;
Xmenu[3].TopEdge = 0;
Xmenu[3].Width = 64;
Xmenu[3].Height = 10;
Xmenu[3].Flags = MENUENABLED;
Xmenu[3].MenuName = "Utility";	   /* text for menu-bar display */
Xmenu[3].FirstItem = &UtilItem[0];  /* pointer to first item in list*/
X}
X
Xvoid do_menu_init(menuitem, menutext, initentry, max)
Xstruct MenuItem menuitem[];
Xstruct IntuiText menutext[];
Xstruct HowToInit *initentry;
Xint max;
X{
X    int n, nplus1;
X    char **temp;
X
X    /* initialize each menu item and IntuiText with loop */
X    for( n=0; n < max; n++ ) {
X	nplus1 = n + 1;
X	temp = initentry->text;
X	menutext[n].IText = (UBYTE *)temp[n];
X	menuitem[n].NextItem = &menuitem[nplus1];
X	menuitem[n].LeftEdge = initentry->LeftEdge;
X	menuitem[n].TopEdge = 10 * n;
X	menuitem[n].Width = initentry->Width;
X	menuitem[n].Height = 10;
X	menuitem[n].Flags = initentry->Flags;
X	menuitem[n].MutualExclude = 0;
X	menuitem[n].ItemFill = (APTR)&menutext[n];
X	menuitem[n].SelectFill = NULL;
X	if((initentry->cmdkeys != NULL) && (initentry->cmdkeys[n] != ' ')) {
X	    menuitem[n].Command  = initentry->cmdkeys[n];
X	    menuitem[n].Flags   |= COMMSEQ;
X	    }
X	else menuitem[n].Command = 0;
X	menuitem[n].SubItem = NULL;
X	menuitem[n].NextSelect = 0;
X    
X	menutext[n].FrontPen = 0;
X	menutext[n].BackPen = 1;
X	menutext[n].DrawMode = JAM2;/* render in fore and background */
X	menutext[n].LeftEdge = 0;
X	menutext[n].TopEdge = 1;
X	menutext[n].ITextFont = NULL;
X	menutext[n].NextText = NULL;
X	}
X    menuitem[max-1].NextItem = NULL;
X}
________This_Is_The_END________
if test `wc -l < init.c` -ne 666; then
	echo 'shar: init.c was damaged during transit (should have been 666 bytes)'
fi
fi		; : end of overwriting check
echo 'x - kermit.c'
if test -f kermit.c; then echo 'shar: not overwriting kermit.c'; else
sed 's/^X//' << '________This_Is_The_END________' > kermit.c
X/*************************************************************
X * vt100 terminal emulator - KERMIT protocol support
X *
X *	v2.8 880117 ACS - See the README file
X *	v2.7 870825 ACS - Fixed the "multiple-send" problem in
X *			  doksend() et al; show status using the *InfoMsg*()
X *			  routines in window.c; fixed erroneous calls to
X *			  spack() and rpack(); better error handling.
X *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
X *	v2.5 870214 DBW - more additions (see readme file)
X *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
X *	v2.3 861101 DBW - minor bug fixes
X *	v2.2 861012 DBW - more of the same
X *	v2.1 860915 DBW - new features (see README)
X *	     860901 ACS - Added eight bit quoting
X *	     860830 Steve Drew Wild card support, err recovry,bugs.
X *	     860823 DBW - Integrated and rewrote lots of code
X *	     860811 Steve Drew multi filexfer, bugs, status line ect..
X *	v2.0 860809 DBW - Major rewrite
X *	v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes
X *	v1.0 860712 DBW - First version released
X *
X *************************************************************/
X
X#include "vt100.h"
X
X#define MAXPACKSIZ 94	    /* Maximum msgpkt size */
X#define CR	   13	    /* ASCII Carriage Return */
X#define LF	   10	    /* ASCII line feed */
X#define SP	   32	    /* ASCII space */
X#define DEL	  127	    /* Delete (rubout) */
X
X#define MAXTRY	  5	   /* Times to retry a msgpkt */
X#define MYQUOTE  '#'	   /* Quote character I will use */
X#define MYRPTQ	 '~'	   /* Repeat quote character */
X#define MYEBQ	 '&'	   /* 8th bit prefix character */
X#define MYPAD	   0	   /* Number of padding charss I will need */
X#define MYPCHAR    0	   /* Padding character I need (NULL) */
X#define MYEOL	'\n'	/* End-Of-Line character I need */
X#define IDOLONG	2	/* I do LONG packets! */
X
X#define tochar(ch)  ((ch) + ' ')
X#define unchar(ch)  ((ch) - ' ')
X#define ctl(ch)     ((ch) ^ 64 )
X
X/* Global Variables */
X
Xint sending,	/* Indicates that we're sending, not receiving */
X    lastpkt,	/* Last successful packet # sent/received */
X    ulp,		/* Using LONG packets */
X    size,	/* Size of present data */
X    osize,	/* Size of last data entry */
X    rpsiz,	/* Maximum receive msgpkt size */
X    spsiz,	/* Maximum send msgpkt size */
X    timint,	/* Time interval to wait */
X    pad,		/* How much padding to send */
X    n,		/* Packet number */
X    tp,		/* total packets */
X    numtry,	/* Times this msgpkt retried */
X    retry,	/* total retries */
X    oldtry,	/* Times previous msgpkt retried */
X    sendabort,	/* flag for aborting send file  */
X    rptflg,	/* are we doing repeat quoting */
X    ebqflg,	/* are we doing 8th bit quoting */
X    notfirst,	/* is this the first file received */
X    first,	/* is this the first time in a file */
X    rpt,		/* current repeat count */
X    next,	/* what is the next character */
X    t;		/* current character */
Xlong totbytes;	/* total bytes xfered on this file */
X
Xchar state,	/* Present state of the automaton */
X    padchar,	/* Padding character to send */
X    eol,		/* End-Of-Line character to send */
X    quote,	/* Quote character in incoming data */
X    rptq,	/* Quote character for repeats */
X    ebq,		/* Quote character for 8th bit quoting */
X    ackpkt[MAXPACKSIZ+20],	/* ACK/NAK packet buffer */
X    *msgpkt,			/* Message Packet buffer is AllocMem()d */
X    *spackbuf,	/* Dynamically allocated buffer for spack() */
X    filnam[40],	/* remote file name */
X    snum[10],
X    mainmode[10];
X
XFILE *fp;	/* file for send/receive */
X
Xchar *
Xgetfname(name)	/* returns ptr to start of file name from spec */
Xchar *name;
X{
X    int l;
X
X    l = strlen(name);
X    while(l && name[l] != '/' && name[l] != ':') l--;
X    if (name[l] == '/' || name[l] == ':') l++;
X    return(name += l);
X}
X
Xdoksend(file,more)
Xchar *file;
Xint more;
X{
X    int amount, c, wild;
X    char *p, **list = NULL;
X
X    msgpkt    = (char *)AllocMem((long)(MAXLONGPKS+20), MEMF_PUBLIC|MEMF_CLEAR);
X    spackbuf  = (char *)AllocMem((long)(MAXLONGPKS+20), MEMF_PUBLIC|MEMF_CLEAR);
X    sending = 1;
X    if (!strcmp(file,"$")) { saybye(); return(USERABORT); }
X    p = file;
X    while(*p && *p != '*' && *p != '?') p++;
X    if (*p) {
X	wild = TRUE;
X	list = expand(file, &amount);
X	if (list == NULL) InfoMsg1Line("KERMIT: No wild card match");
X    }
X    else {
X	wild = FALSE;
X	amount = 1;
X    }
X    /*	  The "multiple send" problem is brought about by attempting to
X    ** send multiple files in a single "batch" (via globbing, e.g. *.foo)
X    ** to a remote kermit that is NOT in server mode.  A 'Z' packet
X    ** (meaning end-of-file) is sent after each of the files with a 'B'
X    ** packet (meaning end-of-batch) coming after the last 'Z' packet.
X    ** The old code reset the packet # on each iteration.  We do it
X    ** outside of the for loop. */
X    n = lastpkt = 0;
X    ulp = 0;	/* Assume we won't use LONG packets */
X    for (c = 0; c < amount; c++) {
X	if (wild == TRUE) p = list[c];
X	    else  p = file;
X	strcpy(filnam,getfname(p));
X	ttime = TTIME_KERMIT;
X	tp = retry = numtry = 0; totbytes = 0L;
X	if ((fp = fopen(p,"r")) == NULL) {
X	    InfoMsg2Line("KERMIT: Can't open send file:", p);
X	    continue;
X	}
X	strcpy(mainmode,"SEND");
X	ClearBuffer();
X
X	/*  This is another piece of the multiple-send fix.  Sendsw() needs
X	** to know 1) that this is the first file so it can send a send-init
X	** packet and 2) if this is the last file so it can send a B packet
X	** to indicate end-of-batch.  The last piece of the multiple-send fix
X	** is in sendsw() itself. */
X	if ( sendsw(c == 0, c >= (amount-1)) ) /* Successful send? */
X	    ScrollInfoMsg(1);
X	fclose(fp);
X    }
X    free_expand(list);
X    FreeMem(spackbuf,	(long)(MAXLONGPKS+20));
X    FreeMem(msgpkt,	(long)(MAXLONGPKS+20));
X    return(TRUE);
X}
X
Xdokreceive(file,more)
Xchar *file;
Xint more;
X{
X    int retval;
X
X    msgpkt    = (char *)AllocMem((long)(MAXLONGPKS+20), MEMF_PUBLIC|MEMF_CLEAR);
X    spackbuf  = (char *)AllocMem((long)(MAXLONGPKS+20), MEMF_PUBLIC|MEMF_CLEAR);
X    ttime = TTIME_KERMIT;
X    sending = 0;
X    if (!strcmp(file,"$")) { saybye(); return(USERABORT); }
X    strcpy(filnam, file);
X    if (server) strcpy(mainmode,"GET");
X    else        strcpy(mainmode,"RECV");
X    tp =  lastpkt = retry = n =  numtry = notfirst = 0; totbytes = 0L;
X    ClearBuffer();
X    retval  = recsw();
X    FreeMem(spackbuf,	(long)(MAXLONGPKS+20));
X    FreeMem(msgpkt,	(long)(MAXLONGPKS+20));
X    return(retval);
X}
X
Xsendsw(firstfile, lastfile)
Xint firstfile, lastfile; /* Multiple-send fix */
X{
X    char sinit(), sfile(), sdata(), seof(), sbreak();
X    sendabort = 0;
X    /* Multiple-send fix.  If this is the first file of the batch then enter
X    ** send-init state otherwise just enter send-file state. */
X    if(firstfile)
X	state = 'S';
X    else
X	state = 'F';
X    while(TRUE) {
X	switch(state) {
X	case 'S':   state = sinit();  break;
X	case 'F':   state = sfile();  break;
X	case 'D':   state = sdata();  break;
X	case 'Z':   state = seof();   break;
X	case 'B':   if (lastfile || sendabort) {
X			/* Multiple-send fix.  If this is the last file then
X			** send a B packet to indicate end-of-batch. */
X			state = sbreak();
X			break;
X		     }
X		     return(TRUE);	/* Otherwise, just return. */
X	case 'C':   if (sendabort) return(FALSE);
X		    else return(TRUE);
X	case 'E':   dostats('E',"ERROR");  /* so print the err and abort */
X		    print_host_err(ackpkt);
X		    return(FALSE);
X	case 'A':   if (timeout == USERABORT) {
X			timeout = GOODREAD;
X			n = (n+1)%64;
X			sendabort = 1;
X			dostats('A',"ABORT");
X			strcpy(msgpkt, "D");
X			state = 'Z';
X			break;
X		    }
X		    if (timeout == TIMEOUT) dostats('A',"TMOUT");
X		    else { /* protocol error dectected by us */
X			dostats('A',"ERROR");
X			print_our_err();
X		    }
X		    return(FALSE);
X	default:    return(FALSE);
X	}
X    }
X}
X
Xchar sinit()
X{
X    int num, len;
X
X    retry++;
X    if (numtry++ > MAXTRY) return('A');
X    spar(msgpkt);
X
X    spack('S',n,13,msgpkt);
X    switch(rpack(&len,&num,ackpkt)) {
X    case 'N':	return(state);
X    case 'Y':	if (n != num) return(state);
X		rpar(ackpkt, len);
X		if (eol == 0) eol = '\n';
X		if (quote == 0) quote = MYQUOTE;
X		numtry = 0;
X		retry--;
X		n = (n+1)%64;
X		return('F');
X    case 'E':	return('E');
X    case FALSE:	if (timeout == USERABORT) state = 'A';
X		return(state);
X    default:	return('A');
X    }
X}
X
Xchar sfile()
X{
X    int num, len;
X
X    retry++;
X    if (numtry++ > MAXTRY) return('A');
X
X    spack('F',n,strlen(filnam),filnam);
X    switch(rpack(&len,&num,ackpkt)) {
X    case 'N':
X	num = (--num<0 ? 63:num);
X	if (n != num) return(state);
X    case 'Y':
X	if (n != num) return(state);
X	numtry = 0;
X	retry--;
X	n = (n+1)%64;
X	first = 1;
X	size = getpkt();
X	return('D');
X    case 'E':
X	return('E');
X    case FALSE:	if (timeout == USERABORT) state = 'A';
X		   return(state);
X    default:
X	return('A');
X    }
X}
X
Xchar sdata()
X{
X    int num, len;
X
X    retry++;
X    if (numtry++ > MAXTRY) return('A');
X
X    spack('D',n,size,msgpkt);
X    switch(rpack(&len,&num,ackpkt)) {
X    case 'N':
X	num = (--num<0 ? 63:num);
X	if (n != num) return(state);
X    case 'Y':
X	if (n != num) return(state);
X	numtry = 0;
X	retry--;
X	n = (n+1)%64;
X	if ((size = getpkt()) == 0) return('Z');
X	return('D');
X    case 'E':
X	return('E');
X    case FALSE: if (timeout == USERABORT) state = 'A';
X		   return(state);
X    default:
X	return('A');
X    }
X}
X
Xchar seof()
X{
X    int num, len;
X    retry++;
X    if (numtry++ > MAXTRY) return('A');
X
X/*   if (timeout == USERABORT) {*/	/* tell host to discard file */
X/*	timeout = GOODREAD;	*/
X/*	  spack('Z',n,1,"D");	*/
X/*	  }			*/
X/*   else			*/
X	spack('Z',n,sendabort,msgpkt);
X    switch(rpack(&len,&num,ackpkt)) {
X    case 'N':
X	num = (--num<0 ? 63:num);
X	if (n != num) return(state);
X    case 'Y':
X	if (n != num) return(state);
X	numtry = 0;
X	dostats('Z',"DONE");
X	retry--;
X	n = (n+1)%64;
X	return('B');
X    case 'E':	return('E');
X    case FALSE:	return(state);
X    default:	return('A');
X    }
X}
X
Xchar sbreak()
X{
X    int num, len;
X    retry++;
X    if (numtry++ > MAXTRY) return('A');
X
X    spack('B',n,0,msgpkt);
X    switch (rpack(&len,&num,ackpkt)) {
X    case 'N':
X	num = (--num<0 ? 63:num);
X	if (n != num) return(state);
X    case 'Y':
X	if (n != num) return(state);
X	dostats('B', "DONE");
X	numtry = 0;
X	retry--;
X	n = (n+1)%64;
X	return('C');
X    case 'E':	return('E');
X    case FALSE:	return(state);
X    default:	return ('A');
X    }
X}
X
X/* timeout equals USERABORT so lets end the file and quit  */
X/* when host receives 'Z' packet with "D" in data field he */
X/* should discard the file.				   */
X/*
Xsabort()
X{
X    dostats(' ',"ABORT");
X    n = (n+1)%64;
X    retry--;
X    state = 'Z';
X    while (state == 'Z') state = seof();
X    while (state == 'B') state = sbreak();
X    return(FALSE);
X}
X*/
X
X
Xrecsw()
X{
X    char rinit(), rfile(), rdata();
X    int first_time = 1;
X
X    state = 'R';
X
X    while(TRUE) {
X	switch(state) {
X	case 'R':	ulp = 0;	/* Assume we won't use LONG packets */
X			state = rinit();
X			break;
X	case 'Z':
X	case 'F':	state = rfile(first_time); first_time = 0;
X			break;
X	case 'D':	state = rdata();
X			break;
X	case 'C':	return(TRUE);
X	case 'E':
X	case 'A':   /* easy way to cleanly abort
X			should really send and ACK
X			with "X" in data field and
X			wait for host to abort but
X			not all kermits support
X			this feature.		*/
X			if (timeout == USERABORT){
X			    /* send an error packet back   */
X			    dostats('A',"ABORT");
X			    spack('E',n,12,"User aborted");
X		        }
X		        else if (timeout == TIMEOUT) {
X			    /* we timed out waiting */
X			    /* will we need to spack here ?*/
X			    dostats('A',"TMOUT");
X			}
X			/* must be 'E' from host or we detected a protocol 
X			** error */
X			else dostats('A',"ERROR");
X
X			if (state == 'E') print_host_err(msgpkt);
X			else if (timeout == GOODREAD) /* tell host why */
X			    print_our_err();
X			    /* will this kill all files ?*/
X			do  {
X			    ttime = 2;
X			    readchar();
X			}  while (timeout == GOODREAD);
X			fclose(fp);
X			sendstring("\r");
X			return(FALSE);
X	default:	return(FALSE);
X	}
X    }
X}
X
Xchar rinit()
X{
X    int len, num, temp;
X    retry++;
X    if (numtry++ > MAXTRY) return('A');
X
X    if (server) spack('R',n,strlen(filnam),filnam);
X    else  spack('N',n,0,"");
X    switch(rpack(&len,&num,msgpkt)) {
X    case 'S':
X	rpar(msgpkt, len);
X	/*   Rpar() will set ulp if we can use long packets.  We can't use
X	** that value right away cause we've gotta ACK with normal pkts. */
X	temp = ulp; ulp = 0;
X	spar(msgpkt);
X	spack('Y',n,13,msgpkt);
X	ulp = temp;	/* Restore using long pkts flag */
X	oldtry = numtry;
X	numtry = 0;
X	retry--;
X	n = (n+1)%64;
X	return('F');
X    case 'E':
X	return('E');
X    case 'N':		/* Other side NAKed us... */
X	return(state); /* ...so try again	  */
X    case FALSE:
X	if (timeout == USERABORT) return('A');
X	if (timeout == TIMEOUT)   return(state); /* Resend Rec-init on a timeout */
X	spack('N',n,0,"");
X	return(state);
X    default:
X	return('A');
X    }
X}
X
Xchar rfile(first_time)
Xint first_time;
X{
X    int num, len, temp;
X    USHORT a, a7, b8;
X    char *fileptr, *buf;
X
X    retry++;
X    if (numtry++ > MAXTRY) return('A');
X
X    switch(rpack(&len,&num,msgpkt)) {
X    case 'S':
X	if (oldtry++ > MAXTRY) return('A');
X	if (num == ((n==0) ? 63:n-1)) {
X	    /*   Rpar() will set ulp if we can use long packets.  We can't use
X	    ** that value right away cause we've gotta ACK with normal pkts. */
X	    temp = ulp; ulp = 0;
X	    spar(msgpkt);
X	    spack('Y',num,13,msgpkt);
X	    ulp = temp;
X	    numtry = 0;
X	    return(state);
X	}
X	else return('A');
X    case 'Z':
X	if (oldtry++ > MAXTRY) return('A');
X	if (num == ((n==0) ? 63:n-1)) {
X	    spack('Y',num,0,"");
X	    ScrollInfoMsg(1);
X	    numtry = 0;
X	    return(state);
X	}
X	else return('A');
X    case 'F':
X	if (num != n) return('A');
X	if(!first_time) {	/* Scroll the Z packet line up */
X	    dostats('Z', "DONE");
X	    ScrollInfoMsg(1);
X	}
X	buf = msgpkt;
X	fileptr = filnam;
X	while ((a = *buf++) != '\0') { /* Terminator added by rpack() */
X	    if (rptflg) {
X		if (a == rptq) {
X		    rpt = unchar(*buf++);
X		    a = *buf++;
X		}
X	    }
X	    b8 = 0;
X	    if (ebqflg) {		/* 8th-bit prefixing? */
X		if (a == ebq) {		/* Yes, got an 8th-bit prefix? */
X		    b8 = 0200;		/* Yes, remember this, */
X		    a = *buf++;		/* and get the prefixed character. */
X		}
X	    }
X	    if (a == quote) {
X		a  = *buf++;
X		a7 = a & 0177;
X		if ((a7 >= 0100 && a7 <= 0137) || a7 == '?') a = ctl(a);
X	    }
X	    a |= b8;
X	    if (rpt == 0) rpt = 1;
X	    if (p_mode == 1 && a == '\r') continue;
X	    for (; rpt > 0; rpt--) *fileptr++ = a;
X	    *fileptr = '\0';	/* Terminate the filename */
X	}
X
X	if (p_convert) {
X	    char *p;
X	    p = &filnam[0];
X	    while (*p) { *p = tolower(*p); p++; }
X	}
X	if (notfirst) {
X	    totbytes = 0L;
X	    dostats('F',"RECV");
X	}
X	else {	/* is the first file so emit actual file name from host */
X	    notfirst++;
X	}
X	if ((fp = fopen(filnam,"w")) == NULL) {
X	    InfoMsg2Line("KERMIT: Unable to create file:", filnam);
X	    strcpy(msgpkt,"VT100 - Kermit - cannot create file: ");
X	    strcat(msgpkt,filnam);
X	    spack('E',n,strlen(msgpkt),msgpkt); /* let host know */
X	    dostats('E',"ERROR");
X	    return ('\0');	 /* abort everything */
X	}
X	spack('Y',n,0,"");
X	oldtry = numtry;
X	numtry = 0;
X	retry--;
X	n = (n+1)%64;
X	return('D');
X
X    /* totaly done server sending no more */
X    case 'B':
X	if (num != n) return ('A');
X	spack('Y',n,0,"");
X	dostats('B', "DONE");
X	ScrollInfoMsg(1);
X	retry--;
X	return('C');
X    case 'E':
X	return('E');
X    case FALSE:
X	if (timeout == USERABORT) return('A');
X	spack('N',n,0,"");
X	return(state);
X    default:
X	return ('A');
X    }
X}
X
Xchar rdata()
X{
X    int num, len;
X    retry++;
X    if (numtry++ > MAXTRY) return('A');
X
X    switch(rpack(&len,&num,msgpkt)) {
X    case 'D':
X	if (num != n) {
X	    if (oldtry++ > MAXTRY) return('A');
X	    if (num == ((n==0) ? 63:n-1)) {
X	       spack('Y',num,6,msgpkt);
X	       numtry = 0;
X	       return(state);
X	    }
X	    else return('A');
X	}
X	decode();
X	spack('Y',n,0,"");
X	oldtry = numtry;
X	numtry = 0;
X	retry--;
X	n = (n+1)%64;
X	return('D');
X    case 'Z':
X	if (num != n) return('A');
X	spack('Y',n,0,"");
X	n = (n+1)%64;
X	dostats('Z',"DONE");
X	retry--;
X	fclose(fp);
X	return('Z');
X    case 'F':
X	if (oldtry++ > MAXTRY) return('A');
X	if (num == ((n==0) ? 63:n-1)) {
X	    spack('Y',num,0,"");
X	    numtry = 0;
X	    return(state);
X	}
X    case 'E':
X	return('E');
X    case FALSE:
X	if (timeout == USERABORT) return('A');
X	spack('N',n,0,"");
X	return(state);
X    default:
X	return('A');
X    }
X}
X
X
Xspack(type,num,len,data)
Xchar type, *data;
Xint num, len;
X{
X    int i;
X    char chksum, t;
X    register char *bufp;
X
X    if(sending && (lastpkt != num)) {
X	tp++;
X	lastpkt = num;
X    }
X    dostats(type,mainmode);
X    bufp = spackbuf;
X    ClearBuffer();
X
X    for (i=1; i<=pad; i++) sendchar(padchar);
X
X    *bufp++ = SOH;
X    if(ulp && len > (MAXPACKSIZ-3))	/* Using long packets */
X	t = tochar(0);
X    else
X	t = tochar(len+3);
X    *bufp++ = t; chksum  = t;
X    t = tochar(num);
X    *bufp++ = t; chksum += t;
X    *bufp++ = type; chksum += type;
X    if(ulp && len > (MAXPACKSIZ-3)) {	/* Using long packets */
X	unsigned int pl = len + 1;
X
X	t = tochar(pl / 95);
X	*bufp++ = t; chksum += t;
X	t = tochar(pl % 95);
X	*bufp++ = t; chksum += t;
X	t = tochar((((chksum&0300) >> 6)+chksum)&077);
X	*bufp++ = t; chksum += t;
X    }
X    for (i=0; i<len; i++) {
X	*bufp++ = data[i]; chksum += data[i];
X    }
X    chksum = (((chksum&0300) >> 6)+chksum)&077;
X    *bufp++ = tochar(chksum);
X    if (eol)
X	*bufp++ = eol; /* Use sender's requested end-of-line */
X    if (eol != '\r')
X	*bufp++ = '\r';
X    *bufp++ = '\n';
X    *bufp   = '\0';
X    sendstring(spackbuf);
X}
X
Xrpack(len,num,data)
Xint *len, *num;
Xchar *data;
X{
X    int i, done;
X    char type, cchksum, rchksum;
X    char t = '\0';
X
X    do {
X	t = readchar();
X	if (timeout != GOODREAD) return(FALSE);
X    } while (t != SOH);
X
X    done = FALSE;
X    while (!done) {
X	t = readchar();
X	if (timeout != GOODREAD) return(FALSE);
X	if (t == SOH) continue;
X	cchksum = t;
X	*len = unchar(t)-3;
X	t = readchar();
X	if (timeout != GOODREAD) return(FALSE);
X	if (t == SOH) continue;
X	cchksum += t;
X	*num = unchar(t);
X	t = readchar();
X	if (timeout != GOODREAD) return(FALSE);
X	if (t == SOH) continue;
X	cchksum += t;
X	type = t;
X	if((*len == -3) && ulp) {	/* Using long packets */
X	    t = readchar();
X	    if (timeout != GOODREAD) return(FALSE);
X	    if (t == SOH) continue;
X	    cchksum += t;
X	    *len = unchar(t)*95;
X	    t = readchar();
X	    if (timeout != GOODREAD) return(FALSE);
X	    if (t == SOH) continue;
X	    cchksum += t;
X	    *len += unchar(t);
X	    (*len)--;
X	    t = readchar();
X	    if (timeout != GOODREAD) return(FALSE);
X	    if (t == SOH) continue;
X	    if(unchar(t) != ((((cchksum&0300) >> 6)+cchksum)&077)) return(FALSE);;
X	    cchksum += t;
X	}
X	for (i=0; i<*len; i++) {
X	    t = readchar();
X	    if (timeout != GOODREAD) return(FALSE);
X	    if (t == SOH) continue;
X	    cchksum = cchksum + t;
X	    data[i] = t;
X	}
X	data[*len] = 0;
X	t = readchar();
X	if (timeout != GOODREAD) return(FALSE);
X	rchksum = unchar(t);
X	t = readchar();
X	if (timeout != GOODREAD) return(FALSE);
X	if (t == SOH) continue;
X	done = TRUE;
X    }
X    if(type != 'B' && type != 'Z')
X	dostats(type,mainmode);
X    cchksum = (((cchksum&0300) >> 6)+cchksum)&077;
X    if (cchksum != rchksum) return(FALSE);
X    if(!sending && (*num != lastpkt)) {
X	tp++;
X	lastpkt = *num;
X    }
X    return((int)type);
X}
X
Xgetpkt() {
X    int i,eof;
X
X    static char leftover[10] = { '\0', '\0', '\0', '\0', '\0',
X				'\0', '\0', '\0', '\0', '\0' };
X
X    if (first == 1) {
X	first = 0;
X	*leftover = '\0';
X	t = getc(fp);
X	if (t == EOF) {
X	    first = 1;
X	    return(size = 0);
X	}
X	totbytes++;
X    }
X    else if (first == -1) {
X	first = 1;
X	return(size = 0);
X    }
X    for (size = 0; (msgpkt[size] = leftover[size]) != '\0'; size++) ;
X    *leftover = '\0';
X    rpt = 0;
X    eof = 0;
X    while (!eof) {
X	next = getc(fp);
X	if (next == EOF) {
X	    first = -1;
X	    eof   =  1;
X	}
X	else totbytes++;
X	osize = size;
X	encode(t);
X	t = next;
X	if (size == spsiz-3) return(size);
X	if (size > spsiz-3) {
X	    for (i = 0; (leftover[i] = msgpkt[osize+i]) != '\0'; i++)
X		;
X	    size = osize;
X	    msgpkt[size] = '\0';
X	    return(size);
X	}
X    }
X    return(size);
X}
X
Xvoid encode(a)
Xchar a;
X{
X    int a7,b8;
X
X    if (p_mode == 1 && a == '\n') {
X	rpt = 0;
X	msgpkt[size++] = quote;
X	msgpkt[size++] = ctl('\r');
X	if (size <= spsiz-3) osize = size;
X	msgpkt[size++] = quote;
X	msgpkt[size++] = ctl('\n');
X	msgpkt[size]   = '\0';
X	return;
X    }
X    if (rptflg) {
X	if (a == next && (first == 0)) {
X	    if (++rpt < 94) return;
X	    else if (rpt == 94) {
X		msgpkt[size++] = rptq;
X		msgpkt[size++] = tochar(rpt);
X		rpt = 0;
X	    }
X	}
X	else if (rpt == 1) {
X	    rpt = 0;
X	    encode(a);
X	    if (size <= spsiz-3) osize = size;
X	    rpt = 0;
X	    encode(a);
X	    return;
X	}
X	else if (rpt > 1) {
X	    msgpkt[size++] = rptq;
X	    msgpkt[size++] = tochar(++rpt);
X	    rpt = 0;
X	}
X    }
X    a7 = a & 0177;
X    b8 = a & 0200;
X
X    if (ebqflg && b8) {			/* Do 8th bit prefix if necessary. */
X	msgpkt[size++] = ebq;
X	a = a7;
X    }
X
X    if ((a7 < SP) || (a7==DEL)) {
X	msgpkt[size++] = quote;
X	a = ctl(a);
X    }
X    if (a7 == quote) msgpkt[size++] = quote;
X    if ((rptflg) && (a7 == rptq)) msgpkt[size++] = quote;
X
X    if ((ebqflg) && (a7 == ebq)) /* Prefix the 8th bit prefix */
X	msgpkt[size++] = quote;	/* if doing 8th-bit prefixes */
X
X    msgpkt[size++] = a;
X    msgpkt[size] = '\0';
X}
X
Xvoid decode()
X{
X    USHORT  a, a7, b8;
X    char *buf;
X
X    buf = msgpkt;
X    rpt = 0;
X
X    while ((a = *buf++) != '\0') { /* Terminator added by rpack() */
X	if (rptflg) {
X	    if (a == rptq) {
X		rpt = unchar(*buf++);
X		a = *buf++;
X	    }
X	}
X	b8 = 0;
X	if (ebqflg) {		     /* 8th-bit prefixing? */
X	    if (a == ebq) {	     /* Yes, got an 8th-bit prefix? */
X		b8 = 0200;	     /* Yes, remember this, */
X		a = *buf++;	     /* and get the prefixed character. */
X	    }
X        }
X	if (a == quote) {
X	    a  = *buf++;
X	    a7 = a & 0177;
X	    if ((a7 >= 0100 && a7 <= 0137) || a7 == '?') a = ctl(a);
X	}
X	a |= b8;
X	if (rpt == 0) rpt = 1;
X	if (p_mode == 1 && a == '\r') continue;
X	totbytes += rpt;
X	for (; rpt > 0; rpt--) putc(a, fp);
X    }
X    return;
X}
X
Xvoid spar(data)
Xchar data[];
X{
X    data[0] = tochar(MAXPACKSIZ);
X    data[1] = tochar(TTIME_KERMIT);
X    data[2] = tochar(MYPAD);
X    data[3] = ctl(MYPCHAR);
X    data[4] = tochar(MYEOL);
X    data[5] = MYQUOTE;
X    if ((p_parity > 0) || ebqflg) {	   /* 8-bit quoting... */
X	data[6] = MYEBQ;	  /* If parity or flag on, send &. */
X	if ((ebq > 0040 && ebq < 0100) || /* If flag off, then turn it on  */
X	   (ebq > 0140 && ebq < 0177) || /* if other side has asked us to */
X	   (ebq == 'Y')) 
X	    ebqflg = 1;
X    }
X    else				    /* Normally, */
X	data[6] = 'Y';			    /* just say we're willing. */
X    data[7] = '1';
X    data[8] = MYRPTQ;
X    data[9] = tochar(IDOLONG);	/* Tell 'em I do LONG packets */
X    data[10] = tochar(0);	/* Don't do windows */
X    data[11] = tochar(p_kmaxpack / 95);
X    data[12] = tochar(p_kmaxpack % 95);
X    data[13] = '\0';
X}
X
Xvoid rpar(data, len)
Xchar data[];
Xint  len;
X{
X    int ospsiz;
X
X    spsiz   = unchar(data[0]);
X    ospsiz  = spsiz;
X    ttime   = unchar(data[1]);
X    pad     = unchar(data[2]);
X    padchar = ctl(data[3]);
X    eol     = unchar(data[4]);
X    quote   = data[5];
X    rptflg  = 0;
X    ebqflg  = 0;
X    if (len >= 6 && data[6] != 0) {
X	ebq = data[6];
X	if ((ebq > 040 && ebq < 0100) ||
X	    (ebq > 0140 && ebq < 0177)) ebqflg = 1;
X	else if (((p_parity > 0) || ebqflg) && (ebq == 'Y')) {
X	    ebqflg = 1;
X	    ebq = '&';
X	}
X	else ebqflg = 0;
X    }
X    if (len >= 8 && data[8] != 0) {
X	rptq    = data[8];
X	rptflg  = ((rptq > 040 && rptq < 0100) ||
X		   (rptq > 0140 && rptq < 0177));
X    }
X    if(len >= 9 && data[9] != 0) {
X	int capas;
X	for(capas=9; data[capas] & 1; capas++) ; /* Skip over continuations */
X	if((ulp = (data[9] & IDOLONG)) == IDOLONG) {
X	    spsiz = 500; /* Default if no packet size specified */
X	    if(len >= capas+3) {
X		spsiz = unchar((data[capas+2]) * 95) + unchar(data[capas+3]);
X		if(spsiz > MAXLONGPKS)
X		    spsiz = MAXLONGPKS;
X		else if(spsiz < 10)	/* Reasonable? */
X		    spsiz = 500;
X	    }
X	}
X    }
X}
X
Xsaybye()
X{
X   int len,num;
X   if(numreqs != 0)	/* Requester's up... */
X	Delay(5L);	/* ...so wait for Intuition, just in case. */
X   spack('G',n,1,"F");  /* shut down server no more files */
X   rpack(&len,&num,ackpkt);
X}
X
Xprint_our_err()
X{
X    if (retry > MAXTRY || oldtry > MAXTRY) {
X	InfoMsg1Line("KERMIT: Too may retries for packet");
X	strcpy(msgpkt,"VT100 KERMIT: Too many retries for packet");
X    }
X    else {
X	InfoMsg1Line("KERMIT: Protocol Error");
X	strcpy(msgpkt,"VT100 KERMIT: Protocol Error");
X    }
X    spack('E',n,strlen(msgpkt),msgpkt);
X}
X
Xprint_host_err(msg)
Xchar *msg;
X{
X    InfoMsg2Line("KERMIT: Host Error:", msg);
X}
X
Xdostats(type,stat)
Xchar type,*stat;
X{
X    char *statusform = "%5s %-15.15s Pkt: %4d Retr: %2d Bytes: %6ld Type: %c",
X	 status[80];
X
X    if (type == 'Y' || type == 'N' || type == 'G') return;
X
X    sprintf(status, statusform, stat, filnam, tp, retry-1,
X	    (LONG)totbytes, type);
X    InfoMsgNoScroll(status);
X}
X
XClearBuffer()
X{
X    AbortIO(Read_Request);
X    Wait(1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit);
X    WaitIO(Read_Request);
X    Read_Request->IOSer.io_Command = CMD_CLEAR;
X    DoIO(Read_Request);
X    Read_Request->IOSer.io_Command = CMD_READ;
X    SendIO(Read_Request);
X}
________This_Is_The_END________
if test `wc -l < kermit.c` -ne 1028; then
	echo 'shar: kermit.c was damaged during transit (should have been 1028 bytes)'
fi
fi		; : end of overwriting check
exit 0

ahh@j.cc.purdue.edu (Brent L. Woods) (02/25/88)

Program Name:  vt100 (version 2.8)
Submitted By:  acs@uts.amdahl.com (Tony Sumrall)
Summary:  vt100 terminal emulator.
Poster Boy:  Brent Woods  (ahh@j.cc.purdue.edu)
Tested.  Part 3 of 4.

NOTES:  This program was tested by our Guest Moderator, Robert Tillotson.
He had a couple of problems with the program at first (a couple of Guru
errors, and we think that the vt100 task hung around instead of exiting
properly; not certain, though), but when we (Rob, Pat, and I) tested it
a few hours ago, none of us had any problems.  I dunno.  It seems to work
okay now.  Probably some fluke or other.



Brent Woods, Co-Moderator, comp.{sources,binaries}.amiga

USENET:  ...!j.cc.purdue.edu!ahh     ARPANET:  ahh@j.cc.purdue.edu
BITNET:  PODUM@PURCCVM               PHONE:  +1 (317) 743-8421
USNAIL:  320 Brown St., #406  /  West Lafayette, IN  47906

====================================cut here============================
#! /bin/sh
#
# This is a shell archive.  Save this into a file, edit it
# and delete all lines above this comment.  Then give this
# file to sh by executing the command "sh file".  The files
# will be extracted into the current directory owned by
# you with default permissions.
#
# The files contained herein are:
#
# -rw-r--r--   1 acs      other      10384 Feb  1 18:54 remote.c
# -rw-r--r--   1 acs      other      24586 Feb  1 18:55 script.c
# -rw-r--r--   1 acs      other      22122 Feb  1 18:56 vt100.c
#
echo 'x - remote.c'
if test -f remote.c; then echo 'shar: not overwriting remote.c'; else
sed 's/^X//' << '________This_Is_The_END________' > remote.c
X/****************************************************
X * vt100 emulator - remote character interpretation
X *
X *	v2.8 880117 ACS - See the README file
X *	v2.7 870227 ACS - No changes to this routine.
X *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
X *	v2.5 870214 DBW - more additions (see readme file)
X *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
X *	v2.3 861101 DBW - minor bug fixes
X *	v2.2 861012 DBW - more of the same
X *	v2.1 860915 DBW - new features (see README)
X *	     860823 DBW - Integrated and rewrote lots of code
X *	v2.0 860803 DRB - Rewrote the control sequence parser
X *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
X *	v1.0 860712 DBW	- First version released
X *
X ****************************************************/
X
X#include "vt100.h"
X
Xstatic int    p[10];
Xstatic int    numpar;
Xstatic char   escseq[40];
X
X/************************************************
X*  function to handle remote characters
X*************************************************/
Xvoid doremote(c)
Xchar c;
X    {
X    if (c == 24) { inesc = 0; inctrl = 0; return; }
X    if (c == 27 || (inesc >= 0 && c >= ' ')) { doesc(c); return; }
X    if (inctrl >= 0 && c >= ' ') { doctrl(c); return; }
X    if (c == 10 || c == 11 || c == 12) {
X	if (nlmode) doindex('E'); else doindex('D');
X	return;
X	}
X    if (c == 13) {
X	if (!nlmode) emit(c);
X	return;
X	}
X    if (c == 15) { alt = 0; return; }
X    if (c == 14) { alt = 1; return; }
X    if (a[alt] && c > 94 && c < 127) { doalt(c); return; }
X    emit(c);
X    }
X
Xvoid doesc(c)
Xchar c;
X{
X    if (inesc < 0) { inesc = 0; return; }
X    if (c == 27 || c == 24) { inesc = -1; return; }
X    if (c < ' ' || c == 127) return;	  /* Ignore control chars */
X
X    /* Collect intermediates */
X    if (c < '0') {escseq[inesc++] = c; return; }
X
X    /* by process of elimination, we have a final character.
X       Put it in the buffer, and dispatch on the first character
X       in the buffer */
X
X    escseq[inesc] = c;
X    inesc = -1;				/* No longer collecting a sequence */
X    switch (escseq[0])			/* Dispatch on the first received */
X    {
X      case '[':				/* Control sequence introducer */
X	numpar = 0;			/* No parameters yet */
X	private = 0;			/* Not a private sequence (yet?) */
X	badseq = 0;			/* Good until proven bad */
X	p[0] = p[1] = 0;		/* But default the first parameter */
X	inctrl = 0;			/* We are in a control sequence */
X	return;				/* All done for now ... */
X
X      case 'D': case 'E': case 'M':	/* Some kind of index */
X	doindex (c);			/* Do the index */
X	return;				/* Return */
X
X      case '7':				/* Save cursor position */
X	savx = x; savy = y; savmode = curmode; savalt = alt;
X	sa[0] = a[0]; sa[1] = a[1];
X	return;
X
X      case '8':				/* Restore cursor position */
X	x = savx; y = savy; alt = savalt; curmode = savmode;
X	a[0] = sa[0]; a[1] = sa[1];
X	return;
X
X      case 'c':				/* Reset */
X	top = MINY; bot = MAXY; savx = MINX; savy = MINY;
X	curmode = FS_NORMAL; p_keyapp = 0; p_curapp = 0;
X	inesc = -1;
X	a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
X	redoutil();
X	emit(12);
X	return;
X
X      case '(':				/* Change character set */
X	if (c == '0' || c == '2') a[0] = 1; else a[0] = 0;
X	return;
X
X      case ')':				/* Change the other character set */
X	if (c == '0' || c == '2') a[1] = 1; else a[1] = 0;
X	return;
X
X      case '=':				/* set keypad application mode */
X	p_keyapp = 1;
X	redoutil();
X	return;
X
X      case '>':				/* reset application mode */
X	p_keyapp = 0;
X	redoutil();
X	return;
X
X      case 'Z':
X	sendchar(27); sendstring("[?1;7c"); return;
X
X      /* If we didn't match anything, we can just return, happy in the
X	 knowledge that we've at least eaten the whole sequence */
X
X    }					/* End of switch */
X    return;
X}
X
Xvoid doctrl(c)
Xchar c;
X{
X    int	    i;
X
X    if (c == 27 || c == 24) { inctrl = -1; return; }
X    if (c < ' ' || c == 127) return;		  /* Ignore control chars */
X
X    /* First, look for some parameter characters.  If the very first
X	parameter character isn't a digit, then we have a
X	private sequence */
X
X    if (c >= '0' && c < '@')
X    {
X	/* can't have parameters after intermediates */
X	if (inctrl > 0) {badseq++ ; return; }
X	switch (c)
X	{
X	  case '0': case '1': case '2': case '3': case '4':
X	  case '5': case '6': case '7': case '8': case '9':
X	    p[numpar] = p[numpar] * 10 + (c - '0');
X	    return;
X
X	  case ';':
X	    p[++numpar] = 0;		/* Start a new parameter */
X	    return;
X
X	  case '<': case '=': case '>': case '?': /* Can only mean private */
X
X	    /* Only allowed BEFORE parameters */
X	    if (inctrl == 0) private = c;
X	    return;
X
X	/* if we come here, it's a bad sequence */
X	}
X	badseq++;			/* Flag the bad sequence */
X    }
X
X    if (c < '0')			/* Intermediate character */
X    {
X	escseq[inctrl++] = c;		/* Save the intermediate character */
X	return;
X    }
X
X    /* if we get here, we have the final character.  Put it in the
X       escape sequence buffer, then dispatch the control sequence */
X
X    numpar++;				/* Reflect the real number of parameters */
X    escseq[inctrl++] = c;		/* Store the final character */
X    escseq[inctrl] = '\000';		/* Tie off the buffer */
X    inctrl = -1;			/* End of the control sequence scan */
X
X    /* Don't know how to do most private sequences right now,
X	so just punt them */
X
X    if ((private != 0 && private != '?') || badseq != 0) return;
X    if (private == '?' && escseq[0] != 'h' &&
X	escseq[0] != 'l') return;
X
X    switch (escseq[0])			/* Dispatch on first intermediate or final */
X    {
X      case 'A': if (p[0]<=0) p[0] = 1;
X		y -= 8*p[0]; if (y<top)  y = top;  return;
X      case 'B': if (p[0]<=0) p[0] = 1;
X		y += 8*p[0]; if (y>bot)  y = bot;  return;
X      case 'C': if (p[0]<=0) p[0] = 1;
X		x += 8*p[0]; if (x>MAXX) x = MAXX; return;
X      case 'D': if (p[0]<=0) p[0] = 1;
X		x -= 8*p[0]; if (x<MINX) x = MINX; return;
X
X      case 'H': case 'f':		/* Cursor position */
X	if (p[0] <= 0) p[0] = 1;
X	if (p[1] <= 0) p[1] = 1;
X	y = (--p[0]*8)+MINY; x = (--p[1]*8)+MINX;
X	if (y > MAXY) y = MAXY;
X	if (x > MAXX) x = MAXX;
X	if (y < MINY) y = MINY;
X	if (x < MINX) x = MINX;
X	return;
X
X      case 'L':				/* ANSI insert line */
X      case 'M':				/* ANSI delete line */
X	if (p[0] <= 0) p[0] = 1;
X	ScrollRaster(mywindow->RPort,0L,
X	    (long)((escseq[0] == 'M' ? 8L : -8L) * p[0]),
X	    (long)MINX,(long)y-6,(long)(MAXX+7),(long)bot+1);
X	return;
X
X      case '@':				/* Insert characters */
X      case 'P':				/* Delete characters */
X	if (p[0] <= 0) p[0] = 1;
X	ScrollRaster(mywindow->RPort, 
X	   	(long) ((escseq[0] == 'P'? 8 : -8)) * p[0], 0L,
X		(long) x, (long) y-6,
X		(long) MAXX+7, (long) y+1);
X	return;
X
X      case 'r':				/* Set scroll region */
X	if (p[0] <= 0) p[0] = 1;
X	if (p[1] <= 0) p[1] = p_lines;
X	top = (--p[0]*8)+MINY; bot = (--p[1]*8)+MINY;
X	if (top < MINY) top = MINY;
X	if (bot > MAXY) bot = MAXY;
X	if (top > bot) { top = MINY; bot = MAXY; }
X	x = MINX; y = MINY;
X	return;
X
X      case 'm':				/* Set graphic rendition */
X	for (i=0;i<numpar;i++) {
X	    if (p[i] < 0) p[i] = 0;
X	    switch (p[i]) {
X		case 0:
X		curmode  = FS_NORMAL;
X		break;
X
X		case 1:
X		curmode |= FSF_BOLD;
X		break;
X
X		case 4:
X		curmode |= FSF_UNDERLINED;
X		break;
X
X		case 5:
X		curmode |= FSF_ITALIC;
X		break;
X
X		default:
X		curmode |= FSF_REVERSE;
X		break;
X		}
X	    }
X	return;
X
X      case 'K':				/* Erase in line */
X	doerase();
X	return;
X
X      case 'J':				/* Erase in display */
X	if (p[0] < 0) p[0] = 0;
X	SetAPen(mywindow->RPort,0L);
X	if (p[0] == 0) {
X	    if (y < MAXY) RectFill(mywindow->RPort,
X		(long)MINX,(long)(y+2),(long)(MAXX+7),(long)(MAXY+1));
X	    }
X	else if (p[0] == 1) {
X	    if (y > MINY) RectFill(mywindow->RPort,
X		(long)MINX,(long)(MINY-6),(long)(MAXX+7),(long)(y-7));
X	    }
X	else RectFill(mywindow->RPort,
X	    (long)MINX,(long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
X	SetAPen(mywindow->RPort,1L);
X	doerase(); return;
X
X      case 'h':				/* Set parameter */
X	if (private == 0 && p[0] == 20)		nlmode = 1;
X	else if (private == '?') {
X	    if      (p[0] == 7)	p_wrap   = 1;
X	    else if (p[0] == 1)	p_curapp = 1;
X	    redoutil();
X	    }
X	return;
X
X      case 'l':				/* Reset parameter */
X	if (private == 0 && p[0] == 20)		nlmode = 0;
X	else if (private == '?') {
X	    if      (p[0] == 7)	p_wrap   = 0;
X	    else if (p[0] == 1) p_curapp = 0;
X	    redoutil();
X	    }
X	return;
X
X      case 'x':
X	sendchar(27); sendstring("[3;1;8;64;64;1;0x"); return;
X
X      case 'n':
X	if (p[0] == 6) {
X	    sendchar(27);
X	    sprintf(escseq,"[%d;%dR",((y-MINY)/8)+1,((x-MINX)/8)+1);
X	    sendstring(escseq); return;
X	    }
X	sendchar(27); sendstring("[0n"); return;
X
X      case 'c':
X	sendchar(27); sendstring("[?1;7c"); return;
X    }
X
X    /* Don't know how to do this one, so punt it */
X}
X
Xvoid doindex(c)
Xchar c;
X    {
X    if (c != 'M') {
X	if (c == 'E') x = MINX;
X	if (y > bot) if (y < MAXY) y += 8;
X	if (y == bot)
X	    ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,(long)(top-6),
X		(long)(MAXX+7),(long)(bot+1));
X	if (y < bot) y += 8;
X	}
X    else {
X	if (y < top) if (y > MINY) y -= 8;
X	if (y == top)
X	    ScrollRaster(mywindow->RPort,0L,-8L,(long)MINX,(long)(top-6),
X		(long)(MAXX+7),(long)(bot+1));
X	if (y > top) y -= 8;
X	}
X    return;
X    }
X
Xdoalt(c)
Xchar c;
X    {
X    int oldx,newx;
X    inesc = -1;
X    oldx = x; emit(' '); newx = x;
X    x = oldx;
X    SetAPen(mywindow->RPort,1L);
X    switch (c) {
X	case 'a':
X	doline(0,-6,8,1);
X	break;
X
X	case 'j':
X	case 'm':
X	case 'v':   doline(4,-6,4,-2);
X	if      (c=='j')  doline(0,-2,4,-2);
X	else if (c=='m')  doline(4,-2,8,-2);
X	else              doline(0,-2,8,-2);
X	break;
X
X	case 'k':
X	case 'l':
X	case 'w': doline(4,-2,4,1);
X	if      (c=='k')  doline(0,-2,4,-2);
X	else if (c=='l')  doline(4,-2,8,-2);
X	else              doline(0,-2,8,-2);
X	break;
X
X	case 'n':
X	case 'q': doline(0,-2,8,-2);
X	if      (c=='n')  doline(4,-6,4,2);
X	break;
X
X	case 't':
X	case 'u':
X	case 'x':   doline(4,-6,4,1);
X	if      (c=='t')  doline(4,-2,8,-2);
X	else if (c=='u')  doline(0,-2,4,-2);
X	break;
X	}
X    x = newx;
X    }
X
Xdoline(x1,y1,x2,y2) {
X    RectFill(mywindow->RPort,(long)(x+x1),(long)(y+y1),
X	(long)(x+x2),(long)(y+y2));
X    }
X
Xvoid doerase()
X    {
X    if (p[0] < 0) p[0] = 0;
X    SetAPen(mywindow->RPort,0L);
X    if (p[0] == 0) RectFill(mywindow->RPort,(long)x,(long)(y-6),
X	(long)(MAXX+7),(long)(y+1));
X    else if (p[0] == 1) RectFill(mywindow->RPort,
X	(long)MINX,(long)(y-6),(long)(x+7),(long)(y+1));
X    else RectFill(mywindow->RPort,
X	(long)MINX,(long)(y-6),(long)(MAXX+7),(long)(y+1));
X    SetAPen(mywindow->RPort,1L);
X    return;
X    }
X
________This_Is_The_END________
if test `wc -l < remote.c` -ne 398; then
	echo 'shar: remote.c was damaged during transit (should have been 398 bytes)'
fi
fi		; : end of overwriting check
echo 'x - script.c'
if test -f script.c; then echo 'shar: not overwriting script.c'; else
sed 's/^X//' << '________This_Is_The_END________' > script.c
X/*************************************************************
X * vt100 terminal emulator - Script file support
X *
X *	v2.8 880117 ACS - See the README file
X *	v2.7 870825 ACS - Wait for the reply from AbortIO().
X *			  Use the *InfoMsg*() routines in window.c.  Provide
X *			  for multiple script files on command line
X *			  (companion to the changes in init.c).  Add the
X *			  ability to set shortcuts from init file.
X *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
X *	v2.5 870214 DBW - more additions (see readme file)
X *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
X *	v2.3 861101 DBW - minor bug fixes
X *	v2.2 861012 DBW - more of the same
X *	v2.1 860915 DBW - new features (see README)
X *	     860901 ACS - Added BAUD, PARITY and WORD commands & handling
X *	     860823 DBW - Integrated and rewrote lots of code
X *	     860815 Steve Drew: Initial version written of SCRIPT.C
X *	v2.0 860809 DBW - Major rewrite
X *	v1.1 860720 DBW - Switches, 80 cols, colors, bug fixes
X *	v1.0 860712 DBW - First version released
X *
X *************************************************************/
X
X#include "vt100.h"
X
X#define FONTNAMESIZE	40
X#define FONTSUFFIX	".font"
X#define MAXFONTVARLEN	34	/* 40 minus sizeof(".font") */
X
Xchar myfontname[FONTNAMESIZE];
X
Xstruct COMMAND {
X    void (*func)();
X    char *cname;
X};
X
Xstruct LABEL  {
X    struct LABEL *next;
X    char *name;
X    long pos;
X};
X
Xextern long atol();
X
Xstruct SHORT_CUTS {
X    char *cname;
X    char *pos;
X};
X    
X/*   Following variables are set up in init.c's InitDefaults.  They tell
X** us if there are any other script files listed on the command line so
X** that we can execute them when a prior script is done.  */
X
Xextern int script_files_todo;
Xextern char **script_files;
X
X/****************  globals  needed  ******************/
X
Xchar		on_string[20];	     /* string to match on for on cmd	 */
Xchar		wait_string[20];     /* string to match of for wait cmd  */
Xchar		golabel[20];	     /* label we are looking for in goto */
Xchar		on_cmd[20];	     /* command to execute when on matchs*/
Xint		onsize;		     /* size of on_string		 */
Xint		waitsize;	     /* size of wait_string		 */
Xint		onpos;		     /* position in on string for search */
Xint		waitpos;	     /* pos in wait_string for search	 */
Xint		on_match;	     /* flag set while doing on_cmd	 */
XFILE		*sf;		     /* file pointer for script file	 */
Xstruct LABEL	*lbase = NULL;	     /* will point to first label	 */
Xstruct LABEL	*labels;	     /* current label pointer		 */
X
Xvoid cmd_short();
X
X/********************** command tables *******************************/
Xstatic struct COMMAND inicmds[] = {	/* initialization commands */
X    cmd_bkg,	"bac",		/* set background color		*/
X    cmd_bold,	"bol",		/* set bold color		*/
X    cmd_buf,	"buf",		/* set buffer size		*/
X    cmd_cursor, "cur",		/* set cursor color		*/
X    cmd_depth,	"dep",		/* set screen depth		*/
X    cmd_fore,	"for",		/* set foreground color		*/
X    cmd_font,	"fon",		/* set font			*/
X    cmd_inter,	"int",		/* interlace ON/OFF		*/
X    cmd_lines,	"lin",		/* num lines			*/
X    cmd_screen, "scr",		/* Screen WB/CUST		*/
X    cmd_unit,	"unit",		/* Unit of serial.device to use */
X    cmd_volume, "vol",		/* set volume			*/
X    cmd_wb,	"wb",		/* use WB colors		*/
X    cmd_short,	"sho",		/* Set shortcuts		*/
X    cmd_null,	NULL		/* mark the end of the list	*/
X};
Xstatic struct COMMAND scrcmds[] = {	/* script only commands */
X    cmd_as,	"asc",		/* ascii send			*/
X    cmd_beep,	"bee",		/* Beep				*/
X    cmd_cap,	"cap",		/* ascii capture on/off		*/
X    cmd_cd,	"cd",		/* change directory		*/
X    cmd_delay,	"del",		/* delay amount of seconds	*/
X    cmd_goto,	"got",		/* goto label			*/
X    cmd_kb,	"kb",		/* kermit bye (for server)	*/
X    cmd_kg,	"kg",		/* kermit get file		*/
X    cmd_kr,	"kr",		/* kermit receive file		*/
X    cmd_ks,	"ks",		/* kermit send file		*/
X    cmd_on,	"on",		/* on a 'string' do a cmd	*/
X    cmd_recf,	"recf",		/* receive a file from host	*/
X    cmd_sb,	"sb",		/* Send a break			*/
X    cmd_send,	"send",		/* send string to host		*/
X    cmd_sendf,	"sendf",	/* send a file to host		*/
X    cmd_xr,	"xr",		/* xmodem receive file		*/
X    cmd_xs,	"xs",		/* xmodem send file		*/
X    cmd_wait,	"wait",		/* wait for a host string	*/
X    cmd_null,	NULL		/* mark the end of the list	*/
X};
Xstatic struct COMMAND commands[]= {	/* generally available commands */
X	    cmd_appcur, "app",		/* turn app. cursor on/off	*/
X    cmd_baud,	"bau",		/* Set Baud Rate		*/
X    cmd_bt,	"bre",		/* Set Break Time		*/
X    cmd_conv,	"con",		/* convert fn to lowercase	*/
X    cmd_echo,	"ech",		/* turn echo on or off		*/
X    cmd_exit,	"exi",		/* exit script file		*/
X    cmd_fnc,	"f",		/* define function key		*/
X    cmd_key,	"key",		/* keyscript character		*/
X    cmd_kmaxpk, "kmaxpack",	/* Kermit maximum packet size	*/
X    cmd_mode,	"mod",		/* KERMIT transfer mode		*/
X    cmd_numkey, "numkey",	/* turn numeric kpad on/off	*/
X    cmd_parity, "parity",	/* Set Parity			*/
X    cmd_swap,	"swap",		/* Swap BS and DEL		*/
X    cmd_wrap,	"wrap",		/* turn wrap on or off		*/
X    cmd_xbeep,	"xbee",		/* Beep at end of xfer		*/
X    cmd_xproto,	"xproto",	/* Xfer Protocol		*/
X    cmd_null,	NULL		/* mark the end of the list	*/
X};
X
Xchar *xprotos[] = {	/* Order *must* be same as corresponding p_xproto values */
X    "ascii", "xmodem", "xmodemcrc", "kermit" };
X
X/*   NB: The structures referenced in the structure may be found in
X** init.c */
Xextern struct filecmd {
X    char mo;	/* Mode			*/
X    char se;	/* Send			*/
X    char re;	/* Receive		*/
X    char kg;	/* Kermit Get		*/
X    char kb;	/* Kermit Bye		*/
X    char ca;	/* Capture or Capturing */
X    char nl;
X} filecmd_chars;
X
Xextern struct mode_cmd {
X    char as;	/* ascii mode		*/
X    char xm;	/* xmodem mode		*/
X    char xmc;	/* xmodem crc mode	*/
X    char ke;	/* kermit mode		*/
X    char nl;
X} modecmd_chars;
X
Xextern struct baducmd {
X    char b03;	/* 0300			*/
X    char b12;	/* 1200			*/
X    char b24;	/* 2400			*/
X    char b48;	/* 4800			*/
X    char b96;	/* 9600			*/
X    char bnl;
X} baudcmd_chars;
X
Xextern struct parcmd {
X    char no;	/* NOne			*/
X    char ma;	/* MArk			*/
X    char sp;	/* SPace		*/
X    char ev;	/* EVen			*/
X    char od;	/* ODd			*/
X    char nl;
X} parcmd_chars;
X
Xextern struct modcmd {
X    char im;	/* IMage		*/
X    char tx;	/* TeXt			*/
X    char cn;	/* CoNvert		*/
X    char nl;
X} modcmd_chars;
X
Xextern struct scrcmd {
X    char em;	/* Execute Macro	*/
X    char ab;	/* Abort Macro		*/
X    char nl;
X} scrcmd_chars;
X
Xextern struct {
X    char sb;	/* Send Break	*/
X    char hu;	/* Hang Up	*/
X    char cd;	/* Change Dir	*/
X    char cs;	/* Clear Screen	*/
X    char ec;	/* ECho		*/
X    char wr;	/* WRap		*/
X    char nk;	/* Num Key	*/
X    char ac;	/* App Cur	*/
X    char bs;	/* BS<->DEL	*/
X    char xb;	/* Beep at end of Xfer	*/
X    char nl;
X} utilcmd_chars;
X
Xstatic struct SHORT_CUTS shortkeys[] = {	/* Short-cut keys */
X	/* File items: */
X    "se", &(filecmd_chars.se),		/* Send file			*/
X    "re", &(filecmd_chars.re),		/* Receive file			*/
X    "kb", &(filecmd_chars.kb),		/* kermit bye (for server)	*/
X    "kg", &(filecmd_chars.kg),		/* kermit get (for server)	*/
X    "cap", &(filecmd_chars.ca),		/* Capture			*/
X	/* Mode items:	*/
X    "asc", &(modecmd_chars.as),		/* ascii mode			*/
X    "xm", &(modecmd_chars.xm),		/* xmodem mode			*/
X    "ke", &(modecmd_chars.ke),		/* kermit mode			*/
X    "xmc", &(modecmd_chars.xmc),	/* xmodemcrc mode		*/
X	/* Comm items:	*/
X    "300", &(baudcmd_chars.b03),	/* Set Baud Rate		*/
X    "1200", &(baudcmd_chars.b12),	/* Set Baud Rate		*/
X    "2400", &(baudcmd_chars.b24),	/* Set Baud Rate		*/
X    "4800", &(baudcmd_chars.b48),	/* Set Baud Rate		*/
X    "9600", &(baudcmd_chars.b96),	/* Set Baud Rate		*/
X    "none", &(parcmd_chars.no),		/* Set Parity			*/
X    "mark", &(parcmd_chars.ma),		/* Set Parity			*/
X    "space", &(parcmd_chars.sp),	/* Set Parity			*/
X    "even", &(parcmd_chars.ev),		/* Set Parity			*/
X    "odd", &(parcmd_chars.od),		/* Set Parity			*/
X    "image", &(modcmd_chars.im),	/* KERMIT transfer mode		*/
X    "text", &(modcmd_chars.tx),		/* KERMIT transfer mode		*/
X    "convert", &(modcmd_chars.cn),	/* KERMIT transfer mode		*/
X	/* Script items:	*/
X    "execute", &(scrcmd_chars.em),	/* execute macro		*/
X    "abort", &(scrcmd_chars.ab),	/* abort macro			*/
X	/* Util items: */
X    "sb", &(utilcmd_chars.sb),		/* send break			*/
X    "hang", &(utilcmd_chars.hu),	/* hang up			*/
X    "cd", &(utilcmd_chars.cd),		/* change directory		*/
X    "clear", &(utilcmd_chars.cs),	/* clear screen			*/
X    "ech", &(utilcmd_chars.ec),		/* turn echo on or off		*/
X    "wrap", &(utilcmd_chars.wr),	/* turn wrap on or off		*/
X    "numkey", &(utilcmd_chars.nk),	/* turn numeric kpad on/off	*/
X    "app", &(utilcmd_chars.ac),		/* turn app. cursor on/off	*/
X    "con", &(utilcmd_chars.bs),		/* convert bs to del		*/
X    "swap", &(utilcmd_chars.bs),	/* Swap BS and DEL		*/
X    "xbeep", &(utilcmd_chars.xb),	/* Beep at end of xfer		*/
X    NULL, NULL
X};
X
X/********************************************************************/
X/* checks char to see if match with on string or wait_string	    */
X/* if on string match oncmd gets executed imediately,		    */
X/* if wait_string match script_wait is set.			    */
X/********************************************************************/
X
Xchk_script(c)
Xchar c;
X{
X    if (on_string[0] != '\0') {
X	if (on_string[onpos] == c) {
X	    onpos++;
X	    if (onpos == onsize) {
X		on_match = TRUE;
X		do_script_cmd(ONCOMMAND);
X		on_match = FALSE;
X		return(0);
X	    }
X	}
X	else onpos = 0;
X    }
X    if (wait_string[0] != '\0') {
X       if (wait_string[waitpos] != c) {
X	    waitpos = 0;
X	    return(0);
X	}
X	waitpos++;
X	if (waitpos != waitsize) return(0);
X	wait_string[0] = '\0';
X	script_wait = FALSE;
X    }
X}
X
Xscript_start(file)
Xchar *file;
X{
X    char *sfile = NULL;
X
X    if (strlen(file) == 0 || *file == '#') return(0);
X    if ((sf = fopen(file, "r")) == NULL) {
X	    sfile = AllocMem((LONG)(strlen(file)+3), MEMF_PUBLIC|MEMF_CLEAR);
X	    strcpy(sfile, "S:");
X	    strcat(sfile, file);
X	    if((sf = fopen(sfile, "r")) == NULL) {
X		InfoMsg2Line("Can't open script file",file);
X		return(0);
X	    }
X    }
X    script_on = TRUE;
X    script_wait = FALSE;
X    wait_string[0] = '\0';
X    on_string[0] = '\0';
X    on_match = FALSE;
X    lbase = NULL;
X    if(sfile)
X	FreeMem(sfile, (LONG)strlen(file)+3);
X}
X
X/* return pointer to next word. set l to size of the word */
X
Xchar *next_wrd(s,l)
Xchar *s;
Xint *l;
X{
X    char *p;
X
X    while(*s && (*s == ' ' || *s == '\t')) s++;
X    p = s;
X    while(*s && (*s != ' ' && *s != '\t')) s++;
X    *l = s-p;
X    return(p);
X}
X
Xexe_cmd(p,l)
Xchar *p;
Xint l;
X{
X    int i,l2;
X
X    /* downcase the command */
X    for (i=0; i<l; i++) p[i] |= ' ';
X
X    /* now search for it (first in the init command list) */
X    if (doing_init)
X	for (i=0; inicmds[i].func != cmd_null; ++i) {
X	    l2 = strlen(inicmds[i].cname);
X	    if (l >= l2 && strncmp(p, inicmds[i].cname, l2) == 0) {
X		(*inicmds[i].func)(next_wrd(p+l, &l));
X		return(TRUE);
X	    }
X	}
X
X    /* or the script command list */
X    else
X	for (i=0; scrcmds[i].func != cmd_null; ++i) {
X	    l2 = strlen(scrcmds[i].cname);
X	    if (l >= l2 && strncmp(p, scrcmds[i].cname, l2) == 0) {
X		(*scrcmds[i].func)(next_wrd(p+l, &l));
X		return(TRUE);
X	    }
X	}
X
X    /* now search for it (in the standard command list) */
X    for (i=0; commands[i].func != cmd_null; ++i) {
X	l2 = strlen(commands[i].cname);
X	if (l >= l2 && strncmp(p, commands[i].cname, l2) == 0) {
X	    (*commands[i].func)(next_wrd(p+l, &l));
X	    return(TRUE);
X	}
X    }
X    if (doing_init) {
X	puts("Init: unknown command:");
X	puts(p);
X    }
X    else InfoMsg2Line("Script - unknown command:",p);
X
X    return(FALSE);
X}
X
Xstruct LABEL *find_label(lname)
Xchar *lname;
X{
X    struct LABEL *label;
X
X    label = lbase;
X    while(label != NULL) {
X	if (strcmp(label->name, lname) == 0) return (label);
X	label = label->next;
X    }
X    return(NULL);
X}
X
Xdo_script_cmd(stat)
Xint stat;
X{
X    int len,l;
X    char line[256];
X    char *p;
X
X    /* if ON command is matched and we were	*/
X    /* doing a DELAY then abort the delay timer,*/
X    /* except if on_cmd was just a SEND.	*/
X    if (stat == ONCOMMAND) {
X	strcpy(line,on_cmd);
X	p = next_wrd(line,&l);
X	if (*p != 's' && script_wait == WAIT_TIMER)  {
X	    if(!CheckIO(&Script_Timer))
X		AbortIO((char *) &Script_Timer);
X	    Wait (1L << Script_Timer_Port->mp_SigBit);
X	    WaitIO(&Script_Timer);
X
X	    /* script will proceed after on command    */
X	    script_wait = FALSE;
X	}
X	exe_cmd(p,l);
X	return(0);
X    }
X    script_wait = FALSE;
X    while(fgets(line,256,sf) != NULL) {
X       len = strlen(line);
X       line[--len] = '\0';
X       p = next_wrd(&line[0], &l);
X       if (*(p + l - 1) == ':') {		/* its a label */
X	   *(p + l - 1) = '\0';
X	   if (find_label(p) == NULL) {		/* it's a new label */
X		if (lbase == NULL)  {		/* it's the first label */
X		    labels = lbase = (struct LABEL *)
X			malloc(sizeof (struct LABEL));
X		}
X		else {
X		    labels->next = (struct LABEL *)
X			malloc(sizeof (struct LABEL));
X		    labels = labels->next;
X		}
X		labels->pos  = ftell(sf);
X		labels->name = malloc(l);
X		labels->next = NULL;
X		strcpy(labels->name, p);
X		if (stat == GOTOLABEL && strcmp(p, golabel) == 0)
X		      stat = NEXTCOMMAND;
X	    }
X	    p = next_wrd(p+l+1, &l);
X	}   /* end of it's a label */
X	if (stat == GOTOLABEL || *p == '#') continue;
X	if (*p) exe_cmd(p,l);
X	return(0);
X    }		    /* end of while */
X    if (stat == GOTOLABEL) InfoMsg2Line("Script: label not found:",golabel);
X    exit_script();
X    if(script_files_todo > 0) {
X	script_files_todo--;
X	script_start(*(script_files++));
X    }
X}
X
Xexit_script()
X{
X    if (script_wait == WAIT_TIMER) {	/* timer not done yet */
X	if(!CheckIO(&Script_Timer))
X	    AbortIO((char *) &Script_Timer); /* so abort it */
X	Wait (1L << Script_Timer_Port->mp_SigBit); /* Wait for the sig */
X	WaitIO(&Script_Timer); /* Get my reply back */
X    }
X    InfoMsg1Line("Script: terminated");
X    script_on = FALSE;
X    script_wait = TRUE;
X    fclose(sf);
X    if (reqwinup && ((reqwindow->Flags) & WINDOWACTIVE))
X	ActivateWindow(mywindow);
X}
X
X/* remove quotes terminate string & return pointer to start */
X
Xchar *tostring(ptr)
Xchar *ptr;
X{
X    char *s1,*s2;
X
X    s1 = ptr;
X    if (*ptr == '"') {
X	while(*ptr++  && *ptr != '"') ;
X	if (*ptr == '"') {
X	    *ptr = '\0';
X	    ptr = s2 = ++s1;
X	    while(*s2) {
X		if	(*s2 != '^')	 *s1++ = *s2;
X		else if (*(s2+1) == '^') *s1++ = *s2++;
X		else			 *s1++ = ((*++s2)|' ')-96;
X		s2++;
X	    }
X	    *s1 = '\0';
X	    return(ptr);
X	}
X    }
X    if (*s1 == '^') {
X	*s1 = (*(s1+1)|' ')-96;
X	*(s1+1) = '\0';
X	return(s1);
X    }
X    *(s1+1) = '\0';
X    return(s1);
X}
X
X/***************************** SCRIPT COMMANDS ********************/
X
Xvoid cmd_goto(lname)
Xchar *lname;
X{
X    struct LABEL *label;
X			    /* if on_cmd was a goto kill wait state */
X    if (on_match) { wait_string[0] = '\0'; script_wait = FALSE; }
X    if ((label = find_label(lname)) == NULL) {	/* is it forward */
X	strcpy(golabel,lname);
X	do_script_cmd(GOTOLABEL);
X    }
X    else {
X	fseek(sf,(long)(label->pos),0);
X    }
X}
X
Xvoid cmd_send(str)
Xchar *str;
X{
X    sendstring(tostring(str));
X}
X
Xvoid cmd_wait(str)
Xchar *str;
X{
X    str = tostring(str);
X    *(str+20) = '\0';	      /* 20 characters max */
X    strcpy(wait_string, str);
X    waitsize = strlen(str);
X    script_wait = WAIT_STRING;
X}
X
Xvoid cmd_on(str)
Xchar *str;
X{
X   char *p;
X
X    p = tostring(str);
X    strcpy(on_string, p);
X    onsize = strlen(p);
X    *(p+onsize+2+20) = '\0';	    /* 20 characters max */
X    strcpy(on_cmd,p+onsize+2);
X}
X
Xvoid cmd_delay(seconds)
Xchar *seconds;
X{
X    script_wait = WAIT_TIMER;
X    Script_Timer.tr_time.tv_secs = atoi(seconds);
X    Script_Timer.tr_time.tv_micro = 0;
X    SendIO((char *) &Script_Timer.tr_node);
X}
X
Xvoid cmd_exit(option)
Xchar *option;
X{
X    char *p;
X    int  l;
X
X    if (doing_init) return;
X
X    if (*option) {
X	p = next_wrd(option,&l);
X	*(p+l) = '\000';
X	if  (strcmp(p,"vt100") == 0 || strcmp(p,"VT100") == 0)
X	    cleanup("Exit vt100 from script",0);
X	exit_script();
X	script_start(p);
X    }
X    else {
X	exit_script();
X	if(script_files_todo > 0) {
X	    script_files_todo--;
X	    script_start(*(script_files++));
X	}
X    }
X}
X
Xvoid cmd_ks(file)
Xchar *file;
X{
X    char name[80], *p;
X
X    name[0] = '\0';
X    if(file == NULL || *file == '\0') {
X	req("Kermit Send:",name,1);
X	p = name;
X    }
X    else p = file;
X    multi_xfer(p, doksend, 1);
X}
X
Xvoid cmd_kr(file)
Xchar *file;
X{
X    char name[80];
X
X    name[0] = '\0';
X
X    multi_xfer(name, dokreceive, 0);
X}
X
Xvoid cmd_kg(file)
Xchar *file;
X{
X    char name[80], *p;
X
X    name[0] = 0;
X    server = TRUE;
X    if(file == NULL || *file == '\0') {
X	req("Kermit GET remote file(s):", name, 1);
X	p = name;
X    }
X    else p = file;
X    multi_xfer(p, dokreceive, 0);
X}
X
Xvoid cmd_kb()
X{
X    saybye();
X}
X
Xvoid cmd_recf(file)
Xchar *file;
X{
X    switch(p_xproto) {
X    case 0:	/* Ascii */
X	do_capture(file);
X	break;
X    case 1:	/* Xmodem */
X    case 2:	/* XmodemCRC */
X	if(p_parity > 0) {
X	    InfoMsg1Line("Parity setting prevents XMODEM receive.");
X	    break;
X	}
X	cmd_xr(file);
X	break;
X    case 3:	/* Kermit */
X    default:
X	cmd_kr(file);
X	break;
X    }
X}
X
Xvoid cmd_sendf(file)
Xchar *file;
X{
X    switch(p_xproto) {
X    case 0:	/* Ascii */
X	do_send(file);
X	break;
X    case 1:	/* Xmodem */
X    case 2:	/* XmodemCRC */
X	if(p_parity > 0) {
X	    InfoMsg1Line("Parity setting prevents XMODEM send.");
X	    break;
X	}
X	cmd_xs(file);
X	break;
X    case 3:	/* Kermit */
X    default:
X	cmd_ks(file);
X	break;
X    }
X}
X
Xvoid cmd_xs(file)
Xchar *file;
X{
X    char name[80], *p;
X
X    name[0] = '\0';
X    if(file == NULL || *file == '\0') {
X	req("Xmodem Send:",name,1);
X	p = name;
X    }
X    else p = file;
X    multi_xfer(p, XMODEM_Send_File, 1);
X}
X
Xvoid cmd_xr(file)
Xchar *file;
X{
X    char name[80], *p;
X
X    name[0] = '\0';
X    if(file == NULL || *file == '\0') {
X	req("Xmodem Receive:",name,1);
X	p = name;
X    }
X    else p = file;
X    multi_xfer(p, XMODEM_Read_File, 1);
X}
X
Xvoid cmd_cd(name)
Xchar *name;
X{
X    set_dir(name);
X}
X
Xvoid cmd_sb(str)
Xchar *str;
X{
X    sendbreak();
X}
X
Xvoid cmd_baud(rate)
Xchar *rate;
X{
X    int i = atoi(rate);
X
X    switch( i ) {
X	case  300:
X	case 1200:
X	case 2400:
X	case 4800:
X	case 9600:
X	if (doing_init) p_baud = i;
X	else		setserbaud(i, TRUE);
X	break;
X
X	default:
X	if (doing_init) {
X	    puts("Init: invalid baud rate:");
X	    puts(rate);
X	}
X	else InfoMsg2Line("Script: invalid baud rate: ",rate);
X	break;
X    }
X}
X
Xvoid cmd_parity(par)
Xchar *par;
X{
X    int i;
X
X    switch( *par|' ' ) {
X	case 'n': i =  0; break;
X	case 'm': i =  1; break;
X	case 's': i =  2; break;
X	case 'e': i =  3; break;
X	case 'o': i =  4; break;
X
X	default:
X	if (doing_init) {
X	    puts("Init: invalid parity:");
X	    puts(par);
X	}
X	else InfoMsg2Line("Script: invalid parity: ",par);
X	return;
X    }
X    p_parity = i;
X    if (doing_init == 0) redocomm();
X
X}
X
Xvoid cmd_bt(breaklength)
Xchar *breaklength;
X{
X    p_break = atol(breaklength);
X    if (doing_init) return;
X
X    AbortIO(Read_Request);
X    Wait(1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit);
X    WaitIO(Read_Request);
X    Read_Request->io_BrkTime = Write_Request->io_BrkTime = p_break;
X    setparams();
X}
X
Xvoid cmd_kmaxpk(pks)
Xchar *pks;
X{
X    int i = atoi(pks);
X
X    if(i <= MAXLONGPKS)
X	p_kmaxpack = i;
X    else {
X    	if(doing_init) {
X	    puts("Init: Kermit packet size too big:");
X	    puts(pks);
X	}
X	else InfoMsg2Line("Script: Kermit packet size too big: ",pks);
X    }
X}
X
Xvoid cmd_mode(tmode)
Xchar *tmode;
X{
X    switch (*tmode|' ') {
X	case 'i':
X	p_mode = 0;
X	break;
X
X	case 'c':
X	p_mode = 1;
X	break;
X
X	default:
X	if (doing_init) {
X	    puts("Init: invalid transfer mode:");
X	    puts(tmode);
X	}
X	else
X	    InfoMsg2Line("Script: invalid transfer mode: ",tmode);
X	return;
X    }
X    if (doing_init == 0) redocomm();
X}
X
Xvoid cmd_as(file)
Xchar *file;
X{
X    do_send(file);
X}
X
Xvoid cmd_cap(file)
Xchar *file;
X{
X    do_capture(file);
X}
X
Xvoid cmd_beep(dummy)
Xchar	*dummy;
X{
X    if (p_volume == 0) DisplayBeep(NULL);
X    else {
X	BeginIO(&Audio_Request);
X	WaitIO(&Audio_Request);
X    }
X}
X
Xvoid setvar(par,typ,var)
Xchar	*par;
Xint	typ,*var;
X{
X    int i;
X
X    switch (typ) {
X	case 0: /* ON/OFF or YES/NO */
X	case 1: /* not case */
X	if ((par[1]|' ') == 'n' || (par[0]|' ') == 'y') *var = 1-typ;
X	else						*var = typ;
X	break;
X
X	case 2: /* read hex number */
X	if (sscanf(par,"%x",&i) == 1) *var = i;
X
X	break;
X
X	case 3: /* read decimal number */
X	if (sscanf(par,"%d",&i) == 1) *var = i;
X	break;
X    }
X}
X
Xvoid cmd_echo(par)
Xchar	*par;
X{
X    setvar(par,0,&p_echo);
X    if (doing_init == 0) redoutil();
X}
X
Xvoid cmd_wrap(par)
Xchar	*par;
X{
X    setvar(par,0,&p_wrap);
X    if (doing_init == 0) redoutil();
X}
X
Xvoid cmd_xbeep(par)
Xchar	*par;
X{
X    setvar(par,0,&p_xbeep);
X    if (doing_init == 0) redoutil();
X}
X
Xvoid cmd_xproto(par)
Xchar	*par;
X{
X    int i, l = strlen(par);
X    char temp[40];
X
X    /* downcase the parameter */
X    for(i=0; i<l; i++) par[i] |= ' ';
X
X    p_xproto = MODEMAX + 1;	/* Establish a default */
X
X    for(i=0; i<MODEMAX; i++) {
X	if(strcmp(par, &(*(xprotos[i]))) == 0) {
X	    p_xproto = i;
X	    break;
X	}
X    }
X    if(p_xproto >= MODEMAX) {
X	p_xproto = MODEMAX - 1;
X	sprintf(temp, "XPROTO \"%.10s\" unknown, %s used", par, &(*(xprotos[p_xproto])));
X	if(doing_init) {
X	    puts("Init:");
X	    puts(temp);
X	}
X	else
X	    InfoMsg2Line("Script:", temp);
X    }
X    if(doing_init == 0) redofile();
X}
X
Xvoid cmd_numkey(par)
Xchar	*par;
X{
X    setvar(par,1,&p_keyapp);
X    if (doing_init == 0) redoutil();
X}
X
Xvoid cmd_appcur(par)
Xchar	*par;
X{
X    setvar(par,0,&p_curapp);
X    if (doing_init == 0) redoutil();
X}
X
Xvoid cmd_swap(par)
Xchar	*par;
X{
X    setvar(par,0,&p_bs_del);
X    if (doing_init == 0)
X	redoutil();	/* Calls InitUtilItems which does swap_bs_del() */
X    else {
X    	swap_bs_del();	/* Setup keys[] properly... */
X    	swap_bs_del();	/* ...for new mode	    */
X    }
X}
X
Xvoid cmd_bkg(par)
Xchar	*par;
X{
X    setvar(par,2,&p_background);
X}
X
Xvoid cmd_bold(par)
Xchar	*par;
X{
X    setvar(par,2,&p_bold);
X}
X
Xvoid cmd_buf(par)
Xchar	*par;
X{
X    setvar(par,3,&p_buffer);
X}
X
Xvoid cmd_cursor(par)
Xchar	*par;
X{
X    setvar(par,2,&p_cursor);
X}
X
Xvoid cmd_depth(par)
Xchar	*par;
X{
X    setvar(par,3,&p_depth);
X}
X
Xvoid cmd_fore(par)
Xchar	*par;
X{
X    setvar(par,2,&p_foreground);
X}
X
Xvoid cmd_font(par)
Xchar	*par;
X{
X    char temp[80]; 
X
X    /*  myfontname has been initialized from p_font in InitDefaults() in
X    ** init.c */
X
X    if(*par) {
X	if(strlen(par) < MAXFONTVARLEN) {
X	    strcpy(myfontname, par);
X	    strcat(myfontname,FONTSUFFIX);
X	}
X	else {
X	    puts("Init:");
X	    sprintf(temp, "Font specification too long, \"%s\" used", myfontname);
X	    puts(temp);
X	}
X    }
X    myattr.ta_Name = (STRPTR)myfontname;
X}
X
Xvoid cmd_inter(par)
Xchar	*par;
X{
X    setvar(par,0,&p_interlace);
X}
X
Xvoid cmd_lines(par)
Xchar	*par;
X{
X    setvar(par,3,&p_lines);
X}
X
Xvoid cmd_screen(par)
Xchar	*par;
X{
X    if ((par[0]|' ') == 'w') p_screen = 0;
X    else		     p_screen = 1;
X}
X
Xvoid cmd_unit(par)
Xchar	*par;
X{
X    setvar(par, 3, &p_unit);
X}
X
Xvoid cmd_wb(par)
Xchar	*par;
X{
X    setvar(par,0,&p_wbcolors);
X}
X
Xvoid cmd_short(par)	/* Set keyboard shortcuts */
Xchar	*par;
X{
X    int	i, l, l2;
X    register char *p = par;
X    
X    /* downcase the next word */
X    for (i=0; p[i] && (p[i] != ' ') && (p[i] != '\t'); i++) p[i] |= ' ';
X    l = i;
X    
X    /*   Find the command name.  If found set the shortcut key to the
X    ** user's value.  If no value then set the key to ' ' to indicate no
X    ** shortcur available. */
X    for(i = 0; shortkeys[i].cname != NULL; i++) {
X	l2 = strlen(shortkeys[i].cname);
X	if (l >= l2 && strncmp(p, shortkeys[i].cname, l2) == 0) {
X	    for( ; p[l] && ((p[l] == ' ') || (p[l] == '\t')) ; l++) ;
X	    if(p[l])
X		*(shortkeys[i].pos) = p[l];
X	    else
X		*(shortkeys[i].pos) = ' ';
X	    return;
X	}
X    }
X    if(doing_init) {
X	puts("Init: Unknown shortcut: ");
X	puts(par);
X    }
X    else
X	InfoMsg2Line("Script: Unknown shortcut:", par);
X}
X
Xvoid cmd_key(par)
Xchar	*par;
X{
X    int i;
X
X    if (sscanf(par,"%x",&i) == 1) p_keyscript = (char)(i & 0x7f);
X}
X
Xvoid cmd_volume(par)
Xchar	*par;
X{
X    setvar(par,3,&p_volume);
X}
X
Xvoid cmd_conv(par)
Xchar	*par;
X{
X    setvar(par,0,&p_convert);
X    if (doing_init == 0) redoutil();
X}
X
Xvoid cmd_fnc(par)
Xchar	*par;
X{
X    char    *s;
X    int     l;
X    int     i = atoi(par);
X
X    s = par;
X    if (*s) s = next_wrd(s,&l);		/* skip key number */
X    if (*s) s = next_wrd(s+l+1,&l);	/* point at desired string */
X    if (*s) s = tostring(s);		/* convert the string */
X    if (*s && i > 0 && i < 21) {
X	if (i > 10) {
X	    p_F[i-11] = malloc(strlen(s)+1);
X	    strcpy(p_F[i-11],s);
X	}
X	else {
X	    p_f[i-1] = malloc(strlen(s)+1);
X	    strcpy(p_f[i-1],s);
X	}
X    }
X}
X
Xvoid cmd_null(dummy)
Xchar *dummy;
X{ }
X
________This_Is_The_END________
if test `wc -l < script.c` -ne 1090; then
	echo 'shar: script.c was damaged during transit (should have been 1090 bytes)'
fi
fi		; : end of overwriting check
echo 'x - vt100.c'
if test -f vt100.c; then echo 'shar: not overwriting vt100.c'; else
sed 's/^X//' << '________This_Is_The_END________' > vt100.c
X/********************************************************************
X *  vt100 terminal emulator with xmodem transfer capability
X *
X *	v2.8 880117 ACS - See the README file
X *	v2.7 870825 ACS - Provide handling of the msgs from the
X *			  info/status window.
X *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
X *	v2.5 870214 DBW - more additions (see readme file)
X *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
X *	v2.3 861101 DBW - minor bug fixes
X *	v2.2 861012 DBW - more of the same
X *	v2.1 860915 DBW - new features (see README)
X *	     860901 ACS - Added Parity and Word Length and support code
X *	     860823 DBW - Integrated and rewrote lots of code
X *	v2.0 860809 DBW - Major rewrite
X *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
X *	v1.0 860712 DBW	- First version released
X *
X *  use <esc> to abort xmodem or kermit transfers
X *
X *  written by Michael Mounier
X *  new version by Dave Wecker
X *******************************************************************/
X
X/*  all includes defines and globals */
X#include "vt100.h"
X
XAPTR OrigWindowPtr;	/* Used by init.c when opening a new screen */
X
X/**************************************************************/
X/* here are all the global definitions that appear in vt100.h */
X/**************************************************************/
X
Xchar    bufr[BufSize];
Xint     fd, timeout = FALSE, ttime;
Xint	multi = FALSE, server;
Xlong    bytes_xferred;
Xchar	MyDir[60];
XBPTR	StartLock = 0;
Xstruct	IntuitionBase *IntuitionBase;
Xstruct	GfxBase *GfxBase;
X
Xextern char myfontname[];		/* In script.c */
X
Xstruct	TextAttr myattr = {
X    (STRPTR)(&(myfontname[0])),
X    8,
X    0,
X    0};
Xstruct	TextFont *myfont = NULL;
Xstruct NewScreen NewScreen = {
X   0,0,640,200,1,		/* left, top, width, height, depth */
X   0,1,HIRES,			/* DetailPen, BlockPen, ViewModes */
X   CUSTOMSCREEN,&myattr,	/* Type, Font */
X   (UBYTE *)"VT100",		/* Title */
X   NULL,NULL };			/* Gadgets, Bitmap */
Xstruct NewWindow NewWindow = {
X   0,0,640,200,			/* left, top, width, height */
X   0,1,				/* detailpen, blockpen */
X   MENUPICK|CLOSEWINDOW|RAWKEY|ACTIVEWINDOW|INACTIVEWINDOW,
X   SMART_REFRESH|ACTIVATE|BORDERLESS|WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG,
X   NULL,NULL,			/* FirstGadget, CheckMark */
X   (UBYTE *)NULL,
X   NULL,			/* set screen after open screen */
X   NULL,			/* bitmap */
X   640, 200, 640, 200,		/* minw, minh, maxw, maxh */
X   CUSTOMSCREEN			/* Type */
X   };
Xstruct NewWindow NewReqWindow = {
X   10, 15, ((54*8)+4+18), ((4*8)+11+2), /* left, top, width, height */
X   0, 1,			/* detailpen, blockpen */
X	/* IDCMP Flags... */
X   CLOSEWINDOW | ACTIVEWINDOW | REQCLEAR | REQSET | NEWSIZE,
X	/* Flags... */
X   SMART_REFRESH | NOCAREREFRESH | ACTIVATE | WINDOWSIZING | SIZEBRIGHT |
X   WINDOWCLOSE | WINDOWDEPTH | WINDOWDRAG,
X
X   NULL,			/* First gadget */
X   NULL,			/* CheckMark */
X   (UBYTE *)"VT100 Info & Xfer Status",	/* Title */
X   NULL,			/* set screen after open screen */
X   NULL,			/* bitmap */
X   ((5*8)+4+18), ((1*8)+11+2), 640, 200,	/* minw, minh, maxw, maxh */
X   CUSTOMSCREEN			/* Type */
X   };
Xstruct IntuiText MyTitle = {
X    0,1,JAM2,26,0,		/* front pen, back pen, mode, left, top */
X    &myattr,			/* font */
X    (UBYTE *)VERSION,		/* title */
X    NULL};			/* next text */
X
Xstruct Screen *myscreen = NULL;		/* ptr to applications screen */
Xstruct Window *mywindow = NULL;		/* ptr to applications window */
Xstruct Window *reqwindow = NULL;	/* ptr to requester's window */
Xstruct ViewPort *myviewport;
Xstruct RastPort *myrastport;
Xstruct IntuiMessage *NewMessage;	/* msg structure for GetMsg() */
Xstruct Preferences  *Prefs;		/* preferences from GetPrefs() */
X
X/**** String requester support ******/
X
Xchar	InpBuf[80],UndoBuf[80],Prompt[80];
Xstruct IntuiText donetxt = {
X    1,0,JAM2,0,0,	/* front pen, back pen, mode, left, top */
X    &myattr,		/* font */
X    (UBYTE *)"DONE",	/* question to ask */
X    NULL};		/* next text */
Xstruct Gadget mydonegad = {
X    &mystrgad,290,2,40,10,	/* next,left,top,width,height */
X    GADGHCOMP|REQGADGET,	/* flags */
X    RELVERIFY|ENDGADGET,	/* activation */
X    BOOLGADGET,			/* gadget type */
X    NULL,NULL,&donetxt,		/* gad render, sel render, gad text */
X    0L,NULL,2,NULL};		/* mutual exclude, special, ID, user data */
Xstruct	StringInfo mystrinfo = {
X    (UBYTE *)InpBuf,
X    (UBYTE *)UndoBuf,
X    0,80,0,0,0,0,	/* initial, max, disp, undo, #chrs, dsp chrs */
X    0,0,NULL,0L,NULL};	/* left,top,layer,longint,keymap */
Xstruct Gadget mystrgad = {
X    NULL,10,12,320,10,	/* next,left,top,width,height */
X    GADGHCOMP|REQGADGET,/* flags */
X    ENDGADGET,STRGADGET,/* activation, type */
X    NULL,NULL,NULL,	/* gad render, sel render, gad text */
X    0L,			/* mutual exclude */
X    (APTR)&mystrinfo,	/* special info */
X    1,NULL};		/* gadget ID, user data */
Xstruct IntuiText mystrtxt = {
X    0,1,JAM2,10,2,	/* front pen, back pen, mode, left, top */
X    &myattr,		/* font */
X    (UBYTE *)Prompt,	/* question to ask */
X    NULL};		/* next text */
Xstruct Requester myrequest = {
X    NULL,5,10,340,22,	/* older requester, left, top, width, height */
X    0,0,&mydonegad,	/* relleft reltop, gadgets */
X    NULL,		/* border */
X    &mystrtxt,		/* text */
X    NULL,1,NULL,	/* flags, back fill pen, layer */
X    {0,0,0,0,0,0,0,0,
X     0,0,0,0,0,0,0,0,
X     0,0,0,0,0,0,0,0,
X     0,0,0,0,0,0,0,0},	/* pad1 */
X    NULL,NULL,		/* image bit map, rquest window */
X    {0,0,0,0,0,0,0,0,0,
X     0,0,0,0,0,0,0,0,0,
X     0,0,0,0,0,0,0,0,0,
X     0,0,0,0,0,0,0,0,0} /* pad2 */
X    };
X
Xint numreqs = 0;		/* number of outstanding requestors */
Xint reqwinup = 0;		/* Requester window is NOT displayed */
Xextern int reqmaxx, reqmaxy, reqmaxlen;	/* Defined in window.c */
Xextern void ReqNewSize();	/* New req window size -- window.c */
Xextern void KillReq();		/* Kill requester window in window.c */	
X
X/***** menu structures *****/
Xstruct MenuItem FileItem[FILEMAX];
Xstruct IntuiText FileText[FILEMAX];
Xstruct MenuItem ModeItem[MODEMAX];
Xstruct IntuiText ModeText[MODEMAX];
Xstruct MenuItem CommItem[COMMAX];
Xstruct IntuiText CommText[COMMAX];
Xstruct MenuItem RSItem[RSMAX];
Xstruct IntuiText RSText[RSMAX];
Xstruct MenuItem ParItem[PARMAX];
Xstruct IntuiText ParText[PARMAX];
Xstruct MenuItem XFItem[XFMAX];
Xstruct IntuiText XFText[XFMAX];
Xstruct MenuItem ScriptItem[SCRIPTMAX];
Xstruct IntuiText ScriptText[SCRIPTMAX];
Xstruct MenuItem UtilItem[UTILMAX];
Xstruct IntuiText UtilText[UTILMAX];
Xstruct Menu menu[MAXMENU];
Xstruct IOExtSer *Read_Request;
Xchar *rs_in;
Xstruct IOExtSer *Write_Request;
Xchar rs_out[2];
Xstruct timerequest Timer;
Xstruct MsgPort *Timer_Port = NULL;
Xstruct timerequest Script_Timer;
Xstruct MsgPort *Script_Timer_Port = NULL;
Xstruct IOAudio Audio_Request;
Xstruct MsgPort *Audio_Port = NULL;
XUBYTE  *BeepWave;
XUBYTE  Audio_AllocMap[4] = { 1, 8, 2, 4 };
Xint x,y,curmode;
Xint MINX	= 0;
Xint MAXX	= 632;
Xint MINY	= 14;
Xint MAXY	= 198;
Xint top		= 14;
Xint bot		= 198;
Xint savx	= 0;
Xint savy	= 14;
Xint savmode	= 0;
Xint nlmode	= 0;
Xint alt		= 0;
Xint savalt	= 0;
Xint a[2]	= { 0, 0 };
Xint sa[2]	= { 0, 0 };
Xint  inesc	= -1;
Xint  inctrl	= -1;
Xint  private	= 0;
Xint  badseq	= 0;
Xint  maxcol	= 79;
X
X/*************************** defaults *******************************/
Xchar	*p_font		= "topaz";	/* Default font. Name must be < 34 chars */
Xint	p_baud		= 1200;	/* baud rate */
Xint	p_screen	= 0;	/* 0 = WORKBENCH, 1 = CUSTOM */
Xint	p_wbcolors	= 1;	/* 0 = Custom, 1 = Workbench colors */
Xint	p_interlace	= 0;	/* 0 = no interlace,    1 = interlace */
Xint	p_depth		= 2;	/* number of bit planes (1 or 2) */
Xint	p_foreground	= 0x840;	/* default foreground RGB color */
Xint	p_background	= 0x000;	/* default background RGB color */
Xint	p_bold		= 0x000;	/* default BOLD       RGB color */
Xint	p_cursor	= 0x00d;	/* default Cursor	  RGB color */
Xint	p_lines		= 24;	/* 0 == use all available (MoreRows) */
Xint	p_mode		= 0;	/* 0 = image, 1 = CRLF (for kermit) */
Xint	p_unit		= 0;	/* unit of serial.device to open */
Xint	p_xproto	= 3;	/* 0=ASCII, 1=Xmodem, 2=XmodemCRC, 3 = Kermit */
Xint	p_buffer	= 512;	/* read buffer size (>= 512 bytes) */
Xint     p_parity	= 0;	/* 0=none,1=mark,2=space,3=even,4=odd */
Xlong	p_break		= 750000;	/* break time (in micro seconds) */
Xint	p_volume	= 64;	/* beep volume (0 = DisplayBeep) */
Xint	p_wrap		= 1;	/* 0 = truncate, 1 = wrap long lines */
Xint	p_keyapp	= 0;	/* 0 = numeric, 1 = application keypad */
Xint	p_curapp	= 0;	/* 0 = cursor, 1 = application cursor */
Xint	p_echo		= 0;	/* 0 = full duplex, 1 = half duplex */
Xint	p_bs_del	= 0;	/* 0 = normal, 1 = swap bs and delete */
Xint	p_convert	= 0;	/* 1 = convert filenames to lower case */
Xint	p_kmaxpack	= 1000;	/* Max packet size for Kermit xfers */
X/*	Must be <= 1000.  <= 94 is standard, > 94 requires a kermit capable
X**	of long packet support. */
Xint	p_xbeep		= 1;	/* 1 = beep at end of xfer */
Xchar	p_keyscript	= 0x7E;	/* function key script introducer = ~ */
Xchar	*p_f[10]	= {	/* function key defaults */
X    "\033OP","\033OQ","\033OR","\033OS",
X    "f5","f6","f7","f8","f9","f10" };
X
Xchar	*p_F[10]     = {	    /* shifted function key defaults */
X    "F1","F2","F3","F4","F5",
X    "F6","F7","F8","F9","F10"};
X
X/* for script file */
Xint script_on;
Xint script_wait;
Xint doing_init = 0;
X
X/******************************************************/
X/*                   Main Program                     */
X/*                                                    */
X/*      This is the main body of the program.         */
X/******************************************************/
X
Xchar lookahead[80];
XFILE *tranr = NULL;
XFILE *trans = NULL;
Xint capture,send;
Xchar name[80];
Xstruct MsgPort *mySerPort;
X
Xmain(argc,argv)
Xint	argc;
Xchar	**argv;
X    {
X    ULONG class, waitmask;
X    unsigned int code, qual;
X    APTR iaddr;
X    int KeepGoing,i,la,dola,actual, len;
X    char c,*ptr;
X    char ascstr[100];	/* Area for string returned by toasc() */
X
X    ptr = InitDefaults(argc,argv);
X    InitDevs();
X    InitFileItems();
X    InitCommItems();
X    InitScriptItems();
X    InitUtilItems();
X    InitMenu();
X    SetMenuStrip(mywindow,&menu[0]);
X    PrintIText(mywindow->RPort,&MyTitle,0L,0L);
X
X    MyDir[0]  =	    '\000';
X    StartLock = ((struct Process *) FindTask(NULL))->pr_CurrentDir;
X    CurrentDir(DupLock(StartLock));
X    KeepGoing =	    TRUE;
X    capture   =	    FALSE;
X    send      =	    FALSE;
X    maxcol    =	    MAXX / 8;
X    la	      =	    0;
X    x	      =	    MINX ;
X    y	      =	    MINY;
X    curmode   =	    FS_NORMAL;
X    script_on =     FALSE;
X    script_wait=    TRUE;
X    SetAPen(mywindow->RPort,1L);
X    cursorflip();
X    cursorflip();
X    emit(12);
X    mySerPort = Read_Request->IOSer.io_Message.mn_ReplyPort;
X    SendIO(Read_Request);
X
X    /* see if we had a startup script */
X    if (ptr != NULL) script_start(ptr);
X
X    while( KeepGoing )
X	    {
X	    /* wait for window message or serial port message */
X	    cursorflip();
X	    if(reqwinup)
X		waitmask = (1L << mySerPort->mp_SigBit) |
X			   (1L << mywindow->UserPort->mp_SigBit) |
X			   (1L << Script_Timer_Port->mp_SigBit) |
X			   (1L << reqwindow->UserPort->mp_SigBit);
X	    else
X		waitmask = (1L << mySerPort->mp_SigBit) |
X			   (1L << mywindow->UserPort->mp_SigBit) |
X			   (1L << Script_Timer_Port->mp_SigBit);
X	    if (script_wait)	/* if script ready dont wait here */
X		Wait(waitmask);
X	    cursorflip();
X
X	    /* do ascii file send */
X	    if (send)
X		{
X		if ((c=getc(trans)) != EOF) {
X		    if (c == '\n') c = '\r';
X		    sendchar(c);
X		    }
X		else {
X		    fclose(trans);
X		    InfoMsg1Line("File Sent");
X		    send=FALSE;
X		    }
X		}
X
X	    /* see if there are any characters from the host */
X	    if (CheckIO(Read_Request)) {
X		WaitIO(Read_Request);
X		c = rs_in[0] & 0x7F;
X		doremote(c);
X		if (script_on) chk_script(c);
X		if (capture && c != 10) {
X		    if (c == 13) c = 10;
X		    putc(c , tranr);
X		    }
X		Read_Request->IOSer.io_Command = SDCMD_QUERY;
X		DoIO(Read_Request);
X		Read_Request->IOSer.io_Command = CMD_READ;
X		actual = (int)Read_Request->IOSer.io_Actual;
X		if (actual > 0) {
X		    if (inesc   <  0 &&
X			inctrl  <  0 &&
X			a[alt]  == 0 &&
X			capture == FALSE) dola = 1;
X		    else dola = 0;
X		    Read_Request->IOSer.io_Length =
X			Read_Request->IOSer.io_Actual;
X		    DoIO(Read_Request);
X		    Read_Request->IOSer.io_Length = 1;
X
X		    for (i = 0; i < actual; i++) {
X			c=rs_in[i] & 0x7f;
X			if (script_on) chk_script(c);
X
X			if (dola == 1) {
X			    if (c >= ' ' && c <= '~' && la < 80)
X				lookahead[la++] = c;
X			    else {
X				if (la > 0) {
X				    emitbatch(la,lookahead);
X				    la = 0;
X				    }
X				doremote(c);
X				dola = 0;
X				}
X			    }
X			else {
X			    doremote(c);
X			    if (inesc   <  0 &&
X				inctrl  <  0 &&
X				a[alt]  == 0 &&
X				capture == FALSE) dola = 1;
X			    if (capture && c != 10) {
X				if (c == 13) c = 10;
X				putc(c , tranr);
X				}
X			    }
X			}
X
X		    /* dump anything left in the lookahead buffer */
X		    if (la > 0) {
X			emitbatch(la,lookahead);
X			la = 0;
X			}
X		    }
X		SendIO(Read_Request);
X 		}
X
X	    while((NewMessage =
X		    (struct IntuiMessage *)GetMsg(mywindow->UserPort))
X			!= FALSE) {
X		class = NewMessage->Class;
X		code = NewMessage->Code;
X		qual = NewMessage->Qualifier;
X		if(class == RAWKEY)
X		    iaddr = *((APTR *)NewMessage->IAddress);
X		ReplyMsg( NewMessage );
X		switch( class )
X		    {
X		    case CLOSEWINDOW:
X		    KeepGoing = FALSE;
X		    break;
X
X		    case RAWKEY:
X		    len = toasc(&(ascstr[0]), code,qual, 100, iaddr, 0);
X		    if (p_echo) {
X			ptr = &(ascstr[0]);
X			for(i = 0; i < len; i++)
X			    doremote(*(ptr++));
X		    }
X		    break;
X
X		    case NEWSIZE:
X		    emit(12);
X		    break;
X
X		    case MENUPICK:
X		    handle_menupick(class,code);
X		    break;
X
X		    default:
X		    PrintIText(mywindow->RPort,&MyTitle,0L,0L);
X		    break;
X		    }   /* end of switch (class) */
X		}   /* end of while ( newmessage )*/
X
X	    if (!script_wait ||
X		 (CheckIO(&Script_Timer) &&
X		    script_wait == WAIT_TIMER))
X		do_script_cmd(NEXTCOMMAND);
X
X	    while( reqwinup &&  
X		   ((NewMessage = (struct IntuiMessage *)
X				  GetMsg(reqwindow->UserPort)) != FALSE)
X		 ) {
X		class = NewMessage->Class;
X		ReplyMsg( NewMessage );
X		switch( class ) {
X		    case REQCLEAR:
X		    numreqs = 0;
X		    break;
X
X		    case CLOSEWINDOW:
X		    KillReq(); /* Kills requester window, set reqwinup = 0 */
X		    break;
X
X		    case NEWSIZE:
X		    ReqNewSize(reqwindow->Height, reqwindow->Width);
X		    break;
X		}   /* end of switch (class) */
X	    } /* end while */
X    }  /* end while ( keepgoing ) */
X
X    /*   It must be time to quit, so we have to clean
X    *   up and exit.
X    */
X
X    cleanup("",0);
X
X} /* end of main */
X
X/* cleanup code */
X
Xcleanup(reason, fault)
Xchar *reason;
Xint fault;
X    {
X	extern struct Device *ConsoleDevice;	/* In init.c */
X	extern struct IOStdReq ConReq;		/* In init.c */
X
X    switch(fault) {
X	case 0:		/* quitting close everything */
X	KillReq();	/* Kill the requester and its window */
X	ClearMenuStrip( mywindow );
X	CloseDevice(&Audio_Request);
X	UnLock(CurrentDir(StartLock));	/* back to original directory */
X
X	case 8:		/* error opening audio */
X	DeletePort(Audio_Port);
X	FreeMem(BeepWave,BEEPSIZE);
X	CloseDevice(&Timer);
X
X	case 7:		/* error opening timer */
X	DeletePort(Timer_Port);
X	CloseDevice(&Script_Timer);
X	DeletePort(Script_Timer_Port);
X
X	case 6:		/* error opening write device */
X	DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
X	FreeMem(Write_Request,(long)sizeof(*Write_Request));
X	CloseDevice(Read_Request);
X
X	case 5:		/* error opening read device */
X	DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
X	FreeMem(Read_Request,(long)sizeof(*Read_Request));
X
X	case 4:		/* error opening window */
X	if (ConsoleDevice != NULL) CloseDevice(&ConReq);
X	if (myfont   != NULL) CloseFont( myfont );
X	if (mywindow != NULL) CloseWindow( mywindow );
X	if (p_screen != 0) {
X	    struct Process *mproc;
X
X	    mproc = (struct Process *)FindTask(0L);
X	    mproc->pr_WindowPtr = OrigWindowPtr;
X	    CloseScreen( myscreen );
X	}
X
X	case 3:		/* error opening screen */
X	case 2:		/* error opening graphics library */
X	CloseLibrary(GfxBase);
X	case 1:		/* error opening intuition */
X	CloseLibrary(IntuitionBase);
X	default:
X	if (*reason) puts (reason);
X	}
X    exit(fault);
X    }
X
Xdo_capture(file)
Xchar *file;
X    {
X    if (capture == TRUE)
X	{
X	capture=FALSE;
X	fclose(tranr);
X	InfoMsg1Line("End File Capture");
X	}
X    else
X	{
X	if (file == NULL || *file == '\0') {
X	    name[0] = '\000';
X	    req("Ascii Capture:",name,1);
X	    }
X	else strcpy(name, file);
X	if ((tranr=fopen(name,"w")) == 0) {
X	    capture=FALSE;
X	    InfoMsg2Line("Error Opening File:", name);
X	    return(FALSE);
X	    }
X	capture=TRUE;
X	}
X    redofile();
X    }
X
Xdo_send(file)
Xchar *file;
X    {
X    if (send == TRUE)
X	{
X	send=FALSE;
X	fclose(trans);
X	InfoMsg1Line("File Send Cancelled");
X	}
X    else
X	{
X	if (file == NULL || *file == '\0') {
X	    name[0] = '\000';
X	    req("Ascii Send:",name,1);
X	    }
X	else strcpy(name, file);
X	if ((trans=fopen(name,"r")) == 0) {
X	    send=FALSE;
X	    InfoMsg2Line("Error Opening File:", name);
X	    return(FALSE);
X	    }
X	send=TRUE;
X	}
X    }
X
Xvoid setparams()
X    {
X    Read_Request->IOSer.io_Command =
X	Write_Request->IOSer.io_Command =
X	    SDCMD_SETPARAMS;
X    DoIO(Read_Request); DoIO(Write_Request);
X    Read_Request->IOSer.io_Command = CMD_READ;
X    SendIO(Read_Request);
X    Write_Request->IOSer.io_Command = CMD_WRITE;
X    }
X
Xvoid hangup ()
X    {
X    if(!CheckIO(Read_Request))
X	AbortIO(Read_Request);
X    Wait (1L <<mySerPort->mp_SigBit);
X    WaitIO(Read_Request);
X    CloseDevice (Read_Request);
X    Timer.tr_time.tv_secs=0L;
X    Timer.tr_time.tv_micro=750000L;
X    DoIO((char *) &Timer.tr_node);
X    OpenDevice (SERIALNAME,(LONG)p_unit,Read_Request,NULL);
X    setparams();
X    }
X
Xvoid redocomm() {
X    ClearMenuStrip( mywindow );         /* Remove old menu */
X    InitCommItems();                    /* Re-do comm menu   */
X    SetMenuStrip(mywindow,&menu[0]);    /* Re-display the menu */
X}
Xvoid redofile() {
X    ClearMenuStrip( mywindow );         /* Remove old menu */
X    InitFileItems();                    /* Re-do file menu   */
X    SetMenuStrip(mywindow,&menu[0]);    /* Re-display the menu */
X}
X
Xvoid setserbaud(baud, redomenu)
Xint baud;
XLONG redomenu;
X    {
X    if(!CheckIO(Read_Request))
X	AbortIO(Read_Request);
X    Wait (1L <<mySerPort->mp_SigBit);
X    WaitIO(Read_Request);
X    Write_Request->io_Baud = Read_Request->io_Baud = baud;
X    setparams();
X    p_baud = baud;
X    if (redomenu) redocomm();
X    }
X
Xvoid redoutil() {
X    ClearMenuStrip(mywindow);
X    InitUtilItems();
X    SetMenuStrip(mywindow,&menu[0]);
X    }
X
Xvoid handle_menupick(class, code)
XULONG class;
Xunsigned int code;
X    {
X    unsigned int menunum, itemnum, subnum, i;
X
X    if (code == MENUNULL) return;
X
X    menunum = MENUNUM( code );
X    itemnum = ITEMNUM( code );
X    subnum  = SUBNUM( code );
X    switch( menunum ) {
X    case 0:
X	switch( itemnum ) {
X	case 0:	/* menunum case 0 itemnum case 0 -- Set xfer mode */
X	    switch( subnum ) {
X	    case 0:	/* Ascii */
X	    case 1:	/* Xmodem */
X	    case 2:	/* XmodemCRC */
X	    case 3:	/* Kermit */
X		i = subnum;
X		break;
X	    default:
X		i = MODEMAX-1;
X	    }
X	    p_xproto = i;
X	    redofile();
X	    break;
X
X	case 1:	/* menunum case 0 itemnum case 1 -- Send a file */
X	    name[0] = '\0';
X	    cmd_sendf(name);
X	    break;
X
X	case 2:	/* menunum case 0 itemnum case 2 -- Receive a file */
X	    name[0] = '\000';
X	    cmd_recf(name);
X	    break;
X
X	case 3:	/* menunum case 0 itemnum case 3 -- Kermit GET */
X	    name[0] = '\000';
X	    cmd_kg(name);
X	    break;
X
X	case 4:	/* menunum case 0 itemnum case 4 -- Kermit BYE */
X	    saybye();
X	    break;
X	case 5: /* menunum case 0 itemnum case 5 -- ASCII capture */
X	    name[0] = '\0';
X	    do_capture(name);
X	    break;
X	} /* End of itemnum switch for menunum case 0 */
X	break;
X
X    case 1:		/* menunum case 1 - Comm Setup */
X	switch( itemnum ) {
X	case 0:	/* Baud */
X	    switch( subnum ) {
X	    case 0:
X		setserbaud(300, FALSE);
X		break;
X
X	    case 1:
X		setserbaud(1200, FALSE);
X		break;
X
X	    case 2:
X		setserbaud(2400, FALSE);
X		break;
X
X	    case 3:
X		setserbaud(4800, FALSE);
X		break;
X
X	    case 4:
X		setserbaud(9600, FALSE);
X		break;
X	    } /* End of subnum switch for itemnum 0 of menunum 1 */
X	    break;
X
X	case 1:    /* menunum case 1 itemnum 1 -- Set  Parity */
X	    p_parity = subnum;
X	    break;
X
X	case 2:    /* menunum case 2 itemnum 2 -- set kermit transfer mode */
X	    if (subnum < 2) p_mode = subnum;
X	    else {
X		if (p_convert)	p_convert = 0;
X		else		p_convert = 1;
X		redocomm();
X	    }
X	    break;
X	}
X	break;	/* End of menunum case 1 */
X
X    case 2:	/* menunum case 2 - Script */
X	if (!itemnum && !script_on) {
X	    name[0] = '\000';
X	    req("Script file name:",name,1);
X	    script_start(name);
X	}
X	if (itemnum && script_on) exit_script();
X	break;
X
X    case 3:	/* menunum case 3 -- Utility */
X	switch( itemnum ) {
X	case 0:
X	    sendbreak();
X	    break;
X
X	case 1:	/* menunum case 3 itemnum case 1 -- Hang Up */
X	    hangup();
X	    break;
X
X	case 2:	/* menunum case 3 itemnum case 2 -- Cd */
X	    strcpy(name,MyDir);
X	    req("Directory:",name,1);
X	    set_dir(name);
X	    break;
X
X	case 3:	/* menunum case 3 itemnum case 3 -- Clear Screen */
X	    top = MINY; bot = MAXY; savx = MINX; savy = MINY;
X	    curmode = FS_NORMAL; inesc = -1;
X	    a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
X	    redoutil();
X	    emit(12);
X	    break;
X
X	case 4:	/* menunum case 3 itemnum case 4 -- Echo mode */
X	    if (p_echo) p_echo = 0;
X	    else	p_echo = 1;
X	    redoutil();
X	    break;
X
X	case 5:	/* menunum case 3 itemnum case 5 -- Wrap mode */
X	    if (p_wrap) p_wrap = 0;
X	    else        p_wrap = 1;
X	    redoutil();
X	    break;
X
X	case 6:	/* menunum case 3 itemnum case 6 -- NumKey */
X	    if (p_keyapp) p_keyapp = 0;
X	    else          p_keyapp = 1;
X	    redoutil();
X	    break;
X
X	case 7:	/* menunum case 3 itemnum case 7 -- App Cur */
X	    if (p_curapp) p_curapp = 0;
X	    else	  p_curapp = 1;
X	    redoutil();
X	    break;
X
X	case 8:	/* menunum case 3 itemnum case 8 -- BS <-> DEL */
X	    swap_bs_del();
X	    redoutil();
X	    break;
X
X	case 9:	/* menunum case 3 itemnum case 9 -- Xfer Beep */
X	    if(p_xbeep) p_xbeep = 0;
X	    else	p_xbeep = 1;
X	    redoutil();
X	    break;
X	}
X
X    break;
X    } /* end of switch ( menunum ) */
X}
________This_Is_The_END________
if test `wc -l < vt100.c` -ne 805; then
	echo 'shar: vt100.c was damaged during transit (should have been 805 bytes)'
fi
fi		; : end of overwriting check
exit 0

ahh@j.cc.purdue.edu (Brent L. Woods) (02/25/88)

Program Name:  vt100 (version 2.8)
Submitted By:  acs@uts.amdahl.com (Tony Sumrall)
Summary:  vt100 terminal emulator.
Poster Boy:  Brent Woods  (ahh@j.cc.purdue.edu)
Tested.  Part 4 of 4.

NOTES:  This program was tested by our Guest Moderator, Robert Tillotson.
He had a couple of problems with the program at first (a couple of Guru
errors, and we think that the vt100 task hung around instead of exiting
properly; not certain, though), but when we (Rob, Pat, and I) tested it
a few hours ago, none of us had any problems.  I dunno.  It seems to work
okay now.  Probably some fluke or other.

     Boy, I bet people are getting pretty tired of the notes about now...



Brent Woods, Co-Moderator, comp.{sources,binaries}.amiga

USENET:  ...!j.cc.purdue.edu!ahh     ARPANET:  ahh@j.cc.purdue.edu
BITNET:  PODUM@PURCCVM               PHONE:  +1 (317) 743-8421
USNAIL:  320 Brown St., #406  /  West Lafayette, IN  47906

====================================cut here============================
#! /bin/sh
#
# This is a shell archive.  Save this into a file, edit it
# and delete all lines above this comment.  Then give this
# file to sh by executing the command "sh file".  The files
# will be extracted into the current directory owned by
# you with default permissions.
#
# The files contained herein are:
#
# -rw-r--r--   1 acs      other       8096 Feb  1 18:56 vt100.h
# -rw-r--r--   1 acs      other      17303 Feb  1 18:56 window.c
# -rw-r--r--   1 acs      other      15067 Feb  1 18:56 xmodem.c
#
echo 'x - vt100.h'
if test -f vt100.h; then echo 'shar: not overwriting vt100.h'; else
sed 's/^X//' << '________This_Is_The_END________' > vt100.h
X/*********************************************************************
X *  a terminal program that has ascii and xmodem transfer capability
X *
X *	v2.8 880117 ACS - See the README file
X *	v2.7 870825 ACS - See README.
X *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
X *	v2.5 870214 DBW - more additions (see readme file)
X *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
X *	v2.3 861101 DBW - minor bug fixes
X *	v2.2 861012 DBW - more of the same
X *	v2.1 860915 DBW - new features (see README)
X *	     860823 DBW - Integrated and rewrote lots of code
X *	v2.0 860809 DBW	- Major release.. LOTS of changes
X *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
X *	v1.0 860712 DBW	- First version released
X *
X *  use esc to abort xmodem transfer
X *
X *  written by Michael Mounier
X *  new version by Dave Wecker 860621
X ********************************************************************/
X
X/********* major version (used for title of terminal window) *********/
X#define	VERSION	"VT100 (V2.8 ACS 880117) Terminal Window"
X
X/*********** ########  define the compiler type here ######## ********/
X#define	LATTICE	0
X#define MANX	1
X
X/*  compiler directives to fetch the necessary header files */
X#include <exec/types.h>
X#include <exec/exec.h>
X#include <intuition/intuition.h>
X#include <intuition/intuitionbase.h>
X#include <graphics/gfxbase.h>
X#include <graphics/gfx.h>
X#include <graphics/text.h>
X#include <graphics/regions.h>
X#include <graphics/copper.h>
X#include <graphics/gels.h>
X#include <devices/serial.h>
X#include <devices/keymap.h>
X#include <devices/inputevent.h>
X#include <devices/audio.h>
X#include <hardware/blit.h>
X
X			/* for Lattice you may have to change these with: */
X#include <stdio.h>	/* #include <lattice/stdio.h> and */
X#include <ctype.h>	/* #include <lattice/ctype.h>	 */
X
X#include <libraries/dos.h>
X#include <libraries/dosextens.h>
X#include <devices/timer.h>
X
X#if MANX
X#include <functions.h>
X#undef NULL
X#define   NULL   ((void *)0)
X#endif
X
X#define INTUITION_REV 1L
X#define GRAPHICS_REV  1L
X
X/* things for xmodem send and recieve */
X#define GOODREAD    0
X#define TIMEOUT	    1
X#define USERABORT   2
X#define SECSIZ   0x80
X#define TTIME_SHORT 5		/* number of seconds for short timeout */
X#define TTIME_LONG  50		/* number of seconds for long  timeout */
X#define TTIME_KERMIT 10		/* number of seconds for KERMIT timeout*/
X#define MAXLONGPKS 1000		/* Maximum long msgpkt size */
X#define BufSize  0x200		/* Text buffer for XMODEM */
X#define ERRORMAX 10		/* Max errors before abort */
X#define RETRYMAX 10		/* Maximum retrys before abort */
X#define SOH      1		/* Start of sector char */
X#define EOT      4		/* end of transmission char */
X#define ACK      6		/* acknowledge sector transmission */
X#define NAK      21		/* error in transmission detected */
X
X#define FILEMAX 6	/* number of file menu items */
X#define MODEMAX 4	/* number of mode menu items */
X#define COMMAX 3	/* number of communication sub menus */
X#define RSMAX 5		/* speed menu items */
X#define PARMAX 5	/* parity items */
X#define XFMAX 3		/* transfer mode items */
X#define SCRIPTMAX 2	/* script menu items */
X#define UTILMAX 10	/* utility menu */
X#define MAXMENU 4	/* total number of menu entries */
X
X#define MAXGADSTR 80	/* Max size of prompts and inputs */
X
X#define FSF_REVERSE 256	/* fake font style to flag INVERSVID mode */
X
X/* things for script support */
X
X#define GOTOLABEL   1
X#define	NEXTCOMMAND 0
X#define ONCOMMAND   2
X
X#define	WAIT_TIMER  2
X#define WAIT_STRING 1
X
X/* things for 'beep' support */
X#define BEEPSIZE    10L
X#define BEEPFREQ    1000L
X#define COLORCLOCK  3579545L
X
Xextern struct	MsgPort *CreatePort();
Xextern char	*malloc(),*strcpy(),*fgets();
Xextern long	ftell();
X
Xextern int	multi;		    /* flags multi file transfers */
Xextern int	server;
Xextern char	bufr[BufSize];
Xextern int	fd, timeout, ttime;
Xextern long	bytes_xferred;
Xextern char	MyDir[60];
Xextern BPTR	StartLock;
Xextern struct	IntuitionBase *IntuitionBase;
Xextern struct	GfxBase *GfxBase;
Xextern struct	TextAttr myattr;
Xextern struct	TextFont *myfont;
Xextern struct	NewScreen NewScreen;
Xextern struct	NewWindow NewWindow;
Xextern struct	NewWindow NewReqWindow;
Xextern struct	Screen *myscreen;
Xextern struct	Window *mywindow;
Xextern struct	Window *reqwindow;
Xextern struct	ViewPort *myviewport;
Xextern struct	RastPort *myrastport;
Xextern struct	IntuiMessage *NewMessage;
Xextern struct	Preferences  *Prefs;
Xextern char	InpBuf[80],UndoBuf[80],Prompt[80];
Xextern struct	StringInfo mystrinfo;
Xextern struct	Gadget     mystrgad;
Xextern struct	IntuiText  donetxt;
Xextern struct	Gadget	   mydonegad;
Xextern struct	IntuiText  mystrtxt;
Xextern struct	Requester  myrequest;
Xextern int	numreqs;
Xextern int	reqwinup;
Xextern struct	MenuItem FileItem[FILEMAX];
Xextern struct	IntuiText FileText[FILEMAX];
Xextern struct	MenuItem ModeItem[MODEMAX];
Xextern struct	IntuiText ModeText[MODEMAX];
Xextern struct	MenuItem CommItem[COMMAX];
Xextern struct	IntuiText CommText[COMMAX];
Xextern struct	MenuItem RSItem[RSMAX];
Xextern struct	IntuiText RSText[RSMAX];
Xextern struct	MenuItem ParItem[PARMAX];
Xextern struct	IntuiText ParText[PARMAX];
Xextern struct	MenuItem XFItem[XFMAX];
Xextern struct	IntuiText XFText[XFMAX];
Xextern struct	MenuItem ScriptItem[SCRIPTMAX];
Xextern struct	IntuiText ScriptText[SCRIPTMAX];
Xextern struct	MenuItem UtilItem[UTILMAX];
Xextern struct	IntuiText UtilText[UTILMAX];
Xextern struct	Menu menu[MAXMENU];
Xextern struct	timerequest Timer, Script_Timer;
Xextern struct	MsgPort *Timer_Port, *Script_Timer_Port;
Xextern struct	IOExtSer *Read_Request;
Xextern char	*rs_in;
Xextern struct	IOExtSer *Write_Request;
Xextern char	rs_out[2];
Xextern int	x,y,curmode;
Xextern int	MINX,MAXX,MINY,MAXY,top,bot,savx,savy;
Xextern int	savmode,nlmode,alt,savalt,a[2],sa[2];
Xextern int	inesc,inctrl,private,badseq,maxcol;
Xextern struct	IOAudio Audio_Request;
Xextern struct	MsgPort *Audio_Port;
Xextern UBYTE	*BeepWave;
Xextern UBYTE	Audio_AllocMap[4];
Xextern int	p_baud,p_screen,p_interlace,p_depth,p_buffer,p_wbcolors;
Xextern int	p_foreground,p_background,p_bold,p_cursor,p_lines,p_mode;
Xextern int	p_parity,p_volume,p_wrap,p_echo,p_keyapp,p_curapp,p_bs_del;
Xextern int	p_xbeep, p_xproto, p_convert, p_kmaxpack, p_unit;
Xextern char	p_keyscript;
Xextern long	p_break;
Xextern char	*p_font, *p_f[10],*p_F[10];
Xextern int	script_on;
Xextern int	script_wait;
Xextern int	doing_init;
X
X/* vt100.c */
Xextern int  do_send(),do_capture(),cleanup();
Xextern void setserpar(), setserbaud(), setparams(), redoutil(), redofile(),
X	    redocomm(),  handle_menupick();
X
X/* init.c */
Xextern void InitDevs(),InitFileItems(),InitCommItems(),
X	 InitScriptItems(),InitUtilItems(),InitMenu();
Xextern char *InitDefaults();
X
X/* window.c */
Xextern	void	swap_bs_del(),req(),emits(),emit(),emitbatch(),cursorflip();
Xextern	int	toasc();
Xextern void	ScrollInfoMsg(), InfoMsgNoScroll(), InfoMsg1Line(),
X		InfoMsg2Line();
X
X/* xmodem.c */
Xextern	void sendchar(),sendstring(),sendbreak(),multi_xfer(),
X	No_XON(),Do_XON();
Xextern	int  readchar(),XMODEM_Read_File(),XMODEM_Send_File();
X
X/* remote.c */
Xextern	void doremote(),doindex(),doctrl(),doesc(),doerase();
X
X/* kermit.c */
Xextern	int	doksend(), dokreceive(), saybye();
Xextern	void	encode(), decode(), rpar(), spar();
X
X/* script.c */
Xextern int	script_start(), chk_script(), exit_script(),
X		do_script_cmd();
Xextern char	*next_wrd(), *tostring();
X
X		/* init commands */
Xextern void	cmd_bkg(), cmd_bold(), cmd_buf(), cmd_cursor(), cmd_depth(),
X		cmd_fore(), cmd_font(), cmd_inter(), cmd_lines(),
X		cmd_screen(), cmd_unit(), cmd_volume(), cmd_wb(), cmd_null(),
X
X		/* script commands */
X		cmd_as(), cmd_beep(), cmd_cap(), cmd_cd(), cmd_delay(),
X		cmd_goto(), cmd_goto(), cmd_kb(), cmd_kg(), cmd_kr(),
X		cmd_ks(), cmd_on(), cmd_recf(), cmd_sb(), cmd_send(),
X		cmd_sendf(), cmd_wait(), cmd_xr(), cmd_xs(),
X
X		/* init and script commands */
X		cmd_appcur(), cmd_baud(), cmd_bt(), cmd_conv(), cmd_echo(),
X		cmd_exit(), cmd_fnc(), cmd_key(), cmd_kmode(), cmd_kmaxpk(),
X		cmd_mode(), cmd_numkey(), cmd_parity(), cmd_swap(), 
X		cmd_wrap(), cmd_xbeep(), cmd_xproto();
X
X/* expand.c */
Xextern char **expand();
Xextern int  set_dir(), free_expand();
X
________This_Is_The_END________
if test `wc -l < vt100.h` -ne 238; then
	echo 'shar: vt100.h was damaged during transit (should have been 238 bytes)'
fi
fi		; : end of overwriting check
echo 'x - window.c'
if test -f window.c; then echo 'shar: not overwriting window.c'; else
sed 's/^X//' << '________This_Is_The_END________' > window.c
X/****************************************************
X * vt100 emulator - window/keyboard support
X *
X *	v2.8 880117 ACS - See the README file
X *	v2.7 870825 ACS - Provide an info/status window rather than using
X *			  req().  Better error handling.
X *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
X *	v2.5 870214 DBW - more additions (see readme file)
X *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
X *	v2.3 861101 DBW - minor bug fixes
X *	v2.2 861012 DBW - more of the same
X *	v2.1 860915 DBW - new features (see README)
X *	     860823 DBW - Integrated and rewrote lots of code
X *	v2.0 860809 DBW - Major rewrite
X *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
X *	v1.0 860712 DBW	- First version released
X *
X ****************************************************/
X
X#include "vt100.h"
X
Xstatic char *infkey[] = {	/* F-keys resulting from RawKeyConvert() */
X    "0~",  "1~",  "2~",  "3~",  "4~",  "5~",  "6~",  "7~",  "8~",  "9~",
X    "10~", "11~", "12~", "13~", "14~", "15~", "16~", "17~", "18~", "19~",
X    NULL};
X
X/* Cursor keys resulting from RawKeyConvert() and their output values */
Xstatic struct {
X    char *in;		/* in sequence */
X    char *out_curapp;	/* out sequence in p_curapp */
X    char *out;		/* out sequence !in p_curapp */
X} ckeys[] = {
X	"A",	"OA",	"[A",
X	"T",	"OA",	"[A",
X	"B",	"OB",	"[B",
X	"S",	"OB",	"[B",
X	"C",	"OC",	"[C",
X	" A~",	"OC",	"[C",
X	"D",	"OD",	"[D",
X	" @~",	"OD",	"[D",
X	NULL,	NULL,	NULL	};
X
X/* Numeric keypad return values excluding HELP, '-' and ENTER */
Xstatic char keypad[] = "pqrstuvwxy";
X/* Numeric keypad return values for HELP, - and ENTER */
Xstatic char speckeypad[] = "-l-.n.\015M\015\0\0\0";
X
X/* For InfoMsg...may be changed by a NEWSIZE msg in vt100.c */
Xint reqminx,	/* Min value for x in reqwindow (pixels) */
X    reqmaxx,	/* Max value for x in reqwindow (pixels) */
X    reqmaxlen,	/* Max # chars in reqwindow */
X    reqminy,	/* Min value for y in reqwindow (scan lines) */	
X    reqmaxy,	/* Max value for y in reqwindow (scan lines) */
X    reqfudge;	/* Clear space between border and start of 1st char */
Xint reqy;	/* Current pixel location in reqwindow */
X
Xvoid ReqNewSize(), OpenReqWindow();
X
X/***************************************************
X *  function to swap the use of backspace and delete
X ***************************************************/
X
Xvoid swap_bs_del()
X{
X    if (p_bs_del)   p_bs_del = 0;
X    else	    p_bs_del = 1;
X}
X
X/*************************************************
X *  function to get file name (via a requestor)
X *************************************************/
Xvoid req(prmpt,name,getinp)
Xchar *prmpt,*name;
Xint  getinp;
X    {
X    ULONG class;
X    USHORT position, RemoveGadget();
X    unsigned int code, qual;
X    int  lprmpt, lname;
X    struct IntuiMessage *Msg;
X
X    if(reqwinup == 0)
X	OpenReqWindow();
X    
X    if(!getinp) {
X    	InfoMsg2Line(prmpt, name);
X    	return;
X    }
X
X    lprmpt = strlen(prmpt);
X    lname = strlen(name);
X
X    /* Don't use strings longer than what we've provided space for. */
X    if(lprmpt > (MAXGADSTR-1)) {
X	emits("Prompt too long - truncated.\n");
X	lprmpt = MAXGADSTR-1;
X    }
X    if(lname > (MAXGADSTR-1)) {
X	emits("Name too long - truncated.\n");
X	lname = MAXGADSTR-1;
X    }
X
X    if (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
X	class = Msg->Class;
X	ReplyMsg(Msg);
X	if(class == REQCLEAR)
X	    numreqs = 0;
X	if(class == NEWSIZE)
X	    ReqNewSize(reqwindow->Height, reqwindow->Width);
X    }
X
X    /* Make sure the prompt gets updated */
X    if (numreqs == 1 && strcmp(Prompt,prmpt) != 0) {
X	EndRequest(&myrequest,reqwindow);
X	do {
X		Wait(1L << reqwindow->UserPort->mp_SigBit);
X		while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
X			class = Msg->Class;
X			ReplyMsg(Msg);
X			if(class == NEWSIZE)
X			    ReqNewSize(reqwindow->Height, reqwindow->Width);
X		}
X	} while (class != REQCLEAR);
X	numreqs = 0;
X	}
X
X    /* copy in a prompt and a default */
X    strncpy(Prompt,prmpt,lprmpt); Prompt[lprmpt] = '\0';
X    strncpy(InpBuf,name,lname); InpBuf[lname] = '\0';
X    mystrinfo.BufferPos = lname;
X
X    if (numreqs == 1) {		/* If there is a requester... reuse it */
X    	RefreshGadgets(&mystrgad, reqwindow, &myrequest);
X    	Delay(2L);
X    }
X    else {			/* otherwise create it */
X	while(numreqs != 1) {
X            if (Request(&myrequest, reqwindow) == 0) {
X		emits("ERROR - CAN'T CREATE REQUESTOR FOR:\n");
X		emits(Prompt); emit('\n'); emits(InpBuf); emit('\n');
X		return;
X	    }
X	    else numreqs = 1;
X
X	    do {
X		Wait(1L << reqwindow->UserPort->mp_SigBit);
X		while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
X		    class = Msg->Class;
X		    ReplyMsg(Msg);
X		    if(class == REQCLEAR)
X			numreqs = 0;
X		    if(class == NEWSIZE)
X			ReqNewSize(reqwindow->Height, reqwindow->Width);
X		}
X	    } while (class != REQSET);
X	} /* end while numreqs != 0 */
X    } /* end else */
X
X    /* if we don't want input, we're done */
X    if (getinp == 0 || numreqs == 0) return;
X
X    if((reqwindow->Flags & WINDOWACTIVE) != WINDOWACTIVE) {
X    	WindowToFront(reqwindow);
X	ActivateWindow(reqwindow);
X	do {
X	    Wait(1L << reqwindow->UserPort->mp_SigBit);
X	    while(Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
X		class = Msg->Class;
X		ReplyMsg(Msg);
X		if(class == NEWSIZE)
X		    ReqNewSize(reqwindow->Height, reqwindow->Width);
X	    }
X	} while (class != ACTIVEWINDOW);
X    }
X    
X    /* here is where we pre-select the gadget   */
X    if (!ActivateGadget(&mystrgad,reqwindow,&myrequest)) {
X
X	/* wait for his/her hands to get off the keyboard (Amiga-key) */
X	Delay(20L);
X	while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
X	    ReplyMsg(Msg);
X	    if(class == NEWSIZE)
X		ReqNewSize(reqwindow->Height, reqwindow->Width);
X	}
X
X	/* try once more before giving up... */
X	ActivateGadget(&mystrgad,reqwindow,&myrequest);
X	}
X
X    /* wait for input to show up */
X    while (1) {
X	if ((NewMessage = (struct IntuiMessage *)
X		GetMsg(reqwindow->UserPort)) == FALSE) {
X	    Wait(1L<<reqwindow->UserPort->mp_SigBit);
X	    continue;
X	    }
X	class = NewMessage->Class;
X	ReplyMsg(NewMessage);
X
X	/* the requestor got terminated... yea!! */
X	if (class == REQCLEAR) break;
X
X	if(class == NEWSIZE)
X	    ReqNewSize(reqwindow->Height, reqwindow->Width);
X	    
X	/* maybe this is a menu item to handle */
X/*	if (class == MENUPICK) handle_menupick(class,code); */
X	}
X
X    /* all done, so return the result */
X    numreqs = 0;
X    strcpy(name,InpBuf);
X    if (reqwinup && ((reqwindow->Flags) & WINDOWACTIVE))
X	ActivateWindow(mywindow);
X    }
X
X/*************************************************
X*  function to print a string
X*************************************************/
Xvoid emits(string)
Xchar string[];
X    {
X    int i;
X    char c;
X
X    i=0;
X    while (string[i] != 0)
X	{
X	c=string[i];
X	if (c == 10) emit(13);
X	emit(c);
X	i += 1;
X	}
X    }
X
X/*************************************************
X*  function to output ascii chars to window
X*************************************************/
Xvoid emit(c)
Xchar c;
X    {
X    static char wrap_flag = 0;	/* are we at column 80? */
X
X    c &= 0x7F;
X    switch( c )
X	{
X	case '\t':
X	x += 64 - ((x-MINX) % 64);
X	break;
X
X	case 10:  /* lf */
X	doindex('D');
X	break;
X
X	case 13:  /* cr */
X	x = MINX;
X	break;
X
X	case 8:   /* backspace */
X	x -= 8;
X	if (x < MINX) x = MINX;
X	break;
X
X	case 12:     /* page */
X	x = MINX;
X	y = MINY;
X	SetAPen(mywindow->RPort,0L);
X	RectFill(mywindow->RPort,(long)MINX,
X	    (long)(MINY-7),(long)(MAXX+7),(long)(MAXY+1));
X	SetAPen(mywindow->RPort,1L);
X	break;
X
X	case 7:     /* bell */
X	cmd_beep(0L);
X	break;
X
X	default:
X	if (c < ' ' || c > '~') break;
X	if (p_wrap && wrap_flag && x >= MAXX) {
X	    x = MINX;
X	    doindex('D');
X	    if (y > MAXY) {
X		y = MAXY;
X		ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,
X		    (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
X		}
X	    }
X	Move(mywindow->RPort,(long)x,(long)y);
X
X	if (curmode&FSF_BOLD) {
X	    if (p_depth > 1) {
X		SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
X		SetSoftStyle(mywindow->RPort,(long)curmode,253L);
X		}
X	    else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
X	    }
X	else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
X
X	if (curmode&FSF_REVERSE) {
X	    SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID));
X	    Text(mywindow->RPort,&c,1L);
X	    SetDrMd(mywindow->RPort,(long)JAM2);
X	    }
X	else Text(mywindow->RPort,&c,1L);
X
X	if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L);
X	x += 8;
X	} /* end of switch */
X
X    if (y > MAXY) {
X	y = MAXY;
X	x = MINX;
X	ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,
X	    (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
X	}
X    if (x > MAXX) {
X	wrap_flag = 1;
X	x = MAXX;
X	}
X    else wrap_flag = 0;
X    }
X
X/*************************************************
X*  function to output ascii chars to window (batched)
X*************************************************/
Xvoid emitbatch(la,lookahead)
Xint la;
Xchar *lookahead;
X    {
X    int i;
X
X    Move(mywindow->RPort,(long)x,(long)y);
X    i = x / 8;
X    if (i+la >= maxcol) {
X	if (p_wrap == 0) la = maxcol - i;
X	else {
X	    lookahead[la] = 0;
X	    emits(lookahead);
X	    return;
X	    }
X	}
X    if (curmode&FSF_BOLD) {
X	if (p_depth > 1) {
X	    SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
X	    SetSoftStyle(mywindow->RPort,(long)curmode,253L);
X	    }
X	else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
X	}
X    else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
X
X    if (curmode&FSF_REVERSE) {
X	SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID));
X	Text(mywindow->RPort,lookahead,(long)la);
X	SetDrMd(mywindow->RPort,(long)JAM2);
X	}
X    else Text(mywindow->RPort,lookahead,(long)la);
X    if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L);
X    x += (8 * la);
X    }
X
X/******************************
X* Manipulate cursor
X******************************/
Xvoid cursorflip()
X    {
X    SetDrMd(mywindow->RPort,(long)COMPLEMENT);
X    SetAPen(mywindow->RPort,3L);
X    RectFill(mywindow->RPort,
X	(long)(x-1),(long)(y-6),(long)(x+8),(long)(y+1));
X    SetAPen(mywindow->RPort,1L);
X    SetDrMd(mywindow->RPort,(long)JAM2);
X    }
X
X/************************************************
X*  function to take raw key data and convert it
X*  into ascii chars
X**************************************************/
Xint toasc(retstr, code, qual, maxlen, ia, local)
Xunsigned char *retstr;
Xunsigned int code,qual;
Xint local, maxlen;
XAPTR ia;
X{
X    unsigned int ctrl, alt, npad;
X    int i,
X	cmatch,
X	length = 0;	/* length of returned string */
X    unsigned char *p = retstr;
X    static struct InputEvent ievent = {NULL, IECLASS_RAWKEY,0,0,0};
X
X    *p = '\0';
X
X    ctrl  = qual & IEQUALIFIER_CONTROL;
X    alt	  = qual & (IEQUALIFIER_LALT | IEQUALIFIER_RALT);
X    npad  = qual & IEQUALIFIER_NUMERICPAD;
X
X    ievent.ie_Qualifier = qual;
X
X    ievent.ie_Code = code;
X    /* get previous codes from location pointed to by IAddress
X     * this "magic" pointer is valid intil the IntiiMessage is
X     * replied
X     */
X    ievent.ie_position.ie_addr = ia;
X    length = RawKeyConvert(&ievent, retstr, (LONG)maxlen, NULL);
X    if(length == 0)
X	return length;
X
X    *(p+length) = '\0';	/* Null terminate the value */
X
X    if(npad && length == 1 && p_keyapp) { /* keypad (excluding HELP key)? */
X	register char t = *p;
X	if((t >= '0') && (t <= '9')) {
X	    if(p_keyapp) {
X		strcpy(p, "\033O");
X		*(p+2) = keypad[t-'0'];
X		*(p+3) = '\0';
X		length = 3;
X	    } /* else *p is correct */
X	}
X	else for(i = 0; speckeypad[i]; i += 3)
X	    if(speckeypad[i] == t) {
X		if(p_keyapp) {
X		    strcpy(p, "\033O");
X		    *(p+2) = speckeypad[i+1];
X		    length = 3;
X		}
X		else *p = speckeypad[i+2];
X		break;
X	    }
X    } else if((length == 3) && (strcmp(p, "\233?~") == 0)) {
X	/* HELP key -- only gen something if in app keypad mode */
X	if(p_keyapp) {
X	    strcpy(p, "\033Om");
X	    length = 3;
X	} else {
X	    *p = '\0';
X	    length = 0;
X	}
X    } else if(length > 1 && retstr[0] == 0x9b) { /* cursor or F-keys? */
X	cmatch = 0;
X	for(i = 0; ckeys[i].in && !cmatch; i++) {
X	    if(p_curapp
X	      && strcmp((p+1), ckeys[i].in) == 0) {
X		strcpy((p+1), ckeys[i].out_curapp);
X		*p = 0x1b;
X		length = strlen(ckeys[i].out_curapp)+1;
X		cmatch = 1;
X	    } else if(strcmp((p+1), ckeys[i].in) == 0) {
X		strcpy((p+1), ckeys[i].out);
X		*p = 0x1b;
X		length = strlen(ckeys[i].out)+1;
X		cmatch = 1;
X	    }
X	}
X	if(!cmatch) { /* Not cursor, try F-keys */
X	    for(i = 0; infkey[i]; i++) {
X		if(strcmp((p+1), infkey[i]) == 0) {
X		    if(i > 9)
X			strcpy(p, p_F[i-10]);
X		    else strcpy(p, p_f[i]);
X		    if(!script_on && *p == p_keyscript) {
X			script_start(p+1);
X			*p = '\0';
X			length = 0;
X		    }
X		    length = strlen(p);
X		    break;
X		}
X	    }
X	}
X    } else if(ctrl && (length == 1)) {
X	/* Control key shortcuts? */
X	switch(*p) {
X	case '6':
X	    *p = 30;
X	    break;
X	case '2':
X	case ' ': /* @ done by RawKeyConvert? */
X	    if(!local)
X		*p = (alt ? 128 : 0);
X		break;
X	case '-':
X	case '?':
X	    *p = 31;
X		break;
X	}
X    } else if(alt && !local && length == 1)
X	*p |= 0x80; /* Add hi bit if ALT is the only modifier */
X    else if(p_bs_del && *p == 8    && length == 1)
X	*p = 0x7f;
X    else if(p_bs_del && *p == 0x7f && length == 1)
X	*p = 8;
X
X/*    if (ctrl) {   Are all of these taken care of?
X	if (c > '`' && c <= 127) c -= 96;
X	else if (c > '@' && c <= '_') c -= 64;
X	else if (c == '6') c = 30;
X	else if (c == '-' || c == '?') c = 31;
X    } */
X    for(i = 0; i < length; i++)
X	sendchar(*(p++));
X    return(length);
X}
X
Xvoid
XKillReq()
X{
X    struct IntuiMessage *Msg;
X    ULONG class;
X    
X    if(numreqs != 0) {
X	EndRequest(&myrequest,reqwindow);
X	do {
X		Wait(1L << reqwindow->UserPort->mp_SigBit);
X		while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
X			class = Msg->Class;
X			ReplyMsg(Msg);
X		}
X	} while (class != REQCLEAR);
X	numreqs = 0;
X    }
X
X    if(reqwinup) {
X    	/* First, clear out all pending messages */
X	while (Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
X	    class = Msg->Class;
X	    ReplyMsg(Msg);
X	}
X	NewReqWindow.LeftEdge = reqwindow->LeftEdge;	/* Remember ...	  */
X	NewReqWindow.TopEdge = reqwindow->TopEdge;	/* ...where...	  */
X	NewReqWindow.Width = reqwindow->Width;		/* ...the user... */
X	NewReqWindow.Height = reqwindow->Height;	/* ...put it.	  */
X	CloseWindow(reqwindow); /* Now we can close the window */
X	reqwinup = 0;
X    }
X}
X
Xvoid
XInfoMsg2Line(header, msg)
Xchar *header, *msg;
X{
X    ScrollInfoMsg(1);
X    InfoMsgNoScroll(header);
X    ScrollInfoMsg(1);
X    InfoMsgNoScroll(msg);
X    ScrollInfoMsg(1);
X}
X
Xvoid
XInfoMsg1Line(msg)
Xchar *msg;
X{
X    ScrollInfoMsg(1);
X    InfoMsgNoScroll(msg);
X    ScrollInfoMsg(1);
X}
X
X/*   Output the specified data to the "info" window  */
Xvoid
XScrollInfoMsg(lines)
Xint lines;
X{
X/*  ULONG class;
X    struct IntuiMessage *Msg; */
X    int pixels = lines << 3;
X    
X    if(!reqwinup)
X	OpenReqWindow();
X
X/*  if(Msg=(struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
X	class = Msg->Class;
X	ReplyMsg(Msg);
X	if(class == NEWSIZE)
X	    ReqNewSize(reqwindow->Height, reqwindow->Width);
X    } */
X
X    if ( (reqy += pixels) > reqmaxy) {
X	reqy = reqmaxy;
X	if(pixels > 0)
X	    ScrollRaster(reqwindow->RPort, 0L, (LONG)pixels,
X		(LONG)reqminx,
X		(LONG)reqminy,
X		(LONG)(reqmaxx+7),
X		(LONG)(reqmaxy+7));
X/* Was:		(LONG)(wp->Width - wp->BorderRight),
X		(LONG)(wp->Height - wp->BorderBottom)); */
X    }
X}
X
Xvoid
XInfoMsgNoScroll(msg)
Xchar *msg;
X{
X    LONG msglen = strlen(msg);
X
X    if(msglen > reqmaxlen)
X	msglen = reqmaxlen;
X
X    ScrollInfoMsg(0);	/* Ensure that the msg willbe visible */
X
X    /*  Position the pen at the baseline of the character (7 scan lines
X    ** into it). */
X    Move(reqwindow->RPort, (LONG)reqminx, (LONG)(reqy+6));
X    Text(reqwindow->RPort, msg, msglen);
X}
X
Xvoid
XReqNewSize(height, width)
XSHORT height, width;
X{
X    register struct Window *wp = reqwindow;
X    int oldmaxy;
X
X    /*   Compute min and max for x and y coordinates.  Note that for y the
X    ** value is for the *top* of the character, not the baseline.  Text()
X    ** uses a baseline value and so it must be adjusted prior to the call
X    ** (characters are assumed to occupy an 8x8 matrix with the baseline at
X    ** 7).  When computing the max values, calculate them so that we will
X    ** sufficient room for an entire character. */
X    oldmaxy = reqmaxy;
X    reqminy = wp->BorderTop + reqfudge;
X    reqmaxy = (((height - reqminy - wp->BorderBottom) >> 3) << 3)
X		+ (reqminy-8);
X    reqminx = wp->BorderLeft + reqfudge;
X    reqmaxx = (((width - reqminx - wp->BorderRight) >> 3) << 3)
X		+ (reqminx-8);
X    reqmaxlen = (reqmaxx+7) / 8;
X    if(oldmaxy > reqmaxy) { /* Clean up the bottom of the window */
X	int temp = height - wp->BorderBottom - reqmaxy;
X	
X	ScrollRaster(wp->RPort, 0L, (LONG)temp,
X	(LONG)reqminx,
X	(LONG)reqmaxy,
X	(LONG)(width - wp->BorderRight),
X	(LONG)(height - wp->BorderBottom));
X    }
X}
X
Xvoid
XOpenReqWindow()
X{
X    struct IntuiMessage *Msg;
X    ULONG class;
X    void ReqNewSize();
X    
X    reqwindow = OpenWindow(&NewReqWindow);
X    do {
X	Wait(1L << reqwindow->UserPort->mp_SigBit);
X	while(Msg = (struct IntuiMessage *)GetMsg(reqwindow->UserPort)) {
X	    class = Msg->Class;
X	    ReplyMsg(Msg);
X	}
X    } while (class != ACTIVEWINDOW);
X    reqfudge = 0;	/* Leave 0 pixels/scan lines between border and char */
X    ReqNewSize(reqwindow->Height, reqwindow->Width);
X    reqy = reqminy;	/* Top of character set by ReqNewSize() */
X    reqwinup = 1;
X    if (reqwinup && ((reqwindow->Flags) & WINDOWACTIVE))
X	ActivateWindow(mywindow);
X}
________This_Is_The_END________
if test `wc -l < window.c` -ne 662; then
	echo 'shar: window.c was damaged during transit (should have been 662 bytes)'
fi
fi		; : end of overwriting check
echo 'x - xmodem.c'
if test -f xmodem.c; then echo 'shar: not overwriting xmodem.c'; else
sed 's/^X//' << '________This_Is_The_END________' > xmodem.c
X/*************************************************************
X * vt100 terminal emulator - XMODEM protocol support
X *
X *	v2.8 880117 ACS - See the README file
X *	v2.7 870825 ACS - Make multi_xfer() non-recursive; on non-ESC in
X *			  readchar() re-do the main window's title. 
X *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
X *	v2.5 870214 DBW - more additions (see readme file)
X *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
X *	v2.3 861101 DBW - minor bug fixes
X *	v2.2 861012 DBW - more of the same
X *	v2.1 860915 DBW - new features (see README)
X *	     860901 ACS - Added Parity and Word Length and support code
X *	     860823 DBW - Integrated and rewrote lots of code
X *	     860815 Steve Drew: readchar inproved with real timeouts
X *	v2.0 860809 DBW - Major rewrite
X *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
X *	v1.0 860712 DBW	- First version released
X *
X *************************************************************/
X
X#include "vt100.h"
X
Xint enablexon = TRUE;
X
Xextern struct IntuiText MyTitle;
X
Xstatic unsigned long parity_settings[4] = {
X    0x96696996,
X    0x69969669,
X    0x69969669,
X    0x96696996 };
X
X/* crctab calculated by Mark G. Mendel, Network Systems Corporation */
Xstatic unsigned short crctab[256] = {
X    0x0000,  0x1021,  0x2042,  0x3063,  0x4084,  0x50a5,  0x60c6,  0x70e7,
X    0x8108,  0x9129,  0xa14a,  0xb16b,  0xc18c,  0xd1ad,  0xe1ce,  0xf1ef,
X    0x1231,  0x0210,  0x3273,  0x2252,  0x52b5,  0x4294,  0x72f7,  0x62d6,
X    0x9339,  0x8318,  0xb37b,  0xa35a,  0xd3bd,  0xc39c,  0xf3ff,  0xe3de,
X    0x2462,  0x3443,  0x0420,  0x1401,  0x64e6,  0x74c7,  0x44a4,  0x5485,
X    0xa56a,  0xb54b,  0x8528,  0x9509,  0xe5ee,  0xf5cf,  0xc5ac,  0xd58d,
X    0x3653,  0x2672,  0x1611,  0x0630,  0x76d7,  0x66f6,  0x5695,  0x46b4,
X    0xb75b,  0xa77a,  0x9719,  0x8738,  0xf7df,  0xe7fe,  0xd79d,  0xc7bc,
X    0x48c4,  0x58e5,  0x6886,  0x78a7,  0x0840,  0x1861,  0x2802,  0x3823,
X    0xc9cc,  0xd9ed,  0xe98e,  0xf9af,  0x8948,  0x9969,  0xa90a,  0xb92b,
X    0x5af5,  0x4ad4,  0x7ab7,  0x6a96,  0x1a71,  0x0a50,  0x3a33,  0x2a12,
X    0xdbfd,  0xcbdc,  0xfbbf,  0xeb9e,  0x9b79,  0x8b58,  0xbb3b,  0xab1a,
X    0x6ca6,  0x7c87,  0x4ce4,  0x5cc5,  0x2c22,  0x3c03,  0x0c60,  0x1c41,
X    0xedae,  0xfd8f,  0xcdec,  0xddcd,  0xad2a,  0xbd0b,  0x8d68,  0x9d49,
X    0x7e97,  0x6eb6,  0x5ed5,  0x4ef4,  0x3e13,  0x2e32,  0x1e51,  0x0e70,
X    0xff9f,  0xefbe,  0xdfdd,  0xcffc,  0xbf1b,  0xaf3a,  0x9f59,  0x8f78,
X    0x9188,  0x81a9,  0xb1ca,  0xa1eb,  0xd10c,  0xc12d,  0xf14e,  0xe16f,
X    0x1080,  0x00a1,  0x30c2,  0x20e3,  0x5004,  0x4025,  0x7046,  0x6067,
X    0x83b9,  0x9398,  0xa3fb,  0xb3da,  0xc33d,  0xd31c,  0xe37f,  0xf35e,
X    0x02b1,  0x1290,  0x22f3,  0x32d2,  0x4235,  0x5214,  0x6277,  0x7256,
X    0xb5ea,  0xa5cb,  0x95a8,  0x8589,  0xf56e,  0xe54f,  0xd52c,  0xc50d,
X    0x34e2,  0x24c3,  0x14a0,  0x0481,  0x7466,  0x6447,  0x5424,  0x4405,
X    0xa7db,  0xb7fa,  0x8799,  0x97b8,  0xe75f,  0xf77e,  0xc71d,  0xd73c,
X    0x26d3,  0x36f2,  0x0691,  0x16b0,  0x6657,  0x7676,  0x4615,  0x5634,
X    0xd94c,  0xc96d,  0xf90e,  0xe92f,  0x99c8,  0x89e9,  0xb98a,  0xa9ab,
X    0x5844,  0x4865,  0x7806,  0x6827,  0x18c0,  0x08e1,  0x3882,  0x28a3,
X    0xcb7d,  0xdb5c,  0xeb3f,  0xfb1e,  0x8bf9,  0x9bd8,  0xabbb,  0xbb9a,
X    0x4a75,  0x5a54,  0x6a37,  0x7a16,  0x0af1,  0x1ad0,  0x2ab3,  0x3a92,
X    0xfd2e,  0xed0f,  0xdd6c,  0xcd4d,  0xbdaa,  0xad8b,  0x9de8,  0x8dc9,
X    0x7c26,  0x6c07,  0x5c64,  0x4c45,  0x3ca2,  0x2c83,  0x1ce0,  0x0cc1,
X    0xef1f,  0xff3e,  0xcf5d,  0xdf7c,  0xaf9b,  0xbfba,  0x8fd9,  0x9ff8,
X    0x6e17,  0x7e36,  0x4e55,  0x5e74,  0x2e93,  0x3eb2,  0x0ed1,  0x1ef0
X};
X
X/*
X * updcrc macro derived from article Copyright (C) 1986 Stephen Satchell. 
X *  NOTE: First srgument must be in range 0 to 255.
X *        Second argument is referenced twice.
X * 
X * Programmers may incorporate any or all code into their programs, 
X * giving proper credit within the source. Publication of the 
X * source routines is permitted so long as proper credit is given 
X * to Stephen Satchell, Satchell Evaluations and Chuck Forsberg, 
X * Omen Technology.
X */
X
X#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
X
X/************************************************************
X* Send a string (using sendchar below)
X************************************************************/
X
Xvoid sendstring(s)
Xchar *s;
X    {
X    char c;
X
X    while ((c = *s++) != '\000') sendchar(c);
X    }
X
X/**************************************************************/
X/* send char and read char functions for the xmodem function */
X/************************************************************/
Xvoid sendchar(ch)
Xint ch;
X    {
X    int doxon,i,j,k;
X
X    doxon = enablexon;
X    if (doxon) No_XON();
X    switch (p_parity) {
X	case 0:	/* no parity */
X	rs_out[0] = ch & 0xFF;
X	break;
X
X	case 1: /* mark */
X	rs_out[0] = (ch & 0x7F) | 0x80;
X	break;
X
X	case 2: /* space */
X	rs_out[0] = ch & 0x7F;
X	break;
X
X	case 3:	/* even */
X	case 4: /* odd  */
X	i     = (ch >> 5) & 0x3;
X	j     = ch & 0x1F;
X	k     = ((parity_settings[i] >> j) & 0x1) << 7;
X	if (p_parity == 3)			/* even parity */
X	    rs_out[0] = (ch & 0x7F) | k;
X	else					/* odd parity */
X	    rs_out[0] = (ch & 0x7F) | (k ^ 0x80);
X	}
X    do {
X	DoIO(Write_Request);
X    } while(Write_Request->IOSer.io_Error != 0);
X    if (doxon) Do_XON();
X    }
X
X/* send a break to the host */
Xvoid sendbreak() {
X    AbortIO(Read_Request);
X    Wait(1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit);
X    WaitIO(Read_Request);
X    Read_Request->IOSer.io_Command = SDCMD_BREAK;
X    DoIO(Read_Request);
X    Read_Request->IOSer.io_Command = CMD_READ;
X    SendIO(Read_Request);
X    }
X
Xint readchar()
X    {
X    int rd,ch;
X    ULONG class, waitmask;
X    USHORT code;
X
X    Timer.tr_time.tv_secs = ttime;
X    Timer.tr_time.tv_micro = 0;
X    SendIO((char *) &Timer.tr_node);
X
X    rd = FALSE;
X    waitmask = ((1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) |
X		( 1L << mywindow->UserPort->mp_SigBit) |
X		( 1L << Timer_Port->mp_SigBit));
X    if(reqwinup)
X	waitmask |= (1L << reqwindow->UserPort->mp_SigBit);
X    while (rd == FALSE) {
X	Wait(waitmask);
X	if (CheckIO(Read_Request)) {
X	    WaitIO(Read_Request);
X	    ch=rs_in[0];
X	    rd = TRUE;
X	    SendIO(Read_Request);
X	}
X	if(reqwinup &&
X	  (NewMessage=(struct IntuiMessage *)GetMsg(reqwindow->UserPort))) {
X	    class = NewMessage->Class;
X	    ReplyMsg(NewMessage);
X	    if(class == NEWSIZE)
X		ReqNewSize(reqwindow->Height, reqwindow->Width);
X	}
X	if (NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
X	   class = NewMessage->Class;
X	   code = NewMessage->Code;
X	   ReplyMsg(NewMessage);
X	   if ((class == RAWKEY) && (code == 69)) {
X		if(!CheckIO(&Timer))
X		    AbortIO((char *) &Timer);
X		Wait (1L << Timer_Port->mp_SigBit);
X		WaitIO((char *) &Timer.tr_node);
X		InfoMsg1Line("ERROR: User aborted transfer");
X		timeout = USERABORT;
X		return('\0');
X	   }
X	   PrintIText(mywindow->RPort, &MyTitle, 0L, 0L);
X/*	   continue; */
X	}
X
X	if (rd == FALSE && CheckIO(&Timer)) {
X	    InfoMsg1Line("ERROR: Timeout waiting for character");
X	    timeout = TIMEOUT;
X	    return('\0');
X	}
X    } /* end while */
X    if(!CheckIO(&Timer))
X	AbortIO((char *) &Timer);
X    Wait (1L << Timer_Port->mp_SigBit);
X    WaitIO((char *) &Timer.tr_node);
X    timeout = GOODREAD;
X    return(ch & (p_parity == 0 ? 0xFF : 0x7F));
X    }
X
Xvoid No_XON() {
X
X    /* turn off XON/XOFF processing */
X    enablexon = FALSE;
X    Write_Request->io_SerFlags |= SERF_XDISABLED;
X    Write_Request->IOSer.io_Command = SDCMD_SETPARAMS;
X    DoIO(Write_Request);
X    Write_Request->IOSer.io_Command = CMD_WRITE;
X    }
X
Xvoid Do_XON() {
X    /* turn on XON/XOFF processing */
X    enablexon = TRUE;
X    Write_Request->io_SerFlags &= ~SERF_XDISABLED;
X    Write_Request->IOSer.io_Command = SDCMD_SETPARAMS;
X    DoIO(Write_Request);
X    Write_Request->IOSer.io_Command = CMD_WRITE;
X    }
X
X/**************************************/
X/* xmodem send and recieve functions */
X/************************************/
X
Xint XMODEM_Read_File(file)
Xchar *file;
X{
X    int firstchar, sectnum, sectcurr, sectcomp, errors, errorflag, use_crc = 0;
X    int c, good_sect;
X    unsigned int checksum, j, bufptr;
X    unsigned short crc;
X    char scrstr2[40];
X
X    bytes_xferred = 0L;
X    ttime = TTIME_SHORT;
X
X    if ((fd = creat(file, 0)) < 0) {
X	InfoMsg2Line("XMODEM Can't Open File:",file);
X	return FALSE;
X    }
X    else
X	InfoMsg1Line("XMODEM Receive, <esc> in VT100 window to abort");
X
X    sectnum = errors = bufptr = 0;
X    if(p_xproto == 2)
X	sendchar('C');
X    else
X	sendchar(NAK);
X    firstchar = 0;
X    No_XON();
X    while (firstchar != EOT && errors != ERRORMAX) {
X	errorflag = FALSE;
X
X	do {                                    /* get sync char */
X	    firstchar = readchar();
X	    if (timeout != GOODREAD) {
X		if (timeout == USERABORT || errors++ == ERRORMAX) {
X		    Do_XON();
X		    return FALSE;
X		}
X	    }
X	} while (firstchar != SOH && firstchar != EOT);
X
X	if  (firstchar == SOH) {
X	    sprintf(scrstr2,"Getting Block %4d...",sectnum);
X	    InfoMsgNoScroll(scrstr2);
X	    sectcurr = readchar();
X	    if (timeout != GOODREAD) { Do_XON(); return FALSE; }
X	    sectcomp = readchar();
X	    if (timeout != GOODREAD) { Do_XON(); return FALSE; }
X	    if ((sectcurr + sectcomp) == 255) {
X		if (sectcurr == ((sectnum + 1) & 0xff)) {
X		    checksum = 0; crc = 0;
X		    for (j = bufptr; j < (bufptr + SECSIZ); j++) {
X			bufr[j] = readchar();
X			if (timeout != GOODREAD) { Do_XON(); return FALSE; }
X			checksum = (checksum + bufr[j]) & 0xff;
X			crc = updcrc(((unsigned int)bufr[j] & 0xff),  crc);
X		    }
X		    c = readchar();
X		    if(timeout != GOODREAD) {
X		    	errorflag = TRUE;
X		    	if(timeout == USERABORT) {Do_XON(); return FALSE; }
X		    }
X		    if(p_xproto == 2) {
X			crc = updcrc(((unsigned int)c & 0xff), crc);
X			c = readchar();
X			if(timeout != GOODREAD) {
X			    errorflag = TRUE;
X			    if(timeout == USERABORT) {Do_XON(); return FALSE; }
X			}
X			crc = updcrc(((unsigned int)c & 0xff), crc);
X			good_sect = (crc == 0);
X		    } else
X			good_sect = (checksum == c);
X		    if (!good_sect) {
X		    	errorflag = TRUE;
X		    	if(timeout == USERABORT) { Do_XON(); return FALSE; }
X		    } else {
X			errors = 0;
X			sprintf(scrstr2,"Block %4d verified",sectnum);
X			sectnum++;
X			bufptr += SECSIZ;
X			bytes_xferred += SECSIZ;
X			InfoMsgNoScroll(scrstr2);
X			if (bufptr == BufSize) {
X			    if (write(fd, bufr, BufSize-128) == EOF) {
X				InfoMsg1Line("XMODEM: Error Writing File");
X				Do_XON();
X				return FALSE;
X			    }
X			    bufptr = 128;
X			    for (j = 0; j < 128; j++)
X				bufr[j] = bufr[(BufSize-128)+j];
X			}
X			sendchar(ACK);
X		    }
X		} else {
X		    /* got a duplicate sector */
X		    if (sectcurr == (sectnum & 0xff)) {
X			/* wait until we time out for 5secs */
X			do {
X			    readchar();
X			} while (timeout == GOODREAD);
X			if (timeout == USERABORT) {
X			    Do_XON();
X			    return FALSE;
X			}
X			InfoMsg1Line("XMODEM: Received Duplicate Sector");
X			sendchar(ACK);
X		    }
X		    else errorflag = TRUE;
X		}
X	    } else errorflag = TRUE;
X	}
X	if (errorflag == TRUE) {
X	    errors++;
X	    InfoMsg1Line("XMODEM: Error");
X	    if(p_xproto == 2)
X		sendchar('C');
X	    else
X		sendchar(NAK);
X	}
X    }        /* end while */
X    if ((firstchar == EOT) && (errors < ERRORMAX)) {
X	sendchar(ACK);
X	if (bufptr) {
X	    /* use firstchar to remember the last char for chopping */
X	    if((firstchar = bufr[--bufptr]) == 0 || firstchar == 0x1A)
X		while (bufptr && bufr[--bufptr] == firstchar)
X		    ;
X	    bufptr++;
X	    write(fd, bufr, bufptr);
X	}
X	close(fd);
X	Do_XON();
X	ScrollInfoMsg(1);
X	return TRUE;
X    }
X    Do_XON();
X    return FALSE;
X}
X
Xint XMODEM_Send_File(file)
Xchar *file;
X{
X    int sectnum, bytes_to_send, size, attempts, c, use_crc = 0;
X    unsigned checksum, j, bufptr;
X    unsigned short crc;
X    char scrstr2[40];
X    bytes_xferred = 0;
X    ttime = TTIME_LONG;
X
X    if ((fd = open(file, 0)) < 0) {
X	InfoMsg1Line("XMODEM: Cannot Open Send File");
X	return FALSE;
X    } else
X	InfoMsg1Line("XMODEM Send, <esc> from VT100 window to abort");
X    attempts = 0;
X    sectnum = 1;
X    No_XON();
X    /* wait for sync char */
X    j=1;
X    while (((c = readchar()) != NAK) && (c != 'C') && (j++ < ERRORMAX))
X	if (timeout == USERABORT) { Do_XON(); return(FALSE); }
X    if (j >= (ERRORMAX)) {
X	InfoMsg1Line("XMODEM: Receiver not sending");
X	Do_XON();
X	return FALSE;
X    }
X
X    if(c == 'C')
X	use_crc = 1;
X    while ((bytes_to_send = read(fd, bufr, BufSize)) &&
X	    attempts != RETRYMAX) {
X	if (bytes_to_send == EOF) {
X	    InfoMsg1Line("XMODEM: Error Reading File");
X	    Do_XON();
X	    return FALSE;
X	}
X
X	bufptr = 0;
X	while (bytes_to_send > 0 && attempts != RETRYMAX) {
X	    attempts = 0;
X	    sprintf(scrstr2,"Sending block %4d",sectnum);
X	    size = SECSIZ <= bytes_to_send ? SECSIZ : bytes_to_send;
X	    bytes_to_send -= size;
X	    do {
X		InfoMsgNoScroll(scrstr2);
X		sendchar(SOH);
X		sendchar(sectnum);
X		sendchar(~sectnum);
X		checksum = 0; crc = 0;
X		for (j = bufptr; j < bufptr + size; j++) {
X		    sendchar(bufr[j]);		/* send buffer data */
X		    checksum += bufr[j];
X		    crc = updcrc(((unsigned int)bufr[j] & 0xff), crc);
X		}
X		if( size < SECSIZ ) {		/* check if we need to pad */
X		    c = bufr[j-1] ? 0 : 0x1A;	/* choose correct padding */
X		    j = SECSIZ - size;
X		    checksum += j * c;
X		    while ( j-- ) {
X			if(use_crc)
X			    crc = updcrc(c, crc);
X			sendchar(c);		/* send padding */
X		    }
X		}
X		if(use_crc) {
X		    crc = updcrc(0, updcrc(0, crc));
X		    sendchar(crc >> 8);
X		    sendchar(crc & 0xff);
X		} else
X		    sendchar(checksum);
X		attempts++;
X		c = readchar();
X		if (timeout == USERABORT) {
X		    InfoMsg1Line("XMODEM: ABORTED");
X		    Do_XON();
X		    return FALSE;
X		}
X	    } while ((c != ACK) && (attempts != RETRYMAX));
X	    bufptr += size;
X	    bytes_xferred += size;
X	    sprintf(scrstr2,"Sent    block %4d",sectnum);
X	    InfoMsgNoScroll(scrstr2);
X	    sectnum++;
X	}
X    }
X    close(fd);
X    if (attempts == RETRYMAX) {
X	InfoMsg1Line("XMODEM: No Acknowledgment, ABORTING");
X	Do_XON();
X	return FALSE;
X    } else {
X	attempts = 0;
X	do {
X	    sendchar(EOT);
X	    attempts++;
X	} while ((readchar() != ACK) &&
X		     (attempts != RETRYMAX) &&
X		     (timeout != USERABORT)) ;
X	if (attempts == RETRYMAX)
X	    InfoMsg1Line("XMODEM: No end of file");
X    }
X    Do_XON();
X    ScrollInfoMsg(1);
X    return TRUE;
X}
X
X/* allow for multi file xfers separated by commas under
X    kermit and XMODEM */
X
Xvoid multi_xfer(name,mode,do_send)
Xchar *name;
Xint (*mode)();
Xint do_send;
X    {
X    int done = 0;
X    int status;
X    char *p, *name_start;
X
X    timeout = USERABORT - 1;
X    for(p=name_start=name; !done && timeout != USERABORT; name_start=++p)
X	{
X	if (*(name_start) == '$' && *(name_start+1) == '\0') {
X	    saybye();
X	    return;
X	    }
X	while(*p == ' ') p++;
X	while(*p && *p != ',' && *p != ' ') p++;
X	if (*p == '\0') {
X	    done = TRUE;
X	    multi = 0;
X	}
X	else
X	    multi = 1;
X	*p = '\0';
X
X	status = ((*mode)(name_start, multi));
X	if (status == FALSE) close(fd);
X	}
X    server = 0;
X    multi = 0;
X    if(p_xbeep)
X	cmd_beep(0L);
X    }
X
________This_Is_The_END________
if test `wc -l < xmodem.c` -ne 514; then
	echo 'shar: xmodem.c was damaged during transit (should have been 514 bytes)'
fi
fi		; : end of overwriting check
exit 0