[net.micro.amiga] VT100 terminal emulator

wecker@cookie.dec.com (DAVE TANSTAAFL WECKER) (08/25/86)

	[I apologize for posting this here (instead of 
	 MOD.AMIGA.SOURCES/BINARIES), but I haven't been
	 able to get through to the moderator for 3 weeks,
	 and people have been asking for the new release.]



#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	readme
#	vt100.doc
#	makefile
#	vt100.h
#	vt100.c
#	init.c
# This archive created: Sun Aug 24 16:25:17 1986
echo shar: extracting readme
sed 's/^XX//' << \SHAR_EOF > readme
XXThis archive contains a vt100 emulator with KERMIT and XMODEM file transfer
XXprotocols by Dave Wecker (V2.0 DBW 860823).
XX
XXThanks:
XX-------
XX	A large part of this release is due to Dawn Banks and Steve Drew
XX	(lots of contributed code). Thanks for all of your efforts!!
XX
XXReleases:
XX---------
XX	v2.0 860823 DBW - Major rewrite
XX	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
XX	v1.0 860712 DBW	- First version released
XX
XXUsage:
XX------
XX	Please read VT100.DOC for usage information and examples.
XX
XXRelease Notes:
XX--------------
XXv2.0 860823 DBW	- Major rewrite:
XX
XX	- Emulator now compiles under either MANX or LATTICE by defining
XX	  the appropriate compiler type in VT100.H.
XX
XX	- Sped up code to an effective baud rate of (about) 8k. This means
XX	  that clear text at 4800 baud should be no problem.
XX
XX	- Added XON/XOFF generation so that characters should not get lost
XX	  any more at 9600 baud (when receiving clear text).
XX
XX	- Got rid of all command line switches and environment variables.
XX	  Instead upon invocation the program searches first for any file
XX	  named on the command line, then looks for VT100.INIT in the
XX	  current directory and finally searches for C:VT100.INIT.
XX
XX	  All parameters can be set in the init file, and a sample VT100.INIT
XX	  is provided in VT100.DOC that shows all possible options.
XX
XX	- All parameters that are set by VT100.INIT are defined in VT100.H
XX	  (variables starting with "p_"). This allows you to compile your
XX	  own defaults into the code.
XX
XX	- You can now set the number of lines (for all you EMACS freaks :-).
XX	  On an interlaced screen this gives you upto a 48 line terminal.
XX
XX	- WORKBENCH colors are NEVER touched.
XX
XX	- In an attempt to keep the size down, the color palette menu item
XX	  has been removed (current). Code is about 36K in size with a
XX	  run time image (using workbench screen) of about 88k.
XX
XX	- Many bugs fixed including reverse scrolling with descenders,
XX	  reverse video at end of line, clearing with scrolling regions,
XX		... and 20 or more others.
XX
XX	- File capture now no longer sends the filename to the host.
XX
XX	- BOLD (<esc>[1m) has now been added by using an additional color
XX	  when you specify a depth of 2 (instead of 1) bitplane.
XX
XX	- UNDERLINE (<esc>[4m) has now been added.
XX
XX	- The handling of remote (host) escape sequences has been completly
XX	  re-written (thanks to Dawn Banks for all the work).
XX
XX	- Function keys (and shifted function keys) can now be bound to
XX	  arbitrary strings (Jim Ravan gets his macros). See VT100.DOC
XX	  for details.
XX
XX	- Cursor has no been reduced to the size of a normal character for
XX	  easier readability.
XX
XX	- XMODEM has been improved (by Steve Drew) to use a timer device
XX	  (for timeouts) and to abort immediately if the user types <ESC>.
XX
XX	- KERMIT has been completely re-written and appears to work fine,
XX	  thanks to the efforts of Steve Drew. Items include:
XX
XX		- supports multi-file transfer in both send and receive modes
XX		- works with binary files (tried with VAX/vms and VAX/unix)
XX		- now has Get file for use with server (receiving files)
XX		- Kermit BYE item will send server bye command.
XX		- A final filename of dollar sign ("$") will send a BYE
XX		  to the host KERMIT server.
XX		- status bar shows pkt type, pkt no., total retransmissions,
XX		  filename, total bytes xfered and status which can be:
XX                      SEND  - sending this file
XX                      RECV  - receiving this file
XX                      ABORT - user hit escape to abort transfer..
XX                      TMOUT - did not receive characters before timeout
XX                      ERROR - some other error detected.
XX                      DONE  - transfer complete
XX		- now uses timer.device to determine if timeout occurrs.
XX		- will cleanly abort when user hits <ESC> if in send mode
XX		  tells host to discard the partial file.
XX
XX	- New menu item allows script file support. Module written by
XX	  Steve Drew. See VT100.DOC for details.
XX
XXKnown problems:
XX---------------
XX
XX	- none yet (need to hear what still doesn't work right).
XX
XXYet to be done (possibly.. not promising anything):
XX---------------------------------------------------
XX
XX	- Add sending/receiving of entire volumes (with data compression).
XX	  Maybe use LZW compression.
XX
XX	- Add BOO file transfer mode for encoding/decoding binary
XX	  files into clear text.
XX
XXInstallation:
XX-------------
XX	The files in this archive may be extracted by the bourne shell
XX	(/bin/sh) or the shar program using the "unshar switch (-u)",
XX	contact me if you need a copy of this version of shar.
XX
XXFiles:
XX------
XX	README		- this file
XX
XX	vt100.doc	- documentation for the terminal emulator
XX
XX	makefile	- make file for the emulator (under MANX AZTEC-C)
XX
XX	vt100.h		- include file used by all other modules
XX
XX	window.c	- manager for window and keyboard
XX
XX	vt100.c		- main module, handles menus
XX
XX	remote.c	- handle remote characters (vt100 emulation)
XX
XX	kermit.c	- kermit protocol (to transfer text files on VMS
XX			  select the CRLF option on the transfer mode menu,
XX			  otherwise use image mode).
XX
XX	init.c		- startup code
XX
XX	xmodem.c	- xmodem protocol that understands AMIGA binary and
XX			  text file formats (automatically).
XX
XX	script.c	- script control package
XX
XXContact:
XX--------
XXPlease send bugs/comments/suggestions to:
XX
XX	Dave Wecker at	ENET:	COOKIE::WECKER
XX			ARPA:	wecker%cookie.dec.com@decwrl.dec.com
XX			USENET:	{decvax|decwrl}!cookie.dec.com!wecker
XX			SNAIL:	Dave Wecker
XX				115 Palm Springs Drive
XX				Colorado Springs, CO  80908
SHAR_EOF
if test 5434 -ne "`wc -c readme`"
then
echo shar: error transmitting readme '(should have been 5434 characters)'
fi
echo shar: extracting vt100.doc
sed 's/^XX//' << \SHAR_EOF > vt100.doc
XXThis is the documentation file for the VT100 terminal emulator by Dave
XXWecker (V2.0 DBW 860823). Comments/suggestions/bugs/problems/praise should
XXbe sent to:
XX
XX	Dave Wecker at	ENET:	COOKIE::WECKER
XX			ARPA:	wecker%cookie.dec.com@decwrl.dec.com
XX			USENET:	{decvax|decwrl}!cookie.dec.com!wecker
XX			SNAIL:	Dave Wecker
XX				115 Palm Springs Drive
XX				Colorado Springs, CO  80908
XX
XXMulti-file transfer, the new version of KERMIT and script support were
XXcontributed by Steve Drew (Aug 20 1986). If you wish to thank Steve
XXdirectly he can be contacted through:
XX
XX    	Steve Drew at	ENET:    CGFSV1::DREW
XX    			ARPA:    drew%cfgsv1.dec.com@decwrl.dec.com
XX    			USENET:  decvax!decwrl!cgfsv1.dec.com!drew    
XX
XXProgram startup:
XX----------------
XX	1> vt100 [initfile]
XX
XX		- At startup, the program will search for an initialization
XX		  file to execute. It will first look for "initfile", then
XX		  VT100.INIT (in the current directory) and finally
XX		  C:VT100.INIT. The format for the init file is described
XX		  later in this document.
XX
XX		- The init file controls the setting of initial defaults
XX		  and screen and macro definitions.
XX
XX		- If none of the files (listed above) are found, the
XX		  built-in defaults (defined in VT100.H as variables,
XX		  beginning with "p_") are used.
XX
XX		- All commands are either menu or script based. Scripts
XX		  are described below.
XX
XXKeypad mapping:
XX---------------
XX		AMIGA		VT100		comments
XX		-------		-------		---------------------------
XX		0-9	==	0-9
XX		.	==	.
XX		ENTER	==	ENTER		(basically, flip the bottom
XX		-	==	,		 2 keys up to get a VT100)
XX		HELP	==	-		(only free key around)
XX		f1-f4	==	PF1-PF4		(or any rebinding you do)
XX		arrows	==	arrows
XX
XXInitialization file example:
XX----------------------------
XXHere is a (hopefully) self-explanatory VT100.INIT file with all options
XXused:
XX
XX#######################################################################
XX#
XX#	VT100 sample initialization file
XX#	v2.0 860823 DBW	- Dave Wecker standard defaults
XX#
XX# Hash mark at the beginning of a line denotes a comment.
XX# White space (space(s) or tab(s)) delimit fields.
XX# Case ignored except for function key bindings.
XX#
XX# All items in this file overide variables of the same name in VT100.H
XX# (all variables in vt100.h have a "p_" prepended to them)
XX#
XX##########################################################################
XX#
XXBAUD		2400		# Anything after required fields is ignored
XXSCREEN		WORKBENCH	# may be CUSTOM or WORKBENCH
XXINTERLACE	OFF		# ON for CUSTOM or interlaced workbench
XXDEPTH		2		# number of bit planes to use (1 or 2)
XXFOREGROUND	840		# Colors are only used on the custom screen
XXBACKGROUND	000		# Colors are in hex RGB from 000 to FFF
XXBOLD		c00		# Color for bold highlighting (in custom)
XXCURSOR		888		# Color for cursor (in custom screen)
XXLINES		24		# normal <= 24 interlaced <= 48
XXMODE		IMAGE		# IMAGE or CRLF (for KERMIT transfers)
XXXOFF		ENABLED		# Do you want automatic XON/XOFF flow cntrl
XX# 
XX# Function bindings (strings to type when any of F1 through F10 are pressed)
XX#	f<num>	= function key
XX#	F<num>	= shifted function key
XX#
XX# The string specified must be delimited and uses one special character:
XX#	^	= control next character
XX#	^^	= up arrow
XX#
XX# Sample control characters:
XX#	^[	= escape	^M	= carriage return
XX#	^J	= line feed	^L	= form feed
XX#
XX# Examples of bindings:
XX#
XXf1	"^[OP"			# f1-f4 = PF1 - PF4 on a VT100
XXf2	"^[OQ"
XXf3	"^[OR"
XXf4	"^[OS"
XXf6	"MAIL^M"		# Reads my mail (note embedded <CR>)
XXf7	"NOTE^M"		# Reads conferences
XXF1	"$2400!"		# dials the phone to work
XXF2	"$bbs1!"		# dials the phone to billboard 1
XXF3	"$bbs2!"		# dials the phone to billboard 2
XXF4	"$bbs3!"		# dials the phone to billboard 3
XX#
XXexit				# all done (clean way to end file)
XX
XXMulti file Xfers:
XX-----------------
XXThe VT100 emulator now supports multiple file transfers. This is specified
XXby using a comma (",") between file names when using XMODEM or KERMIT.
XX(Note: host XMODEM's normally CANNOT support multiple file transfers).
XX
XXWhen specifying a file name to recieve by default the directory path is
XXstripped of the filename when sent to the host but is kept for the local
XXfile spec. eg:
XX
XX        receive file: ram:file.txt,df1:newfile.bin,$
XX
XXwill ask the server for file.txt and put it in ram:, and get newfile.bin
XXand put it on df1: (see explanation of "$" below). If you do a single file
XXtransfer you will get another prompt for the remote name e.g.:
XX
XX        receive file: ram:file.txt
XX        remote file name[file.txt] userdisk1:wantfile.txt
XX
XXThe same rules apply to sending multiple files therefore if you are
XXdoing multi file transfers make sure the host server is connected to the
XXdesired directory.
XX
XXScript file operation:
XX----------------------
XXThe script file can be invoked by selecting 'execute file' from the script 
XXmenu. At any time you can abort the script file by selecting
XX'Abort Execution'.
XX
XXDuring the time script file is running the terminal emulation is still
XXactive and you may type simulataneous to the script file. This may be desired
XXif your script file is WAITing for a string or is DELAYing for a period of
XXtime etc.
XX
XXScript file Commands:
XX---------------------
XX#	Commented line
XX   Format:
XX	# comment		 may not be on same line as a command.
XX   Example:
XX	# this is a comment
XX------------------------------------------------------------
XXASCII_SEND Send an ascii file to the host.
XX   Format:
XX	(same format as CAPTURE)
XX------------------------------------------------------------
XXCAPTURE	To start/stop ascii file capture.
XX   Format:
XX	CAPTURE	file		Start ascii capturing
XX	CAPTURE			End ascii capturing
XX   Example:
XX	CAPTURE foo.bar		Starts capture of file foo.bar
XX	CAPTURE			Ends ascii capture of file foo.bar
XX------------------------------------------------------------
XXDELAY Suspends script file for a specified time
XX   Format:        
XX        DELAY 	n		Suspends execution for n seconds
XX   Example:
XX	DELAY	2		Suspends for 2 seconds
XX------------------------------------------------------------
XXEXIT	Ends execution of the script file.
XX   Format:
XX	EXIT
XX------------------------------------------------------------
XXGOTO	Jumps to a different part of the script file.
XX   Format:
XX	GOTO label		Jumps to a line beginning with label:
XX				Jumps may be forward or backward.
XX   Example:
XX	FOO:			Sets up a label
XX	GOTO FOO		Jumps to FOO
XX------------------------------------------------------------
XXKB  	Send a BYE packet to a host KERMIT server (shut down server).
XX   Format:
XX	KB
XX------------------------------------------------------------
XXKG  	Gets files from host. (which is running as a server).
XX   Format:
XX	(same format as KS)
XX------------------------------------------------------------
XXKR  	Receives a file from kermit host (not running as server)
XX   Format:
XX	(same format as KS)
XX------------------------------------------------------------
XXKS  	Sends files via kermit to the host.
XX   Format:
XX	KS file			Send one file
XX	KS file1,file2,...	Send multiple files
XX	KS file1,file2,...,$	Send multiple files and shut down server
XX   Example:
XX	KS foo.bar		sends foo.bar (note no quoting is used)
XX	KS foo1,foo2,foo3	sends three files
XX	KS foo1,foo2,foo3,$	sends three files and shuts down server
XX------------------------------------------------------------
XXON	Peforms a command every time a string is received
XX   Format:
XX        ON      "string"  cmd	Execute cmd when string is received. Only
XX				one ON string may be installed at a time.
XX
XX  				If cmd is a GOTO and we were previously
XX				WAITing for a string the WAIT is aborted and
XX				execution resumes at the new label.
XX
XX              			If cmd is not SEND and we were previously
XX				DELAYing, then the DELAY is aborted and the
XX				cmd is executed, followed by the next command
XX				after the DELAY.
XX
XX				If cmd is a SEND and we were previously
XX				DELAYing, then the DELAY is continued.
XX   Example:
XX        ON  "LOSS CARRIER" GOTO RESTART
XX				If modem drops carrier, try to redial
XX        ON  "--more--" SEND " "
XX				Send a space every time --more-- is received
XX------------------------------------------------------------
XXSEND 	Sends a string or character to the host.
XX   Format:
XX	SEND    "string"	Sends a string to the host. Beginning and
XX				ending double quotes (") are required. A
XX				vertical bar may be used to send a <CR>.
XX        SEND    chr           	Sends a single character.
XX        SEND    ^chr   	    	Sends a single control character. The chr
XX				must be an upper case letter.
XX   Example:
XX	SEND	"mail"		Send the string mail
XX	SEND    "dir|"		Send the string dir followed by a <CR>
XX	SEND	a		Send the letter a
XX	SEND	^C		Send a control C
XX------------------------------------------------------------
XXWAIT 	Suspends the script file until a certain string is received.
XX   Format:
XX	WAIT	"string"	Same rules for string as SEND
XX	WAIT			Enter an endless wait. Usually used after
XX				some "ON" commands have been set up. Can
XX				still aborted via the script menu.
XX   Example:
XX        WAIT    "User:"    	Waits for the string User:
XX        WAIT               	Waits forever
XX------------------------------------------------------------
XXXR  	Receives a file via XMODEM.
XX   Format:
XX	(same format as KS)
XX------------------------------------------------------------
XXXS  	Sends a file via XMODEM.
XX   Format:
XX	(same format as KS)
XX------------------------------------------------------------
XX
XX
XXScript file example:
XX--------------------
XX#
XX# Script to upload the terminal emulator sources to my host system
XX#	v1.0	860823	DBW
XX#
XX# First get the modem's attention:
XX#
XXStart:
XX	DELAY 1
XX	ON "Ready" GOTO Dial
XX	SEND ^B
XX	DELAY 2
XX	GOTO Start
XX#
XX# Now dial the 2400 baud line to work:
XX#
XXDial:
XX	ON "Attached" GOTO Login
XX	SEND "$2400!"
XX	DELAY 30
XX	GOTO Start
XX#
XX# We got attached, so keep hitting return until the Gandalf terminal
XX# handler wakes up:
XX#
XXLogin:
XX	ON "enter" GOTO Gandalf
XX	DELAY 1
XX	SEND "|"
XX	GOTO Login
XX#
XX# Now connect from the Gandalf to the terminal server (ts1):
XX# (when it asks for a password I need to type the password manually here)
XX#
XXGandalf:
XX	DELAY 1
XX	SEND "ts1|"
XX	WAIT "class start"
XX#
XX# Keep sending <CR>'s until the LAT prompts for a username:
XX#
XXWaitLat:
XX	DELAY 1
XX	ON "username>" GOTO Lat
XX	SEND "|"
XX	GOTO WaitLat
XX#
XX# Tell the LAT that it's me, and connect to the "cookie cluster" (my host
XX# systems). Tell the cluster my user name.
XX# (when it asks for a password I need to type the password manually here)
XX#
XXLat:
XX	SEND "wecker|"
XX	DELAY 1
XX	SEND "connect cookie|"
XX	WAIT "Username:"
XX	SEND "WECKER|"
XX	WAIT "at home"
XX	SEND "||"
XX#
XX# Got through all the LOGIN garbage, so let's do some work.
XX#
XX	WAIT "$ "
XX#
XX# Get into the right directory and no broadcast mode
XX#
XX	SEND "set term/nobroad|"
XX	SEND "set default [wecker.amiga.vt100]|"
XX	WAIT "$ "
XX#
XX# Send the shar file for the terminal emulator via XMODEM:
XX#
XX	SEND "xmodem -r vt100.shar|"
XX	DELAY 3
XX	XS vt100.shar
XX	WAIT "$ "
XX#
XX# Send the shar file via KERMIT (assumes that the emulator is in CRLF mode):
XX#
XXKermitShar:
XX	DELAY 1
XX	SEND "kermit|server|"
XX	DELAY 3
XX	KS vt100.shar
XX	DELAY 1
XX	KB
XX	SEND "|exit|"
XX	WAIT "$ "
XX#
XX# Start up kermit and upload each source file separately
XX# (on VMS this assumes that our transfer mode is CRLF (not image))
XX#
XX	SEND "kermit|server|"
XX	DELAY 3
XX	KS readme,vt100.doc,makefile,vt100.h,vt100.c,init.c,window.c
XX	KS xmodem.c,remote.c,kermit.c,script.c,$
XX#
XX# We popped out of server mode, so exit and we're done
XX#
XX	SEND "|exit|"
XX	EXIT
SHAR_EOF
if test 11252 -ne "`wc -c vt100.doc`"
then
echo shar: error transmitting vt100.doc '(should have been 11252 characters)'
fi
echo shar: extracting makefile
sed 's/^XX//' << \SHAR_EOF > makefile
XX######################################################################
XX#
XX# Makefile to build vt100 terminal emulator
XX#
XX#	     860823 DBW - Integrated and rewrote lots of code
XX#	v2.0 860809 DBW	- Major release.. LOTS of changes
XX# 	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
XX# 	v1.0 860712 DBW	- First version released
XX#
XX######################################################################
XX
XXOBJS	= vt100.o init.o window.o xmodem.o remote.o kermit.o script.o
XX
XXINCL	= vt100.h
XX#INCL	= 
XX
XX#REDIR	= > PRT:
XXREDIR	=
XX
XXvt100	: $(OBJS)
XX	ln $(REDIR) -v -o vt100 $(OBJS) -lc
XX
XXvt100.o	: vt100.c $(INCL)
XX	cc $(REDIR) -b +Hvt100.syms vt100.c
XX
XXinit.o	: init.c $(INCL)
XX	cc $(REDIR) -b +Ivt100.syms init.c
XX
XXwindow.o : window.c $(INCL)
XX	cc $(REDIR) -b +Ivt100.syms window.c
XX
XXxmodem.o : xmodem.c $(INCL)
XX	cc $(REDIR) -b +Ivt100.syms xmodem.c
XX
XXremote.o : remote.c $(INCL)
XX	cc $(REDIR) -b +Ivt100.syms remote.c
XX
XXkermit.o : kermit.c $(INCL)
XX	cc $(REDIR) -b +Ivt100.syms kermit.c
XX
XXscript.o : script.c $(INCL)
XX	cc $(REDIR) -b +Ivt100.syms script.c
XX
SHAR_EOF
if test 1035 -ne "`wc -c makefile`"
then
echo shar: error transmitting makefile '(should have been 1035 characters)'
fi
echo shar: extracting vt100.h
sed 's/^XX//' << \SHAR_EOF > vt100.h
XX/*********************************************************************
XX *  a terminal program that has ascii and xmodem transfer capability
XX *
XX *	     860823 DBW - Integrated and rewrote lots of code
XX *	v2.0 860809 DBW	- Major release.. LOTS of changes
XX *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
XX *	v1.0 860712 DBW	- First version released
XX *
XX *  use esc to abort xmodem transfer
XX *
XX *  written by Michael Mounier
XX *  new version by Dave Wecker 860621
XX ************************************************************************/
XX
XX/* define the compiler type here */
XX#define	LATTICE	0
XX#define MANX	1
XX
XX/*  compiler directives to fetch the necessary header files */
XX#include <exec/types.h>
XX#include <exec/exec.h>
XX#include <intuition/intuition.h>
XX#include <intuition/intuitionbase.h>
XX#include <graphics/gfxbase.h>
XX#include <graphics/gfx.h>
XX#include <graphics/text.h>
XX#include <graphics/regions.h>
XX#include <graphics/copper.h>
XX#include <graphics/gels.h>
XX#include <devices/serial.h>
XX#include <devices/keymap.h>
XX#include <hardware/blit.h>
XX#include <stdio.h>
XX#include <ctype.h>
XX#include <libraries/dos.h>
XX#include <devices/timer.h>
XX
XX#if MANX
XX#include <functions.h>
XX#undef NULL
XX#define   NULL   ((void *)0)
XX#endif
XX
XX#define INTUITION_REV 1L
XX#define GRAPHICS_REV  1L
XX
XX/* things for xmodem send and recieve */
XX#define GOODREAD    0
XX#define TIMEOUT	    1
XX#define USERABORT   2
XX#define SECSIZ   0x80
XX#define TTIME_SHORT 5        /* number of seconds for short timeout */
XX#define TTIME_LONG  50	     /* number of seconds for long  timeout */
XX#define BufSize  0x1000      /* Text buffer */
XX#define ERRORMAX 10          /* Max errors before abort */
XX#define RETRYMAX 10          /* Maximum retrys before abort */
XX#define SOH      1           /* Start of sector char */
XX#define EOT      4           /* end of transmission char */
XX#define ACK      6           /* acknowledge sector transmission */
XX#define NAK      21          /* error in transmission detected */
XX
XX#define FILEMAX 8    /* number of file menu items */
XX#define RSMAX 5      /* speed menu items */
XX#define XFMAX 2      /* transfer mode items */
XX#define SCRIPTMAX 2  /* script menu items */
XX#define MAXMENU 4    /* total number of menu entries */
XX
XX#define BOLD	    1	    /* modes in curmode and savmode */
XX#define	UNDERLINE   2
XX#define	REVERSE	    4
XX#define	BLINK	    8
XX
XX/* things for script support */
XX
XX#define GOTOLABEL   1
XX#define	NEXTCOMMAND 0
XX#define ONCOMMAND   2
XX
XX#define	WAIT_TIMER  2
XX#define WAIT_STRING 1
XX
XXextern struct MsgPort *CreatePort();
XX
XX#ifdef MODULE_MAIN
XXchar    bufr[BufSize];
XXint     fd, timeout = FALSE, ttime;
XXint	multi = FALSE, server;
XXlong    bytes_xferred;
XXstruct IntuitionBase *IntuitionBase;
XXstruct GfxBase *GfxBase;
XX
XXstruct NewScreen NewScreen = {
XX   0L,197L,640L,205L,1L,       /* left, top, width, height, depth */
XX   0,1,HIRES,    /* DetailPen, BlockPen, ViewModes */
XX   CUSTOMSCREEN,NULL,   /* Type, Font */
XX   (UBYTE *)"VT100 Terminal Screen", /* Title */
XX   NULL,NULL };         /* Gadgets, Bitmap */
XX
XXstruct NewWindow NewWindow = {
XX   0,3L,640L,200L,     /* left, top, width, height */
XX   0,1,              /* detailpen, blockpen */
XX   MENUPICK | CLOSEWINDOW | RAWKEY | NEWSIZE,
XX   SMART_REFRESH | REPORTMOUSE | ACTIVATE | BORDERLESS |
XX   WINDOWCLOSE | WINDOWDEPTH | WINDOWDRAG, /* Flags */
XX   NULL,NULL,        /* FirstGadget, CheckMark */
XX   (UBYTE *)
XX   "VT100 Terminal Window                                                  ",
XX   NULL,             /* set screen after open screen */
XX   NULL,             /* bitmap */
XX   640L, 200L, 640L, 200L,/* minw, minh, maxw, maxh */
XX   CUSTOMSCREEN      /* Type */
XX};
XX
XXstruct Screen *myscreen;            /* ptr to applications screen */
XXstruct Window *mywindow;            /* ptr to applications window */
XXstruct ViewPort *myviewport;
XXstruct IntuiMessage *NewMessage;    /* msg structure for GetMsg() */
XXstruct Preferences  *Prefs;	    /* preferences from GetPrefs() */
XX
XXstruct MenuItem FileItem[FILEMAX];
XXstruct IntuiText FileText[FILEMAX];
XXstruct MenuItem RSItem[RSMAX];
XXstruct IntuiText RSText[RSMAX];
XXstruct MenuItem XFItem[XFMAX];
XXstruct IntuiText XFText[XFMAX];
XXstruct MenuItem ScriptItem[SCRIPTMAX];
XXstruct IntuiText ScriptText[SCRIPTMAX];
XXstruct Menu menu[MAXMENU];
XXstruct IOExtSer *Read_Request;
XXchar rs_in[2048];
XXstruct IOExtSer *Write_Request;
XXchar rs_out[2];
XXstruct timerequest Timer;
XXstruct MsgPort *Timer_Port = NULL;
XXstruct timerequest Script_Timer;
XXstruct MsgPort *Script_Timer_Port = NULL;
XXint want_message;
XXint x,y,curmode;
XXint MINX	= 0;
XXint MAXX	= 632;
XXint MINY	= 14;
XXint MAXY	= 198;
XXint top		= 14;
XXint bot		= 198;
XXint savx	= 0;
XXint savy	= 14;
XXint savmode	= 0;
XXint nlmode	= 0;
XXint alt		= 0;
XXint savalt	= 0;
XXint a[2]	= { 0, 0 };
XXint sa[2]	= { 0, 0 };
XXint  inesc	= -1;
XXint  inctrl	= -1;
XXint  private	= 0;
XXint  badseq	= 0;
XXchar *blanks	= "                                                                                 ";
XXint  maxcol	= 79;
XX
XX/*************************** defaults ***********************************/
XXint	p_baud	     = 2400;	    /* baud rate */
XXint	p_screen     = 0;	    /* 0 = WORKBENCH,	    1 = CUSTOM */
XXint	p_interlace  = 0;	    /* 0 = no interlace,    1 = interlace */
XXint	p_depth	     = 2;	    /* number of bit planes (1 or 2) */
XXint	p_foreground = 0x840;	    /* default foreground RGB color */
XXint	p_background = 0x000;	    /* default background RGB color */
XXint	p_bold	     = 0xa00;	    /* default BOLD       RGB color */
XXint	p_cursor     = 0x00d;	    /* default Cursor	  RGB color */
XXint	p_lines	     = 24;	    /* number of lines on the screen */
XXint	p_mode	     = 0;	    /* 0 = image, 1 = CRLF (for kermit) */
XXint	p_xon	     = 0;	    /* 0 = disabled, 1 = enabled */
XXchar	*p_f[10]     = {	    /* function key defaults */
XX    "OP","OQ","OR","OS",
XX    "f5","f6","f7","f8","f9","f10" };
XX
XXchar	*p_F[10]     = {	    /* shifted function key defaults */
XX    "F1","F2","F3","F4","F5",
XX    "F6","F7","F8","F9","F10"};
XX
XX/* for script file */
XXint script_on;
XXint script_wait;
XX
XX#else /* not MODULE_MAIN */
XX
XXextern int     multi;		    /* flags multi file transfers */
XXextern int     server;
XXextern int     want_message;
XXextern char    bufr[BufSize];
XXextern int     fd, timeout, ttime;
XXextern long    bytes_xferred;
XX
XXextern struct IntuitionBase *IntuitionBase;
XXextern struct GfxBase *GfxBase;
XX
XXextern struct NewScreen NewScreen;
XXextern struct NewWindow NewWindow;
XXextern struct Screen *myscreen;
XXextern struct Window *mywindow;
XXextern struct ViewPort *myviewport;
XXextern struct IntuiMessage *NewMessage;
XXextern struct Preferences  *Prefs;
XXextern struct MenuItem FileItem[FILEMAX];
XXextern struct IntuiText FileText[FILEMAX];
XXextern struct MenuItem RSItem[RSMAX];
XXextern struct IntuiText RSText[RSMAX];
XXextern struct MenuItem XFItem[XFMAX];
XXextern struct IntuiText XFText[XFMAX];
XXextern struct MenuItem ScriptItem[SCRIPTMAX];
XXextern struct IntuiText ScriptText[SCRIPTMAX];
XXextern struct Menu menu[MAXMENU];
XXextern struct timerequest Timer, Script_Timer;
XXextern struct MsgPort *Timer_Port, *Script_Timer_Port;
XXextern struct IOExtSer *Read_Request;
XXextern char rs_in[2048];
XXextern struct IOExtSer *Write_Request;
XXextern char rs_out[2];
XXextern int x,y,curmode;
XXextern int MINX,MAXX,MINY,MAXY,top,bot,savx,savy;
XXextern int savmode,nlmode,alt,savalt,a[2],sa[2];
XXextern int inesc,inctrl,private,badseq,maxcol;
XXextern char *blanks;
XXextern int p_baud,p_screen,p_interlace,p_depth;
XXextern int p_foreground,p_background,p_bold,p_cursor,p_lines,p_mode,p_xon;
XXextern char *p_f[10],*p_F[10];
XXextern int script_on;
XXextern int script_wait;
XX
XXextern int do_send(),do_capture();
XX
XX#endif /* not MODULE_MAIN */
XX
XX#ifndef MODULE_INIT
XXextern void InitDefaults(),InitDevs(),InitFileItems(),InitRSItems(),
XX	 InitXFItems(),InitScriptItems(),InitMenu();
XX#endif
XX
XX#ifndef MODULE_WINDOW
XXextern	void filename(),emits(),emit(),emitbatch(),cursoroff(),cursoron();
XXextern	int  toasc();
XX#endif
XX
XX#ifndef MODULE_XMODEM
XXextern	void sendchar(),sendstring();
XXextern	int  readchar(),XMODEM_Read_File(),XMODEM_Send_File();
XX#endif
XX
XX#ifndef MODULE_REMOTE
XXextern	void doremote(),doindex();
XX#endif
XX
XX#ifndef MODULE_KERMIT
XXextern	int  doksend(),dokreceive(), multi_xfer(), saybye();
XX#endif
XX
XX#ifndef MODULE_SCRIPT
XXextern int script_start(), chk_script(), exit_script(), do_script_cmd();
XX#endif
SHAR_EOF
if test 8210 -ne "`wc -c vt100.h`"
then
echo shar: error transmitting vt100.h '(should have been 8210 characters)'
fi
echo shar: extracting vt100.c
sed 's/^XX//' << \SHAR_EOF > vt100.c
XX/************************************************************************
XX *  vt100 terminal emulator with xmodem transfer capability
XX *
XX *	     860823 DBW - Integrated and rewrote lots of code
XX *	v2.0 860809 DBW - Major rewrite
XX *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
XX *	v1.0 860712 DBW	- First version released
XX *
XX *  use <esc> to abort xmodem or kermit transfers
XX *
XX *  written by Michael Mounier
XX *  new version by Dave Wecker
XX ************************************************************************/
XX
XX/*  all includes defines and globals */
XX#define MODULE_MAIN 1
XX#include "vt100.h"
XX
XX/******************************************************/
XX/*                   Main Program                     */
XX/*                                                    */
XX/*      This is the main body of the program.         */
XX/******************************************************/
XX
XXchar lookahead[2048];
XXFILE *tranr = NULL;
XXFILE *trans = NULL;
XXint capture,send;
XXchar name[256];
XX
XXmain(argc,argv)
XXint	argc;
XXchar	**argv;
XX    {
XX    ULONG class;
XX    unsigned int code,menunum,itemnum;
XX    int KeepGoing,i,j,la,dola,xonflg,rxonflg,actual;
XX    char c;
XX
XX    InitDefaults(argc,argv);
XX    InitDevs();
XX    InitFileItems();
XX    InitRSItems();
XX    InitXFItems();
XX    InitScriptItems();
XX    InitMenu();
XX    SetMenuStrip(mywindow,&menu[0]);
XX
XX    KeepGoing =	    TRUE;
XX    capture   =	    FALSE;
XX    send      =	    FALSE;
XX    xonflg    =	    FALSE;
XX    rxonflg   =	    FALSE;
XX    maxcol    =	    MAXX / 8;
XX    la	      =	    0;
XX    x	      =	    MINX ; 
XX    y	      =	    MINY; 
XX    curmode   =	    0;
XX    script_on =     FALSE;
XX    script_wait=    TRUE;
XX    SetAPen(mywindow->RPort,1L);
XX    cursoron();
XX    cursoroff();    
XX    emit(12);
XX    BeginIO(Read_Request);
XX
XX    while( KeepGoing )
XX	    {
XX	    /* wait for window message or serial port message */
XX	    cursoron();
XX	    if (script_wait)	/* if script ready dont wait here */
XX		Wait(
XX		 (1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) |
XX		 (1L << mywindow->UserPort->mp_SigBit) |
XX		 (1L << Script_Timer_Port->mp_SigBit));
XX	    cursoroff();
XX	    
XX	    /* do ascii file send */
XX	    if (send)
XX		{
XX		if ((c=getc(trans)) != EOF) {
XX		    if (c == '\n') c = '\r';
XX		    sendchar(c);
XX		    }
XX		else {
XX		    fclose(trans);
XX		    emits("\nFile Sent\n");
XX		    send=FALSE;
XX		    }
XX		}
XX
XX	    /* see if there are any characters from the host */
XX	    if (CheckIO(Read_Request)) {
XX		WaitIO(Read_Request);
XX		c = rs_in[0] & 0x7F;
XX		doremote(c);
XX		if (script_on) chk_script(c);
XX	        if (capture && c != 10) {
XX	      	    if (c == 13) c = 10;
XX		    putc(c , tranr);
XX		    }
XX		Read_Request->IOSer.io_Command = SDCMD_QUERY;
XX		BeginIO(Read_Request);
XX		WaitIO(Read_Request);
XX		Read_Request->IOSer.io_Command = CMD_READ;
XX		actual = (int)Read_Request->IOSer.io_Actual;
XX		if (actual > 0) {
XX		    if (inesc   <  0 &&
XX			inctrl  <  0 &&
XX			a[alt]  == 0 &&
XX			capture == FALSE) dola = 1;
XX		    else dola = 0;
XX		    Read_Request->IOSer.io_Length =
XX			Read_Request->IOSer.io_Actual;
XX		    BeginIO(Read_Request);
XX		    WaitIO(Read_Request);
XX		    Read_Request->IOSer.io_Length = 1;
XX
XX		    /* if too many use XON/XOFF */
XX		    if (p_xon && actual > 1536 && xonflg == FALSE) {
XX			sendchar(19);
XX			xonflg = TRUE;
XX			}
XX		    for (i = 0; i < actual; i++) {
XX			c=rs_in[i] & 0x7f;
XX			if (script_on) chk_script(c);
XX
XX			/* handle host request for flow control */
XX			if (p_xon) {
XX			    if (rxonflg) {
XX				if (c == 17) {
XX				    rxonflg = FALSE;
XX				    }
XX				continue;
XX				}
XX			    else if (c == 19) {
XX				rxonflg = TRUE;
XX				continue;
XX				}
XX			    }
XX			if (dola == 1) {
XX			    if (c >= ' ' && c <= '~') lookahead[la++] = c;
XX			    else {
XX				if (la > 0) {
XX				    emitbatch(la,lookahead);
XX				    la = 0;
XX				    }
XX				doremote(c);
XX				dola = 0;
XX				}
XX			    }
XX			else {
XX			    doremote(c);
XX			    if (p_xon && xonflg == FALSE && i == 1023) {
XX				Read_Request->IOSer.io_Command = SDCMD_QUERY;
XX				BeginIO(Read_Request);
XX				WaitIO(Read_Request);
XX				Read_Request->IOSer.io_Command = CMD_READ;
XX				j = (int)Read_Request->IOSer.io_Actual;
XX				if (j > 1023) {
XX				    sendchar(19);
XX				    xonflg = TRUE;
XX				    }
XX				}
XX			    if (inesc   <  0 &&
XX				inctrl  <  0 &&
XX				a[alt]  == 0 &&
XX				capture == FALSE) dola = 1;
XX			    if (capture && c != 10) {
XX				if (c == 13) c = 10;
XX				putc(c , tranr);
XX				}
XX			    }
XX			}
XX
XX		    /* dump anything left in the lookahead buffer */
XX		    if (la > 0) {
XX			emitbatch(la,lookahead);
XX			la = 0;
XX			}
XX
XX		    /* tell host to resume transmission */
XX		    if (xonflg == TRUE) {
XX			sendchar(17);
XX			xonflg = FALSE;
XX			}
XX		    }
XX
XX		BeginIO(Read_Request);
XX
XX		/* wait for host to tell us to resume */
XX		while (rxonflg == TRUE) {
XX		    WaitIO(Read_Request);
XX		    if ((rs_in[0] & 0x7F) == 17) rxonflg = FALSE;
XX		    BeginIO(Read_Request);
XX		    }
XX		}
XX
XX	    while( NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort) )
XX		{
XX		class = NewMessage->Class;
XX		code = NewMessage->Code;
XX		ReplyMsg( NewMessage );
XX		switch( class )
XX		    {
XX		    case CLOSEWINDOW:
XX		    KeepGoing = FALSE;
XX		    break;
XX
XX		    case RAWKEY:
XX		    c = toasc(code,0);
XX		    break;
XX
XX		    case NEWSIZE:
XX		    emit(12);
XX		    break;
XX
XX		    case MENUPICK:
XX		    if ( code != MENUNULL )
XX			{
XX			menunum = MENUNUM( code );
XX			itemnum = ITEMNUM( code );
XX			switch( menunum )
XX			    {
XX			    case 0:
XX			    switch( itemnum )
XX				{
XX				case 0:
XX				do_capture(NULL);
XX				break;
XX
XX				case 1:
XX				do_send(NULL);
XX				break;
XX
XX				case 2:
XX				emits("\nXmodem Receive:");
XX				filename(name);
XX				multi_xfer(name,XMODEM_Read_File,0);
XX				break;
XX
XX				case 3:
XX				emits("\nXmodem Send:");
XX				filename(name);
XX				multi_xfer(name,XMODEM_Send_File,1);
XX				break;
XX
XX				case 4:
XX				server = TRUE;
XX				itemnum = 5;
XX
XX				case 5:
XX				emits("\nKermit Receive local name:");
XX				filename(name);
XX				multi_xfer(name,dokreceive,0);
XX				break;
XX
XX				case 6:
XX				server = TRUE;
XX				emits("\nKermit Send local name:");
XX				filename(name);
XX				multi_xfer(name,doksend,1);
XX				break;
XX
XX				case 7:
XX				saybye();
XX				break;
XX				}
XX			    break;
XX
XX			    case 1:
XX			    AbortIO(Read_Request);
XX			    switch( itemnum )
XX				{
XX				case 0:
XX				Read_Request->io_Baud = 300;
XX				break;
XX				case 1:
XX				Read_Request->io_Baud = 1200;
XX				break;
XX				case 2:
XX				Read_Request->io_Baud = 2400;
XX				break;
XX				case 3:
XX				Read_Request->io_Baud = 4800;
XX				break;
XX				case 4:
XX				Read_Request->io_Baud = 9600;
XX				break;
XX				}
XX			    Read_Request->IOSer.io_Command = SDCMD_SETPARAMS;
XX			    DoIO(Read_Request);
XX			    Read_Request->IOSer.io_Command = CMD_READ;
XX			    BeginIO(Read_Request);
XX			    break;
XX
XX			    case 2:
XX			    p_mode = itemnum;
XX			    break;
XX
XX			    case 3:
XX			    if (!itemnum && !script_on) {
XX			    	emits("Script file name: ");
XX			    	filename(name);
XX			    	script_start(name);
XX			        }
XX			    if (itemnum && script_on) {
XX			    	exit_script();
XX			    	}
XX			    break;
XX			    
XX			    } /* end of switch ( menunum ) */
XX			}    /*  end of if ( not null ) */
XX		    }   /* end of switch (class) */
XX		}   /* end of while ( newmessage )*/
XX
XX            if (!script_wait || 
XX                 (CheckIO(&Script_Timer) && script_wait == WAIT_TIMER)) 
XX               do_script_cmd(NEXTCOMMAND);
XX
XX	    }  /* end while ( keepgoing ) */
XX		
XX    /*   It must be time to quit, so we have to clean
XX    *   up and exit.
XX    */
XX
XX    CloseDevice(&Timer);
XX    DeletePort(Timer_Port);
XX    CloseDevice(&Script_Timer);
XX    DeletePort(Script_Timer_Port);
XX    CloseDevice(Read_Request);
XX    DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
XX    FreeMem(Read_Request,(long)sizeof(*Read_Request));
XX    CloseDevice(Write_Request);
XX    DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
XX    FreeMem(Write_Request,(long)sizeof(*Write_Request));
XX    ClearMenuStrip( mywindow );
XX    CloseWindow( mywindow );
XX    if (p_screen != 0) CloseScreen( myscreen );
XX    exit(FALSE);
XX    } /* end of main */
XX
XX
XXdo_capture(file)
XXchar *file;
XX{
XX    if (capture == TRUE)
XX        {
XX        capture=FALSE;
XX        fclose(tranr);
XX        emits("\nEnd File Capture\n");
XX        }
XX    else
XX        {
XX        if (file == NULL) {
XX            emits("\nAscii Capture:");
XX            filename(name);
XX	    } 
XX	else strcpy(name, file);
XX        if ((tranr=fopen(name,"w")) == 0)
XX  	    {
XX	    capture=FALSE;
XX	    emits("\nError Opening File\n");
XX	    return(FALSE);
XX	    }
XX	capture=TRUE;
XX        }
XX}
XX
XXdo_send(file)
XXchar *file;
XX{
XX    if (send == TRUE)
XX	{ 
XX        send=FALSE;
XX        fclose(trans);
XX        emits("\nFile Send Cancelled\n");
XX        }
XX    else
XX        {
XX        if (file == NULL) {
XX            emits("\nAscii Send:");
XX            filename(name);
XX            }
XX	else strcpy(name, file);
XX        if ((trans=fopen(name,"r")) == 0)
XX   	    {
XX   	    send=FALSE;
XX	    emits("\nError Opening File\n");
XX	    return(FALSE);
XX	    }
XX	send=TRUE;
XX	}
XX}
XX
SHAR_EOF
if test 8817 -ne "`wc -c vt100.c`"
then
echo shar: error transmitting vt100.c '(should have been 8817 characters)'
fi
echo shar: extracting init.c
sed 's/^XX//' << \SHAR_EOF > init.c
XX/***************************************************************
XX * vt100 - terminal emulator - initialization
XX *
XX *	     860823 DBW - Integrated and rewrote lots of code
XX *	v2.0 860809 DBW - Major rewrite
XX *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
XX *	v1.0 860712 DBW	- First version released
XX *
XX ***************************************************************/
XX
XX#define MODULE_INIT 1
XX#include "vt100.h"
XX
XXextern char *malloc();
XX
XXvoid InitDefaults(argc,argv)
XXint	argc;
XXchar	**argv;
XX    {
XX    FILE    *fd;
XX    char    line[256],scr[32],delim,macro[256],c0,*ptr;
XX    int	    i,j,k;
XX
XX    if (((argc > 1) && (fd=fopen(argv[1],"r")) != 0) ||
XX	(fd=fopen("vt100.init","r")) != 0 ||
XX	(fd=fopen("c:vt100.init","r")) != 0) {
XX	while (fgets(line,256,fd) != 0) {
XX	    if ((c0 = line[0]) == '#') continue;
XX	    if ((c0|' ') == 'e') break;
XX	    switch (c0|' ') {
XX		case 'b':
XX		if ((line[1]|' ') == 'o') {
XX		    /* bold color */
XX		    if (sscanf(line,"%s %x",scr,&i) == 2) p_bold = i;
XX		    break;
XX		    }
XX		if ((line[1]|' ') != 'a') break;
XX		switch(line[2]|' ') {
XX		    /* baud rate */
XX		    case 'u':
XX		    if (sscanf(line,"%s %d",scr,&i) == 2) p_baud = i;
XX		    break;
XX
XX		    /* background */
XX		    case 'c':
XX		    if (sscanf(line,"%s %x",scr,&i) == 2) p_background = i;
XX		    break;
XX		    }
XX		break;
XX
XX		/* screen type */
XX		case 's':
XX		if (sscanf(line,"%s %s",scr,scr) == 2) {
XX		    if ((scr[0]|' ') == 'w') p_screen = 0;
XX		    else		     p_screen = 1;
XX		    }
XX		break;
XX
XX		/* number of lines */
XX		case 'l':
XX		if (sscanf(line,"%s %d",scr,&i) == 2) p_lines = i;
XX		break;
XX
XX		/* screen depth */
XX		case 'd':
XX		if (sscanf(line,"%s %d",scr,&i) == 2) p_depth = i;
XX		break;
XX
XX		/* cursor color */
XX		case 'c':
XX		if (sscanf(line,"%s %d",scr,&i) == 2) p_cursor = i;
XX		break;
XX
XX		/* interlace type */
XX		case 'i':
XX		if (sscanf(line,"%s %s",scr,scr) == 2) {
XX		    if ((scr[1]|' ') == 'n') p_interlace = 1;
XX		    else		     p_interlace = 0;
XX		    }
XX		break;
XX
XX		case 'f':
XX		switch (line[1]|' ') {
XX
XX		    /* foreground color */
XX		    case 'o':
XX    		    if (sscanf(line,"%s %x",scr,&i) == 2) p_foreground = i;
XX		    break;
XX
XX		    /* function key */
XX		    default:
XX		    if (sscanf(&line[1],"%d",&i) != 1) break;
XX		    if (i < 1 || i > 10) break;
XX		    delim = 0;
XX		    for (j=2; line[j] != 0 &&
XX			      (line[j] == ' ' || line[j] == '\t'); j++) ;
XX		    if (line[j] == 0) {
XX			if (c0 == 'f') p_f[i-1] = NULL;
XX			else	       p_F[i-1] = NULL;
XX			break;
XX			}
XX		    delim = line[j];
XX		    k = 0;
XX		    macro[0] = 0;
XX		    while (line[++j] != delim) {
XX			if (line[j] == 0) {
XX			    if (fgets(line,256,fd) == 0) {
XX				line[0] = delim;
XX				line[1] = 0;
XX				}
XX			    j = -1;
XX			    continue;
XX			    }
XX			if (line[j] == '^' && line[++j] != '^')
XX			    macro[k++] = (line[j]|' ') - 0x60;
XX			else if (line[j] != '\n') macro[k++] = line[j];
XX			macro[k]   = 0;
XX			}
XX		    ptr = malloc(k+1);
XX		    if (c0 == 'f') p_f[i-1] = ptr;
XX		    else	   p_F[i-1] = ptr;
XX		    strcpy(ptr,macro);
XX		    break;
XX		    }
XX		break;
XX
XX		case 'm':
XX		if (sscanf(line,"%s %s",scr,scr) == 2) {
XX		    if ((scr[0]|' ') == 'i')	p_mode = 0;
XX		    else			p_mode = 1;
XX		    }
XX		break;
XX
XX		case 'x':
XX		if (sscanf(line,"%s %s",scr,scr) == 2) {
XX		    if ((scr[0]|' ') == 'd')	p_xon = 0;
XX		    else			p_xon = 1;
XX		    }
XX		break;
XX		}
XX	    }
XX	fclose(fd);
XX	}
XX    /* Now set up all the screen info as necessary */
XX    if (p_interlace == 0) {
XX	if (p_lines > 24) p_lines = 24;
XX	MINY = 14;
XX	NewWindow.Height    = (long)((p_lines*8)+8);
XX	}
XX    else {
XX	if (p_lines > 48) p_lines = 48;
XX	MINY = 16;
XX	NewScreen.ViewModes |= LACE;
XX	NewWindow.Height    = (long)((p_lines*8)+10);
XX	}
XX    NewWindow.MinHeight = NewWindow.Height;
XX    NewWindow.MaxHeight = NewWindow.Height;
XX    NewWindow.TopEdge   = 3L;
XX    MAXY = ((p_lines-1)*8) + MINY;
XX    top  = MINY;
XX    bot	 = MAXY;
XX    savx = MINX;
XX    savy = MINY;
XX    if (p_screen == 1) {
XX	if (p_depth > 2) p_depth = 2;
XX	if (p_depth < 1) p_depth = 1;
XX	NewScreen.Depth	    = (long)p_depth;
XX	NewScreen.Height    = (long)((p_lines*8)+15);
XX	if (p_interlace == 1)
XX	    NewScreen.TopEdge   = (long)(402 - NewScreen.Height);
XX	else
XX	    NewScreen.TopEdge   = 0L;
XX	}
XX    else {
XX	p_depth			= 2L;
XX	NewWindow.TopEdge	= 0L;
XX	NewWindow.Screen	= NULL;
XX	NewWindow.Type	= WBENCHSCREEN;
XX	}
XX    }
XX
XXvoid InitDevs()
XX{
XXUSHORT	colors[4];
XX
XXIntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", INTUITION_REV);
XXif( IntuitionBase == NULL )
XX   {
XX   puts("can't open intuition\n");
XX   exit(TRUE);
XX   }
XX
XXGfxBase = (struct GfxBase *)OpenLibrary("graphics.library",GRAPHICS_REV);
XXif( GfxBase == NULL )
XX   {
XX   puts("can't open graphics library\n");
XX   exit(TRUE);
XX   }
XX
XXif (p_screen == 1) {
XX    if ((myscreen = (struct Screen *)OpenScreen(&NewScreen)) == NULL) {
XX	puts("can't open screen!!\n");
XX	exit(TRUE);
XX	}
XX    NewWindow.Screen = myscreen;
XX    }
XX
XXif(( mywindow = (struct Window *)OpenWindow(&NewWindow) ) == NULL)
XX   {
XX   puts("cant open window\n");
XX   if (p_screen != 0) CloseScreen( myscreen );
XX   exit(TRUE);
XX   }
XX
XXmyviewport   = (struct ViewPort *)ViewPortAddress(mywindow);
XX
XXif (p_screen != 0) {
XX    colors[0] = p_background;
XX    colors[1] = p_foreground;
XX    colors[2] = p_bold;
XX    colors[3] = p_cursor;
XX    if (p_depth == 1)
XX	LoadRGB4(myviewport,(struct ColorMap *)colors,2L);
XX    else
XX	LoadRGB4(myviewport,(struct ColorMap *)colors,4L);
XX    }
XX
XXRead_Request = (struct IOExtSer *)
XX    AllocMem((long)sizeof(*Read_Request),MEMF_PUBLIC|MEMF_CLEAR);
XXRead_Request->io_SerFlags = SERF_SHARED | SERF_XDISABLED;
XXRead_Request->IOSer.io_Message.mn_ReplyPort = CreatePort("Read_RS",0);
XXif(OpenDevice(SERIALNAME,NULL,Read_Request,NULL))
XX   {
XX   puts("Cant open Read device\n");
XX   CloseWindow( mywindow );
XX   if (p_screen != 0) CloseScreen( myscreen );
XX   DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
XX   FreeMem(Read_Request,(long)sizeof(*Read_Request));
XX   exit(TRUE);
XX   }
XXRead_Request->IOSer.io_Command = CMD_READ;
XXRead_Request->IOSer.io_Length = 1;
XXRead_Request->IOSer.io_Data = (APTR) &rs_in[0];
XX
XXWrite_Request = (struct IOExtSer *)
XX    AllocMem((long)sizeof(*Write_Request),MEMF_PUBLIC|MEMF_CLEAR);
XXWrite_Request->io_SerFlags = SERF_SHARED | SERF_XDISABLED;
XXWrite_Request->IOSer.io_Message.mn_ReplyPort = CreatePort("Write_RS",0);
XXif(OpenDevice(SERIALNAME,NULL,Write_Request,NULL))
XX    {
XX    puts("Cant open Write device\n");
XX    CloseDevice(Read_Request);
XX    DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
XX    FreeMem(Read_Request,(long)sizeof(*Read_Request));
XX    DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
XX    FreeMem(Write_Request,(long)sizeof(*Write_Request));
XX    CloseWindow( mywindow );
XX    if (p_screen != 0) CloseScreen( myscreen );
XX    exit(TRUE);
XX    }
XXWrite_Request->IOSer.io_Command = CMD_WRITE;
XXWrite_Request->IOSer.io_Length = 1;
XXWrite_Request->IOSer.io_Data = (APTR) &rs_out[0];
XX
XXRead_Request->io_SerFlags = SERF_SHARED | SERF_XDISABLED;
XXRead_Request->io_Baud = p_baud;
XXRead_Request->io_ReadLen = 8;
XXRead_Request->io_WriteLen = 8;
XXRead_Request->io_CtlChar = 1L;
XXRead_Request->io_RBufLen = 2048;
XXRead_Request->IOSer.io_Command = SDCMD_SETPARAMS;
XXDoIO(Read_Request);
XXRead_Request->IOSer.io_Command = CMD_READ;
XX
XXTimer_Port = CreatePort("Timer Port",0);
XXScript_Timer_Port = CreatePort("Timer Port",0);
XX
XXif (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Timer, 0) ||
XX    OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Script_Timer, 0)) {
XX    puts("can't open timer device");
XX    DeletePort(Timer_Port);
XX    DeletePort(Script_Timer_Port);
XX    CloseDevice(Read_Request);
XX    DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
XX    FreeMem(Read_Request,(long)sizeof(*Read_Request));
XX    CloseDevice(Write_Request);
XX    DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
XX    FreeMem(Write_Request,(long)sizeof(*Write_Request));
XX    CloseWindow( mywindow );
XX    if (p_screen != 0) CloseScreen( myscreen );
XX    exit(TRUE);
XX    }
XX
XXTimer.tr_node.io_Message.mn_ReplyPort = Timer_Port;
XXTimer.tr_node.io_Command = TR_ADDREQUEST;
XXTimer.tr_node.io_Flags = 0;
XXTimer.tr_node.io_Error = 0;
XX
XXScript_Timer.tr_node.io_Message.mn_ReplyPort = Script_Timer_Port;
XXScript_Timer.tr_node.io_Command = TR_ADDREQUEST;
XXScript_Timer.tr_node.io_Flags = 0;
XXScript_Timer.tr_node.io_Error = 0;
XX}
XX
XX/*****************************************************************/
XX/*    The following function initializes the structure arrays    */
XX/*   needed to provide the File menu topic.                      */
XX/*****************************************************************/
XXvoid InitFileItems()
XX{
XXint n;
XX
XX/* initialize each menu item and IntuiText with loop */
XXfor( n=0; n<FILEMAX; n++ )
XX   {
XX   FileItem[n].NextItem = &FileItem[n+1];
XX   FileItem[n].LeftEdge = 0;
XX   FileItem[n].TopEdge = 11 * n;
XX   FileItem[n].Width = 135;
XX   FileItem[n].Height = 11;
XX   FileItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX;
XX   FileItem[n].MutualExclude = 0;
XX   FileItem[n].ItemFill = (APTR)&FileText[n];
XX   FileItem[n].SelectFill = NULL;
XX   FileItem[n].Command = 0;
XX   FileItem[n].SubItem = NULL;
XX   FileItem[n].NextSelect = 0;
XX
XX   FileText[n].FrontPen = 0;
XX   FileText[n].BackPen = 1;
XX   FileText[n].DrawMode = JAM2;     /* render in fore and background */
XX   FileText[n].LeftEdge = 0;
XX   FileText[n].TopEdge = 1;
XX   FileText[n].ITextFont = NULL;
XX   FileText[n].NextText = NULL;
XX   }
XXFileItem[FILEMAX-1].NextItem = NULL;
XX
XX/* initialize text for specific menu items */
XXFileText[0].IText = (UBYTE *)"Ascii Capture";
XXFileText[1].IText = (UBYTE *)"Ascii Send";
XXFileText[2].IText = (UBYTE *)"Xmodem Receive";
XXFileText[3].IText = (UBYTE *)"Xmodem Send";
XXFileText[4].IText = (UBYTE *)"Kermit Get";
XXFileText[5].IText = (UBYTE *)"Kermit Receive";
XXFileText[6].IText = (UBYTE *)"Kermit Send";
XXFileText[7].IText = (UBYTE *)"Kermit BYE";
XX}
XX
XX/*****************************************************************/
XX/*    The following function initializes the structure arrays    */
XX/*   needed to provide the BaudRate menu topic.                  */
XX/*****************************************************************/
XXvoid InitRSItems()
XX{
XXint n;
XX
XX/* initialize each menu item and IntuiText with loop */
XXfor( n=0; n<RSMAX; n++ )
XX   {
XX   RSItem[n].NextItem = &RSItem[n+1];
XX   RSItem[n].LeftEdge = 0;
XX   RSItem[n].TopEdge = 11 * n;
XX   RSItem[n].Width = 85;
XX   RSItem[n].Height = 11;
XX   RSItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX | CHECKIT;
XX   RSItem[n].MutualExclude = (~(1 << n));
XX   RSItem[n].ItemFill = (APTR)&RSText[n];
XX   RSItem[n].SelectFill = NULL;
XX   RSItem[n].Command = 0;
XX   RSItem[n].SubItem = NULL;
XX   RSItem[n].NextSelect = 0;
XX
XX   RSText[n].FrontPen = 0;
XX   RSText[n].BackPen = 1;
XX   RSText[n].DrawMode = JAM2;     /* render in fore and background */
XX   RSText[n].LeftEdge = 0;
XX   RSText[n].TopEdge = 1;
XX   RSText[n].ITextFont = NULL;
XX   RSText[n].NextText = NULL;
XX   }
XXRSItem[RSMAX-1].NextItem = NULL;
XX/* select baud item chekced */
XXswitch (p_baud) {
XX    case 300:	n = 0; break;
XX    case 1200:	n = 1; break;
XX    case 2400:	n = 2; break;
XX    case 4800:	n = 3; break;
XX    case 9600:	n = 4; break;
XX    default:	n = 2; p_baud = 2400;
XX    }
XXRSItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX | CHECKIT | CHECKED;
XX
XX/* initialize text for specific menu items */
XXRSText[0].IText = (UBYTE *)"   300";
XXRSText[1].IText = (UBYTE *)"   1200";
XXRSText[2].IText = (UBYTE *)"   2400";
XXRSText[3].IText = (UBYTE *)"   4800";
XXRSText[4].IText = (UBYTE *)"   9600";
XX}
XX
XX/*****************************************************************/
XX/*    The following function initializes the structure arrays    */
XX/*    needed to provide the Transfer Mode menu topic.            */
XX/*****************************************************************/
XXvoid InitXFItems()
XX{
XXint n;
XX
XX/* initialize each menu item and IntuiText with loop */
XXfor( n=0; n<XFMAX; n++ )
XX   {
XX   XFItem[n].NextItem = &XFItem[n+1];
XX   XFItem[n].LeftEdge = 0;
XX   XFItem[n].TopEdge = 11 * n;
XX   XFItem[n].Width = 85;
XX   XFItem[n].Height = 11;
XX   XFItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX | CHECKIT;
XX   XFItem[n].MutualExclude = (~(1 << n));
XX   XFItem[n].ItemFill = (APTR)&XFText[n];
XX   XFItem[n].SelectFill = NULL;
XX   XFItem[n].Command = 0;
XX   XFItem[n].SubItem = NULL;
XX   XFItem[n].NextSelect = 0;
XX
XX   XFText[n].FrontPen = 0;
XX   XFText[n].BackPen = 1;
XX   XFText[n].DrawMode = JAM2;     /* render in fore and background */
XX   XFText[n].LeftEdge = 0;
XX   XFText[n].TopEdge = 1;
XX   XFText[n].ITextFont = NULL;
XX   XFText[n].NextText = NULL;
XX   }
XXXFItem[XFMAX-1].NextItem = NULL;
XX/* mode checked */
XXXFItem[p_mode].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX | CHECKIT | CHECKED;
XX
XX/* initialize text for specific menu items */
XXXFText[0].IText = (UBYTE *)"  image";
XXXFText[1].IText = (UBYTE *)"  CR LF";
XX}
XX
XX
XX/*****************************************************************/
XX/*    The following function initializes the structure arrays    */
XX/*   needed to provide the Script menu topic.                    */
XX/*****************************************************************/
XXvoid InitScriptItems()
XX{
XXint n;
XX
XX/* initialize each menu item and IntuiText with loop */
XXfor( n=0; n<SCRIPTMAX; n++ )
XX   {
XX   ScriptItem[n].NextItem = &ScriptItem[n+1];
XX   ScriptItem[n].LeftEdge = 0;
XX   ScriptItem[n].TopEdge = 11 * n;
XX   ScriptItem[n].Width = 155;
XX   ScriptItem[n].Height = 11;
XX   ScriptItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHBOX;
XX   ScriptItem[n].MutualExclude = 0;
XX   ScriptItem[n].ItemFill = (APTR)&ScriptText[n];
XX   ScriptItem[n].SelectFill = NULL;
XX   ScriptItem[n].Command = 0;
XX   ScriptItem[n].SubItem = NULL;
XX   ScriptItem[n].NextSelect = 0;
XX
XX   ScriptText[n].FrontPen = 0;
XX   ScriptText[n].BackPen = 1;
XX   ScriptText[n].DrawMode = JAM2;     /* render in fore and background */
XX   ScriptText[n].LeftEdge = 0;
XX   ScriptText[n].TopEdge = 1;
XX   ScriptText[n].ITextFont = NULL;
XX   ScriptText[n].NextText = NULL;
XX   }
XXScriptItem[SCRIPTMAX-1].NextItem = NULL;
XX
XX/* initialize text for specific menu items */
XXScriptText[0].IText = (UBYTE *)"Execute file";
XXScriptText[1].IText = (UBYTE *)"Abort Execution";
XX}
XX
XX/**********************************************************************/
XX/*   The following function initializes the Menu structure array with */
XX/*  appropriate values for our simple menu strip.  Review the manual  */
XX/*  if you need to know what each value means.                        */
XX/**********************************************************************/
XXvoid InitMenu()
XX{
XXmenu[0].NextMenu = &menu[1];
XXmenu[0].LeftEdge = 5;
XXmenu[0].TopEdge = 0;
XXmenu[0].Width = 50;
XXmenu[0].Height = 10;
XXmenu[0].Flags = MENUENABLED;
XXmenu[0].MenuName = "File";           /* text for menu-bar display */
XXmenu[0].FirstItem = &FileItem[0];    /* pointer to first item in list */
XX
XXmenu[1].NextMenu = &menu[2];
XXmenu[1].LeftEdge = 65;
XXmenu[1].TopEdge = 0;
XXmenu[1].Width = 85;
XXmenu[1].Height = 10;
XXmenu[1].Flags = MENUENABLED;
XXmenu[1].MenuName = "BaudRate";        /* text for menu-bar display */
XXmenu[1].FirstItem = &RSItem[0];    /* pointer to first item in list */
XX
XXmenu[2].NextMenu = &menu[3];
XXmenu[2].LeftEdge = 160;
XXmenu[2].TopEdge = 0;
XXmenu[2].Width = 85;
XXmenu[2].Height = 10;
XXmenu[2].Flags = MENUENABLED;
XXmenu[2].MenuName = "Xfer Mode";        /* text for menu-bar display */
XXmenu[2].FirstItem = &XFItem[0];    /* pointer to first item in list */
XX
XXmenu[3].NextMenu = NULL;
XXmenu[3].LeftEdge = 255;
XXmenu[3].TopEdge = 0;
XXmenu[3].Width = 85;
XXmenu[3].Height = 10;
XXmenu[3].Flags = MENUENABLED;
XXmenu[3].MenuName = "Script";        /* text for menu-bar display */
XXmenu[3].FirstItem = &ScriptItem[0];    /* pointer to first item in list */
XX}
XX
SHAR_EOF
if test 15433 -ne "`wc -c init.c`"
then
echo shar: error transmitting init.c '(should have been 15433 characters)'
fi
#	End of shell archive
exit 0

wecker@cookie.dec.com (DAVE TANSTAAFL WECKER) (08/25/86)

	[I apologize for posting this here (instead of 
	 MOD.AMIGA.SOURCES/BINARIES), but I haven't been
	 able to get through to the moderator for 3 weeks,
	 and people have been asking for the new release.]




#	This is a shell archive.
#	Remove everything above and including the cut line.
#	Then run the rest of the file through sh.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	window.c
#	remote.c
#	kermit.c
#	xmodem.c
#	script.c
# This archive created: Sun Aug 24 16:25:59 1986
echo shar: extracting window.c
sed 's/^XX//' << \SHAR_EOF > window.c
XX/****************************************************
XX * vt100 emulator - window/keyboard support
XX *
XX *	     860823 DBW - Integrated and rewrote lots of code
XX *	v2.0 860809 DBW - Major rewrite
XX *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
XX *	v1.0 860712 DBW	- First version released
XX *
XX ****************************************************/
XX
XX#define MODULE_WINDOW 1
XX#include "vt100.h"
XX
XX/* forward declarations for LATTICE */
XXvoid filename();
XXvoid emits();
XXvoid emit();
XXvoid emitbatch();
XXvoid cursoroff();
XXvoid cursoron();
XX
XX/*************************************************
XX*  function to get file name
XX*************************************************/
XXvoid filename(name)
XXchar name[];
XX    {
XX    char c;
XX    ULONG class;
XX    unsigned int code;
XX    int keepgoing,i;
XX    keepgoing = TRUE;
XX    i=0;
XX    while (keepgoing) {
XX	while( NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort) )
XX	    {
XX	    class = NewMessage->Class;
XX	    code = NewMessage->Code;
XX	    ReplyMsg( NewMessage );
XX	    if (class=RAWKEY)
XX		{
XX		c = toasc(code,1);
XX		name[i]=c;
XX		if (name[i] != 0)
XX		    {
XX		    if (name[i] == 13)
XX			{
XX			name[i]=0;
XX			keepgoing = FALSE;
XX			}
XX		    else
XX			{
XX			if (name[i] == 8 || name[i] == 127)
XX			    {
XX			    i -= 2;
XX			    if (i < -1)  i = -1;
XX			    else {
XX				if (x == MINX) { y -= 8; x = MAXX; }
XX				emit(8);
XX				emit(32);
XX				emit(8);
XX				}
XX			    }
XX			else
XX			emit(c);
XX			if (x == MAXX) emits("\n");
XX			}
XX		    i += 1;
XX		    }
XX		}
XX	    } /* end of new message loop */
XX	}   /* end of god knows what */
XX    emit(13);
XX    emit(10);
XX    } /* end of function */
XX
XX
XX/*************************************************
XX*  function to print a string
XX*************************************************/
XXvoid emits(string)
XXchar string[];
XX    {
XX    int i;
XX    char c;
XX
XX    i=0;
XX    while (string[i] != 0)
XX	{
XX	c=string[i];
XX	if (c == 10) emit(13);
XX	emit(c);
XX	i += 1;
XX	}
XX    }
XX
XX/*************************************************
XX*  function to output ascii chars to window
XX*************************************************/
XXvoid emit(c)
XXchar c;
XX    {
XX    Move(mywindow->RPort,(long)x,(long)y);
XX
XX    c &= 0x7F;
XX    switch( c )
XX	{
XX	case '\t':
XX	x += 64 - ((x-MINX) % 64);
XX	break;
XX
XX	case 10:  /* lf */
XX	y += 8;
XX	break;
XX
XX	case 13:  /* cr */
XX	x = MINX;
XX	break;
XX
XX	case 8:   /* backspace */
XX	x -= 8;
XX	if (x < MINX) x = MINX;
XX	break;
XX
XX	case 12:     /* page */
XX	x = MINX;
XX	y = MINY;
XX	SetAPen(mywindow->RPort,0L);
XX	RectFill(mywindow->RPort,(long)MINX,
XX	    (long)(MINY-7),(long)(MAXX+7),(long)(MAXY+1));
XX	SetAPen(mywindow->RPort,1L);
XX	break;
XX
XX	case 7:     /* bell */
XX	DisplayBeep(NULL);
XX	ClipBlit(mywindow->RPort,0L,0L,mywindow->RPort,0L,0L,
XX	    (long)MAXX,(long)MAXY,0x50L);
XX	ClipBlit(mywindow->RPort,0L,0L,mywindow->RPort,0L,0L,
XX	    (long)MAXX,(long)MAXY,0x50L);
XX	break;
XX
XX	default:
XX	if (c < ' ' || c > '~') break;
XX	if (curmode&REVERSE) {
XX	    Text(mywindow->RPort," ",1L);
XX	    Move(mywindow->RPort,(long)x,(long)y);
XX	    SetDrMd(mywindow->RPort,(long)INVERSVID);
XX	    if (curmode&BOLD)
XX		SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
XX	    Text(mywindow->RPort,&c,1L);
XX	    if (curmode&UNDERLINE) RectFill(mywindow->RPort,
XX		(long)(x-1),(long)(y+1),(long)(x+8),(long)(y+1));
XX	    if (curmode&BOLD) SetAPen(mywindow->RPort,1L);
XX	    SetDrMd(mywindow->RPort,(long)JAM2);
XX	    }
XX	else {
XX	    if (curmode&BOLD)
XX		SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
XX	    Text(mywindow->RPort,&c,1L);
XX	    if (curmode&UNDERLINE) RectFill(mywindow->RPort,
XX		(long)(x-1),(long)(y+1),(long)(x+8),(long)(y+1));
XX	    if (curmode&BOLD) SetAPen(mywindow->RPort,1L);
XX	    }
XX	x += 8;
XX	} /* end of switch */
XX
XX    while (x > MAXX) x -= 8;
XX    while (y > MAXY) {
XX	y -= 8;
XX	x  = MINX;
XX	ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,
XX	    (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
XX	}
XX    }
XX
XX/*************************************************
XX*  function to output ascii chars to window (batched)
XX*************************************************/
XXvoid emitbatch(la,lookahead)
XXint la;
XXchar *lookahead;
XX    {
XX    int i;	
XX    Move(mywindow->RPort,(long)x,(long)y);
XX    i = x / 8;
XX    if (i+la > maxcol) la = maxcol-i;
XX    if (curmode&REVERSE) {
XX	Text(mywindow->RPort,blanks,(long)la);
XX	Move(mywindow->RPort,(long)x,(long)y);
XX	SetDrMd(mywindow->RPort,(long)INVERSVID);
XX	if (curmode&BOLD)
XX		SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
XX	Text(mywindow->RPort,lookahead,(long)la);
XX	if (curmode&UNDERLINE) RectFill(mywindow->RPort,
XX	    (long)(x-1),(long)(y+1),(long)((x+8*la)+8),(long)(y+1));
XX	if (curmode&BOLD) SetAPen(mywindow->RPort,1L);
XX	SetDrMd(mywindow->RPort,(long)JAM2);
XX	}
XX    else {
XX	if (curmode&BOLD)
XX		SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
XX	Text(mywindow->RPort,lookahead,(long)la);
XX	if (curmode&UNDERLINE) RectFill(mywindow->RPort,
XX	    (long)(x-1),(long)(y+1),(long)((x+8*la)+8),(long)(y+1));
XX	if (curmode&BOLD) SetAPen(mywindow->RPort,1L);
XX	}
XX    x += (8 * la);
XX    }
XX
XX/******************************
XX* Manipulate cursor
XX******************************/
XXvoid cursoroff()
XX    {
XX    SetDrMd(mywindow->RPort,(long)COMPLEMENT);
XX    SetAPen(mywindow->RPort,3L);
XX    RectFill(mywindow->RPort,
XX	(long)(x-1),(long)(y-6),(long)(x+8),(long)(y+1));
XX    SetAPen(mywindow->RPort,1L);
XX    SetDrMd(mywindow->RPort,(long)JAM2);
XX    }
XX
XXvoid cursoron()
XX    {
XX    SetDrMd(mywindow->RPort,(long)COMPLEMENT);
XX    SetAPen(mywindow->RPort,3L);
XX    RectFill(mywindow->RPort,
XX	(long)(x-1),(long)(y-6),(long)(x+8),(long)(y+1));
XX    SetAPen(mywindow->RPort,1L);
XX    SetDrMd(mywindow->RPort,(long)JAM2);
XX    }
XX
XX/************************************************
XX*  function to take raw key data and convert it 
XX*  into ascii chars
XX**************************************************/
XXint toasc(code,local)
XXunsigned int code;
XXint local;
XX    {
XX    static int ctrl = FALSE;
XX    static int shift = FALSE;
XX    static int capsl = FALSE;
XX    char c;
XX    static char keys[75] = {
XX	'`','1','2','3','4','5','6','7','8','9','0','-' ,
XX	'=','\\', 0, '0','q','w','e','r','t','y','u','i','o' ,
XX	'p','[',']', 0, '1','2','3','a','s','d','f','g','h' ,
XX	'j','k','l',';','\'', 0, 0, '4','5','6', 0, 'z','x','c','v',
XX	'b','n','m',44,'.','/', 0, '.','7','8','9',' ',8,
XX	'\t',13,13,27,127,0,0,0,'-' } ;
XX
XX    switch ( code )
XX	{
XX	case 98:   capsl = TRUE; c = 0;break;
XX	case 226:  capsl = FALSE;c = 0;break;
XX	case 99:   ctrl = TRUE;  c = 0;break;
XX	case 227:  ctrl = FALSE; c = 0;break;
XX	case 96:
XX	case 97:   shift = TRUE; c = 0;break;
XX	case 224:
XX	case 225:  shift = FALSE;c = 0;break;
XX	case 0x50: 
XX	case 0x51: 
XX	case 0x52: 
XX	case 0x53: 
XX	case 0x54: 
XX	case 0x55: 
XX	case 0x56: 
XX	case 0x57: 
XX	case 0x58: 
XX	case 0x59:  c = 0;
XX		    if (shift)	sendstring(p_F[code - 0x50]);
XX		    else	sendstring(p_f[code - 0x50]);
XX		    break;
XX	case 0x0f: c=0; sendstring("Op"); break;
XX	case 0x1d: c=0; sendstring("Oq"); break;
XX	case 0x1e: c=0; sendstring("Or"); break;
XX	case 0x1f: c=0; sendstring("Os"); break;
XX	case 0x2d: c=0; sendstring("Ot"); break;
XX	case 0x2e: c=0; sendstring("Ou"); break;
XX	case 0x2f: c=0; sendstring("Ov"); break;
XX	case 0x3d: c=0; sendstring("Ow"); break;
XX	case 0x3e: c=0; sendstring("Ox"); break;
XX	case 0x3f: c=0; sendstring("Oy"); break;
XX	case 0x43: c=0; sendstring("OM"); break;
XX	case 0x4a: c=0; sendstring("Ol"); break;
XX	case 0x5f: c=0; sendstring("Om"); break;
XX	case 0x3c: c=0; sendstring("On"); break;
XX	case 0x4c: c=0; sendstring("[A"); break;
XX	case 0x4d: c=0; sendstring("[B"); break;
XX	case 0x4e: c=0; sendstring("[C"); break;
XX	case 0x4f: c=0; sendstring("[D"); break;
XX
XX	default:
XX	if (code < 75) c = keys[code];
XX	else c = 0;
XX	}
XX
XX    /* add modifiers to the keys */
XX
XX    if (c != 0) {
XX	if (shift) {
XX	    if ((c <= 'z') && (c >= 'a')) c -= 32;
XX	    else
XX	    switch( c ) {
XX		case '[':  c = '{'; break;
XX		case ']':  c = '}'; break;
XX		case '\\': c = '|'; break;
XX		case '\'': c = '"'; break;
XX		case ';':  c = ':'; break;
XX		case '/':  c = '?'; break;
XX		case '.':  c = '>'; break;
XX		case ',':  c = '<'; break;
XX		case '`':  c = '~'; break;
XX		case '=':  c = '+'; break;
XX		case '-':  c = '_'; break;
XX		case '1':  c = '!'; break;
XX		case '2':  c = '@'; break;
XX		case '3':  c = '#'; break;
XX		case '4':  c = '$'; break;
XX		case '5':  c = '%'; break;
XX		case '6':  c = '^'; break;
XX		case '7':  c = '&'; break;
XX		case '8':  c = '*'; break;
XX		case '9':  c = '('; break;
XX		case '0':  c = ')'; break;
XX		default:            break;
XX		}
XX	    }
XX	else if (capsl && (c <= 'z') && (c >= 'a')) c -= 32;
XX	}
XX    if (ctrl) {
XX	if (c >= '`' && c <= 127) c -= 96;
XX	else if (c >= '@' && c <= '_') c -= 64;
XX	}
XX    if (c != 0 && (!local)) sendchar(c);
XX    return((int)c);
XX    }
XX
SHAR_EOF
if test 8526 -ne "`wc -c window.c`"
then
echo shar: error transmitting window.c '(should have been 8526 characters)'
fi
echo shar: extracting remote.c
sed 's/^XX//' << \SHAR_EOF > remote.c
XX/****************************************************
XX * vt100 emulator - remote character interpretation
XX *
XX *	     860823 DBW - Integrated and rewrote lots of code
XX *	v2.0 860803 DRB - Rewrote the control sequence parser
XX *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
XX *	v1.0 860712 DBW	- First version released
XX *
XX ****************************************************/
XX
XX#define MODULE_REMOTE 1
XX#include "vt100.h"
XX
XXstatic int    p[10];
XXstatic int    numpar;
XXstatic char   escseq[40];
XX
XXvoid doctrl();
XXvoid doesc();				/* force correct denomination */
XXvoid doerase();
XXvoid doindex();
XX
XX/************************************************
XX*  function to handle remote characters
XX*************************************************/
XXvoid doremote(c)
XXchar c;
XX    {
XX    if (c == 27 || inesc >= 0) { doesc(c); return; }
XX    if (inctrl >= 0) { doctrl(c); return; }
XX    if (c == 10 || c == 11 || c == 12) {
XX	if (nlmode) doindex('E'); else doindex('D');
XX	return;
XX	}
XX    if (c == 13) {
XX	if (!nlmode) emit(c);
XX	return;
XX	}
XX    if (c == 15) { alt = 0; return; }
XX    if (c == 14) { alt = 1; return; }
XX    if (a[alt] && c > 94 && c < 127) { doalt(c); return; }
XX    emit(c);
XX    }
XX
XXvoid doesc(c)
XXchar c;
XX{
XX    if (inesc < 0) { inesc = 0; return; }
XX    if (c == 27 || c == 24) { inesc = -1; return; }
XX    if (c < ' ' || c == 127) return;		  /* Ignore control chars */
XX    if (c < '0') {escseq[inesc++] = c; return; }  /* Collect intermediates */
XX
XX    /* by process of elimination, we have a final character.  Put it in
XX       the buffer, and dispatch on the first character in the buffer */
XX
XX    escseq[inesc] = c;
XX    inesc = -1;				/* No longer collecting a sequence */
XX    switch (escseq[0])			/* Dispatch on the first received */
XX    {
XX      case '[':				/* Control sequence introducer */
XX	numpar = 0;			/* No parameters yet */
XX	private = 0;			/* Not a private sequence (yet?) */
XX	badseq = 0;			/* Good until proven bad */
XX	p[0] = p[1] = 0;		/* But default the first parameter */
XX	inctrl = 0;			/* We are in a control sequence */
XX	return;				/* All done for now ... */
XX
XX      case 'D': case 'E': case 'M':	/* Some kind of index */
XX	doindex (c);			/* Do the index */
XX	return;				/* Return */
XX
XX      case '7':				/* Save cursor position */
XX	savx = x; savy = y; savmode = curmode; savalt = alt;
XX	sa[0] = a[0]; sa[1] = a[1];
XX	return;
XX
XX      case '8':				/* Restore cursor position */
XX	x = savx; y = savy; alt = savalt; curmode = savmode;
XX	a[0] = sa[0]; a[1] = sa[1];
XX	return;
XX
XX      case 'c':				/* Reset */
XX	top = MINY; bot = MAXY; savx = MINX; savy = MINY;
XX	a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
XX	emit(12); return;
XX	inesc = -1;
XX	return;
XX
XX      case '(':				/* Change character set */
XX	if (c == '0' || c == '2') a[0] = 1; else a[0] = 0;
XX	return;
XX
XX      case ')':				/* Change the other character set */
XX	if (c == '0' || c == '2') a[1] = 1; else a[1] = 0;
XX	return;
XX
XX      /* If we didn't match anything, we can just return, happy in the
XX	 knowledge that we've at least eaten the whole sequence */
XX
XX    }					/* End of switch */
XX    return;
XX}
XX
XXvoid doctrl(c)
XXchar c;
XX{
XX    int	    i;
XX
XX    if (c == 27 || c == 24) { inctrl = -1; return; }
XX    if (c < ' ' || c == 127) return;		  /* Ignore control chars */
XX
XX    /* First, look for some parameter characters.  If the very first
XX       parameter character isn't a digit, then we have a private sequence */
XX
XX    if (c >= '0' && c < '@')
XX    {
XX	/* can't have parameters after intermediates */
XX	if (inctrl > 0) {badseq++ ; return; }
XX	switch (c)
XX	{
XX	  case '0': case '1': case '2': case '3': case '4':
XX	  case '5': case '6': case '7': case '8': case '9':
XX	    p[numpar] = p[numpar] * 10 + (c - '0');
XX	    return;
XX
XX	  case ';':
XX	    p[++numpar] = 0;		/* Start a new parameter */
XX	    return;
XX
XX	  case '<': case '=': case '>': case '?': /* Can only mean private */
XX	    if (inctrl = 0) private = c; /* Only allowed BEFORE parameters */
XX	    return;
XX
XX	/* if we come here, it's a bad sequence */
XX	}
XX	badseq++;			/* Flag the bad sequence */
XX    }
XX
XX    if (c < '0')			/* Intermediate character */
XX    {
XX	escseq[inctrl++] = c;		/* Save the intermediate character */
XX	return;
XX    }
XX
XX    /* if we get here, we have the final character.  Put it in the 
XX       escape sequence buffer, then dispatch the control sequence */
XX
XX    numpar++;				/* Reflect the real number of parameters */
XX    escseq[inctrl++] = c;		/* Store the final character */
XX    escseq[inctrl] = '\000';		/* Tie off the buffer */
XX    inctrl = -1;			/* End of the control sequence scan */
XX
XX    /* Don't know how to do any private sequences right now, so just punt
XX       them */
XX
XX    if (private != 0 || badseq != 0) return;
XX
XX    switch (escseq[0])			/* Dispatch on first intermediate or final */
XX    {
XX      case 'A': if (p[0]<=0) p[0] = 1;
XX		y -= 8*p[0]; if (y<top)  y = top;  return;
XX      case 'B': if (p[0]<=0) p[0] = 1;
XX		y += 8*p[0]; if (y>bot)  y = bot;  return;
XX      case 'C': if (p[0]<=0) p[0] = 1;
XX		x += 8*p[0]; if (x>MAXX) x = MAXX; return;
XX      case 'D': if (p[0]<=0) p[0] = 1;  
XX		x -= 8*p[0]; if (x<MINX) x = MINX; return;
XX
XX      case 'H': case 'f':		/* Cursor position */
XX	if (p[0] <= 0) p[0] = 1;
XX	if (p[1] <= 0) p[1] = 1;
XX	y = (--p[0]*8)+MINY; x = (--p[1]*8)+MINX;
XX	if (y > MAXY) y = MAXY;
XX	if (x > MAXX) x = MAXX;
XX	if (y < MINY) y = MINY;
XX	if (x < MINX) x = MINX;
XX	return;
XX
XX      case 'r':				/* Set scroll region */
XX	if (p[0] <= 0) p[0] = 1;
XX	if (p[1] <= 0) p[1] = p_lines;
XX	top = (--p[0]*8)+MINY; bot = (--p[1]*8)+MINY;
XX	if (top < MINY) top = MINY;
XX	if (bot > MAXY) bot = MAXY;
XX	if (top > bot) { top = MINY; bot = MAXY; }
XX	x = MINX; y = MINY;
XX	return;
XX
XX      case 'm':				/* Set graphic rendition */
XX	for (i=0;i<numpar;i++) {
XX	    if (p[i] < 0) p[i] = 0;
XX	    switch (p[i]) {
XX		case 0:
XX		curmode  = 0;
XX		break;
XX
XX		case 1:
XX		case 5:
XX		if (p_depth > 1)    curmode |= BOLD;
XX		else		    curmode |= REVERSE;
XX		break;
XX
XX		case 4:
XX		curmode |= UNDERLINE;
XX		break;
XX
XX		default:
XX		curmode |= REVERSE;
XX		break;
XX		}
XX	    }
XX	return;
XX
XX      case 'K':				/* Erase in line */
XX	doerase();
XX	return;
XX
XX      case 'J':				/* Erase in display */
XX	if (p[0] < 0) p[0] = 0;
XX	SetAPen(mywindow->RPort,0L);
XX	if (p[0] == 0) {
XX	    if (y < MAXY) RectFill(mywindow->RPort,
XX		(long)MINX,(long)(y+2),(long)(MAXX+7),(long)(MAXY+1));
XX	    }
XX	else if (p[0] == 1) {
XX	    if (y > MINY) RectFill(mywindow->RPort,
XX		(long)MINX,(long)(MINY-6),(long)(MAXX+7),(long)(y-7));
XX	    }
XX	else RectFill(mywindow->RPort,
XX	    (long)MINX,(long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
XX	SetAPen(mywindow->RPort,1L);
XX	doerase(); return;
XX
XX      case 'h':				/* Set parameter */
XX	if (p[0] == 20) nlmode = 1;
XX	return;
XX
XX      case 'l':				/* Reset parameter */
XX	if (p[0] == 20) nlmode = 0;
XX	return;
XX
XX      case 'x':
XX	sendchar(27); sendstring("[3;1;8;64;64;1;0x"); return;
XX
XX      case 'n':
XX	if (p[0] == 6) {
XX	    sendchar(27);
XX	    sprintf(escseq,"[%d;%dR",((y-MINY)/8)+1,((x-MINX)/8)+1);
XX	    sendstring(escseq); return;
XX	    }
XX	sendchar(27); sendstring("[0n"); return;
XX
XX      case 'c':
XX	sendchar(27); sendstring("[?1;0c"); return;
XX    }
XX
XX    /* Don't know how to do this one, so punt it */
XX}
XX
XXvoid doindex(c)
XXchar c;
XX    {
XX    if (c != 'M') {
XX	if (c == 'E') x = MINX;
XX	if (y > bot) if (y < MAXY) y += 8;
XX	if (y == bot)
XX	    ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,(long)(top-6),
XX		(long)(MAXX+7),(long)(bot+1));
XX	if (y < bot) y += 8;
XX	}
XX    else {
XX	if (y < top) if (y > MINY) y -= 8;
XX	if (y == top)
XX	    ScrollRaster(mywindow->RPort,0L,-8L,(long)MINX,(long)(top-6),
XX		(long)(MAXX+7),(long)(bot+1));
XX	if (y > top) y -= 8;
XX	}
XX    return;
XX    }
XX
XXdoalt(c)
XXchar c;
XX    {
XX    int oldx,newx;
XX    inesc = -1;
XX    oldx = x; emit(' '); newx = x;
XX    x = oldx;
XX    SetAPen(mywindow->RPort,1L);
XX    switch (c) {
XX	case 'j':
XX	case 'm':
XX	case 'v':   doline(4,-8,4,-4);
XX	if      (c=='j')  doline(0,-4,4,-4);
XX	else if (c=='m')  doline(4,-4,8,-4);
XX	else              doline(0,-4,8,-4);
XX	break;
XX
XX	case 'k':
XX	case 'l':
XX	case 'w': doline(4,-4,4,0);
XX	if      (c=='k')  doline(0,-4,4,-4);
XX	else if (c=='l')  doline(4,-4,8,-4);
XX	else              doline(0,-4,8,-4);
XX	break;
XX
XX	case 'n':
XX	case 'q': doline(0,-4,8,-4);
XX	if      (c=='n')  doline(4,-8,4,0);
XX	break;
XX
XX	case 't':
XX	case 'u':
XX	case 'x':   doline(4,-8,4,0);
XX	if      (c=='t')  doline(4,-4,8,-4);
XX	else if (c=='u')  doline(0,-4,4,-4);
XX	break;
XX	}
XX    x = newx;
XX    }
XX
XXdoline(x1,y1,x2,y2) {
XX    RectFill(mywindow->RPort,(long)(x+x1),(long)(y+y1),
XX	(long)(x+x2),(long)(y+y2));
XX    }
XX
XXvoid doerase()
XX    {
XX    if (p[0] < 0) p[0] = 0;
XX    SetAPen(mywindow->RPort,0L);
XX    if (p[0] == 0) RectFill(mywindow->RPort,(long)x,(long)(y-6),
XX	(long)(MAXX+7),(long)(y+1));
XX    else if (p[0] == 1) RectFill(mywindow->RPort,
XX	(long)MINX,(long)(y-6),(long)(x+7),(long)(y+1));
XX    else RectFill(mywindow->RPort,
XX	(long)MINX,(long)(y-6),(long)(MAXX+7),(long)(y+1));
XX    SetAPen(mywindow->RPort,1L);
XX    return;
XX    }
XX
SHAR_EOF
if test 8794 -ne "`wc -c remote.c`"
then
echo shar: error transmitting remote.c '(should have been 8794 characters)'
fi
echo shar: extracting kermit.c
sed 's/^XX//' << \SHAR_EOF > kermit.c
XX/*************************************************************
XX * vt100 terminal emulator - KERMIT protocol support
XX *           
XX *	     860823 DBW - Integrated and rewrote lots of code
XX *           860811 Steve Drew multi filexfer, bugs, status line ect..
XX *	v2.0 860809 DBW - Major rewrite
XX *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
XX *	v1.0 860712 DBW	- First version released
XX *
XX *************************************************************/
XX
XX#define MODULE_KERMIT 1
XX#include "vt100.h"
XX
XX#define MAXPACKSIZ 94       /* Maximum msgpkt size */
XX#define CR         13       /* ASCII Carriage Return */
XX#define LF         10       /* ASCII line feed */
XX#define SP         32       /* ASCII space */
XX#define DEL       127       /* Delete (rubout) */
XX
XX#define MAXTRY    5        /* Times to retry a msgpkt */
XX#define MYQUOTE  '#'       /* Quote character I will use */
XX#define MYRPTQ   '~'       /* Repeat quote character */
XX#define MYPAD      0       /* Number of padding characters I will need */
XX#define MYPCHAR    0       /* Padding character I need (NULL) */
XX#define MYEOL    '\n'      /* End-Of-Line character I need */
XX
XX#define tochar(ch)  ((ch) + ' ')
XX#define unchar(ch)  ((ch) - ' ')
XX#define ctl(ch)     ((ch) ^ 64 )
XX
XX/* Global Variables */
XX
XXint
XX   size,      /* Size of present data */
XX   osize,     /* Size of last data entry */
XX   rpsiz,     /* Maximum receive msgpkt size */
XX   spsiz,     /* Maximum send msgpkt size */
XX   timint,    /* Time interval to wait */
XX   pad,       /* How much padding to send */
XX   n,         /* Packet number */
XX   tp,        /* total packets */
XX   numtry,    /* Times this msgpkt retried */
XX   retry,     /* total retries */
XX   oldtry,    /* Times previous msgpkt retried */
XX   rptflg,    /* are we doing repeat quoting */
XX   first,     /* is this the first time in a file */
XX   rpt,       /* current repeat count */
XX   next,      /* what is the next character */
XX   t;         /* current character */
XXlong
XX   totbytes;  /* total bytes xfered on this file */
XX
XXchar 
XX   state,     /* Present state of the automaton */
XX   padchar,   /* Padding character to send */
XX   eol,       /* End-Of-Line character to send */
XX   quote,     /* Quote character in incoming data */
XX   rptq,      /* Quote character for repeats */
XX   ackpkt[MAXPACKSIZ+20], /* ACK/NAK packet buffer */
XX   msgpkt[MAXPACKSIZ+20], /* Message Packet buffer */
XX   filnam[40];            /* remote file name */
XX   snum[10];
XX
XXvoid encode(), decode(), rpar(), spar();
XX   
XXFILE *fp;     /* file for send/receive */
XX
XXint shutdown = 0;  /* shut down server after all xfers complete */
XX
XXchar *
XXgetfname(name)   /* returns pointer to start of file name from file spec */
XXchar *name;
XX    {
XX    int l;
XX
XX    l = strlen(name);
XX    while(l && name[l] != '/' && name[l] != ':') l--;
XX    if (name[l] == '/' || name[l] == ':') l++;
XX    return(name += l);
XX    }
XX    
XXdoksend(file,more)
XXchar *file;
XXint more;
XX   {
XX   int retval;
XX
XX   ttime = TTIME_LONG;
XX   if (!strcmp(file,"$")) { saybye(); return(2); }
XX   if (file[strlen(file)-1] == '$')  { 
XX             shutdown = 1; 
XX             file[strlen(file)-1] = '\0'; 
XX             }
XX   if ((fp = fopen(file,"r")) == NULL) {
XX      emits("Cannot open send file\n");
XX      return FALSE;
XX      }
XX   getready(file,more);
XX   emits("SEND");
XX   retval  = sendsw();
XX   if (retval) { x = 600; emits("DONE"); }
XX   curmode = 0;
XX   if (shutdown) saybye();
XX   emits("\n");
XX   fclose(fp);
XX   return(retval);
XX   }
XX 
XXdokreceive(file,more)
XXchar *file;
XXint more;
XX   {
XX   int retval;
XX
XX   ttime = TTIME_LONG;
XX   if (!strcmp(file,"$")) { saybye(); return(2); }
XX   if (file[strlen(file)-1] == '$')  { 
XX             shutdown = 1; 
XX             file[strlen(file)-1] = '\0'; 
XX             }
XX   if ((fp = fopen(file,"w")) == NULL) {
XX      emits("Cannot open file\n");
XX      return FALSE;
XX      }
XX   getready(file,more);
XX   emits("RECV");
XX   retval  = recsw();
XX   if (retval) { x = 600; emits("DONE"); }
XX   curmode = 0;
XX   if (shutdown) saybye();
XX   emits("\n");
XX   fclose(fp);
XX   return(retval);
XX   }
XX
XXgetready(file,more)
XX   char *file;
XX   int more;
XX   {
XX   if (!more) {   
XX       emits("Remote file name [");
XX       emits(getfname(file));
XX       emits("]: ");
XX       filename(filnam);
XX       if (filnam[0] == 0) strcpy(filnam,getfname(file));
XX       emits("Type <ESC> to abort transfer\n");
XX       }
XX   else strcpy(filnam,getfname(file));
XX   eatup();
XX   tp =  retry =  0; totbytes = 0L;  n =  numtry = 0;
XX   want_message = FALSE; /* tell readchar no error msgs status bar instead */
XX   statusline();
XX   x = 600;
XX   }
XX
XX
XXsendsw()
XX   {
XX   char sinit(), sfile(), sdata(), seof(), sbreak();
XX
XX   state = 'S';
XX   while(TRUE) {
XX      switch(state) {
XX         case 'S':   state = sinit();  break;
XX         case 'F':   state = sfile();  break;
XX         case 'D':   state = sdata();  break;
XX         case 'Z':   state = seof();   break;
XX         case 'B':   state = sbreak(); break;
XX         case 'C':   return(TRUE);
XX         case 'A':   x = 600;
XX                     if (timeout == USERABORT) { sabort();  return(FALSE); }
XX                     if (timeout == TIMEOUT) emits("TMOUT");
XX                     else emits("ERROR");
XX                     return(FALSE);
XX         default:    return(FALSE);
XX         }
XX      }
XX   }
XX
XXchar sinit()
XX   {
XX   int num, len;
XX   
XX   retry++;
XX   if (numtry++ > MAXTRY) return('A');
XX   spar(msgpkt);
XX
XX   spack('S',n,9,msgpkt);
XX   switch(rpack(&len,&num,ackpkt)) {
XX      case 'N':  return(state);
XX      case 'Y':  if (n != num) return(state);
XX                 rpar(ackpkt);
XX                 if (eol == 0) eol = '\n';
XX                 if (quote == 0) quote = '#';
XX                 numtry = 0;
XX                 retry--;
XX                 n = (n+1)%64;
XX                 return('F');
XX      case 'E':  return('A');
XX      case FALSE:if (timeout == USERABORT) state = 'A';
XX                 return(state);
XX      default:   return('A');
XX      }
XX    }
XX
XXchar sfile()
XX   {
XX   int num, len;
XX
XX   retry++;
XX   if (numtry++ > MAXTRY) return('A');
XX
XX   spack('F',n,strlen(filnam),filnam);
XX   switch(rpack(&len,&num,ackpkt)) {
XX      case 'N':
XX         num = (--num<0 ? 63:num);
XX         if (n != num) return(state);
XX      case 'Y':
XX         if (n != num) return(state);
XX         numtry = 0;
XX         retry--;
XX         n = (n+1)%64;
XX         first = 1;
XX         size = getpkt();
XX         return('D');
XX      case 'E':
XX         return('A');
XX      case FALSE: if (timeout == USERABORT) state = 'A';
XX                  return(state);
XX      default:    return('A');
XX      }
XX   }
XX
XXchar sdata()
XX   {
XX   int num, len;
XX   
XX   retry++;
XX   if (numtry++ > MAXTRY) return('A');
XX
XX   spack('D',n,size,msgpkt);
XX   switch(rpack(&len,&num,ackpkt)) {
XX      case 'N':
XX         num = (--num<0 ? 63:num);
XX         if (n != num) return(state);
XX      case 'Y':
XX         if (n != num) return(state);
XX         numtry = 0;
XX         retry--;
XX         n = (n+1)%64;
XX         if ((size = getpkt()) == 0) return('Z');
XX         return('D');
XX      case 'E':
XX         return('A');
XX      case FALSE: if (timeout == USERABORT) state = 'A';
XX                  return(state);
XX      default:    return('A');
XX      }
XX   }
XX
XXchar seof()
XX   {
XX   int num, len;
XX   retry++;
XX   if (numtry++ > MAXTRY) return('A');
XX
XX   if (timeout == USERABORT) { 
XX        timeout = GOODREAD;
XX        spack('Z',n,1,"D"); /* tell host to discard file */
XX        }
XX   else spack('Z',n,0,msgpkt);
XX   switch(rpack(&len,&num,ackpkt)) {
XX      case 'N':
XX         num = (--num<0 ? 63:num);
XX         if (n != num) return(state);
XX      case 'Y':
XX         if (n != num) return(state);
XX         numtry = 0;
XX         retry--;
XX         n = (n+1)%64;
XX         return('B');
XX      case 'E':
XX         return('A');
XX      case FALSE: return(state);
XX      default:    return('A');
XX      }
XX   }
XX
XXchar sbreak()
XX   {
XX   int num, len;
XX   retry++;
XX   if (numtry++ > MAXTRY) return('A');
XX
XX   spack('B',n,0,msgpkt);
XX   switch (rpack(&len,&num,ackpkt)) {
XX      case 'N':
XX         num = (--num<0 ? 63:num);
XX         if (n != num) return(state);
XX      case 'Y':
XX         if (n != num) return(state);
XX         numtry = 0;
XX	 retry--;
XX         n = (n+1)%64;
XX         return('C');
XX      case 'E':
XX         return('A');
XX      case FALSE: return(state);
XX      default:    return ('A');
XX      }
XX   }
XX
XX/* timeout equals USERABORT so lets end the file and quit  */
XX/* when host receives 'Z' packet with "D" in data field he */
XX/* should discard the file.                                */
XX
XXsabort()
XX   {
XX   emits("ABORT");
XX   n = (n+1)%64;
XX   retry--;
XX   state = 'Z';
XX   while (state == 'Z') state = seof();
XX   while (state == 'B') state = sbreak();
XX   return(FALSE);
XX   }
XX   
XXrecsw()
XX   {
XX   char rinit(), rfile(), rdata(), rbreak();
XX
XX   state = 'R';
XX   
XX   while(TRUE) {
XX      switch(state) {
XX         case 'R':   state = rinit(); break;
XX         case 'F':   state = rfile(); break;
XX         case 'D':   state = rdata(); break;
XX	 case 'Z':   state = rbreak(); break;
XX         case 'C':   return(TRUE);
XX         case 'A':   x = 600;
XX                     if (timeout == USERABORT){/* easy way to cleanly abort 
XX                                                  should really send and ACK
XX                                                  with "X" in data field and 
XX                                                  wait for host to abort but 
XX                                                  not all kermits support
XX                                                  this feature.           */
XX                         emits("ABORT");
XX                         spack('E',n,0,0); /* send an error packet back   */
XX                     }
XX                     else if (timeout == TIMEOUT) emits("TMOUT");
XX                     else emits("ERROR");           
XX                     return(FALSE);
XX         }
XX      }
XX   }
XX
XXchar rinit()
XX   {
XX   int len, num;
XX   retry++;
XX   if (numtry++ > MAXTRY) return('A');
XX
XX   if (server) spack('R',n,strlen(filnam),filnam);
XX   else  spack('N',n,0,0);
XX   switch(rpack(&len,&num,msgpkt)) {
XX      case 'S':
XX         rpar(msgpkt);
XX         spar(msgpkt);
XX         spack('Y',n,9,msgpkt);
XX         oldtry = numtry;
XX         numtry = 0;
XX         retry--;
XX         n = (n+1)%64;
XX         return('F');
XX      case 'E':
XX         return('A');
XX      case FALSE:
XX         if (timeout == USERABORT) return('A');
XX         spack('N',n,0,0);
XX         return(state);
XX      default:
XX         return('A');
XX      }
XX   }
XX
XXchar rfile()
XX   {
XX   int num, len;
XX   retry++;
XX   if (numtry++ > MAXTRY) return('A');
XX
XX   switch(rpack(&len,&num,msgpkt)) {
XX      case 'S':
XX         if (oldtry++ > MAXTRY) return('A');
XX         if (num == ((n==0) ? 63:n-1)) {
XX            spar(msgpkt);
XX            spack('Y',num,9,msgpkt);
XX            retry--;
XX            numtry = 0;
XX            return(state);
XX            }
XX         else return('A');
XX      case 'Z':
XX         if (oldtry++ > MAXTRY) return('A');
XX         if (num == ((n==0) ? 63:n-1)) {
XX            spack('Y',num,0,0);
XX            numtry = 0;
XX            retry--;
XX            return(state);
XX            }
XX         else return('A');
XX      case 'F':
XX         if (num != n) return('A');
XX         spack('Y',n,0,0);
XX         oldtry = numtry;
XX         numtry = 0;
XX         retry--;
XX         n = (n+1)%64;
XX         return('D');
XX      case 'B':
XX         if (num != n) return ('A');
XX         spack('Y',n,0,0);
XX         retry--;
XX         return('C');
XX      case 'E':
XX         return('A');
XX      case FALSE:
XX         if (timeout == USERABORT) return('A');
XX         spack('N',n,0,0);
XX         return(state);
XX      default:
XX         return ('A');
XX      }
XX   }
XX
XXchar rdata()
XX   {
XX   int num, len;
XX   retry++;
XX   if (numtry++ > MAXTRY) return('A');
XX
XX   switch(rpack(&len,&num,msgpkt)) {
XX      case 'D':
XX         if (num != n) {
XX            if (oldtry++ > MAXTRY) return('A');
XX            if (num == ((n==0) ? 63:n-1)) {
XX               spack('Y',num,6,msgpkt);
XX               retry--;
XX               numtry = 0;
XX               return(state);
XX               }
XX            else return('A');
XX            }
XX         decode();
XX         spack('Y',n,0,0);
XX         oldtry = numtry;
XX         numtry = 0;
XX         retry--;
XX         n = (n+1)%64;
XX         return('D');
XX      case 'F':
XX         if (oldtry++ > MAXTRY) return('A');
XX         if (num == ((n==0) ? 63:n-1)) {
XX            spack('Y',num,0,0);
XX            numtry = 0;
XX            retry--;
XX            return(state);
XX            }
XX         else return('A');
XX      case 'Z':
XX         if (num != n) return('A');
XX         spack('Y',n,0,0);
XX         n = (n+1)%64;
XX         retry--;
XX         return('Z');
XX      case 'E':
XX         return('A');
XX      case FALSE:
XX         if (timeout == USERABORT) return('A');
XX         spack('N',n,0,0);
XX         return(state);
XX      default:
XX        return('A');
XX      }
XX   }
XX
XXchar rbreak()
XX   { 
XX   int num, len;
XX   retry++;
XX   if (numtry++ > MAXTRY) return('A');
XX
XX   switch(rpack(&len,&num,msgpkt)) {
XX      case 'B':
XX         spack('Y',n,0,0);
XX         return('C');
XX      case 'Z':
XX         spack('Y',n,0,0);
XX         return('Z');
XX      case 'E':
XX         return('A');
XX      case FALSE:
XX         spack('N',n,0,0);
XX         return(state);
XX      default:
XX        return('A');
XX      }
XX   }
XX
XXspack(type,num,len,data)
XXchar type, *data;
XXint num, len;
XX   {
XX   int i;
XX   char chksum, buffer[100];
XX   register char *bufp;
XX   
XX   dostats(type);
XX   bufp = buffer;
XX   for (i=1; i<=pad; i++) sendchar(padchar);
XX
XX   *bufp++ = SOH;
XX   *bufp++ = tochar(len+3);
XX   chksum  = tochar(len+3);
XX   *bufp++ = tochar(num);
XX   chksum += tochar(num);
XX   *bufp++ = type;
XX   chksum += type;
XX
XX   for (i=0; i<len; i++) {
XX      *bufp++ = data[i];
XX      chksum += data[i];
XX      }
XX   chksum = (((chksum&0300) >> 6)+chksum)&077;
XX   *bufp++ = tochar(chksum);
XX   *bufp++ = '\r';
XX   *bufp++ = '\n';
XX   *bufp   = 0;
XX   sendstring(buffer);
XX   }
XX
XXrpack(len,num,data)
XXint *len, *num;
XXchar *data;
XX   {
XX   int i, done;
XX   char type, cchksum, rchksum;
XX   char t = '\0';
XX
XX    do {
XX       t = readchar();
XX       if (timeout != GOODREAD) return(FALSE);
XX       } while (t != SOH);
XX
XX    done = FALSE;
XX    while (!done) {
XX       t = readchar();
XX       if (timeout != GOODREAD) return(FALSE);
XX       if (t == SOH) continue;
XX       cchksum = t;
XX       *len = unchar(t)-3;
XX       t = readchar();
XX       if (timeout != GOODREAD) return(FALSE);
XX       if (t == SOH) continue;
XX       cchksum = cchksum + t;
XX       *num = unchar(t);
XX       t = readchar();
XX       if (timeout != GOODREAD) return(FALSE);
XX       if (t == SOH) continue;
XX       cchksum = cchksum + t;
XX       type = t;
XX       for (i=0; i<*len; i++) {
XX          t = readchar();
XX          if (timeout != GOODREAD) return(FALSE);
XX          if (t == SOH) continue;
XX          cchksum = cchksum + t;
XX          data[i] = t;
XX          }
XX       data[*len] = 0;
XX       t = readchar();
XX       if (timeout != GOODREAD) return(FALSE);
XX       rchksum = unchar(t);
XX       t = readchar();
XX       if (timeout != GOODREAD) return(FALSE);
XX       if (t == SOH) continue;
XX       done = TRUE;
XX       }
XX   dostats(type);
XX   cchksum = (((cchksum&0300) >> 6)+cchksum)&077;
XX   if (cchksum != rchksum) return(FALSE);
XX   return((int)type);
XX   }
XX
XXgetpkt() {
XX   int i,eof;
XX
XX   static char leftover[10] = { '\0', '\0', '\0', '\0', '\0',
XX			        '\0', '\0', '\0', '\0', '\0' };
XX
XX   if (first == 1) {
XX      first = 0;
XX      *leftover = '\0';
XX      t = getc(fp);
XX      if (t == EOF) {
XX         first = 1;
XX         return(size = 0);
XX         }
XX      totbytes++;
XX      }
XX   else if (first == -1) {
XX      first = 1;
XX      return(size = 0);
XX      }
XX   for (size = 0; (msgpkt[size] = leftover[size]) != '\0'; size++) ;
XX   *leftover = '\0';
XX   rpt = 0;
XX   eof = 0;
XX   while (!eof) {
XX      next = getc(fp);
XX      if (next == EOF) {
XX         first = -1;
XX         eof   =  1;
XX         }
XX      else totbytes++;
XX      osize = size;
XX      encode(t);
XX      t = next;
XX      if (size == spsiz-3) return(size);
XX      if (size > spsiz-3) {
XX         for (i = 0; (leftover[i] = msgpkt[osize+i]) != '\0'; i++) ;
XX         size = osize;
XX         msgpkt[size] = '\0';
XX         return(size);
XX         }
XX      }
XX   return(size);
XX   }
XX
XXvoid encode(a)
XXchar a;
XX   {
XX   int a7,b8;
XX
XX   if (p_mode == 1 && a == '\n') {
XX      rpt = 0;
XX      msgpkt[size++] = quote;
XX      msgpkt[size++] = ctl('\r');
XX      if (size <= spsiz-3) osize = size;
XX      msgpkt[size++] = quote;
XX      msgpkt[size++] = ctl('\n');
XX      msgpkt[size]   = '\0';
XX      return;
XX      }
XX   if (rptflg) {
XX      if (a == next && (first == 0)) {
XX         if (++rpt < 94) return;
XX         else if (rpt == 94) {
XX            msgpkt[size++] = rptq;
XX            msgpkt[size++] = tochar(rpt);
XX            rpt = 0;
XX            }
XX         }
XX      else if (rpt == 1) {
XX         rpt = 0;
XX         encode(a);
XX         if (size <= spsiz-3) osize = size; 
XX         rpt = 0;
XX         encode(a);
XX         return;
XX         }
XX      else if (rpt > 1) {
XX         msgpkt[size++] = rptq;
XX         msgpkt[size++] = tochar(++rpt);
XX         rpt = 0;
XX         }
XX      }
XX   a7 = a & 0177;
XX   b8 = a & 0200;
XX   if ((a7 < SP) || (a7==DEL)) {
XX      msgpkt[size++] = quote;
XX      a = ctl(a);
XX      }
XX   if (a7 == quote) msgpkt[size++] = quote;
XX   if ((rptflg) && (a7 == rptq)) msgpkt[size++] = quote;
XX   msgpkt[size++] = a;
XX   msgpkt[size] = '\0';
XX   }
XX
XXvoid decode()
XX   {
XX   USHORT  a, a7;
XX   char *buf;
XX
XX   buf = msgpkt;
XX   rpt = 0;
XX   
XX   while ((a = *buf++) != '\0') {
XX      if (rptflg) {
XX         if (a == rptq) {
XX            rpt = unchar(*buf++);
XX            a = *buf++;
XX            }
XX         }
XX      if (a == quote) {
XX         a  = *buf++;
XX         a7 = a & 0177;
XX         if ((a7 >= 0100 && a7 <= 0137) || a7 == '?') a = ctl(a);
XX         }
XX      if (rpt == 0) rpt = 1;
XX      if (p_mode == 1 && a == '\r') continue;
XX      totbytes += rpt;
XX      for (; rpt > 0; rpt--) putc(a, fp);
XX      }
XX   return;
XX   }
XX
XXvoid spar(data)
XXchar data[];
XX   {
XX   data[0] = tochar(MAXPACKSIZ);
XX   data[1] = tochar(TTIME_LONG);
XX   data[2] = tochar(MYPAD);
XX   data[3] = ctl(MYPCHAR);
XX   data[4] = tochar(MYEOL);
XX   data[5] = MYQUOTE;
XX   data[6] = 'N';
XX   data[7] = '1';
XX   data[8] = MYRPTQ;
XX   data[9] = '\0';
XX   }
XX
XXvoid rpar(data)
XXchar data[];
XX   {
XX   spsiz   = unchar(data[0]);
XX   timint  = unchar(data[1]);
XX   pad     = unchar(data[2]);
XX   padchar = ctl(data[3]);
XX   eol     = unchar(data[4]);
XX   quote   = data[5];
XX   rptflg  = 0;
XX   if (data[6] == 0) return;
XX   if (data[7] == 0) return;
XX   if (data[8] == 0) return;
XX   rptq    = data[8];
XX   rptflg  = ((rptq > 040 && rptq < 0100) || (rptq > 0140 && rptq < 0177));
XX   }
XX
XXsaybye()
XX  {
XX  int len,num;
XX  shutdown = 0;
XX  spack('G',n,1,"F");  /* shut down server no more files */
XX  rpack(&len,&num,ackpkt);
XX  }
XX
XXstatusline()
XX  {
XX  emits ("\nFile:                 Pckt:   Pckt No:      Retrn:    Bytes:         Stat:      ");
XX  x = 48;
XX  curmode = 1;
XX  emits (filnam);
XX  return(0);
XX  }
XX
XXdostats(type)
XXchar type;
XX  {
XX   if (type != 'Y' && type != 'N' && type != 'G') {
XX      x = 224;
XX      emit(type);
XX      x = 312;
XX      sprintf(snum,"%4d",n+(tp * 64));
XX      emits(snum);
XX      if (n==63) tp++;
XX      x = 408;
XX      sprintf(snum,"%2d",retry-1);
XX      emits(snum);
XX      x = 488;
XX      sprintf(snum,"%6ld",(long)totbytes);
XX      emits(snum);
XX      }
XX  }
XX
XX/* allow for multi file xfers separated by commas under kermit and XMODEM */
XX
XXmulti_xfer(name,mode,do_send)
XXchar *name;
XXint (*mode)();
XXint do_send;
XX    {
XX    int done = 0;
XX    int status;
XX    char *p;
XX    
XX    p = name;  
XX    while(*p && *p != ',')   p++;
XX    if (*p == '\0') { 
XX         done = TRUE; 
XX         if (multi == 1) multi++;
XX         }
XX     else multi = 1;
XX    *p = '\0';
XX    status = ((*mode)(name, multi));
XX    if (status == TRUE) {
XX        if (do_send) emits("Sent File: ");
XX          else emits("Received File: ");
XX    	emits(name);
XX    	emits("\n");
XX    	emit(8);
XX        }
XX    else if (status == FALSE)
XX        {
XX        close(fd);
XX        if (do_send) emits("Send Failed: ");
XX          else emits("Receive Failed: ");
XX        emits(name);
XX        emits("\n");	
XX        emit(8);
XX        }    
XX    if (!done) multi_xfer(++p, mode, do_send);
XX    server = 0;
XX    multi = 0;
XX    }
XX
XX/* gobble up all garb that we received while getting file name strings */
XX
XXeatup()
XX   {
XX  while(CheckIO(Read_Request))  {
XX     	WaitIO(Read_Request);
XX     	BeginIO(Read_Request);
XX        }
XX   }   
XX
SHAR_EOF
if test 20179 -ne "`wc -c kermit.c`"
then
echo shar: error transmitting kermit.c '(should have been 20179 characters)'
fi
echo shar: extracting xmodem.c
sed 's/^XX//' << \SHAR_EOF > xmodem.c
XX/*************************************************************
XX * vt100 terminal emulator - XMODEM protocol support
XX *
XX *	     860823 DBW - Integrated and rewrote lots of code
XX *	     860815 Steve Drew: readchar inproved with real timeouts
XX *	v2.0 860809 DBW - Major rewrite
XX *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
XX *	v1.0 860712 DBW	- First version released
XX *
XX *************************************************************/
XX
XX#define MODULE_XMODEM 1
XX#include "vt100.h"
XX
XX/* forward declarations for LATTICE */
XXvoid sendstring();
XXvoid sendchar();
XX
XX/************************************************************
XX* Send a string (using sendchar below)
XX************************************************************/
XX
XXvoid sendstring(s)
XXchar *s;
XX    {
XX    char c;
XX
XX    while ((c = *s++) != '\000') sendchar(c);
XX    }
XX
XX/**************************************************************/
XX/* send char and read char functions for the xmodem function */
XX/************************************************************/
XXvoid sendchar(ch)
XXint ch;
XX    {
XX    rs_out[0] = ch & 0xFF;
XX    DoIO(Write_Request);
XX    }
XX
XXint readchar()
XX    {
XX    int rd,ch;
XX    
XX    Timer.tr_time.tv_secs = ttime;
XX    Timer.tr_time.tv_micro = 0;
XX    SendIO((char *) &Timer.tr_node);
XX    
XX    rd = FALSE;
XX    while (rd == FALSE)  
XX        {	
XX	Wait((1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) |
XX            ( 1L << mywindow->UserPort->mp_SigBit) |
XX            ( 1L << Timer_Port->mp_SigBit));
XX	if (CheckIO(Read_Request))
XX            {
XX	    WaitIO(Read_Request);
XX	    ch=rs_in[0];
XX	    rd = TRUE;
XX	    BeginIO(Read_Request);
XX	    }
XX	if (NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
XX	   if ((NewMessage->Class == RAWKEY) && (NewMessage->Code == 69))
XX	         {
XX                 AbortIO((char *) &Timer);
XX                 Wait (1L << Timer_Port->mp_SigBit);
XX	         if (want_message) 
XX	           emits("\nUser aborted transfer\n");
XX	         timeout = USERABORT;
XX                 return('\0');
XX	         }
XX            continue;
XX            }
XX        if (rd == FALSE && CheckIO(&Timer)) {
XX            if (want_message)
XX              emits("\nTimeout waiting for character\n");
XX            timeout = TIMEOUT;
XX            return('\0');
XX            }
XX	}     /* end while */
XX    AbortIO((char *) &Timer);
XX    Wait (1L << Timer_Port->mp_SigBit);
XX    timeout = GOODREAD;
XX    return(ch & 0xFF);
XX    }
XX
XX/**************************************/
XX/* xmodem send and recieve functions */
XX/************************************/
XX
XXint XMODEM_Read_File(file)
XXchar *file;
XX    {
XX    int firstchar, sectnum, sectcurr, sectcomp, errors, errorflag;
XX    unsigned int checksum, j, bufptr;
XX    char numb[10];
XX    bytes_xferred = 0L;
XX    ttime = TTIME_SHORT;
XX    want_message = TRUE; /* tell readchar to print any error msgs */
XX
XX    if ((fd = creat(file, 0)) < 0)
XX	{
XX	emits("Cannot Open File\n");
XX	return FALSE;
XX	}
XX    else
XX    emits("Receiving File\n\nType <ESC> to abort transfer\n");
XX
XX    sectnum = errors = bufptr = 0;
XX    sendchar(NAK);
XX    firstchar = 0;
XX    while (firstchar != EOT && errors != ERRORMAX)
XX	{
XX	errorflag = FALSE;
XX
XX	do {                                    /* get sync char */
XX	    firstchar = readchar();
XX	    if (timeout != GOODREAD) {
XX		if (timeout == USERABORT || errors++ == ERRORMAX)
XX		    return FALSE;
XX		}
XX	    } while (firstchar != SOH && firstchar != EOT);
XX
XX	if  (firstchar == SOH)
XX	    {
XX	    emits("Getting Block ");
XX	    sprintf(numb, "%d", sectnum);
XX	    emits(numb);
XX	    emits("...");
XX	    sectcurr = readchar();
XX	    if (timeout != GOODREAD) return FALSE;
XX	    sectcomp = readchar();
XX	    if (timeout != GOODREAD) return FALSE;
XX	    if ((sectcurr + sectcomp) == 255)
XX		{
XX		if (sectcurr == ((sectnum + 1) & 0xff))
XX		    {
XX		    checksum = 0;
XX		    for (j = bufptr; j < (bufptr + SECSIZ); j++)
XX			{
XX			bufr[j] = readchar();
XX			if (timeout != GOODREAD) return FALSE;
XX			checksum = (checksum + bufr[j]) & 0xff;
XX			}
XX		    if (checksum == readchar() && timeout == GOODREAD)
XX			{
XX			errors = 0;
XX			sectnum++;
XX			bufptr += SECSIZ;
XX			bytes_xferred += SECSIZ;
XX			emits("verified\n");
XX			if (bufptr == BufSize)
XX			    {
XX			    if (write(fd, bufr, BufSize-128) == EOF)
XX				{
XX				emits("\nError Writing File\n");
XX				return FALSE;
XX				}
XX			    bufptr = 128;
XX			    for (j = 0; j < 128; j++)
XX				bufr[j] = bufr[(BufSize-128)+j];
XX			    }
XX			sendchar(ACK);
XX			}
XX		    else
XX			{
XX			errorflag = TRUE;
XX			if (timeout == USERABORT) return FALSE;
XX			}
XX		    }
XX		else
XX		    {
XX		    /* got a duplicate sector */	
XX		    if (sectcurr == (sectnum & 0xff))
XX			{
XX			/* wait until we time out for 5secs */
XX			do {
XX			    readchar();
XX			    } while (timeout == GOODREAD);
XX			if (timeout == USERABORT) return FALSE;
XX			emits("\nReceived Duplicate Sector\n");
XX			sendchar(ACK);
XX			}
XX		    else errorflag = TRUE;
XX    		    }
XX		}
XX	    else errorflag = TRUE;
XX	    }
XX	if (errorflag == TRUE)
XX	    {
XX	    errors++;
XX	    emits("\nError\n");
XX	    sendchar(NAK);
XX	    }
XX	}        /* end while */
XX    if ((firstchar == EOT) && (errors < ERRORMAX))
XX	{
XX	sendchar(ACK);
XX	while (bufptr > 0 && (bufr[--bufptr] == 0x00 ||
XX			      bufr[bufptr]   == 0x1A)) ;
XX	write(fd, bufr, ++bufptr);
XX	close(fd);
XX	return TRUE;
XX	}
XX    return FALSE;
XX    }
XX
XXint XMODEM_Send_File(file)
XXchar *file;
XX    {
XX    int sectnum, bytes_to_send, size, attempts, c;
XX    unsigned checksum, j, bufptr;
XX    char numb[10];
XX    bytes_xferred = 0;
XX    ttime = TTIME_LONG;
XX    want_message = TRUE; /* tell readchar to print any error msgs */
XX
XX    if ((fd = open(file, 0)) < 0) {
XX	emits("Cannot Open Send File\n");
XX	return FALSE;
XX	}
XX    else
XX    emits("Sending File\n\nType <ESC> to abort transfer\n");
XX    attempts = 0;
XX    sectnum = 1;
XX    /* wait for sync char */
XX    j=1;
XX    while (((c = readchar()) != NAK) && (j++ < ERRORMAX))
XX	if (timeout == USERABORT) return(FALSE);
XX    if (j >= (ERRORMAX))
XX	{
XX	emits("\nReceiver not sending NAKs\n");
XX	return FALSE;
XX	}
XX
XX    while ((bytes_to_send = read(fd, bufr, BufSize)) && attempts != RETRYMAX)
XX	{
XX	if (bytes_to_send == EOF)
XX	    {
XX	    emits("\nError Reading File\n");
XX	    return FALSE;
XX	    }
XX
XX	bufptr = 0;
XX	while (bytes_to_send > 0 && attempts != RETRYMAX)
XX	    {
XX	    attempts = 0;
XX	    emits("Block ");
XX	    sprintf(numb, "%d ", sectnum);
XX	    emits(numb);
XX	    do {
XX		emits(".");    
XX		sendchar(SOH);
XX		sendchar(sectnum);
XX		sendchar(~sectnum);
XX		checksum = 0;
XX		size = SECSIZ <= bytes_to_send ? SECSIZ : bytes_to_send;
XX		bytes_to_send -= size;
XX		for (j = bufptr; j < (bufptr + SECSIZ); j++)
XX		if (j < (bufptr + size)) {
XX		    sendchar(bufr[j]);
XX		    checksum += bufr[j];
XX		    }
XX		else sendchar(0);
XX		sendchar(checksum);
XX		attempts++;
XX		c = readchar();
XX		if (timeout == USERABORT) {emits("\n"); return FALSE;}
XX		} while ((c != ACK) && (attempts != RETRYMAX));
XX	    bufptr += size;
XX	    bytes_xferred += size;
XX	    emits(" sent\n");
XX	    sectnum++;
XX	    }
XX	}
XX    close(fd);
XX    if (attempts == RETRYMAX)
XX	{
XX	emits("\nNo Acknowledgment Of Sector, Aborting\n");
XX	return FALSE;
XX	}
XX    else
XX	{
XX	attempts = 0;
XX	do {
XX	    sendchar(EOT);
XX	    attempts++;
XX	    } while ((readchar() != ACK) &&
XX		     (attempts != RETRYMAX) &&
XX		     (timeout != USERABORT)) ;
XX	if (attempts == RETRYMAX)
XX	    emits("\nNo Acknowledgment Of End Of File\n");
XX	}
XX    return TRUE;
XX    }
XX
SHAR_EOF
if test 7250 -ne "`wc -c xmodem.c`"
then
echo shar: error transmitting xmodem.c '(should have been 7250 characters)'
fi
echo shar: extracting script.c
sed 's/^XX//' << \SHAR_EOF > script.c
XX/*************************************************************
XX * vt100 terminal emulator - Script file support
XX *
XX *	     860823 DBW - Integrated and rewrote lots of code
XX *	     860815 Steve Drew: Initial version written of SCRIPT.C
XX *	v2.0 860809 DBW - Major rewrite
XX *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
XX *	v1.0 860712 DBW	- First version released
XX *
XX *************************************************************/
XX
XX#define MODULE_SCRIPT 1
XX
XX#include "vt100.h"
XX
XXextern	char *fgets(),*malloc();
XXextern	long ftell();
XX
XXstruct COMMAND {
XX                 int (*func)();
XX                 char *cname;
XX};
XX
XXstruct LABEL  {
XX                 struct LABEL *next;
XX                 char *name;
XX                 long pos;
XX};
XX
XX
XX
XX/****************  globals  needed  ******************/
XX
XXchar		on_string[20];       /* string to match on for on cmd    */
XXchar 		wait_string[20];     /* string to match of for wait cmd  */
XXchar 		golabel[20];         /* label we are looking for in goto */
XXchar 		on_cmd[255];         /* command to execute when on matchs*/
XXint 		onsize;		     /* size of on_string                */
XXint 		waitsize;            /* size of wait_string              */
XXint 		onpos;               /* position in on string for search */
XXint 		waitpos;             /* pos in wait_string for search    */
XXint 		on_match;            /* flag set while doing on_cmd      */
XXFILE 		*sf;                 /* file pointer for script file     */
XXstruct LABEL 	*lbase = NULL;       /* will point to first label        */
XXstruct LABEL 	*labels;             /* current label pointer            */
XX
XXint  cmd_send(), cmd_wait(), cmd_on(), cmd_goto(), cmd_delay(), cmd_done(),
XX     cmd_ks(), cmd_kg(), cmd_kr(), cmd_xs(), cmd_xr(), cmd_cap(), cmd_as(),
XX     cmd_null(), cmd_kb();
XX
XXchar *next_wrd(), *tostring();
XX
XX
XX/********************** command table **********************************/
XX
XXstatic struct COMMAND commands[]= {
XX                 cmd_send,   "SEND",         /* send string to host      */
XX                 cmd_wait,   "WAIT",         /* wait for a string from host */
XX                 cmd_on,     "ON", 	     /* on a 'string' do a cmd   */
XX                 cmd_goto,   "GOTO",         /* goto label               */
XX                 cmd_delay,  "DELAY",        /* delay amount of seconds  */
XX                 cmd_done,   "EXIT",         /* exit script file         */
XX                 cmd_ks,     "KS",           /* kermit send file         */
XX                 cmd_kr,     "KR",           /* kermit receive file      */
XX                 cmd_kg,     "KG",           /* kermit get file          */
XX		 cmd_kb,     "KB",	     /* kermit bye (for server)	 */
XX                 cmd_xs,     "XS",           /* xmodem send file         */
XX                 cmd_xr,     "XR",           /* xmodem receive file      */
XX                 cmd_cap,    "CAPTURE",      /* ascii capture on/off     */
XX                 cmd_as,     "ASCII_SEND",   /* ascii send               */
XX		 cmd_null,   NULL
XX};
XX
XX/********************************************************************/
XX/* checks char to see if match with on string or wait_string        */
XX/* if on string match oncmd gets executed imediately,               */
XX/* if wait_string match script_wait is set.                         */
XX/********************************************************************/
XX
XXchk_script(c)
XXchar c;
XX{
XX    if (on_string[0] != '\0') {
XX        if (on_string[onpos] == c) {
XX            onpos++;
XX            if (onpos == onsize) {
XX                on_match = TRUE;
XX                do_script_cmd(ONCOMMAND); 
XX                on_match = FALSE;
XX                return(0);
XX            }
XX        }
XX        else onpos = 0;
XX    }
XX
XX    if (wait_string[0] != '\0') {
XX       if (wait_string[waitpos] != c) {
XX            waitpos = 0;
XX            return(0);
XX        }
XX        waitpos++;
XX        if (waitpos != waitsize) return(0);
XX        wait_string[0] = '\0';
XX        script_wait = FALSE;
XX    }
XX}
XX
XXscript_start(file)
XXchar *file;
XX{
XX    if ((sf = fopen(file, "r")) == NULL) {
XX        emits("Can't open script file\n");
XX        return(0);
XX    }
XX    script_on = TRUE;
XX    script_wait = FALSE;
XX    wait_string[0] = '\0';
XX    on_string[0] = '\0';
XX    on_match = FALSE;
XX    lbase = NULL;
XX}
XX
XX/* return pointer to next word. set l to size of the word */
XX
XXchar *next_wrd(s,l)
XXchar *s;
XXint *l;
XX{
XX    char *p;
XX    while(*s && (*s == ' ' || *s == 9)) s++;
XX    p = s;
XX    while(*s && (*s != ' ' && *s != 9)) s++;
XX    *l = s-p;
XX    return(p);
XX}
XX
XXexe_cmd(p,l)
XXchar *p;
XXint l;
XX{
XX    int i;
XX    
XX    for (i=0; commands[i].func != cmd_null; ++i) 
XX        if (strncmp(p, commands[i].cname, l) == 0) {
XX            (*commands[i].func)(next_wrd(p+l, &l));
XX            return(TRUE);
XX	}
XX        emits ("\nScript - unknown command: ");
XX        emits (p);
XX        emits ("\n"); 
XX}
XX
XXstruct LABEL *find_label(lname)
XXchar *lname;
XX{
XX    struct LABEL *label;
XX  
XX    label = lbase;
XX    while(label != NULL) {
XX       if (strcmp(label->name, lname) == 0) return (label);
XX       label = label->next;
XX    }
XX    return(NULL);
XX}
XX
XX
XXdo_script_cmd(stat)
XXint stat;
XX{
XX    int len,l;
XX    char line[256];
XX    char *p;
XX
XX    if (stat == ONCOMMAND) {    /* if ON command is matched and we were     */
XX        strcpy(line,on_cmd);    /* doing a DELAY then abort the delay timer,*/
XX        p = next_wrd(line,&l);  /* except if on_cmd was just a SEND.        */
XX	if (*p != 'S' && script_wait == WAIT_TIMER)  {
XX            AbortIO((char *) &Script_Timer);
XX            Wait (1L << Script_Timer_Port->mp_SigBit);
XX            script_wait = FALSE; /* script will proceed after on command    */
XX        }
XX	exe_cmd(p,l);
XX        return(0);
XX    }
XX
XX    script_wait = FALSE;
XX    while(fgets(line,256,sf) != NULL) {
XX       len = strlen(line);
XX       line[--len] = '\0';
XX       p = next_wrd(&line[0], &l);
XX       if (*(p + l - 1) == ':') {       	/* its a label */
XX           *(p + l - 1) = '\0';
XX           if (find_label(p) == NULL) {   	/* it's a new label */
XX               if (lbase == NULL)  {  		/* it's the first label */
XX                   labels = lbase = (struct LABEL *) malloc (sizeof (struct LABEL));
XX               }
XX               else {
XX                   labels->next = 
XX                           (struct LABEL *) malloc (sizeof (struct LABEL));
XX                   labels = labels->next;
XX               }
XX               labels->pos  = ftell(sf);
XX               labels->name = malloc(l);
XX               labels->next = NULL;
XX               strcpy(labels->name, p);
XX               if (stat == GOTOLABEL && strcmp(p, golabel) == 0) 
XX                      stat = NEXTCOMMAND;
XX           }
XX           if (l < len) p = next_wrd(p+l+1, &l);
XX           else return(0);
XX       } 	/* end of it's a label */
XX       if (stat == GOTOLABEL || *p == '#') continue;
XX       if (*p) exe_cmd(p,l);
XX       return(0);
XX    } 		/* end of while */
XX    if (stat == GOTOLABEL) {
XX          emits("\nScript - label not found: ");
XX          emits(golabel);
XX          emits("\n");
XX    }         
XX    exit_script();
XX}
XX
XXexit_script()
XX{
XX    if (script_wait == WAIT_TIMER)      /* timer not done yet */
XX       AbortIO((char *) &Script_Timer); /* so abort it */
XX    emits("\nScript - terminated\n");    
XX    script_on = FALSE;
XX    script_wait = TRUE;
XX    fclose(sf);
XX}
XX
XX/* remove quotes terminate string & return pointer to start */
XX
XXchar *tostring(ptr)
XXchar *ptr;
XX{
XX    char *s;
XX
XX    s = ptr;
XX    if (*ptr == '"') {
XX         while(*ptr++  && *ptr !='"');
XX         if (*ptr == '"') {
XX             *ptr = '\0';  
XX             ptr = s+1;
XX             while(*s++)  if (*s == '|') *s = '\r';
XX             return(ptr);
XX         }
XX    }
XX    if (*s == '^') {
XX        *s = *(s+1)-64;
XX        *(s+1) = '\0';
XX        return(s);
XX        }
XX    *(s+1) = '\0';
XX    return(s);
XX}   
XX        
XXcmd_goto(lname)
XXchar *lname;
XX{
XX    struct LABEL *label;
XX   	                    /* if on_cmd was a goto kill wait state */
XX    if (on_match) { wait_string[0] = '\0'; script_wait = FALSE; }
XX    if ((label = find_label(lname)) == NULL) {  /* is it forward */
XX        strcpy(golabel,lname);
XX        do_script_cmd(GOTOLABEL);
XX    }
XX    else {
XX        fseek(sf,(long)(label->pos),0);
XX    }
XX}
XX
XXcmd_send(str)
XXchar *str;
XX{
XX  sendstring(tostring(str));
XX}
XX
XX 
XXcmd_wait(str)
XXchar *str;
XX{
XX        str = tostring(str);
XX        *(str+20) = '\0';         /* 20 characters max */
XX        strcpy(wait_string, str);
XX        waitsize = strlen(str);
XX        script_wait = WAIT_STRING;
XX}
XX
XXcmd_on(str)
XXchar *str;
XX{
XX   char *p;
XX
XX   p = tostring(str);
XX   strcpy(on_string, p);
XX   onsize = strlen(p);
XX   *(p+onsize+2+20) = '\0';        /* 20 characters max */
XX   strcpy(on_cmd,p+onsize+2);
XX}
XX
XXcmd_delay(seconds)
XXchar *seconds;
XX{
XX    script_wait = WAIT_TIMER;
XX    Script_Timer.tr_time.tv_secs = atoi(seconds);
XX    Script_Timer.tr_time.tv_micro = 0;
XX    SendIO((char *) &Script_Timer.tr_node);
XX}
XX
XXcmd_done()
XX{
XX    exit_script();
XX}
XX
XXcmd_ks(file)
XXchar *file;
XX{
XX   multi_xfer(file, doksend, 1);
XX}
XX
XXcmd_kr(file)
XXchar *file;
XX{
XX   multi_xfer(file, dokreceive, 0);
XX}
XX
XXcmd_kg(file)
XXchar *file;
XX{
XX   server = TRUE;
XX   multi_xfer(file, dokreceive, 0);
XX}
XX
XXcmd_kb()
XX{
XX   saybye();
XX}
XX
XXcmd_xs(file)
XXchar *file;
XX{
XX   multi_xfer(file, XMODEM_Send_File, 1);
XX}
XX
XXcmd_xr(file)
XXchar *file;
XX{
XX   multi_xfer(file, XMODEM_Read_File, 1);
XX}
XX
XXcmd_cap(file)
XXchar *file;
XX{
XXdo_capture(file);
XX}
XX
XXcmd_as(file)
XXchar *file;
XX{
XXdo_send(file);
XX}
XX
XXcmd_null(file)
XXchar *file;
XX{
XX}
XX
SHAR_EOF
if test 9364 -ne "`wc -c script.c`"
then
echo shar: error transmitting script.c '(should have been 9364 characters)'
fi
#	End of shell archive
exit 0

cjp@vax135.UUCP (Charles Poirier) (08/28/86)

In article <4992@decwrl.DEC.COM> wecker@cookie.dec.com (DAVE  TANSTAAFL  WECKER) writes:
>
>#	This is a shell archive.
>#	Remove everything 

This is where our file system truncated Part 1 of the VT100 emulator.
It *did* remove everything.
Would someone nearby please offer to mail me a whole copy?
Thanks very much.

	Charles Poirier   USENET <backbone>!vax135!cjp

vanam@pttesac.UUCP (Marnix van Ammers) (08/28/86)

Great program!  I am absolutely delighted with it.  I liked
the first version, but this is getting really good.

Here are my notes from last night.

There were errors in the shar file.  When I unshared, it I got
complaints about vt100.h and window.c .  Everything compiled
just fine, but the PF and arrow keys didn't work as they should have.

It later turned out that both vt100.h and window.c were missing
escape characters from some character definitions.  In vt100.h
look for the definitions of the PF keys.  Set the first character
in those strings to "\033".  It should be on line 173 which now
looks like:

    "OP","OQ","OR","OS",

Change it to look like:

    "\033OP","\033OQ","\033OR","\033OS",

In window.c wherever you see sendstring(, (I show them on lines
276 through 293), put an escape character at the beginning of
each string.  So, for instance line 290 which now looks like:

    case 0x4c:  c=0;  sendstring("[A"); break;

should look like:

    case 0x4c:  c=0;  sendstring("\033[A"); break;

Undoubtedly these escapes were at one time in the program but
were accidentally stripped out by an editor or through some
transfer process.  Putting them in there with the octal number
method (\033) helps prevent such accidents.

The vt100.doc file says that the program looks for 3 initfiles,
the first one being "initfile".  Not True, program only looks
for "vt100.init" and for "c:vt100.init".

When I first noticed that my vt100 arrow keys and PF keys weren't
working right, I tried to set them in the init file but somehow
that didn't work.  I was able to set the other variables in my
init file (except for cursor color which always remained blue).

I looked in init.c and couldn't see the problem.  I did see that
there are several instances where there was a constant integer 0
where a constant character '\0' should have been.  Changing
that didn't fix the problem with setting the function keys however.
Perhaps I'm doing something wrong or misunderstanding the documentation.
I did want to get this out early to spare any of you the troubles
I had with those escapes.

I used Xmodem to receive a file successfully.  I didn't try
sending and I didn't try KERMIT.

I used 48 lines successfully.  By setting the background to
000 and the foreground to 888 I could make the interlace
flicker almost unnoticeable.

I did have a little trouble with the go-away gadget while in interlace
mode.  It seems that the tip of my mouse pointer would have to be
somewhere beyond the center of the gadget.  Usually I use the tip of
my pointer, but in this case, I had to point with the center of my
pointer.  I also did have to fiddle with the screen and window drag
bars a bit to get the bottom line fully on the screen.

Still haven't tried the script capabilities.

For me this is the best free program I've ever had.  Now if Matt
will just hurry up with that new shell ...

Marnix

phils@tekigm.UUCP (Phil Staub) (08/30/86)

In article <269@pttesac.UUCP> vanam@pttesac.UUCP (Marnix van Ammers) writes:
>
>Great program!  I am absolutely delighted with it.  I liked
>the first version, but this is getting really good.
>

I fully agree.
>
>When I first noticed that my vt100 arrow keys and PF keys weren't
>working right, I tried to set them in the init file but somehow
>that didn't work.  I was able to set the other variables in my
>init file (except for cursor color which always remained blue).
>

The cursor color problem is in init.c. Beginning about line 69 is a section
which is used to set the cursor color. There is a "sscanf" call which 
has a "%d" which should be "%x", because it is looking for a *hex* 
value in the vt100.init file, not decimal. Thus,

if (sscanf(line,"%s %d",scr,&i) == 2) p_cursor = i;

Should look like:

if (sscanf(line,"%s %x",scr,&i) == 2) p_cursor = i;
                     ^


>
>I used Xmodem to receive a file successfully.  I didn't try
>sending and I didn't try KERMIT.
>

I have used KERMIT successfully, but I don't remember if I used the
"receive" function. I do know that "get" and "send" work properly, and
binary file transfer works properly.


Phil Staub
Tektronix, Inc.
ISI Engineering
P.O. Box 3500
Vancouver, Washington 98668
C1-904, (206) 253-5634
..tektronix!tekigm!phils

jec@iuvax.UUCP (08/30/86)

	I've noticed that the vt100 emulator has a strange broken red
line at the bottom of the screen.  Has anyone else noticed this?  I'm
not sure what the cause is, but suspect that it might have something to
do with the window/screen positioning.

	Also, any chance we could get a 132 column font and support for
VT100?  That would be real cool.

	By the way, VT100 is other than these minor things absolutely
great!  


    III          Usenet:     {ihnp4,pur-ee,purdue}!iuvax!jec
UUU  I  UUU      Phone:      (812) 335-5561
 U   I   U
 U   I   U       U.S. Mail:  Indiana University
 U   I   U                   Dept. of Computer Science
  UUUUUUU                    021-C Lindley Hall
     I                       Bloomington, IN. 47405
    III

bill@dayton.UUCP (bill) (09/02/86)

	Could someone who received the two part vt100 program (V2)
mail it to me?  The files that ended up in MN where toasted.
(The files vt100.c and init.c in the first shar did not exist
at all, and at the SHAR_EOF that was to end vt100.h it did a 
wc of init.c.  As if something had eaten a good number of lines
out of the middle of the file.)

	Thanks
	 -Bill


-- 
UUCP: ihnp4!rosevax!dayton!bill         Bill Argyros
ATT:  (612) 375-2816                    Dayton-Hudson Dept. Store. Co.
                                        700 on the Mall
                                        Mpls, Mn. 55402