[comp.sys.amiga] vt100

wecker@cookie.dec.com (DAVE TANSTAAFL WECKER) (11/16/86)

For all of you who have been waiting, I sent V2.3 of the emulator to doc
(the amiga source moderator) over 2 weeks ago. I don't know what the delay is,
but hopefully you will all see it soon.

Sorry about delays beyond my control...

dave	{decwrl|decvax}!cookie.dec.com!wecker
	(ARPA: wecker%cookie.dec.com@decwrl.dec.com)

kim@amdahl.UUCP (Kim DeVaughn) (11/18/86)

In article <6424@decwrl.DEC.COM>, wecker@cookie.dec.com (DAVE  TANSTAAFL  WECKER) writes:
> For all of you who have been waiting, I sent V2.3 of the emulator to doc
> (the amiga source moderator) over 2 weeks ago.

Over the past few weeks, I've noticed that a number of people have mentioned
that they've sent things to mod.amiga.sources, including some things from
CBM.  None of these have been posted anywhere to my knowledge.

What with the new net organization, etc., I'd like to suggest that *all*
Amiga related postings be made to *this* group (comp.sys.amiga) until
we find out if there still *is* a moderated group/moderator around.

Please don't take this as a flame, it isn't intended to be ... just an
observation and a suggestion.

/kim


-- 
UUCP:  {sun,decwrl,hplabs,pyramid,ihnp4,seismo,oliveb}!amdahl!kim
DDD:   408-746-8462
USPS:  Amdahl Corp.  M/S 249,  1250 E. Arques Av,  Sunnyvale, CA 94086
CIS:   76535,25

[  Any thoughts or opinions which may or may not have been expressed  ]
[  herein are my own.  They are not necessarily those of my employer. ]

rissa@chinet.UUCP (Garret and Trish) (11/21/86)

In article <4196@amdahl.UUCP> kim@amdahl.UUCP (Kim DeVaughn) writes:
>
>Over the past few weeks, I've noticed that a number of people have mentioned
>that they've sent things to mod.amiga.sources, including some things from
>CBM.  None of these have been posted anywhere to my knowledge.
>

Yeah, I have been mailing to ulowell for some time and all I get is
the sound of silence.

Maybe I have the wrong address, or have made the wrong incantations,
or maybe I need to sacrifice some more goats.  Do those guys accept
sheep ?  Visa ?  Thats it, I need to slice my Visa card into shreds
at midnight while repeating the introduction to K&R backwards...

Never mind.

Has anyone talked to the amiga.mod lately ?

Garret         ...!ihnp4!chinet!rissa

fwp@unccvax.UUCP (Rick Pasotto) (12/09/86)

	I have come across a very strange happening while using Dave
Wecker's VT100 program.  This is the situation: I have a disk labeled
'executables' which has on it the vt100 program, vt100.init, and a
script file that dials my modem and logs me in to the host (unix)
computer. The script file is bound to a function key in the init file.
Normally I'll insert the disk in df1:, cd to df1: and type 'run vt100'.
If I then press the appropriate function key everything works exactly
as it should, ie. the modem is dialed, I get logged in, the script
terminates and I do what I need to.

	The strangeness occurrs when the 'executables' disk is not in
a drive when I press the function key.  What happens is that a
requester comes up to insert the 'executables' disk (which I do), the
script file is read and executed and everything appears normal: the
modem is dialed and I get logged in.  BUT, at this point I can't do
anything because I am in CAPS mode. The unix host will not recognize
any commands because the case is wrong. Since I 'ran' the program, I
can push the screen to the back and type normally (upper and lower) on
the workbench screen. At this point all I can do on the host system is
ctl-d out.  So now VT100 is waiting to dial another number and I AM
STILL STUCK IN CAPS MODE.  The only way out now is to kill VT100 and
start all over making sure that the 'executables' disk is actually in
a drive whenever I press the function key to execute the script.

	Anybody have any ideas what could be causing this????

(BTW, this is VT100 v2.3, compiled with manx, running under WB 1.2G.)

Rick Pasotto

chas@gtss.UUCP (Charles Cleveland) (12/09/86)

Here are the (context) diffs for adding normal/application cursor capability
to Wecker's vt100 (v2.3).  I have had several requests for them, but have
also seen more incorrect solutions to this problem posted, so I thought I'd
better put in my contribution.  In general, the host needs to be able to
toggle normal/application mode for the cursor keys independently of the
keypad mode.

All I have to say about the questions of timing and queueing of input which
several writers have said makes UNIX vi misbehave as per vt100's cursor 
keys because the escape sequences in termcap [or terminfo?] aren't actually 
the vt100 escape sequences (or some such, my eyes were glazing over),
is that that means termcap (or vi) ought to be fixed, not vt100 emulators.
A good emulation of a turd does not smell like a rose.  There are times one
needs a turd :-).  I'm on a vt100 on a Sun 2/170 in vi right now, and here, 
where the escape sequences given in termcap for the up, down, right, and left 
cursor keys, with no modification on my part, are <esc>OA, <esc>OB, <esc>OC, 
<esc>OD (the 'application' values, which the cursor keys are set to on 
entering vi), I find it impossible to produce, at 9600 baud, any misbehavior 
on the part of my cursor keys.  I may just be lucky though.

Of course if I try to move the cursor while in insert mode I spew A's, B's,
C's, and D's all over the place, but the vt100 is not, according to termcap, 
one of those terminal for which it is safe to try this.  One gets used to 
hitting <esc> before cursor motions.  On the other hand, if I *force* the
cursor keys into 'normal' mode, I always get the A's, B's, C's, & D's, and 
have to revert to k's, j's, l's, and h's to move around.

Different hosts and different programs on those hosts may want different
settings.  Just as the host can set the the keypad to either application or
normal mode, it is supposed to be able to set the cursor keys to either 
application or normal mode.  These patches do this.  I suspect that some of 
the problems that people are having with cursor keys will go away if these 
patches are installed, especially on non-UNIX systems, and I suspect that 
others will go away if termcap is altered (You can make your own termcap 
entry in your own directory if you can't muck around in /etc/termcap.
You can even make a vtamiga entry.).  I strongly suspect that other cursor 
key problems will still remain for some folks.

----------------------------------------
here the crap ends and the patches begin
----------------------------------------
diff -c remote.c remote.c.fixed
*** remote.c		Mon Nov 24 19:00:56 1986
--- remote.c.fixed	Mon Dec  8 21:15:59 1986
***************
*** 88,94
  
        case 'c':				/* Reset */
  	top = MINY; bot = MAXY; savx = MINX; savy = MINY;
! 	curmode = FS_NORMAL; keyapp = FALSE;
  	inesc = -1;
  	a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
  	emit(12);

--- 88,94 -----
  
        case 'c':				/* Reset */
  	top = MINY; bot = MAXY; savx = MINX; savy = MINY;
! 	curmode = FS_NORMAL; keyapp = FALSE; curapp = FALSE;
  	inesc = -1;
  	a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
  	emit(12);
***************
*** 267,273
  
        case 'h':				/* Set parameter */
  	if (private == 0 && p[0] == 20)		nlmode = 1;
! 	else if (private == '?' && p[0] == 7)	p_wrap = 1;
  	return;
  
        case 'l':				/* Reset parameter */

--- 267,276 -----
  
        case 'h':				/* Set parameter */
  	if (private == 0 && p[0] == 20)		nlmode = 1;
! 	else if (private == '?'){
! 		if( p[0] == 7)	p_wrap = 1;
! 		else if( p[0] == 1)	curapp = 1;
! 	}
  	return;
  
        case 'l':				/* Reset parameter */
***************
*** 272,278
  
        case 'l':				/* Reset parameter */
  	if (private == 0 && p[0] == 20)		nlmode = 0;
! 	else if (private == '?' && p[0] == 7)	p_wrap = 0;
  	return;
  
        case 'x':

--- 275,284 -----
  
        case 'l':				/* Reset parameter */
  	if (private == 0 && p[0] == 20)		nlmode = 0;
! 	else if (private == '?'){
! 		if(p[0] == 7)	p_wrap = 0;
! 		else if( p[0] == 1)	curapp = 0;
! 	}
  	return;
  
        case 'x':
diff -c vt100.c vt100.c.fixed
*** vt100.c		Mon Nov 24 19:00:24 1986
--- vt100.c.fixed	Mon Dec  8 21:12:01 1986
***************
*** 61,66
      y	      =	    MINY; 
      curmode   =	    FS_NORMAL;
      keyapp    =	    0;
      script_on =     FALSE;
      script_wait=    TRUE;
      SetAPen(mywindow->RPort,1L);

--- 61,67 -----
      y	      =	    MINY; 
      curmode   =	    FS_NORMAL;
      keyapp    =	    0;
+     curapp    =	    0;
      script_on =     FALSE;
      script_wait=    TRUE;
      SetAPen(mywindow->RPort,1L);
diff -c vt100.h vt100.h.fixed
*** vt100.h		Mon Nov 24 19:00:19 1986
--- vt100.h.fixed	Mon Dec  8 21:23:37 1986
***************
*** 159,165
  UBYTE  *BeepWave;
  UBYTE  Audio_AllocMap[4] = { 1, 8, 2, 4 };
  int want_message;
! int x,y,curmode,keyapp;
  int MINX	= 0;
  int MAXX	= 632;
  int MINY	= 14;

--- 159,165 -----
  UBYTE  *BeepWave;
  UBYTE  Audio_AllocMap[4] = { 1, 8, 2, 4 };
  int want_message;
! int x,y,curmode,keyapp,curapp;
  int MINX	= 0;
  int MAXX	= 632;
  int MINY	= 14;
***************
*** 254,260
  extern char *rs_in;
  extern struct IOExtSer *Write_Request;
  extern char rs_out[2];
! extern int x,y,curmode,keyapp;
  extern int MINX,MAXX,MINY,MAXY,top,bot,savx,savy;
  extern int savmode,nlmode,alt,savalt,a[2],sa[2];
  extern int inesc,inctrl,private,badseq,maxcol;

--- 254,260 -----
  extern char *rs_in;
  extern struct IOExtSer *Write_Request;
  extern char rs_out[2];
! extern int x,y,curmode,keyapp,curapp;
  extern int MINX,MAXX,MINY,MAXY,top,bot,savx,savy;
  extern int savmode,nlmode,alt,savalt,a[2],sa[2];
  extern int inesc,inctrl,private,badseq,maxcol;
diff -c window.c window.c.fixed
*** window.c		Mon Nov 24 19:01:00 1986
--- window.c.fixed	Mon Dec  8 21:07:41 1986
***************
*** 310,316
  	case 0x4d: 
  	case 0x4e: 
  	case 0x4f: sendchar(27);            /* cursor keys */
! 		   if (keyapp) sendchar('O');
  		   else sendchar('[');
  		   sendchar(code - 11);
  		   break;

--- 310,316 -----
  	case 0x4d: 
  	case 0x4e: 
  	case 0x4f: sendchar(27);            /* cursor keys */
! 		   if (curapp) sendchar('O');
  		   else sendchar('[');
  		   sendchar(code - 11);
  		   break;
----------------------------------------
end of patches
----------------------------------------
-- 
Charles Cleveland			chas@ss.physics.gatech.edu
Georgia Tech School of Physics
Atlanta, GA 30332			Georgia Tech Surface Studies

...!{akgua,allegra,amd,hplabs,ihnp4,masscomp,ut-ngp,rlgvax,sb1,
	uf-cgrl,unmvax,ut-sally}!gatech!gtss!chas

fwp@unccvax.UUCP (12/10/86)

	An additional note:  I have discovered that the strangeness
occurs only when the script is bound to a SHIFTED function key.

Rick Pasotto

wecker@cookie.dec.com (DAVE CUM GRANO SALIS WECKER) (12/15/86)

#	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 Dec 14 17:42:23 1986
echo shar: extracting readme
sed 's/^XX//' << \SHAR_EOF > readme
XXThis archive contains a vt100 emulator with KERMIT and XMODEM file
XXtransfer protocols by Dave Wecker (V2.4 DBW 861214).
XX
XXThanks:
XX-------
XX	To everyone who sent in code and suggestions!
XX
XXReleases:
XX---------
XX	v2.4 861214 DBW - lots of fixes/additions
XX	v2.3 861101 DBW - minor bug fixes
XX	v2.2 861012 DBW - more of the same
XX 	v2.1 860915 DBW - new features (see README)
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.4 861214 DBW - lots of fixes/additions
XX	- Beep should now work under Lattice
XX	- CreatePort now passes longs (as it should always have)
XX	- Nested comments in KERMIT.C removed
XX	- Beep volume of 0 (DisplayBeep) now works
XX	- snum[] declaration in KERMIT.C fixed
XX	- multi_xfer is now void and return fixed (in kermit)
XX	- "." can no longer get "stuck" as the break key
XX
XX	- RIGHT-AMIGA-keys have been added for most menu items
XX	- The ALT key is now an EIGHTth bit shifter
XX	- Control-@, Control-2, Control-space send the NULL character
XX	- Control-6 now sends Control-^
XX	- Control-- and Control-? now sends Control-_
XX	- Cursor application mode (<esc>[?1h and <esc>[?1l) now work
XX	- XMODEM now masks the eighth bit if parity is other than NONE
XX
XXv2.3 861101 DBW - minor bug fixes:
XX
XX	- added p_wbcolors to allow workbench colors on custom screen
XX	  (In the init file you can specify WBCOLORS to be NO (use color
XX	   definitions in INIT FILE or VT100.H) or YES (use WORKBENCH
XX	   colors for everything)).
XX	- "$" now sends a kermit-bye (like it says in VT100.DOC).
XX	- made window/screen heights more reasonable
XX	- Added ANSI insert line and delete line (<csi><num>L and
XX	  <csi><num>M) to speed up various editors (like emacs).
XX	  NOTE: This is NOT a VT100 sequence (new extension).
XX	- ctrl-space now also sends a null (along with ^@ and ^`)
XX	- RAWKEY fixed in WINDOW.C
XX	- p_wrap fixed in WINDOW.C
XX	- removed WRDMAX from VT100.H
XX	- fixed exit with no params in SCRIPT.C
XX	- fixed parity comparisons in KERMIT.C
XX	- init file [n+1] changed to [nplus1] to make Lattice happy.
XX	- cursoron(), cursoroff() changed to one routine cursorflip().
XX	- long lines shortened to less than 80 characters (for gateways).
XX	- blanks following exit (or comments) now work in scripts.
XX
XXv2.2 861012 DBW - more of the same:
XX
XX	- The INIT file "exit" can now chain to a script
XX	- The SCRIPT command "exit" can now chain to another script
XX	- Hangup menu item now works.
XX	- Autowrap can now be set from VT100.H, VT100.INIT (<esc>[?7h l)
XX	- Control-G is now handled with an audible beep
XX	- Script now used "^chr" to send control characters
XX	- The graphics "box" character (a) was added
XX	- Control-@ and Control-` now send the NULL character
XX	- Alternate color for BOLD has been re-instated by popular demand
XX	- Menus have been cleaned up.
XX	- Lattice compilation cleaned up.
XX	- No more wordsize parameter since PARITY takes care of all cases
XX	- Function keys can now call scripts
XX	- Double shift keys are now handled correctly.
XX	- Version has been added to the title bar (for bug reports).
XX
XXv2.1 860915 DBW - new features / bug fixes
XX
XX	- Now identifies as a VT100 (including the response to <esc>Z)
XX	- Cursor color now gets read in as hex (instead of decimal)
XX	- REPORTMOUSE taken out of definitions (not needed)
XX	- XON/XOFF now being handled by the device driver instead of me
XX	- Literal escape characters have been replaced with \033
XX	- At init time the user can now specify the input BUFFER size
XX	  (typically between 512 and 2048 bytes) depending on baud rate
XX	- Script files are now case insensitive for commands
XX	- XMODEM now turns off the driver XON/XOFF during transfers
XX	- Graphic rendition now done by the OS instead of me.
XX	- Initialization files are now searched for in S: instead of C:
XX	- Forward GOTO bug fixed in the script package.
XX	- Keypad can now be used in both numeric and application mode
XX	- General purpose cleanup() routine added for all exits.
XX	- Utility menu added (sendbreak, hangup, change directory).
XX	  NOTE: hangup is not implemented yet.
XX	- Full wild card support in file transfers (see vt100.doc).
XX	- Kermit cleaned up with better filename handling (from host).
XX	- Script now has CD (changed directory) and SB (send break) commands
XX	- Added Parity and Wordsize choices in VT100.H, VT100.INIT, menu
XX	  and scripts. (Generates parity from a table).
XX	- Added 8th bit quoting in KERMIT when using 7 bit words (ODD or
XX	  EVEN parity).
XX	- Break time can be set from VT100.H, VT100.INIT or a script file.
XX	- Transfer mode (image or CRLF) can now be set from a script file.
XX	- Control characters in escape sequences now act like a true VT100.
XX	- F10 now works from init files.
XX	- Right (or Left) AMIGA with period (".") sends a BREAK to the host
XX	  from the keyboard.
XX	- XMODEM status kept down to one line for a file transfer.
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	- 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	- Added XON/XOFF generation so that characters should not get lost
XX	  any more at 9600 baud (when receiving clear text).
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	  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	- 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	- 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	- WORKBENCH colors are NEVER touched.
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	- 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	- File capture now no longer sends the filename to the host.
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	- UNDERLINE (<esc>[4m) has now been added.
XX	- The handling of remote (host) escape sequences has been completly
XX	  re-written (thanks to Dawn Banks for all the work).
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	- Cursor has no been reduced to the size of a normal character for
XX	  easier readability.
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	- KERMIT has been completely re-written and appears to work fine,
XX	  thanks to the efforts of Steve Drew.
XX	- New menu item allows script file support. Module written by
XX	  Steve Drew. See VT100.DOC for details.
XX
XXKnown problems:
XX---------------
XX	- Wraping a line at the end of a scrolling region will not scroll
XX	  correctly.
XX
XX	- Caps get locked on after a volume is requested during a file xfer
XX	  (I have not looked into this one yet).
XX
XX	- Cursor hot spot sometimes moves on custom screen.
XX	  (I've seen this one, and don't understand it).
XX
XXSuggestions/bug fixes not implemented:
XX--------------------------------------
XX	- "Custom colors are getting ignored"
XX
XX	  Wrong... you probably forgot to say "WBCOLORS NO" in the INIT file.
XX
XX	- "ASCII capture uses synchronous I/O so capture of game playing
XX	  is jerky"
XX
XX	  This change MAY be made if someone else wants to write the code.
XX
XX	- "Beep should be in stereo"
XX
XX	  I am trying to use as FEW system resources as possible, therefore
XX	  beep only ties up 1 of the 4 possible channels.
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
XX	REMEMBER: Set the correct compiler definition in VT100.H
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
XX	expand.c	- filename expansion (wildcards) and dir setting
XX
XXContact:
XX--------
XXPlease send bugs/comments/suggestions/praise 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 9408 -ne "`wc -c readme`"
then
echo shar: error transmitting readme '(should have been 9408 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.4 DBW 861214). Comments/suggestions/bugs/problems/praise
XXshould be 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
XXMany other pieces of code/suggestions have been sent in..
XX
XX	thanks to all!
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 the specified
XX		  "initfile", then VT100.INIT (in the current directory)
XX		  and finally S:VT100.INIT. The format for the init file
XX		  is described 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
XXMenus (Commands in parenthesis are keyboard bindings: Right-Amiga-chr):
XX-----------------------------------------------------------------------
XXFile 	  			- file transfers
XX	Ascii Capture		- Begin/end a script of the current session
XX	Ascii Send		- Type a file to the host
XX	Xmodem Receive	(A-V)	- Receive a file using XMODEM protocol
XX	Xmodem Send	(A-^)	- Send    a file using XMODEM protocol
XX	Kermit Get	(A-G)	- Receive files from a host KERMIT SERVER
XX	Kermit Receive	(A-R)	- Receive files from a host KERMIT
XX	Kermit Send	(A-S)	- Send    files to   a host KERMIT [SERVER]
XX	Kermit Bye	(A-B)	- Terminate a host KERMIT SERVER
XXComm Setup			- Setup communications
XX	Baud Rate		- Set the terminal baud rate
XX		300, 
XX		1200,	(A-L)
XX		2400,	(A-H)
XX		4800,
XX		9600
XX	Parity			- Type of parity
XX		NONE, 	(A-X)
XX		MARK,
XX		SPACE,
XX		EVEN,	(A-E)
XX		ODD	(A-O)
XX	Xfer Mode
XX		Image	(A-I)	- Send files verbatim (for UNIX hosts or
XX				  binary files)
XX		Text	(A-T)	- Send CR LF as line terminator and strip
XX				  CR on received files (VMS text).
XXScript 	  			- Script commands
XX	Execute file		- Start up an asynchronous script file
XX	Abort Execution		- Terminate a script file
XXUtility   			- Utility commands
XX	Send Break	(A-.)	- send a break to the host
XX	Hang Up			- close line (not implemented yet)
XX	Change Dir	(A-D)	- change the local directory (for transfers)
XX
XXKeypad mapping (in application mode):
XX-------------------------------------
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
XXNote:	Right AMIGA key in conjunction with a period (".")
XX	will send a break to the host.
XX
XX	CTRL in conjunction with an at-sign ("@") a two ("2") or a
XX	space (" ") will send a NULL to the host.
XX
XX	CTRL in conjunction with a six  ("6") will send a CTRL-^
XX	CTRL in conjunction with a dash ("-") or question mark ("?")
XX		will send a CTRL-_ to the host.
XX
XXInitialization file example:
XX----------------------------
XXHere is a (hopefully) self-explanatory VT100.INIT file with all
XXoptions used:
XX
XX#####################################################################
XX#
XX#	VT100 sample initialization file
XX#	v2.4 861214 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		CUSTOM		# may be CUSTOM or WORKBENCH
XXINTERLACE	ON		# ON for CUSTOM or interlaced workbench
XXDEPTH		1		# number of bit planes to use (1 or 2)
XXWBCOLORS	YES		# ignore custom colors and use defaults
XXFOREGROUND	950		# Colors are only used on the custom screen
XXBACKGROUND	000		# Colors are in hex RGB from 000 to FFF
XXBOLD		a00		# Color for bold highlighting (in custom)
XXCURSOR		00a		# Color for cursor (in custom screen)
XXLINES		48		# normal <= 24 interlaced <= 48
XXMODE		CRLF		# IMAGE or CRLF (for KERMIT transfers)
XXBUFFER		512		# 512 <= Input buffer size <= 2048
XXPARITY		NONE		# NONE (= 8 bit), MARK, SPACE, ODD or EVEN
XXBREAK		750000		# Length for break key in microseconds
XXVOLUME		64		# Beep Volume (0 = Visual Beep)
XXWRAP		OFF		# Auto wrap ON or OFF
XXKEYSCRIPT	7E		# Hex value for script introducer
XX#
XX# Function bindings (strings to type when any of F1 - 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 char:
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# If the first character of the string is a script introducer
XX# (KEYSCRIPT) then the string is interpreted as a script filename
XX# to be executed when the key is pressed.
XX#
XX# Examples of bindings:
XX#
XXf1	"^[OP"			# f1-f4 = PF1 - PF4 on a VT100
XXf2	"^[OQ"
XXf3	"^[OR"
XXf4	"^[OS"
XX#
XX# f5,6,7 = scripts to execute (assuming that KEYSCRIPT = '~' = 0x7E)
XX#
XXf5	"~df1:vt100_source/dialwork.script"
XXf6	"~df1:vt100_source/sendvt100.script"
XXf7	"~df1:vt100_source/getpics.script"
XX#
XXf8	"MAIL^M"		# Reads my mail (note embedded <CR>)
XXf9	"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#
XX# all done with init, now execute script as startup sequence
XX#
XXexit df1:vt100_source/dialwork.script
XX
XXMulti file Xfers:
XX-----------------
XXThe VT100 emulator now supports multiple file transfers. This is
XXspecified by using a comma (",") between file names when using XMODEM
XXor KERMIT. (NOTE: host XMODEM's normally CANNOT support multiple file
XXtransfers).
XX
XXWhen specifying a file name to recieve by default the directory path
XXis stripped of the filename when sent to the host but is kept for the
XXlocal file 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
XXnewfile.bin and put it on df1: (see explanation of "$" below). If you
XXdo a single file transfer you will get another prompt for the remote
XXname 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
XXthe desired directory.
XX
XXIn addition KERMIT now supports wildcards (* = any number of
XXcharacters, ? = any single character). Examples:
XX
XX	send:	*.c,*.h,*.doc
XX	get:	*.c,*.h,$
XX
XXKERMIT receive is now smart enough to use the host filename so no
XXfilename needs to be specified on the AMIGA's side.
XX
XXScript file operation:
XX----------------------
XXThe script file can be invoked by selecting 'execute file' from the
XXscript menu. 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
XXdesired if your script file is WAITing for a string or is DELAYing for
XXa period of time etc.
XX
XXScript file Commands (case insensitive):
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------------------------------------------------------------
XXBAUD 	Set baud rate
XX   Format:
XX	BAUD rate		Sets the baud rate for send/receive
XX   Example:
XX	BAUD 2400		Sets the baud rate at 2400 baud
XX------------------------------------------------------------
XXBT	Set the break time (for an SB command)
XX   Format:
XX	BT value		Value is in micro-seconds
XX   Example:
XX	BT 750000
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------------------------------------------------------------
XXCD 	To change the local directory
XX   Format:
XX	CD	newdir		set a new directory for file transfers
XX   Example:
XX	CD	DF1:foo/bar	set the directory as specified
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 current script file.
XX   Format:
XX	EXIT			Exit the current script
XX	EXIT VT100		Exit vt100 program
XX	EXIT newscript		Exit this script and start up newscript
XX   Example:
XX	EXIT DF1:FOO.BAR	Exit the current script and start FOO.BAR
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.
XX				Only one ON string may be installed at a
XX				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------------------------------------------------------------
XXPARITY	Sets the parity
XX   Format:
XX	PARITY	type		Set the parity type
XX   Example:
XX	PARITY	NONE		no parity
XX	PARITY	MARK		mark parity
XX	PARITY	SPACE		space parity
XX	PARITY	ODD		odd parity
XX	PARITY	EVEN		even parity
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				carat (^) may be used to send control chars.
XX				Two carats transmits a carat character.
XX        SEND    chr           	Sends a single character.
XX        SEND    ^chr   	    	Sends a single control character. The chr
XX				is NOT case sensitve
XX   Example:
XX	SEND	"mail"		Send the string mail
XX	SEND    "dir^M"		Send the string dir followed by a <CR>
XX	SEND	a		Send the letter a
XX	SEND	^C		Send a control C
XX	SEND	"abc^^def"	Send the string abc^def
XX	SEND	^^		Send a control-uparrow
XX	SEND	"		Send the '"' character
XX------------------------------------------------------------
XXSB	Sends a break character to the host
XX   Format:
XX	SB			Note that any pending character to send
XX   Example:				is aborted by this call
XX	SB
XX------------------------------------------------------------
XXTM	Set a transfer mode for KERMIT to use
XX   Format:
XX	TM type			type of transfers to perform
XX   Example:
XX	TM IMAGE		image mode transfers
XX	TM CRLF			<CR><LF> text transfers (VMS Kermit).
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 examples:
XX--------------------
XX###################################################################
XX# Script to dial work (dialwork.script)
XX#	v2.4	861214	DBW
XX###################################################################
XX#
XX# Make sure that we have all the parameters we want
XX#
XX	DELAY	2
XX	BAUD	2400
XX	PARITY	NONE
XX	TM	CRLF
XX	BT	750000
XX	SB
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 ^M
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 
XX# manually here)
XX#
XXGandalf:
XX	DELAY 2
XX	SEND "ts1^M"
XX	WAIT "class start"
XX#
XX# Keep sending <CR>'s until the LAT prompts for a username:
XX#
XXWaitLat:
XX	DELAY 2
XX	ON "username>" GOTO Lat
XX	SEND ^M
XX	GOTO WaitLat
XX#
XX# Tell the LAT that it's me, and connect to the "cookie cluster"
XX# (my host systems). Tell the cluster my user name.
XX# (when it asks for a password I need to type the password
XX# manually here)
XX#
XXLat:
XX	SEND "wecker^M"
XX	DELAY 1
XX	SEND "connect cookie^M"
XX	WAIT "Username:"
XX	SEND "WECKER^M"
XX	WAIT "at home"
XX	SEND "^M^M^M"
XX#
XX# Got through all the LOGIN garbage, so let's do some work.
XX#
XX	WAIT "$ "
XX#
XX# Now go back to the LAT and connect to my workstation
XX#
XX	SEND "^]connect child^M"
XX	WAIT "login:"
XX	SEND "wecker^M"
XX	WAIT "at home"
XX	SEND "^M^M^M"
XX#
XX# Leave us on VMS
XX#
XX	SEND ^^
XX	DELAY 2
XX#
XX# Go run the next script
XX#
XX	EXIT df1:vt100_source/sendvt100.script
XX
XX#####################################################################
XX# Script to upload the terminal emulator sources (sendvt100.script)
XX#	v2.4	861214	DBW
XX#####################################################################
XX#
XX# Make sure that we have all the parameters we want
XX#
XX	DELAY	2
XX	PARITY	NONE
XX	TM	IMAGE
XX#
XX# Get into the right directory and upload to my U**X workstation
XX#
XX	CD df1:vt100_source
XX	SEND ^^
XX	SEND "cd ~/amiga/vt100^M"
XX	SEND "rm -f *^M"
XX	WAIT "% "
XX	DELAY 2
XX#
XX# Send the readme file for the terminal emulator via XMODEM:
XX#
XX	SEND "xmodem -r readme^M"
XX	DELAY 3
XX	XS readme
XX	WAIT "% "
XX#
XX# Send the other terminal emulator files via KERMIT:
XX#
XX	DELAY 1
XX	SEND "kermit -x^M"
XX	DELAY 3
XX	KS vt100.doc,makefile,vt100.h,*.c
XX	DELAY 2
XX	KB
XX	WAIT "% "
XX#
XX# We popped out of server mode, so send the compiled code
XX#
XX	DELAY 1
XX	SEND "kermit -i -x^M"
XX	DELAY 3
XX	KS vt100
XX	DELAY 2
XX	KB
XX	WAIT "% "
XX#
XX# Now build the target shar files
XX#
XX	SEND "shar -a readme vt100.doc makefile vt100.h vt100.c init.c "
XX	SEND "> vt100_24a.shar^M"
XX	SEND "shar -a script.c remote.c window.c expand.c kermit.c xmodem.c "
XX	SEND "> vt100_24b.shar^M"
XX#
XX# Time to pull copies over to VMS
XX#
XX	SEND ^^
XX	SEND "swi [wecker.amiga]^M"
XX	SEND "cop child::"
XX	SEND "
XX	SEND "/staff/wecker/amiga/vt100/vt100_24a.shar"
XX	SEND "
XX	SEND " []vt100_24a.shar^M"
XX	WAIT "$ "
XX	SEND "cop child::"
XX	SEND "
XX	SEND "/staff/wecker/amiga/vt100/vt100_24b.shar"
XX	SEND "
XX	SEND " []vt100_24b.shar^M"
XX	WAIT "$ "
XX	SEND "cop child::"
XX	SEND "
XX	SEND "/staff/wecker/amiga/vt100/vt100"
XX	SEND "
XX	SEND " []vt100_24.bin^M"
XX	WAIT "$ "
XX#
XX# Make them available to the world
XX#
XX	SEND "pub vt100_24*.*^M"
XX	WAIT "$ "
XX#
XX# All done so go to the next script
XX#
XX	EXIT df1:vt100_source/getpics.script
XX
XX###################################################################
XX# Script to download images (getpics.script)
XX#	v2.4	861214	DBW
XX###################################################################
XX#
XX# Make sure that we have all the parameters we want
XX#
XX	DELAY	2
XX	PARITY	NONE
XX	TM	CRLF
XX#
XX# Get into the right directory and download
XX#
XX	CD RAY:
XX	SEND "swi [wecker.render]^M"
XX	SEND "kermit server^M"
XX	DELAY 3
XX	KG *.img
XX	DELAY 2
XX	KB
XX	WAIT "$ "
XX#
XX# Now get out of the emulator
XX#
XX	EXIT VT100
XX
SHAR_EOF
if test 17610 -ne "`wc -c vt100.doc`"
then
echo shar: error transmitting vt100.doc '(should have been 17610 characters)'
fi
echo shar: extracting makefile
sed 's/^XX//' << \SHAR_EOF > makefile
XX######################################################################
XX#
XX# Makefile to build vt100 terminal emulator
XX#
XX#	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX#	v2.3 861101 DBW - minor bug fixes
XX#	v2.2 861012 DBW	- more of the same
XX#	v2.1 860915 DBW - new features (see README)
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# Don't forget to define the right compiler (MANX or LATTICE) in VT100.H
XX#
XX######################################################################
XX
XXOBJS	= vt100.o init.o window.o xmodem.o remote.o \
XX	  kermit.o script.o expand.o
XX
XXINCL	= vt100.h
XX#INCL	= 
XX
XXvt100	: $(OBJS)
XX	copy df0:lib/c.lib ram:
XX	ln -v -o vt100 $(OBJS) ram:c.lib
XX	delete ram:#?.lib
XX
XXvt100.o	: vt100.c $(INCL)
XX	cc +Hvt100.syms vt100.c
XX
XXinit.o	: init.c $(INCL)
XX	cc +Ivt100.syms init.c
XX
XXwindow.o : window.c $(INCL)
XX	cc +Ivt100.syms window.c
XX
XXxmodem.o : xmodem.c $(INCL)
XX	cc +Ivt100.syms xmodem.c
XX
XXremote.o : remote.c $(INCL)
XX	cc +Ivt100.syms remote.c
XX
XXkermit.o : kermit.c $(INCL)
XX	cc +Ivt100.syms kermit.c
XX
XXscript.o : script.c $(INCL)
XX	cc +Ivt100.syms script.c
XX
XXexpand.o : expand.c $(INCL)
XX	cc +Ivt100.syms expand.c
XX
XX
SHAR_EOF
if test 1295 -ne "`wc -c makefile`"
then
echo shar: error transmitting makefile '(should have been 1295 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 *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
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 diretives 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 <devices/audio.h>
XX#include <hardware/blit.h>
XX#include <stdio.h>
XX#include <ctype.h>
XX#include <libraries/dos.h>
XX#include <libraries/dosextens.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 TTIME_KERMIT 10	     /* number of seconds for KERMIT timeout*/
XX#define BufSize  0x200       /* Text buffer for XMODEM */
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 COMMAX 3     /* number of communication sub menus */
XX#define RSMAX 5      /* speed menu items */
XX#define PARMAX 5     /* parity items */
XX#define XFMAX 2      /* transfer mode items */
XX#define SCRIPTMAX 2  /* script menu items */
XX#define UTILMAX 3    /* utility menu */
XX#define MAXMENU 4    /* total number of menu entries */
XX
XX#define FSF_REVERSE 256	/* fake font style to flag INVERSVID mode */
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
XX/* things for 'beep' support */
XX#define BEEPSIZE    10L
XX#define BEEPFREQ    1000L
XX#define COLORCLOCK  3579545L
XX
XXextern struct MsgPort *CreatePort();
XXextern char *malloc(),*strcpy(),*fgets();
XXextern long ftell();
XX
XX#ifdef MODULE_MAIN
XXchar    bufr[BufSize];
XXint     fd, timeout = FALSE, ttime;
XXint	multi = FALSE, server;
XXlong    bytes_xferred;
XXchar	MyDir[60];
XXstruct IntuitionBase *IntuitionBase;
XXstruct GfxBase *GfxBase;
XX
XXstruct NewScreen NewScreen = {
XX   0L,0L,640L,200L,1L,       /* left, top, width, height, depth */
XX   0,1,HIRES,    /* DetailPen, BlockPen, ViewModes */
XX   CUSTOMSCREEN,NULL,   /* Type, Font */
XX   (UBYTE *)"VT100", /* Title */
XX   NULL,NULL };         /* Gadgets, Bitmap */
XX
XXstruct NewWindow NewWindow = {
XX   0,0L,640L,200L,     /* left, top, width, height */
XX   0,1,              /* detailpen, blockpen */
XX   MENUPICK | CLOSEWINDOW | RAWKEY | NEWSIZE,
XX   SMART_REFRESH | ACTIVATE | BORDERLESS |
XX   WINDOWCLOSE | WINDOWDEPTH | WINDOWDRAG, /* Flags */
XX   NULL,NULL,        /* FirstGadget, CheckMark */
XX   (UBYTE *)"VT100 (v2.4 861214 DBW) 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 CommItem[COMMAX];
XXstruct IntuiText CommText[COMMAX];
XXstruct MenuItem RSItem[RSMAX];
XXstruct IntuiText RSText[RSMAX];
XXstruct MenuItem ParItem[PARMAX];
XXstruct IntuiText ParText[PARMAX];
XXstruct MenuItem XFItem[XFMAX];
XXstruct IntuiText XFText[XFMAX];
XXstruct MenuItem ScriptItem[SCRIPTMAX];
XXstruct IntuiText ScriptText[SCRIPTMAX];
XXstruct MenuItem UtilItem[UTILMAX];
XXstruct IntuiText UtilText[UTILMAX];
XXstruct Menu menu[MAXMENU];
XXstruct IOExtSer *Read_Request;
XXchar *rs_in;
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;
XXstruct IOAudio Audio_Request;
XXstruct MsgPort *Audio_Port = NULL;
XXUBYTE  *BeepWave;
XXUBYTE  Audio_AllocMap[4] = { 1, 8, 2, 4 };
XXint want_message;
XXint x,y,curmode,keyapp,curapp;
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	=
XX    "                                                      ";
XXint  maxcol	= 79;
XX
XX/*************************** defaults *******************************/
XXint	p_baud	     = 2400;	    /* baud rate */
XXint	p_screen     = 1;	    /* 0 = WORKBENCH,	    1 = CUSTOM */
XXint	p_wbcolors   = 1;	    /* 0 = Custom, 1 = Workbench colors */
XXint	p_interlace  = 1;	    /* 0 = no interlace,    1 = interlace */
XXint	p_depth	     = 1;	    /* number of bit planes (1 or 2) */
XXint	p_foreground = 0x950;	    /* default foreground RGB color */
XXint	p_background = 0x000;	    /* default background RGB color */
XXint	p_bold	     = 0x900;	    /* default BOLD       RGB color */
XXint	p_cursor     = 0x009;	    /* default Cursor	  RGB color */
XXint	p_lines	     = 48;	    /* number of lines on the screen */
XXint	p_mode	     = 1;	    /* 0 = image, 1 = CRLF (for kermit) */
XXint	p_buffer     = 512;	    /* read buffer size (>= 512 bytes) */
XXint     p_parity     = 0;	    /* 0=none,1=mark,2=space,3=even,4=odd */
XXlong	p_break	     = 750000;	    /* break time (in micro seconds) */
XXint	p_volume     = 64;	    /* beep volume (0 = DisplayBeep) */
XXint	p_wrap	     = 0;	    /* 0 = truncate, 1 = wrap long lines */
XXchar	p_keyscript  = 0x7E;	    /* function key script introducer = ~ */
XXchar	*p_f[10]     = {	    /* function key defaults */
XX    "\033OP","\033OQ","\033OR","\033OS",
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;
XXvoid setserbaud(), setparams(), handle_menupick();
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;
XXextern char    MyDir[60];
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 CommItem[COMMAX];
XXextern struct IntuiText CommText[COMMAX];
XXextern struct MenuItem RSItem[RSMAX];
XXextern struct IntuiText RSText[RSMAX];
XXextern struct MenuItem ParItem[PARMAX];
XXextern struct IntuiText ParText[PARMAX];
XXextern struct MenuItem XFItem[XFMAX];
XXextern struct IntuiText XFText[XFMAX];
XXextern struct MenuItem ScriptItem[SCRIPTMAX];
XXextern struct IntuiText ScriptText[SCRIPTMAX];
XXextern struct MenuItem UtilItem[UTILMAX];
XXextern struct IntuiText UtilText[UTILMAX];
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;
XXextern struct IOExtSer *Write_Request;
XXextern char rs_out[2];
XXextern int x,y,curmode,keyapp,curapp;
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 struct IOAudio Audio_Request;
XXextern struct MsgPort *Audio_Port;
XXextern UBYTE  *BeepWave;
XXextern UBYTE  Audio_AllocMap[4];
XX
XXextern int p_baud,p_screen,p_interlace,p_depth,p_buffer,p_wbcolors;
XXextern int p_foreground,p_background,p_bold,p_cursor,p_lines,p_mode;
XXextern int p_parity,p_volume,p_wrap,p_keyscript;
XXextern long p_break;
XXextern char *p_f[10],*p_F[10];
XXextern int script_on;
XXextern int script_wait;
XX
XXextern int do_send(),do_capture(),cleanup();
XXextern void setserpar(), setserbaud(), setparams(),
XX	handle_menupick();
XX
XX#endif /* not MODULE_MAIN */
XX
XX#ifndef MODULE_INIT
XXextern void InitDevs(),InitFileItems(),InitCommItems(),
XX	 InitScriptItems(),InitUtilItems(),InitMenu();
XXextern char *InitDefaults();
XX#endif
XX
XX#ifndef MODULE_WINDOW
XXextern	void filename(),emits(),emit(),emitbatch(),cursorflip();
XXextern	int  toasc();
XX#endif
XX
XX#ifndef MODULE_XMODEM
XXextern	void sendchar(),sendstring(),sendbreak();
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(), saybye();
XXextern	void	multi_xfer();
XX#endif
XX
XX#ifndef MODULE_SCRIPT
XXextern int script_start(), chk_script(), exit_script(),
XX    do_script_cmd();
XX#endif
XX
XX#ifndef MODULE_EXPAND
XXextern char **expand();
XXextern int  set_dir(), free_expand();
XX#endif
XX
SHAR_EOF
if test 10265 -ne "`wc -c vt100.h`"
then
echo shar: error transmitting vt100.h '(should have been 10265 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 *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
XX *	     860901 ACS - Added Parity and Word Length and support code
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[80];
XXFILE *tranr = NULL;
XXFILE *trans = NULL;
XXint capture,send;
XXchar name[80];
XXstruct MsgPort *mySerPort;
XX
XXmain(argc,argv)
XXint	argc;
XXchar	**argv;
XX    {
XX    ULONG class;
XX    unsigned int code;
XX    int KeepGoing,i,la,dola,actual;
XX    char c,*ptr;
XX
XX    ptr = InitDefaults(argc,argv);
XX    InitDevs();
XX    InitFileItems();
XX    InitCommItems();
XX    InitScriptItems();
XX    InitUtilItems();
XX    InitMenu();
XX    SetMenuStrip(mywindow,&menu[0]);
XX
XX    MyDir[0]  =	    '\000';
XX    KeepGoing =	    TRUE;
XX    capture   =	    FALSE;
XX    send      =	    FALSE;
XX    maxcol    =	    MAXX / 8;
XX    la	      =	    0;
XX    x	      =	    MINX ; 
XX    y	      =	    MINY; 
XX    curmode   =	    FS_NORMAL;
XX    keyapp    =	    0;
XX    curapp    =	    0;
XX    script_on =     FALSE;
XX    script_wait=    TRUE;
XX    SetAPen(mywindow->RPort,1L);
XX    cursorflip();
XX    cursorflip();    
XX    emit(12);
XX    mySerPort = Read_Request->IOSer.io_Message.mn_ReplyPort;
XX    SendIO(Read_Request);
XX
XX    /* see if we had a startup script */
XX    if (ptr != NULL) script_start(ptr);
XX
XX    while( KeepGoing )
XX	    {
XX	    /* wait for window message or serial port message */
XX	    cursorflip();
XX	    if (script_wait)	/* if script ready dont wait here */
XX		Wait(
XX		 (1L << mySerPort->mp_SigBit) |
XX		 (1L << mywindow->UserPort->mp_SigBit) |
XX		 (1L << Script_Timer_Port->mp_SigBit));
XX	    cursorflip();
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		DoIO(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		    DoIO(Read_Request);
XX		    Read_Request->IOSer.io_Length = 1;
XX
XX		    for (i = 0; i < actual; i++) {
XX			c=rs_in[i] & 0x7f;
XX			if (script_on) chk_script(c);
XX
XX			if (dola == 1) {
XX			    if (c >= ' ' && c <= '~' && la < 80)
XX				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 (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		SendIO(Read_Request);
XX		}
XX
XX	    while((NewMessage = 
XX		    (struct IntuiMessage *)GetMsg(mywindow->UserPort))
XX			!= FALSE) {
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		    handle_menupick(class,code);
XX		    break;				    
XX		    }   /* end of switch (class) */
XX		}   /* end of while ( newmessage )*/
XX
XX            if (!script_wait || 
XX                 (CheckIO(&Script_Timer) && 
XX		    script_wait == WAIT_TIMER))
XX		do_script_cmd(NEXTCOMMAND);
XX	    }  /* end while ( keepgoing ) */
XX		
XX    /*   It must be time to quit, so we have to clean
XX    *   up and exit.
XX    */
XX
XX    cleanup("",0);
XX
XX    } /* end of main */
XX
XX/* cleanup code */
XX
XXcleanup(reason, fault)
XXchar *reason;
XXint fault;
XX    {
XX    switch(fault) {
XX	case 0:		/* quitting close everything */
XX	ClearMenuStrip( mywindow ); 
XX	CloseDevice(&Audio_Request);
XX
XX	case 8:		/* error opening audio */
XX	DeletePort(Audio_Port);
XX	FreeMem(BeepWave,BEEPSIZE);
XX	CloseDevice(&Timer);
XX
XX	case 7:		/* error opening timer */
XX	DeletePort(Timer_Port);  
XX	CloseDevice(&Script_Timer);
XX	DeletePort(Script_Timer_Port);
XX
XX	case 6:		/* error opening write device */
XX	DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
XX	FreeMem(Write_Request,(long)sizeof(*Write_Request));
XX	CloseDevice(Read_Request);
XX
XX	case 5:		/* error opening read device */
XX	DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
XX	FreeMem(Read_Request,(long)sizeof(*Read_Request));
XX	CloseWindow( mywindow );
XX
XX	case 4:		/* error opening window */
XX	if (p_screen != 0) CloseScreen( myscreen );
XX
XX	case 3:		/* error opening screen */
XX	case 2:		/* error opening graphics library */
XX	case 1:		/* error opening intuition */
XX	default:
XX	if (*reason) puts (reason);
XX	}
XX    exit(fault);
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	    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   	    send=FALSE;
XX	    emits("\nError Opening File\n");
XX	    return(FALSE);
XX	    }
XX	send=TRUE;
XX	}
XX    }
XX
XXvoid setparams()
XX    {
XX    Read_Request->IOSer.io_Command = 
XX	Write_Request->IOSer.io_Command = 
XX	    SDCMD_SETPARAMS;
XX    DoIO(Read_Request); DoIO(Write_Request);
XX    Read_Request->IOSer.io_Command = CMD_READ;
XX    SendIO(Read_Request);
XX    Write_Request->IOSer.io_Command = CMD_WRITE;
XX    }
XX
XXvoid hangup ()
XX    {
XX    AbortIO(Read_Request);
XX    CloseDevice (Read_Request);
XX    Timer.tr_time.tv_secs=0L;
XX    Timer.tr_time.tv_micro=750000L;
XX    DoIO((char *) &Timer.tr_node);
XX    OpenDevice (SERIALNAME,NULL,Read_Request,NULL);
XX    setparams();
XX    }
XX
XXvoid setserbaud(baud, redomenu)
XXint baud;
XXLONG redomenu;
XX    {
XX    AbortIO(Read_Request);
XX    Write_Request->io_Baud = Read_Request->io_Baud = baud;
XX    setparams();
XX    p_baud = baud;
XX    if (redomenu) {
XX	ClearMenuStrip( mywindow );         /* Remove old menu */
XX	InitCommItems();                    /* Re-do comm menu   */
XX	SetMenuStrip(mywindow,&menu[0]);    /* Re-display the menu */	
XX	}
XX    }
XX
XXvoid handle_menupick(class, code)
XXULONG class;
XXunsigned int code;
XX    {
XX    unsigned int menunum, itemnum, subnum;
XX
XX    if (code == MENUNULL) return;
XX
XX    menunum = MENUNUM( code );
XX    itemnum = ITEMNUM( code );
XX    subnum  = SUBNUM( code );
XX    switch( menunum ) {
XX	case 0:
XX	switch( itemnum ) {
XX	    case 0:
XX	    do_capture(NULL);
XX	    break;
XX
XX	    case 1:
XX	    do_send(NULL);
XX	    break;
XX
XX	    case 2:
XX	    if (p_parity > 0) {
XX		emits("\nParity setting prevents this\n");
XX		break;
XX		}
XX	    emits("\nXmodem Receive:");
XX	    filename(name);
XX	    multi_xfer(name,XMODEM_Read_File,0);
XX	    break;
XX
XX	    case 3:
XX	    if (p_parity > 0) {
XX		emits("\nParity setting prevents this\n");
XX		break;
XX		}
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	    emits("\nKermit GET remote file(s):");
XX	    filename(name);
XX	    multi_xfer(name,dokreceive,0);
XX            break;
XX
XX	    case 5:
XX	    multi_xfer("",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	switch( itemnum ) {
XX	    case 0:
XX	    switch( subnum ) {
XX		case 0:
XX		setserbaud(300, FALSE);
XX		break;
XX
XX		case 1:
XX		setserbaud(1200, FALSE);
XX		break;
XX
XX		case 2:
XX		setserbaud(2400, FALSE);
XX		break;
XX
XX		case 3:
XX		setserbaud(4800, FALSE);
XX		break;
XX
XX		case 4:
XX		setserbaud(9600, FALSE);
XX		break;
XX		}
XX	    break;	    
XX
XX	    case 1:
XX	    /* Set  Parity */
XX	    p_parity = subnum;
XX	    break;
XX
XX	    case 2:
XX	    /* set transfer mode */
XX	    p_mode = subnum;
XX	    break;
XX	    }
XX	break;
XX
XX	case 2:
XX	if (!itemnum && !script_on) {
XX	    emits("Script file name: ");
XX	    filename(name);
XX	    script_start(name);
XX	    }
XX	if (itemnum && script_on) exit_script();
XX	break;
XX
XX	case 3:
XX	switch( itemnum ) {
XX	    case 0:
XX	    sendbreak();
XX	    break;
XX
XX	    case 1:
XX	    hangup();
XX	    break;
XX
XX	    case 2:
XX	    emits("\nDirectory [");
XX	    emits(MyDir);
XX	    emits("]: ");
XX	    filename(name);
XX	    set_dir(name);
XX	    break;
XX	    }
XX
XX	break;
XX	} /* end of switch ( menunum ) */
XX    }
XX
SHAR_EOF
if test 10134 -ne "`wc -c vt100.c`"
then
echo shar: error transmitting vt100.c '(should have been 10134 characters)'
fi
echo shar: extracting init.c
sed 's/^XX//' << \SHAR_EOF > init.c
XX/***************************************************************
XX * vt100 - terminal emulator - initialization
XX *
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
XX *	     860901 ACS	- Added Parity and Word Length and support code
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
XXchar line[256];
XXstatic char cmds[] = "V^GRSBLHXEOIT.D";
XX
XXchar *InitDefaults(argc,argv)
XXint	argc;
XXchar	**argv;
XX    {
XX    FILE    *fd;
XX    char    scr[32],delim,macro[256],c0,*ptr,*ptr2;
XX    int	    i,j,k;
XX    long    li;
XX
XX    if (((argc > 1) && (fd=fopen(argv[1],"r")) != 0) ||
XX	(fd=fopen("vt100.init","r")) != 0 ||
XX	(fd=fopen("s: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]|' ') == 'u') {
XX		    /* buffer size */
XX		    if (sscanf(line,"%s %d",scr,&i) == 2) p_buffer = i;
XX		    if (p_buffer < 512) p_buffer = 512;
XX		    break;
XX		    }
XX		if ((line[1]|' ') == 'r') {
XX		    /* break time */
XX		    if (sscanf(line,"%s %ld",scr,&li) == 2) p_break = li;
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)
XX			switch (i) {
XX			    case  300:
XX			    case 1200:
XX			    case 2400:
XX			    case 4800:
XX			    case 9600:	p_baud = i; break;
XX			    }
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 %x",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=(i==10?3: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 'k':
XX		/*keyscript*/
XX		if (sscanf(line,"%s %x",scr,&i) == 2)
XX		    p_keyscript = i & 0x7F;
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 'p': /*parity*/
XX		if (sscanf(line,"%s %s",scr,scr) == 2)
XX		    switch(*scr|' ') {
XX			case 'n':   p_parity =  0; break;
XX			case 'm':   p_parity =	1; break;
XX			case 's':   p_parity =  2; break;
XX			case 'e':   p_parity =  3; break;
XX			case 'o':   p_parity =  4; break;
XX			}
XX		break;
XX
XX		case 'v': /*volume*/
XX		if (sscanf(line,"%s %d",scr,&i) == 2)
XX		    if (i >= 0) p_volume = i;
XX		break;
XX
XX		case 'w':
XX		/*wrap*/
XX		if ((line[1]|' ') == 'r') {
XX		    if (sscanf(line,"%s %s",scr,scr) == 2) {
XX			if ((scr[1]|' ') == 'n') p_wrap = 1;
XX			else			 p_wrap = 0;
XX			}
XX		    }
XX
XX		/* workbench or custom colors */
XX		else if ((line[1]|' ') == 'b' &&
XX			 sscanf(line,"%s %s",scr,scr) == 2) {
XX		    if ((scr[0]|' ') == 'n') p_wbcolors = 0;
XX		    else		     p_wbcolors = 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   = 0L;
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)+16);
XX	if (p_interlace == 1)
XX	    NewScreen.TopEdge   = (long)(400 - NewScreen.Height);
XX	else
XX	    NewScreen.TopEdge   = (long)(208 - NewScreen.Height);
XX	}
XX    else {
XX	p_depth			= 2L;
XX	NewWindow.TopEdge	= 0L;
XX	NewWindow.Screen	= NULL;
XX	NewWindow.Type		= WBENCHSCREEN;
XX	}
XX    /* see if we exit with a startup script */
XX    if ((c0|' ') == 'e') {
XX	ptr = &line[0];
XX	while (*ptr != '\000' && *ptr != ' ' && *ptr != '\t') ptr++;
XX	if (*ptr == '\000') return(NULL);
XX	while (*ptr != '\000' && (*ptr == ' ' || *ptr == '\t')) ptr++;
XX	if (*ptr == '\000') return(NULL);
XX	ptr2 = ptr;	
XX	while (*ptr2 != '\000' && *ptr2 != ' ' &&
XX	       *ptr2 != '\t'   && *ptr2 != '\n') ptr2++;
XX	*ptr2 = '\000';
XX	return(ptr);
XX	}
XX    else return(NULL);
XX    }
XX
XXvoid InitDevs()
XX{
XXUSHORT	colors[4];
XXint	i;
XXBYTE	*b,*c;
XX
XXIntuitionBase = (struct IntuitionBase *)
XX    OpenLibrary("intuition.library", INTUITION_REV);
XXif( IntuitionBase == NULL )
XX    cleanup("can't open intuition",1);
XX
XXGfxBase = (struct GfxBase *)
XX    OpenLibrary("graphics.library",GRAPHICS_REV);
XXif( GfxBase == NULL )
XX    cleanup("can't open graphics library",2);
XX
XXif (p_screen == 1) {
XX    if ((myscreen = (struct Screen *)OpenScreen(&NewScreen)) == NULL)
XX	cleanup("can't open screen",3);
XX    NewWindow.Screen = myscreen;
XX    }
XX
XXif(( mywindow = (struct Window *)OpenWindow(&NewWindow) ) == NULL)
XX    cleanup("can't open window",4);
XX
XXmyviewport   = (struct ViewPort *)ViewPortAddress(mywindow);
XX
XXif (p_screen != 0 && p_wbcolors == 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 = 0L;
XXRead_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L);
XXif(OpenDevice(SERIALNAME,NULL,Read_Request,NULL))
XX    cleanup("Cant open Read device",5);
XXrs_in = malloc(p_buffer+1);
XXRead_Request->io_SerFlags = 0L;
XXRead_Request->io_Baud	  = p_baud;
XXRead_Request->io_ReadLen  = 8L;
XXRead_Request->io_WriteLen = 8L;
XXRead_Request->io_CtlChar  = 0x11130000L;
XXRead_Request->io_RBufLen  = p_buffer;
XXRead_Request->io_BrkTime  = p_break;
XXRead_Request->IOSer.io_Command = SDCMD_SETPARAMS;
XXDoIO(Read_Request);
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);
XXb = (BYTE *)Read_Request;
XXc = (BYTE *)Write_Request;
XXfor (i=0;i<sizeof(struct IOExtSer);i++) *c++ = *b++;
XXWrite_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L);
XXWrite_Request->IOSer.io_Command = CMD_WRITE;
XXWrite_Request->IOSer.io_Length  = 1;
XXWrite_Request->IOSer.io_Data    = (APTR) &rs_out[0];
XX
XXTimer_Port = CreatePort("Timer Port",0L);
XXScript_Timer_Port = CreatePort("Timer Port",0L);
XX
XXif (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Timer, 0) ||
XX    OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Script_Timer, 0)) 
XX	cleanup("can't open timer device",7);
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
XXBeepWave   = (UBYTE *)AllocMem(BEEPSIZE,(long)(MEMF_CHIP|MEMF_CLEAR));
XXif (BeepWave != 0) BeepWave[0] = 100;
XX
XXAudio_Port = CreatePort("Audio Port",0L);
XX
XXAudio_Request.ioa_Request.io_Message.mn_ReplyPort   = Audio_Port;
XXAudio_Request.ioa_Request.io_Message.mn_Node.ln_Pri = 85;
XXAudio_Request.ioa_Data		    = Audio_AllocMap;
XXAudio_Request.ioa_Length	    = (ULONG) sizeof(Audio_AllocMap);
XX
XXif (OpenDevice(AUDIONAME, NULL, (char *) &Audio_Request, NULL))
XX	cleanup("can't open audio device",8);
XX
XXAudio_Request.ioa_Request.io_Command	= CMD_WRITE;
XXAudio_Request.ioa_Request.io_Flags	= ADIOF_PERVOL;
XXAudio_Request.ioa_Data		= BeepWave;
XXAudio_Request.ioa_Length	= BEEPSIZE;
XXAudio_Request.ioa_Period	= COLORCLOCK / (BEEPSIZE * BEEPFREQ);
XXAudio_Request.ioa_Volume	= p_volume;
XXAudio_Request.ioa_Cycles	= 100;
XX}
XX
XX/*****************************************************************/
XX/*    The following function initializes the structure arrays    */
XX/*   needed to provide the File menu topic.                      */
XX/*****************************************************************/
XXvoid InitFileItems()
XX    {
XX    int	    n,nplus1;
XX
XX/* initialize each menu item and IntuiText with loop */
XXfor( n=0; n<FILEMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    FileItem[n].NextItem = &FileItem[nplus1];
XX    FileItem[n].LeftEdge = 0;
XX    FileItem[n].TopEdge = 10 * n;
XX    FileItem[n].Width = 120+40;
XX    FileItem[n].Height = 10;
XX    FileItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
XX    FileItem[n].MutualExclude = 0;
XX    FileItem[n].ItemFill = (APTR)&FileText[n];
XX    FileItem[n].SelectFill = NULL;
XX    if (n >= 2 && n <= 7) {
XX	FileItem[n].Command  = cmds[n-2];
XX	FileItem[n].Flags   |= COMMSEQ;
XX	}
XX    else 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 */
XX
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/*			Main Comm menu
XX/*		set up for Baud & Parity submenus
XX/******************************************************************/
XXvoid InitCommItems()
XX    {
XX    int	    n,nplus1;
XX
XX/* initialize each menu item and IntuiText with loop */
XXfor( n=0; n<COMMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    CommItem[n].NextItem = &CommItem[nplus1];
XX    CommItem[n].LeftEdge = 0;
XX    CommItem[n].TopEdge = 10 * n;
XX    CommItem[n].Width = 88;
XX    CommItem[n].Height = 10;
XX    CommItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP ;
XX    CommItem[n].MutualExclude = 0;
XX    CommItem[n].ItemFill = (APTR)&CommText[n];
XX    CommItem[n].SelectFill = NULL;
XX    CommItem[n].Command = 0;
XX    CommItem[n].NextSelect = 0;
XX
XX    CommText[n].FrontPen = 0;
XX    CommText[n].BackPen = 1;
XX    CommText[n].DrawMode = JAM2;    
XX    CommText[n].LeftEdge = 0;
XX    CommText[n].TopEdge = 1;
XX    CommText[n].ITextFont = NULL;
XX    CommText[n].NextText = NULL;
XX    }
XXCommItem[COMMAX-1].NextItem = NULL;
XX
XXCommText[0].IText = (UBYTE *)"Baud Rate";
XXCommText[1].IText = (UBYTE *)"Parity   ";
XXCommText[2].IText = (UBYTE *)"Xfer Mode";
XXCommItem[0].SubItem = RSItem;
XXCommItem[1].SubItem = ParItem;
XXCommItem[2].SubItem = XFItem;
XX
XX/*****************************************************************/
XX/*    The following initializes the structure arrays		 */
XX/*   needed to provide the BaudRate Submenu topic.               */
XX/*****************************************************************/
XX
XXfor( n=0; n<RSMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    RSItem[n].NextItem = &RSItem[nplus1];
XX    RSItem[n].LeftEdge = 75;
XX    RSItem[n].TopEdge = 10 * n;
XX    RSItem[n].Width = 56+40;
XX    RSItem[n].Height = 10;
XX    RSItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT;
XX    RSItem[n].MutualExclude = (~(1 << n));
XX    RSItem[n].ItemFill = (APTR)&RSText[n];
XX    RSItem[n].SelectFill = NULL;
XX    if (n >= 1 && n <= 2) {
XX	RSItem[n].Command    = cmds[n+5];
XX	RSItem[n].Flags	    |= COMMSEQ;
XX	}
XX    else 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
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 |= 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/*    The following initializes the structure arrays		 */
XX/*   needed to provide the Parity   Submenu topic.               */
XX/*****************************************************************/
XX
XXfor( n=0; n<PARMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    ParItem[n].NextItem = &ParItem[nplus1];
XX    ParItem[n].LeftEdge = 75;
XX    ParItem[n].TopEdge = 10 * n;
XX    ParItem[n].Width = 56+40;
XX    ParItem[n].Height = 10;
XX    ParItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT;
XX    ParItem[n].MutualExclude = (~(1 << n));
XX    ParItem[n].ItemFill = (APTR)&ParText[n];
XX    ParItem[n].SelectFill = NULL;
XX    if (n == 0 || n == 3 || n == 4) {
XX	ParItem[n].Command   = cmds[(n==0)?8:n+6];
XX	ParItem[n].Flags    |= COMMSEQ;
XX	}
XX    else ParItem[n].Command = 0;
XX    ParItem[n].SubItem = NULL;
XX    ParItem[n].NextSelect = 0;
XX
XX    ParText[n].FrontPen = 0;
XX    ParText[n].BackPen = 1;
XX    ParText[n].DrawMode = JAM2;/* render in fore and background */
XX    ParText[n].LeftEdge = 0;
XX    ParText[n].TopEdge = 1;
XX    ParText[n].ITextFont = NULL;
XX    ParText[n].NextText = NULL;
XX    }
XXParItem[PARMAX-1].NextItem = NULL;
XX
XX/* select parity item chekced */
XXParItem[p_parity].Flags |= CHECKED;
XX
XX/* initialize text for specific menu items */
XXParText[0].IText = (UBYTE *)"  None ";
XXParText[1].IText = (UBYTE *)"  Mark ";
XXParText[2].IText = (UBYTE *)"  Space";
XXParText[3].IText = (UBYTE *)"  Even ";
XXParText[4].IText = (UBYTE *)"  Odd  ";
XX
XX/*****************************************************************/
XX/*    The following initializes the structure arrays		 */
XX/*    needed to provide the Transfer Mode menu topic.            */
XX/*****************************************************************/
XX
XX/* initialize each menu item and IntuiText with loop */
XXfor( n=0; n<XFMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    XFItem[n].NextItem = &XFItem[nplus1];
XX    XFItem[n].LeftEdge = 75;
XX    XFItem[n].TopEdge = 10 * n;
XX    XFItem[n].Width = 80+40;
XX    XFItem[n].Height = 10;
XX    XFItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT;
XX    XFItem[n].MutualExclude = (~(1 << n));
XX    XFItem[n].ItemFill = (APTR)&XFText[n];
XX    XFItem[n].SelectFill = NULL;
XX    if (n < 2) {
XX	XFItem[n].Command    = cmds[n+11];
XX	XFItem[n].Flags	    |= COMMSEQ;
XX	}
XX    else 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;
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 |= CHECKED;
XX
XX/* initialize text for specific menu items */
XXXFText[0].IText = (UBYTE *)"  Image";
XXXFText[1].IText = (UBYTE *)"  Text ";
XX
XX} /* end of InitCommItems() */
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,nplus1;
XX
XX/* initialize each menu item and IntuiText with loop */
XXfor( n=0; n<SCRIPTMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    ScriptItem[n].NextItem = &ScriptItem[nplus1];
XX    ScriptItem[n].LeftEdge = 0;
XX    ScriptItem[n].TopEdge = 10 * n;
XX    ScriptItem[n].Width = 128;
XX    ScriptItem[n].Height = 10;
XX    ScriptItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
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 structure arrays    */
XX/*   needed to provide the Util menu topic.                    */
XX/*****************************************************************/
XXvoid InitUtilItems()
XX    {
XX    int	    n,nplus1;
XX
XX/* initialize each menu item and IntuiText with loop */
XXfor( n=0; n<UTILMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    UtilItem[n].NextItem = &UtilItem[nplus1];
XX    UtilItem[n].LeftEdge = 0;
XX    UtilItem[n].TopEdge = 10 * n;
XX    UtilItem[n].Width = 88+40;
XX    UtilItem[n].Height = 10;
XX    UtilItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
XX    UtilItem[n].MutualExclude = 0;
XX    UtilItem[n].ItemFill = (APTR)&UtilText[n];
XX    UtilItem[n].SelectFill = NULL;
XX    if (n == 0 || n == 2) {
XX	UtilItem[n].Command   = cmds[(n==0)?13:14];
XX	UtilItem[n].Flags    |= COMMSEQ;
XX	}
XX    else UtilItem[n].Command = 0;
XX    UtilItem[n].SubItem = NULL;
XX    UtilItem[n].NextSelect = 0;
XX
XX    UtilText[n].FrontPen = 0;
XX    UtilText[n].BackPen = 1;
XX    UtilText[n].DrawMode = JAM2;/* render in fore and background */
XX    UtilText[n].LeftEdge = 0;
XX    UtilText[n].TopEdge = 1;
XX    UtilText[n].ITextFont = NULL;
XX    UtilText[n].NextText = NULL;
XX    }
XX
XX/*  until we know how to toggle DTR */
XX/* UtilItem[1].Flags ^= ITEMENABLED; */
XX
XXUtilItem[UTILMAX-1].NextItem = NULL;
XX
XX/* initialize text for specific menu items */
XXUtilText[0].IText = (UBYTE *)"Send Break";
XXUtilText[1].IText = (UBYTE *)"Hang Up";
XXUtilText[2].IText = (UBYTE *)"Change Dir";
XX}
XX
XX/****************************************************************/
XX/*   The following function inits the Menu structure array with */
XX/*  appropriate values for our simple menu.  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 = 40;
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 = 55;
XXmenu[1].TopEdge = 0;
XXmenu[1].Width = 88;
XXmenu[1].Height = 10;
XXmenu[1].Flags = MENUENABLED;
XXmenu[1].MenuName = "Comm Setup";   /* text for menu-bar display */
XXmenu[1].FirstItem = &CommItem[0];  /* pointer to first item in list */
XX
XXmenu[2].NextMenu = &menu[3];
XXmenu[2].LeftEdge = 153;
XXmenu[2].TopEdge = 0;
XXmenu[2].Width = 56;
XXmenu[2].Height = 10;
XXmenu[2].Flags = MENUENABLED;
XXmenu[2].MenuName = "Script";        /* text for menu-bar display */
XXmenu[2].FirstItem = &ScriptItem[0]; /* pointer to first item in list*/
XX
XXmenu[3].NextMenu = NULL;
XXmenu[3].LeftEdge = 225;
XXmenu[3].TopEdge = 0;
XXmenu[3].Width = 64;
XXmenu[3].Height = 10;
XXmenu[3].Flags = MENUENABLED;
XXmenu[3].MenuName = "Utility";      /* text for menu-bar display */
XXmenu[3].FirstItem = &UtilItem[0];  /* pointer to first item in list*/
XX}
XX
SHAR_EOF
if test 21517 -ne "`wc -c init.c`"
then
echo shar: error transmitting init.c '(should have been 21517 characters)'
fi
#	End of shell archive
exit 0

wecker@cookie.dec.com (DAVE CUM GRANO SALIS WECKER) (12/15/86)

#	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:
#	script.c
#	remote.c
#	window.c
#	expand.c
#	kermit.c
#	xmodem.c
# This archive created: Sun Dec 14 17:42:27 1986
echo shar: extracting script.c
sed 's/^XX//' << \SHAR_EOF > script.c
XX/*************************************************************
XX * vt100 terminal emulator - Script file support
XX *
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
XX *	     860901 ACS - Added BAUD, PARITY and WORD commands & handling
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
XXstruct COMMAND {
XX    void (*func)();
XX    char *cname;
XX    };
XX
XXstruct LABEL  {
XX    struct LABEL *next;
XX    char *name;
XX    long pos;
XX    };
XX
XXextern long atol();
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[20];          /* 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
XXvoid cmd_send(), cmd_wait(), cmd_on(), cmd_goto(), cmd_delay(),
XX     cmd_done(), cmd_ks(), cmd_kg(), cmd_kr(), cmd_xs(), cmd_xr(),
XX     cmd_cap(), cmd_as(), cmd_null(), cmd_kb(), cmd_cd(), cmd_sb(),
XX     cmd_baud(), cmd_word(), cmd_parity(), cmd_bt(), cmd_tm();
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_cd,     "cd",		/* change directory	    */
XX    cmd_sb,     "sb",		/* Send a break		    */
XX    cmd_baud,   "baud",		/* Set Baud Rate            */
XX    cmd_parity, "parity",	/* Set Parity		    */
XX    cmd_bt,     "bt",		/* Set Break Time	    */
XX    cmd_tm,     "tm",		/* Set KERMIT transfer mode */
XX    cmd_null,   NULL		/* mark the end of the list */
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    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 (strlen(file) == 0 || *file == '#') return(0);
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    /* downcase the command */
XX    for (i=0; i<l; i++) p[i] |= ' ';    
XX
XX    /* now search for it */
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    return(FALSE);
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
XXdo_script_cmd(stat)
XXint stat;
XX    {
XX    int len,l;
XX    char line[256];
XX    char *p;
XX
XX    /* if ON command is matched and we were     */
XX    /* doing a DELAY then abort the delay timer,*/
XX    /* except if on_cmd was just a SEND.        */
XX    if (stat == ONCOMMAND) {
XX        strcpy(line,on_cmd);
XX        p = next_wrd(line,&l);
XX	if (*p != 'S' && script_wait == WAIT_TIMER)  {
XX            AbortIO((char *) &Script_Timer);
XX            Wait (1L << Script_Timer_Port->mp_SigBit);
XX
XX	    /* script will proceed after on command    */
XX            script_wait = FALSE;
XX	    }
XX	exe_cmd(p,l);
XX        return(0);
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 *) 
XX			malloc(sizeof (struct LABEL));
XX		    }
XX		else {
XX		    labels->next = (struct LABEL *)
XX			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	    p = next_wrd(p+l+1, &l);
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 *s1,*s2;
XX
XX    s1 = ptr;
XX    if (*ptr == '"') {
XX        while(*ptr++  && *ptr != '"') ;
XX        if (*ptr == '"') {
XX            *ptr = '\0';  
XX            ptr = s2 = ++s1;
XX            while(*s2) {
XX		if	(*s2 != '^')	 *s1++ = *s2;
XX		else if (*(s2+1) == '^') *s1++ = *s2++;
XX		else			 *s1++ = ((*++s2)|' ')-96;
XX		s2++;
XX		}
XX	    *s1 = '\0';
XX            return(ptr);
XX	    }
XX	}
XX    if (*s1 == '^') {
XX        *s1 = (*(s1+1)|' ')-96;
XX        *(s1+1) = '\0';
XX        return(s1);
XX        }
XX    *(s1+1) = '\0';
XX    return(s1);
XX    }   
XX        
XX/***************************** SCRIPT COMMANDS ********************/
XX
XXvoid cmd_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
XXvoid cmd_send(str)
XXchar *str;
XX    {
XX    sendstring(tostring(str));
XX    }
XX
XXvoid cmd_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
XXvoid cmd_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
XXvoid cmd_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
XXvoid cmd_done(option)
XXchar *option;
XX    {
XX    char *p;
XX    int  l;
XX
XX    if (*option) {
XX	p = next_wrd(option,&l);
XX	*(p+l) = '\000';
XX	if  (strcmp(p,"vt100") == 0 || strcmp(p,"VT100") == 0)
XX	    cleanup("Exit vt100 from script",0);
XX	exit_script();
XX	script_start(p);
XX	}
XX    else exit_script();
XX    }
XX
XXvoid cmd_ks(file)
XXchar *file;
XX    {
XX    multi_xfer(file, doksend, 1);
XX    }
XX
XXvoid cmd_kr(file)
XXchar *file;
XX    {
XX    multi_xfer(file, dokreceive, 0);
XX    }
XX
XXvoid cmd_kg(file)
XXchar *file;
XX    {
XX    server = TRUE;
XX    multi_xfer(file, dokreceive, 0);
XX    }
XX
XXvoid cmd_kb()
XX    {
XX    saybye();
XX    }
XX
XXvoid cmd_xs(file)
XXchar *file;
XX    {
XX    multi_xfer(file, XMODEM_Send_File, 1);
XX    }
XX
XXvoid cmd_xr(file)
XXchar *file;
XX    {
XX    multi_xfer(file, XMODEM_Read_File, 1);
XX    }
XX
XXvoid cmd_cap(file)
XXchar *file;
XX    {
XX    do_capture(file);
XX    }
XX
XXvoid cmd_as(file)
XXchar *file;
XX    {
XX    do_send(file);
XX    }
XX
XXvoid cmd_cd(name)
XXchar *name;
XX    {
XX    set_dir(name);
XX    }
XX
XXvoid cmd_sb(str)
XXchar *str;
XX    {
XX    sendbreak();
XX    }
XX
XXvoid cmd_baud(rate)
XXchar *rate;
XX    {
XX    int i = atoi(rate);
XX
XX    switch( i )
XX	{
XX	case  300:
XX	case 1200:
XX	case 2400:
XX	case 4800:
XX	case 9600:
XX	setserbaud(i, TRUE);
XX	break;
XX
XX	default:
XX	emits("\nScript - invalid baud rate: ");
XX	emits(rate);
XX	emits("\n");
XX	break;
XX	}
XX    }
XX
XXvoid cmd_parity(par)
XXchar *par;
XX    {
XX    int i;
XX
XX    switch( *par|' ' )
XX	{
XX	case 'n': i =  0; break;
XX	case 'm': i =  1; break;
XX	case 's': i =  2; break;
XX	case 'e': i =  3; break;
XX	case 'o': i =  4; break;
XX
XX	default:
XX	emits("\nScript - invalid parity: ");
XX	emits(par);
XX	emits("\n");
XX	return;
XX	}
XX    p_parity = i;
XX    ClearMenuStrip( mywindow );         /* Remove old menu */
XX    InitCommItems();                    /* Re-do comm menu   */
XX    SetMenuStrip(mywindow,&menu[0]);    /* Re-display the menu */	
XX    }
XX
XXvoid cmd_bt(breaklength)
XXchar *breaklength;
XX    {
XX    long i = atol(breaklength);
XX    AbortIO(Read_Request);
XX    Read_Request->io_BrkTime = Write_Request->io_BrkTime = i;
XX    setparams();
XX    }
XX
XXvoid cmd_tm(tmode)
XXchar *tmode;
XX    {
XX    switch (*tmode|' ') {
XX	case 'i':
XX	p_mode = 0;
XX	break;
XX
XX	case 'c':
XX	p_mode = 1;
XX	break;
XX
XX	default:
XX	emits("\nScript - invalid transfer mode: ");
XX	emits(tmode);
XX	emits("\n");
XX	return;
XX	}
XX
XX    ClearMenuStrip(mywindow);
XX    InitCommItems();                    /* Re-do comm menu   */
XX    SetMenuStrip(mywindow,&menu[0]);
XX    }
XX
XXvoid cmd_null(file)
XXchar *file;
XX    {
XX    }
SHAR_EOF
if test 11781 -ne "`wc -c script.c`"
then
echo shar: error transmitting script.c '(should have been 11781 characters)'
fi
echo shar: extracting remote.c
sed 's/^XX//' << \SHAR_EOF > remote.c
XX/****************************************************
XX * vt100 emulator - remote character interpretation
XX *
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
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 == 24) { inesc = 0; inctrl = 0; return; }
XX    if (c == 27 || (inesc >= 0 && c >= ' ')) { doesc(c); return; }
XX    if (inctrl >= 0 && c >= ' ') { 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
XX    /* Collect intermediates */
XX    if (c < '0') {escseq[inesc++] = c; return; }
XX
XX    /* by process of elimination, we have a final character.
XX       Put it in the buffer, and dispatch on the first character
XX       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	curmode = FS_NORMAL; keyapp = FALSE; curapp = FALSE;
XX	inesc = -1;
XX	a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
XX	emit(12);
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      case '=':				/* set keypad application mode */
XX        keyapp = TRUE;
XX        return;
XX        
XX      case '>':				/* reset application mode */
XX        keyapp = FALSE;
XX        return;
XX        
XX      case 'Z':
XX	sendchar(27); sendstring("[?1;7c"); 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 
XX	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
XX	    /* Only allowed BEFORE parameters */
XX    	    if (inctrl == 0) private = c;
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 most private sequences right now,
XX	so just punt them */
XX
XX    if ((private != 0 && private != '?') || badseq != 0) return;
XX    if (private == '?' && escseq[0] != 'h' &&
XX	escseq[0] != 'l') 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 'L':				/* ANSI insert line */
XX      case 'M':				/* ANSI delete line */
XX	if (p[0] <= 0) p[0] = 1;
XX	ScrollRaster(mywindow->RPort,0L,
XX	    (long)((escseq[0] == 'M' ? 8L : -8L) * p[0]),
XX	    (long)MINX,(long)y-6,(long)(MAXX+7),(long)bot+1);
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  = FS_NORMAL;
XX		break;
XX
XX		case 1:
XX		curmode |= FSF_BOLD;
XX		break;
XX
XX		case 4:
XX		curmode |= FSF_UNDERLINED;
XX		break;
XX
XX		case 5:
XX		curmode |= FSF_ITALIC;
XX		break;
XX
XX		default:
XX		curmode |= FSF_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 (private == 0 && p[0] == 20)		nlmode = 1;
XX	else if (private == '?') {
XX	    if      (p[0] == 7)	p_wrap = 1;
XX	    else if (p[0] == 1)	curapp = 1;
XX	    }
XX	return;
XX
XX      case 'l':				/* Reset parameter */
XX	if (private == 0 && p[0] == 20)		nlmode = 0;
XX	else if (private == '?') {
XX	    if      (p[0] == 7)	p_wrap = 0;
XX	    else if (p[0] == 1) curapp = 0;
XX	    }
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;7c"); 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 'a':
XX	doline(0,-6,8,1);
XX	break;
XX
XX	case 'j':
XX	case 'm':
XX	case 'v':   doline(4,-6,4,-2);
XX	if      (c=='j')  doline(0,-2,4,-2);
XX	else if (c=='m')  doline(4,-2,8,-2);
XX	else              doline(0,-2,8,-2);
XX	break;
XX
XX	case 'k':
XX	case 'l':
XX	case 'w': doline(4,-2,4,1);
XX	if      (c=='k')  doline(0,-2,4,-2);
XX	else if (c=='l')  doline(4,-2,8,-2);
XX	else              doline(0,-2,8,-2);
XX	break;
XX
XX	case 'n':
XX	case 'q': doline(0,-2,8,-2);
XX	if      (c=='n')  doline(4,-6,4,2);
XX	break;
XX
XX	case 't':
XX	case 'u':
XX	case 'x':   doline(4,-6,4,1);
XX	if      (c=='t')  doline(4,-2,8,-2);
XX	else if (c=='u')  doline(0,-2,4,-2);
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 10022 -ne "`wc -c remote.c`"
then
echo shar: error transmitting remote.c '(should have been 10022 characters)'
fi
echo shar: extracting window.c
sed 's/^XX//' << \SHAR_EOF > window.c
XX/****************************************************
XX * vt100 emulator - window/keyboard support
XX *
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
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/* keyboard definitions for toasc() */
XXstatic 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/* forward declarations for LATTICE */
XXvoid filename();
XXvoid emits();
XXvoid emit();
XXvoid emitbatch();
XXvoid cursorflip();
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    static char wrap_flag = 0;	/* are we at column 80? */
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	if (p_volume == 0) DisplayBeep(NULL);
XX	else {
XX	    BeginIO(&Audio_Request);
XX	    WaitIO(&Audio_Request);
XX	    }
XX	break;
XX
XX	default:
XX	if (c < ' ' || c > '~') break;
XX	if (p_wrap && wrap_flag && x >= MAXX) {
XX	    x = MINX;
XX	    y += 8;
XX	    if (y > MAXY) {
XX		y = MAXY;
XX		ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,
XX		    (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
XX		}
XX	    }
XX	Move(mywindow->RPort,(long)x,(long)y);
XX
XX	if (curmode&FSF_BOLD) {
XX	    if (p_depth > 1) {
XX		SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
XX		SetSoftStyle(mywindow->RPort,(long)curmode,253L);
XX		}
XX	    else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
XX	    }
XX	else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
XX
XX	if (curmode&FSF_REVERSE) {
XX	    SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID));
XX	    Text(mywindow->RPort,&c,1L);
XX	    SetDrMd(mywindow->RPort,(long)JAM2);
XX	    }
XX	else Text(mywindow->RPort,&c,1L);
XX
XX	if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L);
XX	x += 8;
XX	} /* end of switch */
XX
XX    if (y > MAXY) {
XX	y = MAXY;
XX	x = MINX;
XX	ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,
XX	    (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
XX	}
XX    if (x > MAXX) {
XX	wrap_flag = 1;
XX	x = MAXX;
XX	}
XX    else wrap_flag = 0;
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
XX    Move(mywindow->RPort,(long)x,(long)y);
XX    i = x / 8;
XX    if (i+la >= maxcol) {
XX	if (p_wrap == 0) la = maxcol - i;
XX	else {
XX	    lookahead[la] = 0;
XX	    emits(lookahead);
XX	    return;
XX	    }
XX	}
XX    if (curmode&FSF_BOLD) {
XX	if (p_depth > 1) {
XX	    SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
XX	    SetSoftStyle(mywindow->RPort,(long)curmode,253L);
XX	    }
XX	else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
XX	}
XX    else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
XX
XX    if (curmode&FSF_REVERSE) {
XX	SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID));
XX	Text(mywindow->RPort,lookahead,(long)la);
XX	SetDrMd(mywindow->RPort,(long)JAM2);
XX	}
XX    else Text(mywindow->RPort,lookahead,(long)la);
XX    if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L);
XX    x += (8 * la);
XX    }
XX
XX/******************************
XX* Manipulate cursor
XX******************************/
XXvoid cursorflip()
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 = 0;
XX    static int shift = 0;
XX    static int capsl = 0;
XX/*  static int amiga = 0; */
XX    static int meta  = 0;
XX    char c = 0, keypad = 0;
XX    char *ptr;
XX
XX    switch ( code )
XX	{
XX	case 98:   capsl = 1; c = 0;break;
XX	case 226:  capsl = 0; c = 0;break;
XX	case 99:   ctrl  = 1; c = 0;break;
XX	case 227:  ctrl  = 0; c = 0;break;
XX	case 96:
XX	case 97:   if(++shift > 2) shift = 0; c = 0; break;
XX	case 224:
XX	case 225:  if (--shift < 0) shift = 0; c = 0;break;
XX	case 100:
XX	case 101:  if (++meta > 2) meta = 0; c = 0; break;
XX	case 228:
XX        case 229:  if (--meta < 0) meta = 0; c = 0; break;
XX/*
XX
XX	case 102:
XX	case 103:  if (++amiga > 2) amiga = 0; c = 0; break;
XX	case 230:
XX	case 231:  if (--amiga < 0) amiga = 0; c = 0; break;
XX*/
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)	ptr = p_F[code - 0x50];
XX		    else	ptr = p_f[code - 0x50];
XX		    if (!script_on && *ptr == p_keyscript)
XX			    script_start(++ptr);
XX		    else    sendstring(ptr);
XX		    break;
XX	case 0x0f: c = (keyapp) ? 'p' : '0'; keypad = TRUE; break;
XX	case 0x1d: c = (keyapp) ? 'q' : '1'; keypad = TRUE; break;
XX	case 0x1e: c = (keyapp) ? 'r' : '2'; keypad = TRUE; break;
XX	case 0x1f: c = (keyapp) ? 's' : '3'; keypad = TRUE; break;
XX	case 0x2d: c = (keyapp) ? 't' : '4'; keypad = TRUE; break;
XX	case 0x2e: c = (keyapp) ? 'u' : '5'; keypad = TRUE; break;
XX	case 0x2f: c = (keyapp) ? 'v' : '6'; keypad = TRUE; break;
XX	case 0x3d: c = (keyapp) ? 'w' : '7'; keypad = TRUE; break;
XX	case 0x3e: c = (keyapp) ? 'x' : '8'; keypad = TRUE; break;
XX	case 0x3f: c = (keyapp) ? 'y' : '9'; keypad = TRUE; break;
XX	case 0x43: c = (keyapp) ? 'M' : 13 ; keypad = TRUE; break;
XX	case 0x4a: c = (keyapp) ? 'l' : '-'; keypad = TRUE; break;
XX	case 0x5f: sendstring("\033Om") ;break;
XX	case 0x3c: c = (keyapp) ? 'n' : '.'; keypad = TRUE; break;
XX	case 0x4c:
XX	case 0x4d: 
XX	case 0x4e: 
XX	case 0x4f: sendchar(27);            /* cursor keys */
XX		   if (curapp) sendchar('O');
XX		   else sendchar('[');
XX		   sendchar(code - 11);
XX		   break;
XX
XX	default:
XX	if (code < 75) c = keys[code];
XX	else c = 0;
XX	}
XX
XX    if (keypad) {
XX        if (keyapp) sendstring("\033O");
XX        sendchar(c);
XX        return(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	else if (c == '6') c = 30;
XX	else if (c == '-' || c == '?') c = 31;
XX	}
XX/*
XX    if (amiga && c == '.') {
XX	if (!local) sendbreak();
XX	c = 0;
XX	}
XX    else
XX*/
XX    if (ctrl && (c == '@' || c == '2' || c == ' ')) {
XX	if (!local) sendchar(meta?128:0);
XX	c = 0;
XX	}
XX    else if (c != 0 && (!local)) sendchar(meta?c+128:c);
XX    return((int)c);
XX    }
SHAR_EOF
if test 9466 -ne "`wc -c window.c`"
then
echo shar: error transmitting window.c '(should have been 9466 characters)'
fi
echo shar: extracting expand.c
sed 's/^XX//' << \SHAR_EOF > expand.c
XX/*************************************************************
XX * vt100 terminal emulator - Wild card and Directory support
XX *
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW	- new features (see README)
XX *           860830 Steve Drew Added Wild card support,
XX *		    features(expand.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 *      Much of the code from this module extracted from
XX *      Matt Dillons Shell program. (Thanxs Matt.)
XX *************************************************************/
XX
XX#define MODULE_EXPAND 1
XX#include "vt100.h"
XX
XXstruct DPTR {                    /* Format of directory fetch ptr */
XX   struct FileLock *lock;        /* lock on directory   */
XX   struct FileInfoBlock *fib;    /* mod'd fib for entry */
XX};
XX
XX/*
XX * Disk directory routines
XX *
XX *
XX * dopen() returns a struct DPTR, or NULL if the given file does not
XX * exist.  stat will be set to 1 if the file is a directory.  If the
XX * name is "", then the current directory is openned.
XX *
XX * dnext() returns 1 until there are no more entries.  The **name and
XX * *stat are set.  *stat = 1 if the file is a directory.
XX *
XX * dclose() closes a directory channel.
XX *
XX */
XX
XXstruct DPTR *
XXdopen(name, stat)
XXchar *name;
XXint *stat;
XX{
XX   struct DPTR *dp;
XX   int namelen, endslash = 0;
XX   struct FileLock *MyLock;
XX   
XX   MyLock = (struct FileLock *)( (ULONG) ((struct Process *)
XX                                 (FindTask(NULL)))->pr_CurrentDir);
XX   namelen = strlen(name);
XX   if (namelen && name[namelen - 1] == '/') {
XX      name[namelen - 1] = '\0';
XX      endslash = 1;
XX   }
XX   *stat = 0;
XX   dp = (struct DPTR *)malloc(sizeof(struct DPTR));
XX   if (*name == '\0') 
XX      dp->lock = (struct FileLock *)DupLock (MyLock);
XX   else
XX      dp->lock = (struct FileLock *)Lock (name, ACCESS_READ);
XX   if (endslash)
XX      name[namelen - 1] = '/';
XX   if (dp->lock == NULL) {
XX      free (dp);
XX      return (NULL);
XX   }
XX   dp->fib = (struct FileInfoBlock *)
XX         AllocMem((long)sizeof(struct FileInfoBlock), MEMF_PUBLIC);
XX   if (!Examine (dp->lock, dp->fib)) {
XX      dclose (dp);
XX      return (NULL);
XX   }
XX   if (dp->fib->fib_DirEntryType >= 0)
XX      *stat = 1;
XX   return (dp);
XX}
XX
XXdnext(dp, pname, stat)
XXstruct DPTR *dp;
XXchar **pname;
XXint *stat;
XX{
XX   if (dp == NULL)
XX      return (0);
XX   if (ExNext (dp->lock, dp->fib)) {
XX      *stat = (dp->fib->fib_DirEntryType < 0) ? 0 : 1;
XX      *pname = dp->fib->fib_FileName;
XX      return (1);
XX   }
XX   return (0);
XX}
XX
XX
XXdclose(dp)
XXstruct DPTR *dp;
XX{
XX   if (dp == NULL)
XX      return (1);
XX   if (dp->fib)
XX      FreeMem (dp->fib, (long)sizeof(*dp->fib));
XX   if (dp->lock)
XX      UnLock (dp->lock);
XX   free (dp);
XX   return (1);
XX}
XX
XXfree_expand(av)
XXchar **av;
XX{
XX   char **base = av;
XX
XX   if (av) {
XX      while (*av) {
XX         free (*av);
XX         ++av;
XX      }
XX      free (base);
XX   }
XX}
XX
XX/*
XX * EXPAND(wild_name, pac)
XX *    wild_name      - char * (example: "df0:*.c")
XX *    pac            - int  *  will be set to # of arguments.
XX *
XX */
XX
XX
XXchar **
XXexpand(base, pac)
XXchar *base;
XXint *pac;
XX{
XX   char **eav = (char **)malloc (sizeof(char *));
XX   int  eleft, eac;
XX
XX   char *ptr, *name;
XX   char *bname, *ename, *tail;
XX   int stat, scr;
XX   struct DPTR *dp;
XX
XX   *pac = eleft = eac = 0;
XX   base = strcpy(malloc(strlen(base)+1), base);
XX   for (ptr = base; *ptr && *ptr != '?' && *ptr != '*'; ++ptr);
XX   for (; ptr >= base && !(*ptr == '/' || *ptr == ':'); --ptr);
XX   if (ptr < base) {
XX      bname = strcpy (malloc(1), "");
XX   } else {
XX      scr = ptr[1];
XX      ptr[1] = '\0';
XX      bname = strcpy (malloc(strlen(base)+1), base);
XX      ptr[1] = scr;
XX   }
XX   ename = ptr + 1;
XX   for (ptr = ename; *ptr && *ptr != '/'; ++ptr);
XX   scr = *ptr;
XX   *ptr = '\0';
XX   tail = (scr) ? ptr + 1 : NULL;
XX
XX   if ((dp = dopen (bname, &stat)) == NULL  ||  stat == 0) {
XX      free (bname);
XX      free (base);
XX      free (eav);
XX      emits ("Could not open directory");
XX      return (NULL);
XX   }
XX   while (dnext (dp, &name, &stat)) {
XX      if (compare_ok(ename, name)) {
XX         if (tail) {
XX            int alt_ac;
XX            char *search, **alt_av, **scrav;
XX            struct FileLock *lock;
XX
XX            if (!stat)      /* expect more dirs, but this not a dir */
XX               continue;
XX            lock = (struct FileLock *)CurrentDir (dp->lock);
XX            search = malloc(strlen(name)+strlen(tail)+2);
XX            strcpy (search, name);
XX            strcat (search, "/");
XX            strcat (search, tail);
XX            scrav = alt_av = expand (search, &alt_ac);
XX            CurrentDir (lock);
XX            if (scrav) {
XX               while (*scrav) {
XX                  if (eleft < 2) {
XX                     char **scrav = (char **)
XX			malloc(sizeof(char *) * (eac + 10));
XX                     movmem (eav, scrav, sizeof(char *) * (eac + 1));
XX                     free (eav);
XX                     eav = scrav;
XX                     eleft = 10;
XX                  }
XX                  eav[eac] = malloc(strlen(bname)+strlen(*scrav)+1);
XX                  strcpy(eav[eac], bname);
XX                  strcat(eav[eac], *scrav);
XX                  free (*scrav);
XX                  ++scrav;
XX                  --eleft, ++eac;
XX               }
XX               free (alt_av);
XX            }
XX         } else {
XX            if (eleft < 2) {
XX               char **scrav = (char **)
XX		    malloc(sizeof(char *) * (eac + 10));
XX               movmem (eav, scrav, sizeof(char *) * (eac + 1));
XX               free (eav);
XX               eav = scrav;
XX               eleft = 10;
XX            }
XX            eav[eac] = malloc (strlen(bname)+strlen(name)+1);
XX            eav[eac] = strcpy(eav[eac], bname);
XX            strcat(eav[eac], name);
XX            --eleft, ++eac;
XX         }
XX      }
XX   }
XX   dclose (dp);
XX   *pac = eac;
XX   eav[eac] = NULL;
XX   free (bname);
XX   free (base);
XX   if (eac)
XX      return (eav);
XX   free (eav);
XX   return (NULL);
XX}
XX
XX/*
XX * Compare a wild card name with a normal name
XX */
XX
XX#define MAXB   8
XX
XXcompare_ok(wild, name)
XXchar *wild, *name;
XX{
XX   char *w = wild;
XX   char *n = name;
XX   char *back[MAXB][2];
XX   int  bi = 0;
XX
XX   while (*n || *w) {
XX      switch (*w) {
XX      case '*':
XX         if (bi == MAXB) {
XX            emits ("Too many levels of '*'");
XX            return (0);
XX         }
XX         back[bi][0] = w;
XX         back[bi][1] = n;
XX         ++bi;
XX         ++w;
XX         continue;
XXgoback:
XX         --bi;
XX         while (bi >= 0 && *back[bi][1] == '\0')
XX            --bi;
XX         if (bi < 0)
XX            return (0);
XX         w = back[bi][0] + 1;
XX         n = ++back[bi][1];
XX         ++bi;
XX         continue;
XX      case '?':
XX         if (!*n) {
XX            if (bi)
XX               goto goback;
XX            return (0);
XX         }
XX         break;
XX      default:
XX         if (toupper(*n) != toupper(*w)) {
XX            if (bi)
XX               goto goback;
XX            return (0);
XX         }
XX         break;
XX      }
XX      if (*n)  ++n;
XX      if (*w)  ++w;
XX   }
XX   return (1);
XX}
XX
XXset_dir(new)
XXchar *new;
XX{
XX   register 	char 		*s;
XX   int   			i;
XX   struct 	FileLock 	*lock;
XX   char 			temp[60];
XX   struct       FileInfoBlock   fib;
XX  
XX   if (*new != '\000') {
XX      strcpy(temp, MyDir);
XX      s = new;
XX      if (*s == '/') {
XX         s++;
XX         for (i=strlen(MyDir);
XX              MyDir[i] != '/' && MyDir[i] != ':';
XX              i--);
XX         MyDir[i+1] = '\0';
XX           strcat(MyDir, s);
XX         }
XX      else if (exists(s, ':') == 0) {
XX         if (MyDir[strlen(MyDir)-1] != ':')
XX            strcat(MyDir, "/");
XX         strcat(MyDir, s);
XX         }
XX      else
XX         strcpy(MyDir, s);
XX
XX      if ((lock = (struct FileLock *)Lock(MyDir)) == 0) {
XX         emits("Directory not found\n");
XX         strcpy(MyDir, temp);
XX         }
XX      else {
XX      	 if (Examine(lock, &fib)) {
XX      	    if (fib.fib_DirEntryType > 0) {
XX               if (lock = (struct FileLock *)CurrentDir(lock))
XX                  UnLock(lock);
XX               if (MyDir[strlen(MyDir)-1] == '/')
XX                  MyDir[strlen(MyDir)-1] = '\0';
XX               }
XX            else {
XX            	emits("Not a Directory\n");               
XX            	strcpy(MyDir,temp);
XX               }
XX            }
XX         }
XX      }
XX}
XX
XXexists(s,c)
XXchar *s,c;
XX    {
XX    while (*s != '\000')
XX	if (*s++ == c) return(1);
XX    return(0);
XX    }
SHAR_EOF
if test 8361 -ne "`wc -c expand.c`"
then
echo shar: error transmitting expand.c '(should have been 8361 characters)'
fi
echo shar: extracting kermit.c
sed 's/^XX//' << \SHAR_EOF > kermit.c
XX/*************************************************************
XX * vt100 terminal emulator - KERMIT protocol support
XX *
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
XX *	     860901 ACS - Added eight bit quoting
XX *           860830 Steve Drew Wild card support, err recovry,bugs.
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 CONVERTNAME TRUE    /* file name to lower case for receive */
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 MYEBQ	 '&'	   /* 8th bit prefix character */
XX#define MYPAD      0       /* Number of padding charss 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   sendabort, /* flag for aborting send file  */
XX   rptflg,    /* are we doing repeat quoting */
XX   ebqflg,    /* are we doing 8th bit quoting */
XX   notfirst,  /* is this the first file received */
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   ebq,	      /* Quote character for 8th bit quoting */
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
XXchar *
XXgetfname(name)   /* returns ptr to start of file name from 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 amount, c, wild;
XX   char *p, **list = NULL;
XX
XX   if (!strcmp(file,"$")) { saybye(); return(2); }
XX   want_message = FALSE;        /* tell readchar no error msgs */
XX   p = file;
XX   while(*p && *p != '*' && *p != '?') p++;
XX   if (*p) { 
XX       wild = TRUE;
XX       list = expand(file, &amount);
XX       if (list == NULL)  emits("No wild card match\n");
XX       }
XX   else {
XX       wild = FALSE;
XX       amount = 1;
XX       }
XX   for (c = 0; c < amount; c++) {
XX       if (wild == TRUE) p = list[c];
XX         else  p = file;
XX       strcpy(filnam,getfname(p));
XX       ttime = TTIME_KERMIT;
XX       tp = retry = n = numtry = 0; totbytes = 0L;
XX       statusline();
XX       if ((fp = fopen(p,"r")) == NULL) {
XX           emits("ERROR");
XX           emits("\nVT100 - Kermit - Cannot open send file: ");
XX           emits(p); 
XX           curmode = FS_NORMAL;
XX           continue;
XX           }
XX       emits("SEND");
XX       ClearBuffer();
XX       if (sendsw()) { x = 600; emits("DONE"); }
XX       fclose(fp);
XX       curmode = FS_NORMAL;
XX       } 
XX   free_expand(list);
XX   return TRUE;
XX   }
XX 
XXdokreceive(file,more)
XXchar *file;
XXint more;
XX   {
XX   int retval;
XX   
XX   ttime = TTIME_KERMIT;
XX   if (!strcmp(file,"$")) { saybye(); return(2); }
XX   strcpy(filnam, file);   
XX   statusline();   
XX   if (server) emits("GET ");
XX   else emits("RECV");
XX   tp =  retry = n =  numtry = notfirst = 0; totbytes = 0L;
XX   want_message = FALSE; /* no error msgs status bar instead */
XX   ClearBuffer();
XX   retval  = recsw();
XX   curmode = FS_NORMAL;
XX   return(retval);
XX   }
XX
XXsendsw()
XX   {
XX   char sinit(), sfile(), sdata(), seof(), sbreak();
XX   sendabort = 0;
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':   if (sendabort) return FALSE;
XX                     else return TRUE;
XX         case 'E':   x = 600;         /* host sent us error packet */
XX                     emits("ERROR");  /* so print the err and abort */
XX                     print_host_err(ackpkt);
XX                     return(FALSE);
XX         case 'A':   x = 600;
XX                     if (timeout == USERABORT) {
XX			 timeout = GOODREAD;
XX                         n = (n+1)%64;			 
XX                     	 sendabort = 1;
XX                     	 emits("ABORT");
XX                     	 strcpy(msgpkt, "D");
XX                     	 state = 'Z'; 
XX                     	 break;
XX                     	 }
XX                     if (timeout == TIMEOUT)  emits("TMOUT");
XX                     else { /* protocol error dectected by us */
XX			 emits("ERROR");
XX			 print_our_err();
XX			 }
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 = MYQUOTE;
XX                 numtry = 0;
XX                 retry--;
XX                 n = (n+1)%64;
XX                 return('F');
XX      case 'E':  return('E');
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('E');
XX      case FALSE: if (timeout == USERABORT) state = 'A';
XX                  return(state);
XX      default:
XX         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('E');
XX      case FALSE: if (timeout == USERABORT) state = 'A';
XX                  return(state);
XX      default:    
XX         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) {*/	/* tell host to discard file */
XX/*      timeout = GOODREAD;	*/
XX/*        spack('Z',n,1,"D");	*/
XX/*        }			*/
XX/*   else			*/
XX	spack('Z',n,sendabort,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('E');
XX      case FALSE: return(state);
XX      default:
XX         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('E');
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*/ 
XX
XX
XXrecsw()
XX   {
XX   char rinit(), rfile(), rdata();
XX
XX   state = 'R';
XX   
XX   while(TRUE) {
XX      switch(state) {
XX         case 'R':   state = rinit(); break;
XX         case 'Z':
XX         case 'F':   state = rfile(); break;
XX         case 'D':   state = rdata(); break;
XX         case 'C':   return(TRUE);
XX         case 'E':
XX         case 'A':   x = 600;
XX		    /* 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		    if (timeout == USERABORT){
XX			/* send an error packet back   */
XX                         emits("ABORT");
XX                         spack('E',n,12,"User aborted"); 
XX                     }
XX                     else if (timeout == TIMEOUT) {
XX			    /* we timed out waiting */
XX    			    /* will we need to spack here ?*/
XX			 emits("TMOUT");
XX			 }
XX			    /* must be 'E' from host or we
XX			     detected a protocol error */
XX                         else emits("ERROR");
XX
XX		     if (state == 'E') print_host_err(msgpkt);
XX
XX		     else if (timeout == GOODREAD) /* tell host why */
XX			print_our_err();
XX			   /* will this kill all files ?*/
XX                     do  {
XX                         ttime = 2;        
XX                         readchar();
XX                         }  while (timeout == GOODREAD);
XX                     fclose(fp);
XX                     sendstring("\r");
XX                     return(FALSE);
XX	 default:    return(FALSE);	
XX         }
XX      }
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('E');
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            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            return(state);
XX            }
XX         else return('A');
XX      case 'F':
XX         if (num != n) return('A');
XX	 strcpy(filnam,msgpkt);
XX         if (CONVERTNAME) {
XX             char *p;
XX	     p = &filnam[0];
XX             while (*p) { *p = tolower(*p); p++; }
XX             }
XX	 if (notfirst) { 
XX             curmode = FS_NORMAL;
XX             totbytes = 0L;
XX	     statusline();
XX             emits("RECV");
XX             }
XX	 /* is the first file so emit actual file name from host */
XX         else {
XX  	     x = 48; emits("                ");
XX	     x = 48; emits(filnam);
XX	     notfirst++;
XX	     }
XX         if ((fp = fopen(filnam,"w")) == NULL) {
XX	     strcpy(msgpkt,"VT100 - Kermit - Unable to create file: ");
XX	     strcat(msgpkt,filnam);
XX	     spack('E',n,strlen(msgpkt),msgpkt); /* let host know */
XX             x = 600; emits("ERROR");
XX             emits("\n");
XX             emits(msgpkt);       /* let user know */
XX             return ('\0');       /* abort everything */
XX             }
XX         spack('Y',n,0,0);
XX         oldtry = numtry;
XX         numtry = 0;
XX         retry--;
XX         n = (n+1)%64;
XX         return('D');
XX
XX      /* totaly done server sending no more */
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('E');
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               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 'Z':
XX         if (num != n) return('A');
XX         spack('Y',n,0,0);
XX         n = (n+1)%64;
XX         retry--;
XX         x = 600;
XX         emits("DONE");
XX	 fclose(fp);
XX         return('Z');
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	     return(state);
XX             }
XX      case 'E':
XX         return('E');
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
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   ClearBuffer();
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
XX   if (ebqflg && b8) {			/* Do 8th bit prefix if necessary. */
XX	msgpkt[size++] = ebq;
XX	a = a7;
XX	}
XX   
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
XX   if ((ebqflg) && (a7 == ebq))	/* Prefix the 8th bit prefix */
XX       msgpkt[size++] = quote;  /* if doing 8th-bit prefixes */
XX
XX   msgpkt[size++] = a;
XX   msgpkt[size] = '\0';
XX   }
XX
XXvoid decode()
XX   {
XX   USHORT  a, a7, b8;
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      b8 = 0;
XX      if (ebqflg) {                  /* 8th-bit prefixing? */
XX	  if (a == ebq) {            /* Yes, got an 8th-bit prefix? */
XX	      b8 = 0200;             /* Yes, remember this, */
XX	      a = *buf++;            /* and get the prefixed character. */
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      a |= b8;
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_KERMIT);
XX   data[2] = tochar(MYPAD);
XX   data[3] = ctl(MYPCHAR);
XX   data[4] = tochar(MYEOL);
XX   data[5] = MYQUOTE;
XX   if ((p_parity > 0) || ebqflg) {         /* 8-bit quoting... */
XX	data[6] = MYEBQ;          /* If parity or flag on, send &. */
XX	if ((ebq > 0040 && ebq < 0100) || /* If flag off, then turn it on  */
XX	   (ebq > 0140 && ebq < 0177) || /* if other side has asked us to */
XX	   (ebq == 'Y')) ebqflg = 1;
XX	}
XX    else				    /* Normally, */
XX       data[6] = 'Y';			    /* just say we're willing. */
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    ttime   = 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    ebqflg  = 0;
XX    if (data[6] == 0) return;
XX    ebq = data[6];
XX    if ((ebq > 040 && ebq < 0100) || 
XX	(ebq > 0140 && ebq < 0177)) ebqflg = 1;
XX    else if (((p_parity > 0) || ebqflg) && (ebq == 'Y')) {
XX	ebqflg = 1;
XX	ebq = '&';
XX	}
XX    else ebqflg = 0;
XX    if (data[7] == 0) return;
XX    if (data[8] == 0) return;
XX    rptq    = data[8];
XX    rptflg  = ((rptq > 040 && rptq < 0100) || 
XX	(rptq > 0140 && rptq < 0177));
XX    }
XX
XXsaybye()
XX  {
XX  int len,num;
XX  spack('G',n,1,"F");  /* shut down server no more files */
XX  rpack(&len,&num,ackpkt);
XX  }
XX
XXprint_our_err()
XX  {
XX  if (retry > MAXTRY || oldtry > MAXTRY)
XX      strcpy(msgpkt,"VT100 - Kermit - Too many retries for packet");
XX  else
XX      strcpy(msgpkt,"VT100 - Kermit - Protocol Error");
XX  spack('E',n,strlen(msgpkt));
XX  emits("\n");
XX  emits(msgpkt);
XX  }
XX
XXprint_host_err(msg)
XX  char *msg;
XX  {
XX  curmode = FS_NORMAL;
XX  emits("\n");
XX  emits("Host Error: ");
XX  curmode = FSF_BOLD;
XX  emits(msg);
XX  }
XX
XXstatusline()
XX  {
XX  emits ("\nFile:                 Pckt:   Pckt No:      ");
XX  emits ("Retrn:    Bytes:         Stat:      ");
XX  x = 48;
XX  curmode = FSF_BOLD;  
XX  emits (filnam);
XX  x = 600;
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
XX    kermit and XMODEM */
XX
XXvoid multi_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    if (name[0] == '$' && name[1] == '\0') {
XX	saybye();
XX	return;
XX	}
XX    p = name;
XX    while(*p == ' ') p++;
XX    while(*p && *p != ',' && *p != ' ') p++;
XX    if (*p == '\0')   done = TRUE;
XX    else	      multi = 1;
XX    *p = '\0';
XX
XX    status = ((*mode)(name, multi));
XX    if (status == TRUE && want_message) {
XX        if (do_send) emits("Sent File: ");
XX          else emits("Received File: ");
XX    	emits(name);
XX    	emits("\n");
XX        }
XX    else if (status == FALSE && want_message)
XX        {
XX        close(fd);
XX        if (do_send) emits("Send Failed: ");
XX          else emits("Receive Failed: ");
XX        emits(name);
XX        emits("\n");	
XX        }    
XX    if (!done && timeout != USERABORT) multi_xfer(++p, mode, do_send);
XX    else emits("\n");
XX    server = 0;
XX    multi = 0;
XX    }
XX
XXClearBuffer()
XX   {
XX	AbortIO(Read_Request);
XX        Read_Request->IOSer.io_Command = CMD_CLEAR;
XX     	DoIO(Read_Request);
XX        Read_Request->IOSer.io_Command = CMD_READ;
XX        SendIO(Read_Request);
XX   }
XX
SHAR_EOF
if test 23798 -ne "`wc -c kermit.c`"
then
echo shar: error transmitting kermit.c '(should have been 23798 characters)'
fi
echo shar: extracting xmodem.c
sed 's/^XX//' << \SHAR_EOF > xmodem.c
XX/*************************************************************
XX * vt100 terminal emulator - XMODEM protocol support
XX *
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
XX *	     860901 ACS - Added Parity and Word Length and support code
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
XXint enablexon = TRUE;
XX
XX/* forward declarations for LATTICE */
XXvoid sendstring();
XXvoid sendchar();
XXvoid sendbreak();
XXvoid No_XON();
XXvoid Do_XON();
XX
XXstatic unsigned long parity_settings[4] = {
XX    0x96696996,
XX    0x69969669,
XX    0x69969669,
XX    0x96696996 };
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    int doxon,i,j,k;
XX
XX    doxon = enablexon;
XX    if (doxon) No_XON();
XX    switch (p_parity) {
XX	case 0:	/* no parity */
XX	rs_out[0] = ch & 0xFF;
XX	break;
XX
XX	case 1: /* mark */
XX	rs_out[0] = (ch & 0x7F) | 0x80;
XX	break;
XX
XX	case 2: /* space */
XX	rs_out[0] = ch & 0x7F;
XX	break;
XX	
XX	case 3:	/* even */
XX	case 4: /* odd  */
XX        i     = (ch >> 5) & 0x3;
XX	j     = ch & 0x1F;
XX	k     = ((parity_settings[i] >> j) & 0x1) << 7;
XX	if (p_parity == 3)			/* even parity */
XX	    rs_out[0] = (ch & 0x7F) | k;
XX	else					/* odd parity */
XX	    rs_out[0] = (ch & 0x7F) | (k ^ 0x80);
XX	}
XX    DoIO(Write_Request);
XX    if (doxon) Do_XON();
XX    }
XX
XX/* send a break to the host */
XXvoid sendbreak() {
XX    AbortIO(Read_Request);
XX    Read_Request->IOSer.io_Command = SDCMD_BREAK;
XX    DoIO(Read_Request);
XX    Read_Request->IOSer.io_Command = CMD_READ;
XX    SendIO(Read_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	    SendIO(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 & (p_parity == 0 ? 0xFF : 0x7F));
XX    }
XX
XXvoid No_XON() {
XX
XX    /* turn off XON/XOFF processing */
XX    enablexon = FALSE;
XX    Write_Request->io_SerFlags |= SERF_XDISABLED;
XX    Write_Request->IOSer.io_Command = SDCMD_SETPARAMS;
XX    DoIO(Write_Request);
XX    Write_Request->IOSer.io_Command = CMD_WRITE;
XX    }
XX
XXvoid Do_XON() {
XX    /* turn on XON/XOFF processing */
XX    enablexon = TRUE;
XX    Write_Request->io_SerFlags &= ~SERF_XDISABLED;
XX    Write_Request->IOSer.io_Command = SDCMD_SETPARAMS;
XX    DoIO(Write_Request);
XX    Write_Request->IOSer.io_Command = CMD_WRITE;
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    No_XON();
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		    Do_XON();
XX		    return FALSE;
XX		}
XX	    } while (firstchar != SOH && firstchar != EOT);
XX
XX	if  (firstchar == SOH)
XX	    {
XX	    emits(blanks);
XX	    emits("\rGetting Block ");
XX	    sprintf(numb, "%d", sectnum);
XX	    emits(numb);
XX	    emits("...");
XX	    sectcurr = readchar();
XX	    if (timeout != GOODREAD) { Do_XON(); return FALSE; }
XX	    sectcomp = readchar();
XX	    if (timeout != GOODREAD) { Do_XON(); 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) { Do_XON(); 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\r");
XX			if (bufptr == BufSize)
XX			    {
XX			    if (write(fd, bufr, BufSize-128) == EOF)
XX				{
XX				emits("\nError Writing File\n");
XX				Do_XON();
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) { Do_XON(); 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) {
XX			    Do_XON();
XX			    return FALSE;
XX			    }
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	Do_XON();
XX	return TRUE;
XX	}
XX    Do_XON();
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    No_XON();
XX    /* wait for sync char */
XX    j=1;
XX    while (((c = readchar()) != NAK) && (j++ < ERRORMAX))
XX	if (timeout == USERABORT) { Do_XON(); return(FALSE); }
XX    if (j >= (ERRORMAX))
XX	{
XX	emits("\nReceiver not sending NAKs\n");
XX	Do_XON();
XX	return FALSE;
XX	}
XX
XX    while ((bytes_to_send = read(fd, bufr, BufSize)) && 
XX	    attempts != RETRYMAX)
XX	{
XX	if (bytes_to_send == EOF)
XX	    {
XX	    emits("\nError Reading File\n");
XX	    Do_XON();
XX	    return FALSE;
XX	    }
XX
XX	bufptr = 0;
XX	while (bytes_to_send > 0 && attempts != RETRYMAX)
XX	    {
XX	    attempts = 0;
XX	    emits(blanks);
XX	    emits("\rBlock ");
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) {
XX		    emits("\n");
XX		    Do_XON();
XX		    return FALSE;
XX		    }
XX		} while ((c != ACK) && (attempts != RETRYMAX));
XX	    bufptr += size;
XX	    bytes_xferred += size;
XX	    emits(" sent\r");
XX	    sectnum++;
XX	    }
XX	}
XX    close(fd);
XX    if (attempts == RETRYMAX)
XX	{
XX	emits("\nNo Acknowledgment Of Sector, Aborting\n");
XX	Do_XON();
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    Do_XON();
XX    return TRUE;
XX    }
XX
SHAR_EOF
if test 9344 -ne "`wc -c xmodem.c`"
then
echo shar: error transmitting xmodem.c '(should have been 9344 characters)'
fi
#	End of shell archive
exit 0

wecker@cookie.dec.com.UUCP (02/19/87)

#	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 Feb 15 18:07:18 1987
echo shar: extracting readme
sed 's/^XX//' << \SHAR_EOF > readme
XXThis archive contains a vt100 emulator with KERMIT and XMODEM file
XXtransfer protocols by Dave Wecker (V2.5 DBW 870214).
XX
XXThanks:
XX-------
XX	To everyone who sent in code and suggestions!
XX
XXReleases:
XX---------
XX	v2.5 870214 DBW - more additions (see readme file)
XX	v2.4 861214 DBW - lots of fixes/additions
XX	v2.3 861101 DBW - minor bug fixes
XX	v2.2 861012 DBW - more of the same
XX 	v2.1 860915 DBW - new features (see README)
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.5 870214 DBW - more additions (see readme file)
XX	- All prompting now done through a string requester/gadget.
XX	  NOTE: YOU MUST SELECT THE INPUT STRING OF THE REQUESTER BEFORE
XX		YOU CAN TYPE A RESPONSE.
XX	- Local echo mode added (half duplex for Carolyn)
XX	- BEEP command added to SCRIPT
XX	- New menu/init/script items:
XX		CLEAR SCREEN	- clears the screen
XX	 	ECHO		- turns on/off half duplex mode
XX		WRAP		- turns on/off autowrap on long lines
XX		NUMKEY		- turns on/off numeric keypad mode
XX		APPCUR		- turns on/off application cursor mode
XX	- Rewrote toasc() to use qualifier field (no more getting the
XX	  keyboard "stuck")
XX	- Fixed locking of directories (should now run under workbench ok)
XX	- Cleaned up VT100.H to really check includes on compile
XX	- Setting font explicitly to TOPAZ 8 (no more dumb assumptions)
XX
XXv2.4 861214 DBW - lots of fixes/additions
XX	- Beep should now work under Lattice
XX	- CreatePort now passes longs (as it should always have)
XX	- Nested comments in KERMIT.C removed
XX	- Beep volume of 0 (DisplayBeep) now works
XX	- snum[] declaration in KERMIT.C fixed
XX	- multi_xfer is now void and return fixed (in kermit)
XX	- "." can no longer get "stuck" as the break key
XX
XX	- RIGHT-AMIGA-keys have been added for most menu items
XX	- The ALT key is now an EIGHTth bit shifter
XX	- Control-@, Control-2, Control-space send the NULL character
XX	- Control-6 now sends Control-^
XX	- Control-- and Control-? now sends Control-_
XX	- Cursor application mode (<esc>[?1h and <esc>[?1l) now work
XX	- XMODEM now masks the eighth bit if parity is other than NONE
XX
XXv2.3 861101 DBW - minor bug fixes:
XX	- added p_wbcolors to allow workbench colors on custom screen
XX	  (In the init file you can specify WBCOLORS to be NO (use color
XX	   definitions in INIT FILE or VT100.H) or YES (use WORKBENCH
XX	   colors for everything)).
XX	- "$" now sends a kermit-bye (like it says in VT100.DOC).
XX	- made window/screen heights more reasonable
XX	- Added ANSI insert line and delete line (<csi><num>L and
XX	  <csi><num>M) to speed up various editors (like emacs).
XX	  NOTE: This is NOT a VT100 sequence (new extension).
XX	- ctrl-space now also sends a null (along with ^@ and ^`)
XX	- RAWKEY fixed in WINDOW.C
XX	- p_wrap fixed in WINDOW.C
XX	- removed WRDMAX from VT100.H
XX	- fixed exit with no params in SCRIPT.C
XX	- fixed parity comparisons in KERMIT.C
XX	- init file [n+1] changed to [nplus1] to make Lattice happy.
XX	- cursoron(), cursoroff() changed to one routine cursorflip().
XX	- long lines shortened to less than 80 characters (for gateways).
XX	- blanks following exit (or comments) now work in scripts.
XX
XXv2.2 861012 DBW - more of the same:
XX	- The INIT file "exit" can now chain to a script
XX	- The SCRIPT command "exit" can now chain to another script
XX	- Hangup menu item now works.
XX	- Autowrap can now be set from VT100.H, VT100.INIT (<esc>[?7h l)
XX	- Control-G is now handled with an audible beep
XX	- Script now used "^chr" to send control characters
XX	- The graphics "box" character (a) was added
XX	- Control-@ and Control-` now send the NULL character
XX	- Alternate color for BOLD has been re-instated by popular demand
XX	- Menus have been cleaned up.
XX	- Lattice compilation cleaned up.
XX	- No more wordsize parameter since PARITY takes care of all cases
XX	- Function keys can now call scripts
XX	- Double shift keys are now handled correctly.
XX	- Version has been added to the title bar (for bug reports).
XX
XXv2.1 860915 DBW - new features / bug fixes
XX	- Now identifies as a VT100 (including the response to <esc>Z)
XX	- Cursor color now gets read in as hex (instead of decimal)
XX	- REPORTMOUSE taken out of definitions (not needed)
XX	- XON/XOFF now being handled by the device driver instead of me
XX	- Literal escape characters have been replaced with \033
XX	- At init time the user can now specify the input BUFFER size
XX	  (typically between 512 and 2048 bytes) depending on baud rate
XX	- Script files are now case insensitive for commands
XX	- XMODEM now turns off the driver XON/XOFF during transfers
XX	- Graphic rendition now done by the OS instead of me.
XX	- Initialization files are now searched for in S: instead of C:
XX	- Forward GOTO bug fixed in the script package.
XX	- Keypad can now be used in both numeric and application mode
XX	- General purpose cleanup() routine added for all exits.
XX	- Utility menu added (sendbreak, hangup, change directory).
XX	  NOTE: hangup is not implemented yet.
XX	- Full wild card support in file transfers (see vt100.doc).
XX	- Kermit cleaned up with better filename handling (from host).
XX	- Script now has CD (changed directory) and SB (send break) commands
XX	- Added Parity and Wordsize choices in VT100.H, VT100.INIT, menu
XX	  and scripts. (Generates parity from a table).
XX	- Added 8th bit quoting in KERMIT when using 7 bit words (ODD or
XX	  EVEN parity).
XX	- Break time can be set from VT100.H, VT100.INIT or a script file.
XX	- Transfer mode (image or CRLF) can now be set from a script file.
XX	- Control characters in escape sequences now act like a true VT100.
XX	- F10 now works from init files.
XX	- Right (or Left) AMIGA with period (".") sends a BREAK to the host
XX	  from the keyboard.
XX	- XMODEM status kept down to one line for a file transfer.
XX
XXv2.0 860823 DBW	- Major rewrite:
XX	- Emulator now compiles under either MANX or LATTICE by defining
XX	  the appropriate compiler type in VT100.H.
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	- Added XON/XOFF generation so that characters should not get lost
XX	  any more at 9600 baud (when receiving clear text).
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	  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	- 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	- 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	- WORKBENCH colors are NEVER touched.
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	- 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	- File capture now no longer sends the filename to the host.
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	- UNDERLINE (<esc>[4m) has now been added.
XX	- The handling of remote (host) escape sequences has been completly
XX	  re-written (thanks to Dawn Banks for all the work).
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	- Cursor has no been reduced to the size of a normal character for
XX	  easier readability.
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	- KERMIT has been completely re-written and appears to work fine,
XX	  thanks to the efforts of Steve Drew.
XX	- New menu item allows script file support. Module written by
XX	  Steve Drew. See VT100.DOC for details.
XX
XXKnown problems:
XX---------------
XX	none
XX
XXSuggestions/bug fixes not implemented (as of yet):
XX--------------------------------------------------
XX	- Custom screen should use a borderless backdrop window
XX	- Quit from keyboard should be supported (for above)
XX	- Automatic maximum sizing of window should happen
XX	- Screen should be resizable
XX	- AT TIME should be implemented in scripts (besides DELAY)
XX	- Amiga keys for script execution/abort
XX	- Alternate execute of script files through the S: directory
XX	- Command line arguments to allow for scripts
XX	- Kermit toggle to leave file names alone
XX	- Kermit should create sub directories (when necessary)
XX	- Use the system keymap
XX	- Use a disk font for graphic character set
XX	- Allow the mouse to be sent to the host (for various EMACSs)
XX	- Kermit VM/CMS (IBM) protocol support
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
XX	REMEMBER: Set the correct compiler definition in VT100.H
XX
XXFiles:
XX------
XX	README		- this file
XX	vt100.doc	- documentation for the terminal emulator
XX	makefile	- make file for the emulator (under MANX AZTEC-C)
XX	vt100.h		- include file used by all other modules
XX	window.c	- manager for window and keyboard
XX	vt100.c		- main module, handles menus
XX	remote.c	- handle remote characters (vt100 emulation)
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	init.c		- startup code
XX	xmodem.c	- xmodem protocol that understands AMIGA binary and
XX			  text file formats (automatically).
XX	script.c	- script control package
XX	expand.c	- filename expansion (wildcards) and dir setting
XX
XXContact:
XX--------
XXPlease send bugs/comments/suggestions/praise 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 10253 -ne "`wc -c readme`"
then
echo shar: error transmitting readme '(should have been 10253 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.5 DBW 870214). Comments/suggestions/bugs/problems/praise
XXshould be 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
XXMANY pieces of code/suggestions have been sent in..
XX
XX	thanks to all!
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 the specified
XX		  "initfile", then VT100.INIT (in the current directory)
XX		  and finally S:VT100.INIT. The format for the init file
XX		  is described 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
XX**********************************************************************
XXREMEMBER:	ALL QUESTIONS WILL BE HANDLED BY A REQUESTER. You are
XX		required to select the requester before input will be
XX		directed to it (click on the input line or the DONE
XX		gadget).
XX**********************************************************************
XX
XXMenus (Commands in parenthesis are keyboard bindings: Right-Amiga-chr):
XX-----------------------------------------------------------------------
XXFile 	  			- file transfers
XX	Ascii Capture		- Begin/end a script of the current session
XX	Ascii Send		- Type a file to the host
XX	Xmodem Receive	(A-V)	- Receive a file using XMODEM protocol
XX	Xmodem Send	(A-^)	- Send    a file using XMODEM protocol
XX	Kermit Get	(A-G)	- Receive files from a host KERMIT SERVER
XX	Kermit Receive	(A-R)	- Receive files from a host KERMIT
XX	Kermit Send	(A-S)	- Send    files to   a host KERMIT [SERVER]
XX	Kermit Bye	(A-B)	- Terminate a host KERMIT SERVER
XXComm Setup			- Setup communications
XX	Baud Rate		- Set the terminal baud rate
XX		300, 
XX		1200,	(A-L)
XX		2400,	(A-H)
XX		4800,
XX		9600
XX	Parity			- Type of parity
XX		NONE, 	(A-X)
XX		MARK,
XX		SPACE,
XX		EVEN,	(A-E)
XX		ODD	(A-O)
XX	Xfer Mode
XX		Image	(A-I)	- Send files verbatim (for UNIX hosts or
XX				  binary files)
XX		Text	(A-T)	- Send CR LF as line terminator and strip
XX				  CR on received files (VMS text).
XXScript 	  			- Script commands
XX	Execute file		- Start up an asynchronous script file
XX	Abort Execution		- Terminate a script file
XXUtility   			- Utility commands
XX	Send Break	(A-.)	- send a break to the host
XX	Hang Up			- close line (not implemented yet)
XX	Change Dir	(A-D)	- change the local directory (for transfers)
XX	Clear Scrn		- clear the screen (initial state)
XX	Echo			- turn on/off half duplex mode
XX	Wrap		(A-W)	- turn on/off long line wrapping mode
XX	Num Key		(A-K)	- turn on/off numeric keypad mode
XX	App Cur		(A-C)	- turn on/off application cursor mode
XX
XXKeypad mapping (in application keypad mode):
XX--------------------------------------------
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
XXNote:	Right AMIGA key in conjunction with a period (".")
XX	will send a break to the host.
XX
XX	CTRL in conjunction with an at-sign ("@") a two ("2") or a
XX	space (" ") will send a NULL to the host.
XX
XX	CTRL in conjunction with a six  ("6") will send a CTRL-^
XX	CTRL in conjunction with a dash ("-") or question mark ("?")
XX		will send a CTRL-_ to the host.
XX
XXInitialization file example:
XX----------------------------
XXHere is a (hopefully) self-explanatory VT100.INIT file with all
XXoptions used:
XX
XX#####################################################################
XX#
XX#	VT100 sample initialization file
XX#	v2.4 861214 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		CUSTOM		# may be CUSTOM or WORKBENCH
XXINTERLACE	ON		# ON for CUSTOM or interlaced workbench
XXDEPTH		1		# number of bit planes to use (1 or 2)
XXWBCOLORS	YES		# ignore custom colors and use defaults
XXFOREGROUND	950		# Colors are only used on the custom screen
XXBACKGROUND	000		# Colors are in hex RGB from 000 to FFF
XXBOLD		a00		# Color for bold highlighting (in custom)
XXCURSOR		00a		# Color for cursor (in custom screen)
XXLINES		48		# normal <= 24 interlaced <= 48
XXMODE		CRLF		# IMAGE or CRLF (for KERMIT transfers)
XXBUFFER		512		# 512 <= Input buffer size <= 2048
XXPARITY		NONE		# NONE (= 8 bit), MARK, SPACE, ODD or EVEN
XXBREAK		750000		# Length for break key in microseconds
XXVOLUME		64		# Beep Volume (0 = Visual Beep)
XXWRAP		OFF		# Auto wrap ON or OFF
XXECHO		OFF		# Full duplex mode in use
XXNUMKEY		ON		# The keypad should be numeric
XXAPPCUR		ON		# Application keypad mode is being used
XXKEYSCRIPT	7E		# Hex value for script introducer
XX#
XX# Function bindings (strings to type when any of F1 - 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 char:
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# If the first character of the string is a script introducer
XX# (KEYSCRIPT) then the string is interpreted as a script filename
XX# to be executed when the key is pressed.
XX#
XX# Examples of bindings:
XX#
XXf1	"^[OP"			# f1-f4 = PF1 - PF4 on a VT100
XXf2	"^[OQ"
XXf3	"^[OR"
XXf4	"^[OS"
XX#
XX# f5,6,7 = scripts to execute (assuming that KEYSCRIPT = '~' = 0x7E)
XX#
XXf5	"~df1:vt100_source/dialwork.script"
XXf6	"~df1:vt100_source/sendvt100.script"
XXf7	"~df1:vt100_source/getpics.script"
XX#
XXf8	"MAIL^M"		# Reads my mail (note embedded <CR>)
XXf9	"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#
XX# all done with init, now execute script as startup sequence
XX#
XXexit df1:vt100_source/dialwork.script
XX
XXMulti file Xfers:
XX-----------------
XXThe VT100 emulator now supports multiple file transfers. This is
XXspecified by using a comma (",") between file names when using XMODEM
XXor KERMIT. (NOTE: host XMODEM's normally CANNOT support multiple file
XXtransfers).
XX
XXWhen specifying a file name to recieve by default the directory path
XXis stripped of the filename when sent to the host but is kept for the
XXlocal file 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
XXnewfile.bin and put it on df1: (see explanation of "$" below). If you
XXdo a single file transfer you will get another prompt for the remote
XXname 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
XXthe desired directory.
XX
XXIn addition KERMIT now supports wildcards (* = any number of
XXcharacters, ? = any single character). Examples:
XX
XX	send:	*.c,*.h,*.doc
XX	get:	*.c,*.h,$
XX
XXKERMIT receive is now smart enough to use the host filename so no
XXfilename needs to be specified on the AMIGA's side.
XX
XXScript file operation:
XX----------------------
XXThe script file can be invoked by selecting 'execute file' from the
XXscript menu. 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
XXdesired if your script file is WAITing for a string or is DELAYing for
XXa period of time etc.
XX
XXScript file Commands (case insensitive):
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------------------------------------------------------------
XXAPPCUR	Set the application cursor mode
XX   Format:
XX	APPCUR	ON/OFF
XX   Example:
XX	APPCUR	ON
XX------------------------------------------------------------
XXASCII_SEND Send an ascii file to the host.
XX   Format:
XX	(same format as CAPTURE)
XX------------------------------------------------------------
XXBAUD 	Set baud rate
XX   Format:
XX	BAUD rate		Sets the baud rate for send/receive
XX   Example:
XX	BAUD 2400		Sets the baud rate at 2400 baud
XX------------------------------------------------------------
XXBEEP	Beep at the console
XX   Format:
XX	BEEP
XX   Example:
XX	BEEP
XX------------------------------------------------------------
XXBT	Set the break time (for an SB command)
XX   Format:
XX	BT value		Value is in micro-seconds
XX   Example:
XX	BT 750000
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------------------------------------------------------------
XXCD 	To change the local directory
XX   Format:
XX	CD	newdir		set a new directory for file transfers
XX   Example:
XX	CD	DF1:foo/bar	set the directory as specified
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------------------------------------------------------------
XXECHO	Turn on/off local echo
XX   Format:
XX	ECHO	ON/OFF
XX   Example:
XX	ECHO	ON		Half duplex mode
XX------------------------------------------------------------
XXEXIT	Ends execution of the current script file.
XX   Format:
XX	EXIT			Exit the current script
XX	EXIT VT100		Exit vt100 program
XX	EXIT newscript		Exit this script and start up newscript
XX   Example:
XX	EXIT DF1:FOO.BAR	Exit the current script and start FOO.BAR
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------------------------------------------------------------
XXNUMKEY	Numeric keypad mode
XX   Format:
XX	NUMKEY	ON/OFF
XX   Example:
XX	NUMKEY	ON		Keypad is pure numbers
XX------------------------------------------------------------
XXON	Peforms a command every time a string is received
XX   Format:
XX        ON      "string"  cmd	Execute cmd when string is received.
XX				Only one ON string may be installed at a
XX				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------------------------------------------------------------
XXPARITY	Sets the parity
XX   Format:
XX	PARITY	type		Set the parity type
XX   Example:
XX	PARITY	NONE		no parity
XX	PARITY	MARK		mark parity
XX	PARITY	SPACE		space parity
XX	PARITY	ODD		odd parity
XX	PARITY	EVEN		even parity
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				carat (^) may be used to send control chars.
XX				Two carats transmits a carat character.
XX        SEND    chr           	Sends a single character.
XX        SEND    ^chr   	    	Sends a single control character. The chr
XX				is NOT case sensitve
XX   Example:
XX	SEND	"mail"		Send the string mail
XX	SEND    "dir^M"		Send the string dir followed by a <CR>
XX	SEND	a		Send the letter a
XX	SEND	^C		Send a control C
XX	SEND	"abc^^def"	Send the string abc^def
XX	SEND	^^		Send a control-uparrow
XX	SEND	"		Send the '"' character
XX------------------------------------------------------------
XXSB	Sends a break character to the host
XX   Format:
XX	SB			Note that any pending character to send
XX   Example:				is aborted by this call
XX	SB
XX------------------------------------------------------------
XXTM	Set a transfer mode for KERMIT to use
XX   Format:
XX	TM type			type of transfers to perform
XX   Example:
XX	TM IMAGE		image mode transfers
XX	TM CRLF			<CR><LF> text transfers (VMS Kermit).
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------------------------------------------------------------
XXWRAP	Set long line wrapping
XX   Format:
XX	WRAP	ON/OFF
XX   Example:
XX	WRAP	ON		Long lines will wrap
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 examples:
XX--------------------
XX###################################################################
XX# Script to dial work (dialwork.script)
XX#	v2.4	861214	DBW
XX###################################################################
XX#
XX# Make sure that we have all the parameters we want
XX#
XX	DELAY	2
XX	BAUD	2400
XX	PARITY	NONE
XX	TM	CRLF
XX	BT	750000
XX	SB
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 ^M
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 
XX# manually here)
XX#
XXGandalf:
XX	DELAY 2
XX	SEND "ts1^M"
XX	WAIT "class start"
XX#
XX# Keep sending <CR>'s until the LAT prompts for a username:
XX#
XXWaitLat:
XX	DELAY 2
XX	ON "username>" GOTO Lat
XX	SEND ^M
XX	GOTO WaitLat
XX#
XX# Tell the LAT that it's me, and connect to the "cookie cluster"
XX# (my host systems). Tell the cluster my user name.
XX# (when it asks for a password I need to type the password
XX# manually here)
XX#
XXLat:
XX	SEND "wecker^M"
XX	DELAY 1
XX	SEND "connect cookie^M"
XX	WAIT "Username:"
XX	SEND "WECKER^M"
XX	WAIT "at home"
XX	SEND "^M^M^M"
XX#
XX# Got through all the LOGIN garbage, so let's do some work.
XX#
XX	WAIT "$ "
XX#
XX# Now go back to the LAT and connect to my workstation
XX#
XX	SEND "^]connect child^M"
XX	WAIT "login:"
XX	SEND "wecker^M"
XX	WAIT "at home"
XX	SEND "^M^M^M"
XX#
XX# Leave us on VMS
XX#
XX	SEND ^^
XX	DELAY 2
XX#
XX# Go run the next script
XX#
XX	EXIT df1:vt100_source/sendvt100.script
XX
XX#####################################################################
XX# Script to upload the terminal emulator sources (sendvt100.script)
XX#	v2.4	861214	DBW
XX#####################################################################
XX#
XX# Make sure that we have all the parameters we want
XX#
XX	DELAY	2
XX	PARITY	NONE
XX	TM	IMAGE
XX#
XX# Get into the right directory and upload to my U**X workstation
XX#
XX	CD df1:vt100_source
XX	SEND ^^
XX	SEND "cd ~/amiga/vt100^M"
XX	SEND "rm -f *^M"
XX	WAIT "% "
XX	DELAY 2
XX#
XX# Send the readme file for the terminal emulator via XMODEM:
XX#
XX	SEND "xmodem -r readme^M"
XX	DELAY 3
XX	XS readme
XX	WAIT "% "
XX#
XX# Send the other terminal emulator files via KERMIT:
XX#
XX	DELAY 1
XX	SEND "kermit -x^M"
XX	DELAY 3
XX	KS vt100.doc,makefile,vt100.h,*.c
XX	DELAY 2
XX	KB
XX	WAIT "% "
XX#
XX# We popped out of server mode, so send the compiled code
XX#
XX	DELAY 1
XX	SEND "kermit -i -x^M"
XX	DELAY 3
XX	KS vt100
XX	DELAY 2
XX	KB
XX	WAIT "% "
XX#
XX# Now build the target shar files
XX#
XX	SEND "shar -a readme vt100.doc makefile vt100.h vt100.c init.c "
XX	SEND "> vt100_24a.shar^M"
XX	SEND "shar -a script.c remote.c window.c expand.c kermit.c xmodem.c "
XX	SEND "> vt100_24b.shar^M"
XX#
XX# Time to pull copies over to VMS
XX#
XX	SEND ^^
XX	SEND "swi [wecker.amiga]^M"
XX	SEND "cop child::"
XX	SEND "
XX	SEND "/staff/wecker/amiga/vt100/vt100_24a.shar"
XX	SEND "
XX	SEND " []vt100_24a.shar^M"
XX	WAIT "$ "
XX	SEND "cop child::"
XX	SEND "
XX	SEND "/staff/wecker/amiga/vt100/vt100_24b.shar"
XX	SEND "
XX	SEND " []vt100_24b.shar^M"
XX	WAIT "$ "
XX	SEND "cop child::"
XX	SEND "
XX	SEND "/staff/wecker/amiga/vt100/vt100"
XX	SEND "
XX	SEND " []vt100_24.bin^M"
XX	WAIT "$ "
XX#
XX# Make them available to the world
XX#
XX	SEND "pub vt100_24*.*^M"
XX	WAIT "$ "
XX#
XX# All done so go to the next script
XX#
XX	EXIT df1:vt100_source/getpics.script
XX
XX###################################################################
XX# Script to download images (getpics.script)
XX#	v2.4	861214	DBW
XX###################################################################
XX#
XX# Make sure that we have all the parameters we want
XX#
XX	DELAY	2
XX	PARITY	NONE
XX	TM	CRLF
XX#
XX# Get into the right directory and download
XX#
XX	CD RAY:
XX	SEND "swi [wecker.render]^M"
XX	SEND "kermit server^M"
XX	DELAY 3
XX	KG *.img
XX	DELAY 2
XX	KB
XX	WAIT "$ "
XX#
XX# Now get out of the emulator
XX#
XX	EXIT VT100
XX
SHAR_EOF
if test 18734 -ne "`wc -c vt100.doc`"
then
echo shar: error transmitting vt100.doc '(should have been 18734 characters)'
fi
echo shar: extracting makefile
sed 's/^XX//' << \SHAR_EOF > makefile
XX######################################################################
XX#
XX# Makefile to build vt100 terminal emulator
XX#
XX#	v2.5 870214 DBW - more additions (see readme file)
XX#	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX#	v2.3 861101 DBW - minor bug fixes
XX#	v2.2 861012 DBW	- more of the same
XX#	v2.1 860915 DBW - new features (see README)
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# Don't forget to define the right compiler (MANX or LATTICE) in VT100.H
XX#
XX######################################################################
XX
XXOBJS	= vt100.o init.o window.o xmodem.o remote.o \
XX	  kermit.o script.o expand.o
XX
XXvt100	: vt100.syms $(OBJS)
XX	ln -v -o vt100 $(OBJS) df0:lib/c.lib
XX
XXvt100.syms : vt100.h
XX	cc -A +Hvt100.syms vt100.h
XX
XXvt100.o	: vt100.c
XX	cc +Ivt100.syms vt100.c
XX
XXinit.o	: init.c
XX	cc +Ivt100.syms init.c
XX
XXwindow.o : window.c
XX	cc +Ivt100.syms window.c
XX
XXxmodem.o : xmodem.c
XX	cc +Ivt100.syms xmodem.c
XX
XXremote.o : remote.c
XX	cc +Ivt100.syms remote.c
XX
XXkermit.o : kermit.c
XX	cc +Ivt100.syms kermit.c
XX
XXscript.o : script.c
XX	cc +Ivt100.syms script.c
XX
XXexpand.o : expand.c
XX	cc +Ivt100.syms expand.c
XX
XX
SHAR_EOF
if test 1280 -ne "`wc -c makefile`"
then
echo shar: error transmitting makefile '(should have been 1280 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 *	v2.5 870214 DBW - more additions (see readme file)
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
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 <devices/inputevent.h>
XX#include <devices/audio.h>
XX#include <hardware/blit.h>
XX
XX			/* for Lattice you may have to change these with: */
XX#include <stdio.h>	/* #include <lattice/stdio.h> and */
XX#include <ctype.h>	/* #include <lattice/ctype.h>	 */
XX
XX#include <libraries/dos.h>
XX#include <libraries/dosextens.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 TTIME_KERMIT 10	     /* number of seconds for KERMIT timeout*/
XX#define BufSize  0x200       /* Text buffer for XMODEM */
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 COMMAX 3     /* number of communication sub menus */
XX#define RSMAX 5      /* speed menu items */
XX#define PARMAX 5     /* parity items */
XX#define XFMAX 2      /* transfer mode items */
XX#define SCRIPTMAX 2  /* script menu items */
XX#define UTILMAX 8    /* utility menu */
XX#define MAXMENU 4    /* total number of menu entries */
XX
XX#define FSF_REVERSE 256	/* fake font style to flag INVERSVID mode */
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
XX/* things for 'beep' support */
XX#define BEEPSIZE    10L
XX#define BEEPFREQ    1000L
XX#define COLORCLOCK  3579545L
XX
XXextern struct	MsgPort *CreatePort();
XXextern char	*malloc(),*strcpy(),*fgets();
XXextern long	ftell();
XX
XXextern int	multi;		    /* flags multi file transfers */
XXextern int	server;
XXextern char	bufr[BufSize];
XXextern int	fd, timeout, ttime;
XXextern long	bytes_xferred;
XXextern char	MyDir[60];
XXextern struct	FileLock *MyDirLock;
XXextern struct	IntuitionBase *IntuitionBase;
XXextern struct	GfxBase *GfxBase;
XXextern struct	TextAttr myattr;
XXextern struct	TextFont *myfont;
XXextern struct	NewScreen NewScreen;
XXextern struct	NewWindow NewWindow;
XXextern struct	Screen *myscreen;
XXextern struct	Window *mywindow;
XXextern struct	ViewPort *myviewport;
XXextern struct	RastPort *myrastport;
XXextern struct	IntuiMessage *NewMessage;
XXextern struct	Preferences  *Prefs;
XXextern char	InpBuf[80],UndoBuf[80],Prompt[80];
XXextern struct	StringInfo mystrinfo;
XXextern struct	Gadget     mystrgad;
XXextern struct	IntuiText  donetxt;
XXextern struct	Gadget	   mydonegad;
XXextern struct	IntuiText  mystrtxt;
XXextern struct	Requester  myrequest;
XXextern int	numreqs;
XXextern struct	MenuItem FileItem[FILEMAX];
XXextern struct	IntuiText FileText[FILEMAX];
XXextern struct	MenuItem CommItem[COMMAX];
XXextern struct	IntuiText CommText[COMMAX];
XXextern struct	MenuItem RSItem[RSMAX];
XXextern struct	IntuiText RSText[RSMAX];
XXextern struct	MenuItem ParItem[PARMAX];
XXextern struct	IntuiText ParText[PARMAX];
XXextern struct	MenuItem XFItem[XFMAX];
XXextern struct	IntuiText XFText[XFMAX];
XXextern struct	MenuItem ScriptItem[SCRIPTMAX];
XXextern struct	IntuiText ScriptText[SCRIPTMAX];
XXextern struct	MenuItem UtilItem[UTILMAX];
XXextern struct	IntuiText UtilText[UTILMAX];
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;
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 struct	IOAudio Audio_Request;
XXextern struct	MsgPort *Audio_Port;
XXextern UBYTE	*BeepWave;
XXextern UBYTE	Audio_AllocMap[4];
XXextern int	p_baud,p_screen,p_interlace,p_depth,p_buffer,p_wbcolors;
XXextern int	p_foreground,p_background,p_bold,p_cursor,p_lines,p_mode;
XXextern int	p_parity,p_volume,p_wrap,p_echo,p_keyapp,p_curapp;
XXextern char	p_keyscript;
XXextern long	p_break;
XXextern char	*p_f[10],*p_F[10];
XXextern int	script_on;
XXextern int	script_wait;
XX
XX/* vt100.c */
XXextern int  do_send(),do_capture(),cleanup();
XXextern void setserpar(), setserbaud(), setparams(), redoutil(),
XX	    handle_menupick();
XX
XX/* init.c */
XXextern void InitDevs(),InitFileItems(),InitCommItems(),
XX	 InitScriptItems(),InitUtilItems(),InitMenu();
XXextern char *InitDefaults();
XX
XX/* window.c */
XXextern	void req(),emits(),emit(),emitbatch(),cursorflip();
XXextern	int  toasc();
XX
XX/* xmodem.c */
XXextern	void sendchar(),sendstring(),sendbreak(),multi_xfer(),
XX        No_XON(),Do_XON();
XXextern	int  readchar(),XMODEM_Read_File(),XMODEM_Send_File();
XX
XX/* remote.c */
XXextern	void doremote(),doindex(),doctrl(),doesc(),doerase();
XX
XX/* kermit.c */
XXextern	int	doksend(), dokreceive(), saybye();
XXextern	void	encode(), decode(), rpar(), spar();
XX
XX/* script.c */
XXextern int	script_start(), chk_script(), exit_script(),
XX		do_script_cmd();
XXextern char	*next_wrd(), *tostring();
XXextern void	cmd_send(), cmd_wait(), cmd_on(), cmd_goto(), cmd_delay(),
XX		cmd_done(), cmd_ks(), cmd_kg(), cmd_kr(), cmd_xs(), cmd_xr(),
XX		cmd_cap(), cmd_as(), cmd_null(), cmd_kb(), cmd_cd(),
XX		cmd_sb(), cmd_baud(), cmd_word(), cmd_parity(), cmd_bt(),
XX		cmd_tm(), cmd_beep(), cmd_echo(), cmd_wrap(),
XX		cmd_numkey(), cmd_appcur();
XX
XX
XX/* expand.c */
XXextern char **expand();
XXextern int  set_dir(), free_expand();
XX
SHAR_EOF
if test 7004 -ne "`wc -c vt100.h`"
then
echo shar: error transmitting vt100.h '(should have been 7004 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 *	v2.5 870214 DBW - more additions (see readme file)
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
XX *	     860901 ACS - Added Parity and Word Length and support code
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#include "vt100.h"
XX
XX/**************************************************************/
XX/* here are all the global definitions that appear in vt100.h */
XX/**************************************************************/
XX
XXchar    bufr[BufSize];
XXint     fd, timeout = FALSE, ttime;
XXint	multi = FALSE, server;
XXlong    bytes_xferred;
XXchar	MyDir[60];
XXstruct	FileLock *MyDirLock = NULL;
XXstruct	IntuitionBase *IntuitionBase;
XXstruct	GfxBase *GfxBase;
XX
XXstruct	TextAttr myattr = {
XX    (STRPTR) "topaz.font",
XX    8,
XX    0,
XX    0};
XXstruct	TextFont *myfont = NULL;
XXstruct NewScreen NewScreen = {
XX   0L,0L,640L,200L,1L,       /* left, top, width, height, depth */
XX   0,1,HIRES,    /* DetailPen, BlockPen, ViewModes */
XX   CUSTOMSCREEN,&myattr,   /* Type, Font */
XX   (UBYTE *)"VT100", /* Title */
XX   NULL,NULL };         /* Gadgets, Bitmap */
XXstruct NewWindow NewWindow = {
XX   0,0L,640L,200L,     /* left, top, width, height */
XX   0,1,              /* detailpen, blockpen */
XX   MENUPICK | CLOSEWINDOW | RAWKEY | NEWSIZE | REQCLEAR,
XX   SMART_REFRESH | ACTIVATE | BORDERLESS |
XX   WINDOWCLOSE | WINDOWDEPTH | WINDOWDRAG, /* Flags */
XX   NULL,NULL,        /* FirstGadget, CheckMark */
XX   (UBYTE *)"VT100 (v2.5 870214 DBW) 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   };
XXstruct Screen *myscreen = NULL;      /* ptr to applications screen */
XXstruct Window *mywindow = NULL;     /* ptr to applications window */
XXstruct ViewPort *myviewport;
XXstruct RastPort *myrastport;
XXstruct IntuiMessage *NewMessage;    /* msg structure for GetMsg() */
XXstruct Preferences  *Prefs;	    /* preferences from GetPrefs() */
XX
XX/**** String requester support ******/
XX
XXchar	InpBuf[80],UndoBuf[80],Prompt[80];
XXstruct	StringInfo mystrinfo = {
XX    (UBYTE *)InpBuf,
XX    (UBYTE *)UndoBuf,
XX    0,80,0,0,0,0,	/* initial, max, disp, undo, #chrs, dsp chrs */
XX    0,0,NULL,0L,NULL};	/* left,top,layer,longint,keymap */
XXstruct Gadget mystrgad = {
XX    NULL,10,12,320,10,	/* next,left,top,width,height */
XX    GADGHCOMP,		/* flags */
XX    ENDGADGET,STRGADGET,/* activation, type */
XX    NULL,NULL,NULL,	/* gad render, sel render, gad text */
XX    0L,			/* mutual exclude */
XX    (APTR)&mystrinfo,	/* special info */
XX    1,NULL};		/* gadget ID, user data */
XXstruct IntuiText donetxt = {
XX    1,0,JAM2,0,0,	/* front pen, back pen, mode, left, top */
XX    &myattr,		/* font */
XX    (UBYTE *)"DONE",	/* question to ask */
XX    NULL};		/* next text */
XXstruct Gadget mydonegad = {
XX    &mystrgad,290,2,40,10,/* next,left,top,width,height */
XX    GADGHCOMP,		/* flags */
XX    RELVERIFY|ENDGADGET,/* activation */
XX    BOOLGADGET,		/* gadget type */
XX    NULL,NULL,&donetxt,	/* gad render, sel render, gad text */
XX    0L,NULL,2,NULL};	/* mutual exclude, special, ID, user data */
XXstruct IntuiText mystrtxt = {
XX    0,1,JAM2,10,2,	/* front pen, back pen, mode, left, top */
XX    &myattr,		/* font */
XX    (UBYTE *)Prompt,	/* question to ask */
XX    NULL};		/* next text */
XXstruct Requester myrequest = {
XX    NULL,200,40,340,22,	/* older requester, left, top, width, height */
XX    0,0,&mydonegad,	/* relleft reltop, gadgets */
XX    NULL,		/* border */
XX    &mystrtxt,		/* text */
XX    NULL,1,NULL,	/* flags, back fill pen, layer */
XX    {0,0,0,0,0,0,0,0,
XX     0,0,0,0,0,0,0,0,
XX     0,0,0,0,0,0,0,0,
XX     0,0,0,0,0,0,0,0},	/* pad1 */
XX    NULL,NULL,		/* image bit map, rquest window */
XX    {0,0,0,0,0,0,0,0,0,
XX     0,0,0,0,0,0,0,0,0,
XX     0,0,0,0,0,0,0,0,0,
XX     0,0,0,0,0,0,0,0,0} /* pad2 */
XX    };
XXint numreqs = 0;	/* number of outstanding requestors */
XX
XX/***** menu structures *****/
XXstruct MenuItem FileItem[FILEMAX];
XXstruct IntuiText FileText[FILEMAX];
XXstruct MenuItem CommItem[COMMAX];
XXstruct IntuiText CommText[COMMAX];
XXstruct MenuItem RSItem[RSMAX];
XXstruct IntuiText RSText[RSMAX];
XXstruct MenuItem ParItem[PARMAX];
XXstruct IntuiText ParText[PARMAX];
XXstruct MenuItem XFItem[XFMAX];
XXstruct IntuiText XFText[XFMAX];
XXstruct MenuItem ScriptItem[SCRIPTMAX];
XXstruct IntuiText ScriptText[SCRIPTMAX];
XXstruct MenuItem UtilItem[UTILMAX];
XXstruct IntuiText UtilText[UTILMAX];
XXstruct Menu menu[MAXMENU];
XXstruct IOExtSer *Read_Request;
XXchar *rs_in;
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;
XXstruct IOAudio Audio_Request;
XXstruct MsgPort *Audio_Port = NULL;
XXUBYTE  *BeepWave;
XXUBYTE  Audio_AllocMap[4] = { 1, 8, 2, 4 };
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;
XXint  maxcol	= 79;
XX
XX/*************************** defaults *******************************/
XXint	p_baud	     = 2400;	    /* baud rate */
XXint	p_screen     = 1;	    /* 0 = WORKBENCH,	    1 = CUSTOM */
XXint	p_wbcolors   = 1;	    /* 0 = Custom, 1 = Workbench colors */
XXint	p_interlace  = 1;	    /* 0 = no interlace,    1 = interlace */
XXint	p_depth	     = 1;	    /* number of bit planes (1 or 2) */
XXint	p_foreground = 0x950;	    /* default foreground RGB color */
XXint	p_background = 0x000;	    /* default background RGB color */
XXint	p_bold	     = 0x900;	    /* default BOLD       RGB color */
XXint	p_cursor     = 0x009;	    /* default Cursor	  RGB color */
XXint	p_lines	     = 48;	    /* number of lines on the screen */
XXint	p_mode	     = 1;	    /* 0 = image, 1 = CRLF (for kermit) */
XXint	p_buffer     = 512;	    /* read buffer size (>= 512 bytes) */
XXint     p_parity     = 0;	    /* 0=none,1=mark,2=space,3=even,4=odd */
XXlong	p_break	     = 750000;	    /* break time (in micro seconds) */
XXint	p_volume     = 64;	    /* beep volume (0 = DisplayBeep) */
XXint	p_wrap	     = 0;	    /* 0 = truncate, 1 = wrap long lines */
XXint	p_keyapp     = 0;	    /* 0 = numeric, 1 = application keypad */
XXint	p_curapp     = 0;	    /* 0 = cursor, 1 = application cursor */
XXint	p_echo	     = 0;	    /* 0 = full duplex, 1 = half duplex */
XXchar	p_keyscript  = 0x7E;	    /* function key script introducer = ~ */
XXchar	*p_f[10]     = {	    /* function key defaults */
XX    "\033OP","\033OQ","\033OR","\033OS",
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/******************************************************/
XX/*                   Main Program                     */
XX/*                                                    */
XX/*      This is the main body of the program.         */
XX/******************************************************/
XX
XXchar lookahead[80];
XXFILE *tranr = NULL;
XXFILE *trans = NULL;
XXint capture,send;
XXchar name[80];
XXstruct MsgPort *mySerPort;
XX
XXmain(argc,argv)
XXint	argc;
XXchar	**argv;
XX    {
XX    ULONG class;
XX    unsigned int code, qual;
XX    int KeepGoing,i,la,dola,actual;
XX    char c,*ptr;
XX
XX    ptr = InitDefaults(argc,argv);
XX    InitDevs();
XX    InitFileItems();
XX    InitCommItems();
XX    InitScriptItems();
XX    InitUtilItems();
XX    InitMenu();
XX    SetMenuStrip(mywindow,&menu[0]);
XX
XX    MyDir[0]  =	    '\000';
XX    KeepGoing =	    TRUE;
XX    capture   =	    FALSE;
XX    send      =	    FALSE;
XX    maxcol    =	    MAXX / 8;
XX    la	      =	    0;
XX    x	      =	    MINX ; 
XX    y	      =	    MINY; 
XX    curmode   =	    FS_NORMAL;
XX    script_on =     FALSE;
XX    script_wait=    TRUE;
XX    SetAPen(mywindow->RPort,1L);
XX    cursorflip();
XX    cursorflip();    
XX    emit(12);
XX    mySerPort = Read_Request->IOSer.io_Message.mn_ReplyPort;
XX    SendIO(Read_Request);
XX
XX    /* see if we had a startup script */
XX    if (ptr != NULL) script_start(ptr);
XX
XX    while( KeepGoing )
XX	    {
XX	    /* wait for window message or serial port message */
XX	    cursorflip();
XX	    if (script_wait)	/* if script ready dont wait here */
XX		Wait(
XX		 (1L << mySerPort->mp_SigBit) |
XX		 (1L << mywindow->UserPort->mp_SigBit) |
XX		 (1L << Script_Timer_Port->mp_SigBit));
XX	    cursorflip();
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		    req("File Sent","",0);
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		DoIO(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		    DoIO(Read_Request);
XX		    Read_Request->IOSer.io_Length = 1;
XX
XX		    for (i = 0; i < actual; i++) {
XX			c=rs_in[i] & 0x7f;
XX			if (script_on) chk_script(c);
XX
XX			if (dola == 1) {
XX			    if (c >= ' ' && c <= '~' && la < 80)
XX				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 (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		SendIO(Read_Request);
XX		}
XX
XX	    while((NewMessage = 
XX		    (struct IntuiMessage *)GetMsg(mywindow->UserPort))
XX			!= FALSE) {
XX		class = NewMessage->Class;
XX		code = NewMessage->Code;
XX		qual = NewMessage->Qualifier;
XX		ReplyMsg( NewMessage );
XX		switch( class )
XX		    {
XX		    case REQCLEAR:
XX		    numreqs = 0;
XX		    break;
XX
XX		    case CLOSEWINDOW:
XX		    KeepGoing = FALSE;
XX		    break;
XX
XX		    case RAWKEY:
XX		    c = toasc(code,qual,0);
XX		    if (p_echo) doremote(c);
XX		    break;
XX
XX		    case NEWSIZE:
XX		    emit(12);
XX		    break;
XX
XX		    case MENUPICK:
XX		    handle_menupick(class,code);
XX		    break;				    
XX		    }   /* end of switch (class) */
XX		}   /* end of while ( newmessage )*/
XX
XX            if (!script_wait || 
XX                 (CheckIO(&Script_Timer) && 
XX		    script_wait == WAIT_TIMER))
XX		do_script_cmd(NEXTCOMMAND);
XX	    }  /* end while ( keepgoing ) */
XX		
XX    /*   It must be time to quit, so we have to clean
XX    *   up and exit.
XX    */
XX
XX    cleanup("",0);
XX
XX    } /* end of main */
XX
XX/* cleanup code */
XX
XXcleanup(reason, fault)
XXchar *reason;
XXint fault;
XX    {
XX    switch(fault) {
XX	case 0:		/* quitting close everything */
XX	ClearMenuStrip( mywindow ); 
XX	CloseDevice(&Audio_Request);
XX	if (MyDirLock != NULL) UnLock(MyDirLock);
XX
XX	case 8:		/* error opening audio */
XX	DeletePort(Audio_Port);
XX	FreeMem(BeepWave,BEEPSIZE);
XX	CloseDevice(&Timer);
XX
XX	case 7:		/* error opening timer */
XX	DeletePort(Timer_Port);  
XX	CloseDevice(&Script_Timer);
XX	DeletePort(Script_Timer_Port);
XX
XX	case 6:		/* error opening write device */
XX	DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
XX	FreeMem(Write_Request,(long)sizeof(*Write_Request));
XX	CloseDevice(Read_Request);
XX
XX	case 5:		/* error opening read device */
XX	DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
XX	FreeMem(Read_Request,(long)sizeof(*Read_Request));
XX
XX	case 4:		/* error opening window */
XX	if (myfont   != NULL) CloseFont( myfont );
XX	if (mywindow != NULL) CloseWindow( mywindow );
XX	if (p_screen != 0) CloseScreen( myscreen );
XX
XX	case 3:		/* error opening screen */
XX	case 2:		/* error opening graphics library */
XX	case 1:		/* error opening intuition */
XX	default:
XX	if (*reason) puts (reason);
XX	}
XX    exit(fault);
XX    } 
XX
XXdo_capture(file)
XXchar *file;
XX    {
XX    if (capture == TRUE)
XX        {
XX        capture=FALSE;
XX        fclose(tranr);
XX        req("End File Capture","",0);
XX        }
XX    else
XX        {
XX        if (file == NULL) {
XX	    name[0] = '\000';
XX            req("Ascii Capture:",name,1);
XX	    } 
XX	else strcpy(name, file);
XX        if ((tranr=fopen(name,"w")) == 0) {
XX	    capture=FALSE;
XX	    req("Error Opening File","",0);
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        req("File Send Cancelled","",0);
XX        }
XX    else
XX        {
XX        if (file == NULL) {
XX	    name[0] = '\000';
XX            req("Ascii Send:",name,1);
XX            }
XX	else strcpy(name, file);
XX        if ((trans=fopen(name,"r")) == 0) {
XX   	    send=FALSE;
XX	    req("Error Opening File","",0);
XX	    return(FALSE);
XX	    }
XX	send=TRUE;
XX	}
XX    }
XX
XXvoid setparams()
XX    {
XX    Read_Request->IOSer.io_Command = 
XX	Write_Request->IOSer.io_Command = 
XX	    SDCMD_SETPARAMS;
XX    DoIO(Read_Request); DoIO(Write_Request);
XX    Read_Request->IOSer.io_Command = CMD_READ;
XX    SendIO(Read_Request);
XX    Write_Request->IOSer.io_Command = CMD_WRITE;
XX    }
XX
XXvoid hangup ()
XX    {
XX    AbortIO(Read_Request);
XX    CloseDevice (Read_Request);
XX    Timer.tr_time.tv_secs=0L;
XX    Timer.tr_time.tv_micro=750000L;
XX    DoIO((char *) &Timer.tr_node);
XX    OpenDevice (SERIALNAME,NULL,Read_Request,NULL);
XX    setparams();
XX    }
XX
XXvoid setserbaud(baud, redomenu)
XXint baud;
XXLONG redomenu;
XX    {
XX    AbortIO(Read_Request);
XX    Write_Request->io_Baud = Read_Request->io_Baud = baud;
XX    setparams();
XX    p_baud = baud;
XX    if (redomenu) {
XX	ClearMenuStrip( mywindow );         /* Remove old menu */
XX	InitCommItems();                    /* Re-do comm menu   */
XX	SetMenuStrip(mywindow,&menu[0]);    /* Re-display the menu */	
XX	}
XX    }
XX
XXvoid redoutil() {
XX    ClearMenuStrip(mywindow);
XX    InitUtilItems();
XX    SetMenuStrip(mywindow,&menu[0]);
XX    }
XX
XXvoid handle_menupick(class, code)
XXULONG class;
XXunsigned int code;
XX    {
XX    unsigned int menunum, itemnum, subnum;
XX
XX    if (code == MENUNULL) return;
XX
XX    menunum = MENUNUM( code );
XX    itemnum = ITEMNUM( code );
XX    subnum  = SUBNUM( code );
XX    switch( menunum ) {
XX	case 0:
XX	switch( itemnum ) {
XX	    case 0:
XX	    do_capture(NULL);
XX	    break;
XX
XX	    case 1:
XX	    do_send(NULL);
XX	    break;
XX
XX	    case 2:
XX	    if (p_parity > 0) {
XX		req("Parity setting prevents this","",0);
XX		break;
XX		}
XX	    name[0] = '\000';
XX	    req("Xmodem Receive:",name,1);
XX	    multi_xfer(name,XMODEM_Read_File,0);
XX	    break;
XX
XX	    case 3:
XX	    if (p_parity > 0) {
XX		req("Parity setting prevents this","",0);
XX		break;
XX		}
XX	    name[0] = '\000';
XX	    req("Xmodem Send:",name,1);
XX	    multi_xfer(name,XMODEM_Send_File,1);
XX	    break;
XX
XX	    case 4:
XX	    server = TRUE;
XX	    name[0] = '\000';
XX	    req("Kermit GET remote file(s):",name,1);
XX	    multi_xfer(name,dokreceive,0);
XX            break;
XX
XX	    case 5:
XX	    multi_xfer("",dokreceive,0);
XX	    break;
XX
XX	    case 6:
XX	    server = TRUE;
XX	    name[0] = '\000';
XX	    req("Kermit Send local name:",name,1);
XX	    multi_xfer(name,doksend,1);
XX	    break;
XX
XX	    case 7:
XX	    saybye();
XX	    break;
XX	    }
XX	break;
XX
XX	case 1:
XX	switch( itemnum ) {
XX	    case 0:
XX	    switch( subnum ) {
XX		case 0:
XX		setserbaud(300, FALSE);
XX		break;
XX
XX		case 1:
XX		setserbaud(1200, FALSE);
XX		break;
XX
XX		case 2:
XX		setserbaud(2400, FALSE);
XX		break;
XX
XX		case 3:
XX		setserbaud(4800, FALSE);
XX		break;
XX
XX		case 4:
XX		setserbaud(9600, FALSE);
XX		break;
XX		}
XX	    break;	    
XX
XX	    case 1:
XX	    /* Set  Parity */
XX	    p_parity = subnum;
XX	    break;
XX
XX	    case 2:
XX	    /* set transfer mode */
XX	    p_mode = subnum;
XX	    break;
XX	    }
XX	break;
XX
XX	case 2:
XX	if (!itemnum && !script_on) {
XX	    name[0] = '\000';
XX	    req("Script file name:",name,1);
XX	    script_start(name);
XX	    }
XX	if (itemnum && script_on) exit_script();
XX	break;
XX
XX	case 3:
XX	switch( itemnum ) {
XX	    case 0:
XX	    sendbreak();
XX	    break;
XX
XX	    case 1:
XX	    hangup();
XX	    break;
XX
XX	    case 2:
XX	    strcpy(name,MyDir);
XX	    req("Directory:",name,1);
XX	    set_dir(name);
XX	    break;
XX
XX	    case 3:
XX	    top = MINY; bot = MAXY; savx = MINX; savy = MINY;
XX	    curmode = FS_NORMAL; inesc = -1;
XX	    a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
XX	    redoutil();
XX	    emit(12);
XX	    break;
XX
XX	    case 4:
XX	    if (p_echo) p_echo = 0;
XX	    else	p_echo = 1;
XX	    redoutil();
XX	    break;
XX
XX	    case 5:
XX	    if (p_wrap) p_wrap = 0;
XX	    else        p_wrap = 1;
XX	    redoutil();
XX	    break;
XX
XX	    case 6:
XX	    if (p_keyapp) p_keyapp = 0;
XX	    else          p_keyapp = 1;
XX	    redoutil();
XX	    break;
XX
XX	    case 7:
XX	    if (p_curapp) p_curapp = 0;
XX	    else          p_curapp = 1;
XX	    redoutil();
XX	    break;	    
XX	    }
XX
XX	break;
XX	} /* end of switch ( menunum ) */
XX    }
XX
SHAR_EOF
if test 17559 -ne "`wc -c vt100.c`"
then
echo shar: error transmitting vt100.c '(should have been 17559 characters)'
fi
echo shar: extracting init.c
sed 's/^XX//' << \SHAR_EOF > init.c
XX/***************************************************************
XX * vt100 - terminal emulator - initialization
XX *
XX *	v2.5 870214 DBW - more additions (see readme file)
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
XX *	     860901 ACS	- Added Parity and Word Length and support code
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#include "vt100.h"
XX
XXchar line[256];
XXstatic char cmds[] = "V^GRSBLHXEOIT.DWKC";
XX
XXchar *InitDefaults(argc,argv)
XXint	argc;
XXchar	**argv;
XX    {
XX    FILE    *fd;
XX    char    scr[32],delim,macro[256],c0,*ptr,*ptr2;
XX    int	    i,j,k;
XX    long    li;
XX
XX    if (((argc > 1) && (fd=fopen(argv[1],"r")) != 0) ||
XX	(fd=fopen("vt100.init","r")) != 0 ||
XX	(fd=fopen("s:vt100.init","r")) != 0) {
XX	while (fgets(line,256,fd) != 0) {
XX	    if ((c0 = line[0]) == '#') continue;
XX	    if ((c0|' ') == 'e' && (line[1]|' ') == 'x') break;
XX	    switch (c0|' ') {
XX
XX		case 'a':
XX		/*application cursor*/
XX		if (sscanf(line,"%s %s",scr,scr) == 2) {
XX		    if ((scr[1]|' ') == 'n') p_curapp = 1;
XX		    else		     p_curapp = 0;
XX		    }
XX		break;
XX
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]|' ') == 'u') {
XX		    /* buffer size */
XX		    if (sscanf(line,"%s %d",scr,&i) == 2) p_buffer = i;
XX		    if (p_buffer < 512) p_buffer = 512;
XX		    break;
XX		    }
XX		if ((line[1]|' ') == 'r') {
XX		    /* break time */
XX		    if (sscanf(line,"%s %ld",scr,&li) == 2) p_break = li;
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)
XX			switch (i) {
XX			    case  300:
XX			    case 1200:
XX			    case 2400:
XX			    case 4800:
XX			    case 9600:	p_baud = i; break;
XX			    }
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		/* cursor color */
XX		case 'c':
XX		if (sscanf(line,"%s %x",scr,&i) == 2) p_cursor = 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		/* echo mode (half duplex) */
XX		case 'e':
XX		if (sscanf(line,"%s %s",scr,scr) == 2) {
XX		    if ((scr[1]|' ') == 'n') p_echo = 1;
XX		    else		     p_echo = 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=(i==10?3: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		/* 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 'k':
XX		/*keyscript*/
XX		if (sscanf(line,"%s %x",scr,&i) == 2)
XX		    p_keyscript = i & 0x7F;
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		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 'n':
XX		/*numeric keypad*/
XX		if (sscanf(line,"%s %s",scr,scr) == 2) {
XX		    if ((scr[1]|' ') == 'n') p_keyapp = 0;
XX		    else		     p_keyapp = 1;
XX		    }
XX		break;
XX
XX		case 'p': /*parity*/
XX		if (sscanf(line,"%s %s",scr,scr) == 2)
XX		    switch(*scr|' ') {
XX			case 'n':   p_parity =  0; break;
XX			case 'm':   p_parity =	1; break;
XX			case 's':   p_parity =  2; break;
XX			case 'e':   p_parity =  3; break;
XX			case 'o':   p_parity =  4; 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		case 'v': /*volume*/
XX		if (sscanf(line,"%s %d",scr,&i) == 2)
XX		    if (i >= 0) p_volume = i;
XX		break;
XX
XX		case 'w':
XX		/*wrap*/
XX		if ((line[1]|' ') == 'r') {
XX		    if (sscanf(line,"%s %s",scr,scr) == 2) {
XX			if ((scr[1]|' ') == 'n') p_wrap = 1;
XX			else			 p_wrap = 0;
XX			}
XX		    }
XX
XX		/* workbench or custom colors */
XX		else if ((line[1]|' ') == 'b' &&
XX			 sscanf(line,"%s %s",scr,scr) == 2) {
XX		    if ((scr[0]|' ') == 'n') p_wbcolors = 0;
XX		    else		     p_wbcolors = 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   = 0L;
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)+16);
XX	if (p_interlace == 1)
XX	    NewScreen.TopEdge   = (long)(400 - NewScreen.Height);
XX	else
XX	    NewScreen.TopEdge   = (long)(208 - NewScreen.Height);
XX	}
XX    else {
XX	p_depth			= 2L;
XX	NewWindow.TopEdge	= 0L;
XX	NewWindow.Screen	= NULL;
XX	NewWindow.Type		= WBENCHSCREEN;
XX	}
XX    /* see if we exit with a startup script */
XX    if ((c0|' ') == 'e') {
XX	ptr = &line[0];
XX	while (*ptr != '\000' && *ptr != ' ' && *ptr != '\t') ptr++;
XX	if (*ptr == '\000') return(NULL);
XX	while (*ptr != '\000' && (*ptr == ' ' || *ptr == '\t')) ptr++;
XX	if (*ptr == '\000') return(NULL);
XX	ptr2 = ptr;	
XX	while (*ptr2 != '\000' && *ptr2 != ' ' &&
XX	       *ptr2 != '\t'   && *ptr2 != '\n') ptr2++;
XX	*ptr2 = '\000';
XX	return(ptr);
XX	}
XX    else return(NULL);
XX    }
XX
XXvoid InitDevs()
XX{
XXUSHORT	colors[4];
XXint	i;
XXBYTE	*b,*c;
XX
XXIntuitionBase = (struct IntuitionBase *)
XX    OpenLibrary("intuition.library", INTUITION_REV);
XXif( IntuitionBase == NULL )
XX    cleanup("can't open intuition",1);
XX
XXGfxBase = (struct GfxBase *)
XX    OpenLibrary("graphics.library",GRAPHICS_REV);
XXif( GfxBase == NULL )
XX    cleanup("can't open graphics library",2);
XX
XXif (p_screen == 1) {
XX    if ((myscreen = (struct Screen *)OpenScreen(&NewScreen)) == NULL)
XX	cleanup("can't open screen",3);
XX    NewWindow.Screen = myscreen;
XX    }
XX
XXif ((mywindow = (struct Window *)OpenWindow(&NewWindow)) == NULL)
XX    cleanup("can't open window",4);
XXif ((myfont = (struct TextFont *)OpenFont(&myattr)) == NULL)
XX    cleanup("can't open font",4);
XX
XXmyviewport   = (struct ViewPort *)ViewPortAddress(mywindow);
XXmyrastport   = (struct RastPort *)mywindow->RPort;
XX
XXSetFont(myrastport,myfont);
XX
XXif (p_depth > 1) myrequest.BackFill = 2;
XXif (p_screen != 0 && p_wbcolors == 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 = 0L;
XXRead_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L);
XXif(OpenDevice(SERIALNAME,NULL,Read_Request,NULL))
XX    cleanup("Cant open Read device",5);
XXrs_in = malloc(p_buffer+1);
XXRead_Request->io_SerFlags = 0L;
XXRead_Request->io_Baud	  = p_baud;
XXRead_Request->io_ReadLen  = 8L;
XXRead_Request->io_WriteLen = 8L;
XXRead_Request->io_CtlChar  = 0x11130000L;
XXRead_Request->io_RBufLen  = p_buffer;
XXRead_Request->io_BrkTime  = p_break;
XXRead_Request->IOSer.io_Command = SDCMD_SETPARAMS;
XXDoIO(Read_Request);
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);
XXb = (BYTE *)Read_Request;
XXc = (BYTE *)Write_Request;
XXfor (i=0;i<sizeof(struct IOExtSer);i++) *c++ = *b++;
XXWrite_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L);
XXWrite_Request->IOSer.io_Command = CMD_WRITE;
XXWrite_Request->IOSer.io_Length  = 1;
XXWrite_Request->IOSer.io_Data    = (APTR) &rs_out[0];
XX
XXTimer_Port = CreatePort("Timer Port",0L);
XXScript_Timer_Port = CreatePort("Timer Port",0L);
XX
XXif (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Timer, 0) ||
XX    OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Script_Timer, 0)) 
XX	cleanup("can't open timer device",7);
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
XXBeepWave   = (UBYTE *)AllocMem(BEEPSIZE,(long)(MEMF_CHIP|MEMF_CLEAR));
XXif (BeepWave != 0) BeepWave[0] = 100;
XX
XXAudio_Port = CreatePort("Audio Port",0L);
XX
XXAudio_Request.ioa_Request.io_Message.mn_ReplyPort   = Audio_Port;
XXAudio_Request.ioa_Request.io_Message.mn_Node.ln_Pri = 85;
XXAudio_Request.ioa_Data		    = Audio_AllocMap;
XXAudio_Request.ioa_Length	    = (ULONG) sizeof(Audio_AllocMap);
XX
XXif (OpenDevice(AUDIONAME, NULL, (char *) &Audio_Request, NULL))
XX	cleanup("can't open audio device",8);
XX
XXAudio_Request.ioa_Request.io_Command	= CMD_WRITE;
XXAudio_Request.ioa_Request.io_Flags	= ADIOF_PERVOL;
XXAudio_Request.ioa_Data		= BeepWave;
XXAudio_Request.ioa_Length	= BEEPSIZE;
XXAudio_Request.ioa_Period	= COLORCLOCK / (BEEPSIZE * BEEPFREQ);
XXAudio_Request.ioa_Volume	= p_volume;
XXAudio_Request.ioa_Cycles	= 100;
XX}
XX
XX/*****************************************************************/
XX/*    The following function initializes the structure arrays    */
XX/*   needed to provide the File menu topic.                      */
XX/*****************************************************************/
XXvoid InitFileItems()
XX    {
XX    int	    n,nplus1;
XX
XX/* initialize each menu item and IntuiText with loop */
XXfor( n=0; n<FILEMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    FileItem[n].NextItem = &FileItem[nplus1];
XX    FileItem[n].LeftEdge = 0;
XX    FileItem[n].TopEdge = 10 * n;
XX    FileItem[n].Width = 120+40;
XX    FileItem[n].Height = 10;
XX    FileItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
XX    FileItem[n].MutualExclude = 0;
XX    FileItem[n].ItemFill = (APTR)&FileText[n];
XX    FileItem[n].SelectFill = NULL;
XX    if (n >= 2 && n <= 7) {
XX	FileItem[n].Command  = cmds[n-2];
XX	FileItem[n].Flags   |= COMMSEQ;
XX	}
XX    else 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 */
XX
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/*			Main Comm menu
XX/*		set up for Baud & Parity submenus
XX/******************************************************************/
XXvoid InitCommItems()
XX    {
XX    int	    n,nplus1;
XX
XX/* initialize each menu item and IntuiText with loop */
XXfor( n=0; n<COMMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    CommItem[n].NextItem = &CommItem[nplus1];
XX    CommItem[n].LeftEdge = 0;
XX    CommItem[n].TopEdge = 10 * n;
XX    CommItem[n].Width = 88;
XX    CommItem[n].Height = 10;
XX    CommItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP ;
XX    CommItem[n].MutualExclude = 0;
XX    CommItem[n].ItemFill = (APTR)&CommText[n];
XX    CommItem[n].SelectFill = NULL;
XX    CommItem[n].Command = 0;
XX    CommItem[n].NextSelect = 0;
XX
XX    CommText[n].FrontPen = 0;
XX    CommText[n].BackPen = 1;
XX    CommText[n].DrawMode = JAM2;    
XX    CommText[n].LeftEdge = 0;
XX    CommText[n].TopEdge = 1;
XX    CommText[n].ITextFont = NULL;
XX    CommText[n].NextText = NULL;
XX    }
XXCommItem[COMMAX-1].NextItem = NULL;
XX
XXCommText[0].IText = (UBYTE *)"Baud Rate";
XXCommText[1].IText = (UBYTE *)"Parity   ";
XXCommText[2].IText = (UBYTE *)"Xfer Mode";
XXCommItem[0].SubItem = RSItem;
XXCommItem[1].SubItem = ParItem;
XXCommItem[2].SubItem = XFItem;
XX
XX/*****************************************************************/
XX/*    The following initializes the structure arrays		 */
XX/*   needed to provide the BaudRate Submenu topic.               */
XX/*****************************************************************/
XX
XXfor( n=0; n<RSMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    RSItem[n].NextItem = &RSItem[nplus1];
XX    RSItem[n].LeftEdge = 75;
XX    RSItem[n].TopEdge = 10 * n;
XX    RSItem[n].Width = 56+40;
XX    RSItem[n].Height = 10;
XX    RSItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT;
XX    RSItem[n].MutualExclude = (~(1 << n));
XX    RSItem[n].ItemFill = (APTR)&RSText[n];
XX    RSItem[n].SelectFill = NULL;
XX    if (n >= 1 && n <= 2) {
XX	RSItem[n].Command    = cmds[n+5];
XX	RSItem[n].Flags	    |= COMMSEQ;
XX	}
XX    else 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
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 |= 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/*    The following initializes the structure arrays		 */
XX/*   needed to provide the Parity   Submenu topic.               */
XX/*****************************************************************/
XX
XXfor( n=0; n<PARMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    ParItem[n].NextItem = &ParItem[nplus1];
XX    ParItem[n].LeftEdge = 75;
XX    ParItem[n].TopEdge = 10 * n;
XX    ParItem[n].Width = 56+40;
XX    ParItem[n].Height = 10;
XX    ParItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT;
XX    ParItem[n].MutualExclude = (~(1 << n));
XX    ParItem[n].ItemFill = (APTR)&ParText[n];
XX    ParItem[n].SelectFill = NULL;
XX    if (n == 0 || n == 3 || n == 4) {
XX	ParItem[n].Command   = cmds[(n==0)?8:n+6];
XX	ParItem[n].Flags    |= COMMSEQ;
XX	}
XX    else ParItem[n].Command = 0;
XX    ParItem[n].SubItem = NULL;
XX    ParItem[n].NextSelect = 0;
XX
XX    ParText[n].FrontPen = 0;
XX    ParText[n].BackPen = 1;
XX    ParText[n].DrawMode = JAM2;/* render in fore and background */
XX    ParText[n].LeftEdge = 0;
XX    ParText[n].TopEdge = 1;
XX    ParText[n].ITextFont = NULL;
XX    ParText[n].NextText = NULL;
XX    }
XXParItem[PARMAX-1].NextItem = NULL;
XX
XX/* select parity item chekced */
XXParItem[p_parity].Flags |= CHECKED;
XX
XX/* initialize text for specific menu items */
XXParText[0].IText = (UBYTE *)"  None ";
XXParText[1].IText = (UBYTE *)"  Mark ";
XXParText[2].IText = (UBYTE *)"  Space";
XXParText[3].IText = (UBYTE *)"  Even ";
XXParText[4].IText = (UBYTE *)"  Odd  ";
XX
XX/*****************************************************************/
XX/*    The following initializes the structure arrays		 */
XX/*    needed to provide the Transfer Mode menu topic.            */
XX/*****************************************************************/
XX
XX/* initialize each menu item and IntuiText with loop */
XXfor( n=0; n<XFMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    XFItem[n].NextItem = &XFItem[nplus1];
XX    XFItem[n].LeftEdge = 75;
XX    XFItem[n].TopEdge = 10 * n;
XX    XFItem[n].Width = 80+40;
XX    XFItem[n].Height = 10;
XX    XFItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT;
XX    XFItem[n].MutualExclude = (~(1 << n));
XX    XFItem[n].ItemFill = (APTR)&XFText[n];
XX    XFItem[n].SelectFill = NULL;
XX    if (n < 2) {
XX	XFItem[n].Command    = cmds[n+11];
XX	XFItem[n].Flags	    |= COMMSEQ;
XX	}
XX    else 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;
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 |= CHECKED;
XX
XX/* initialize text for specific menu items */
XXXFText[0].IText = (UBYTE *)"  Image";
XXXFText[1].IText = (UBYTE *)"  Text ";
XX
XX} /* end of InitCommItems() */
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,nplus1;
XX
XX/* initialize each menu item and IntuiText with loop */
XXfor( n=0; n<SCRIPTMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    ScriptItem[n].NextItem = &ScriptItem[nplus1];
XX    ScriptItem[n].LeftEdge = 0;
XX    ScriptItem[n].TopEdge = 10 * n;
XX    ScriptItem[n].Width = 128;
XX    ScriptItem[n].Height = 10;
XX    ScriptItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
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 structure arrays    */
XX/*   needed to provide the Util menu topic.                    */
XX/*****************************************************************/
XXvoid InitUtilItems()
XX    {
XX    int	    n,nplus1;
XX
XX/* initialize each menu item and IntuiText with loop */
XXfor( n=0; n<UTILMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    UtilItem[n].NextItem = &UtilItem[nplus1];
XX    UtilItem[n].LeftEdge = 0;
XX    UtilItem[n].TopEdge = 10 * n;
XX    UtilItem[n].Width = 88+40;
XX    UtilItem[n].Height = 10;
XX    UtilItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
XX    if (n > 3) UtilItem[n].Flags |= CHECKIT;
XX    UtilItem[n].MutualExclude = 0;
XX    UtilItem[n].ItemFill = (APTR)&UtilText[n];
XX    UtilItem[n].SelectFill = NULL;
XX    if (n == 0 || n == 2) {
XX	UtilItem[n].Command   = cmds[(n==0)?13:14];
XX	UtilItem[n].Flags    |= COMMSEQ;
XX	}
XX    else if (n >= 5) {
XX	UtilItem[n].Command   = cmds[n+10];
XX	UtilItem[n].Flags    |= COMMSEQ;
XX	}
XX    else UtilItem[n].Command = 0;
XX    UtilItem[n].SubItem = NULL;
XX    UtilItem[n].NextSelect = 0;
XX
XX    UtilText[n].FrontPen = 0;
XX    UtilText[n].BackPen = 1;
XX    UtilText[n].DrawMode = JAM2;/* render in fore and background */
XX    UtilText[n].LeftEdge = 0;
XX    UtilText[n].TopEdge = 1;
XX    UtilText[n].ITextFont = NULL;
XX    UtilText[n].NextText = NULL;
XX    }
XXUtilItem[UTILMAX-1].NextItem = NULL;
XX
XXif (p_echo)	    UtilItem[4].Flags |= CHECKED;
XXif (p_wrap)	    UtilItem[5].Flags |= CHECKED;
XXif (p_keyapp == 0)  UtilItem[6].Flags |= CHECKED;
XXif (p_curapp)	    UtilItem[7].Flags |= CHECKED;
XX
XX/* initialize text for specific menu items */
XXUtilText[0].IText = (UBYTE *)"Send Break";
XXUtilText[1].IText = (UBYTE *)"Hang Up";
XXUtilText[2].IText = (UBYTE *)"Change Dir";
XXUtilText[3].IText = (UBYTE *)"Clear Scrn";
XXUtilText[4].IText = (UBYTE *)"  Echo";
XXUtilText[5].IText = (UBYTE *)"  Wrap";
XXUtilText[6].IText = (UBYTE *)"  Num Key";
XXUtilText[7].IText = (UBYTE *)"  App Cur";
XX}
XX
XX/****************************************************************/
XX/*   The following function inits the Menu structure array with */
XX/*  appropriate values for our simple menu.  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 = 40;
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 = 55;
XXmenu[1].TopEdge = 0;
XXmenu[1].Width = 88;
XXmenu[1].Height = 10;
XXmenu[1].Flags = MENUENABLED;
XXmenu[1].MenuName = "Comm Setup";   /* text for menu-bar display */
XXmenu[1].FirstItem = &CommItem[0];  /* pointer to first item in list */
XX
XXmenu[2].NextMenu = &menu[3];
XXmenu[2].LeftEdge = 153;
XXmenu[2].TopEdge = 0;
XXmenu[2].Width = 56;
XXmenu[2].Height = 10;
XXmenu[2].Flags = MENUENABLED;
XXmenu[2].MenuName = "Script";        /* text for menu-bar display */
XXmenu[2].FirstItem = &ScriptItem[0]; /* pointer to first item in list*/
XX
XXmenu[3].NextMenu = NULL;
XXmenu[3].LeftEdge = 225;
XXmenu[3].TopEdge = 0;
XXmenu[3].Width = 64;
XXmenu[3].Height = 10;
XXmenu[3].Flags = MENUENABLED;
XXmenu[3].MenuName = "Utility";      /* text for menu-bar display */
XXmenu[3].FirstItem = &UtilItem[0];  /* pointer to first item in list*/
XX}
XX
SHAR_EOF
if test 22776 -ne "`wc -c init.c`"
then
echo shar: error transmitting init.c '(should have been 22776 characters)'
fi
#	End of shell archive
exit 0

wecker@cookie.dec.com.UUCP (02/19/87)

#	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:
#	script.c
#	remote.c
#	window.c
#	expand.c
#	kermit.c
#	xmodem.c
# This archive created: Sun Feb 15 18:07:22 1987
echo shar: extracting script.c
sed 's/^XX//' << \SHAR_EOF > script.c
XX/*************************************************************
XX * vt100 terminal emulator - Script file support
XX *
XX *	v2.5 870214 DBW - more additions (see readme file)
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
XX *	     860901 ACS - Added BAUD, PARITY and WORD commands & handling
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#include "vt100.h"
XX
XXstruct COMMAND {
XX    void (*func)();
XX    char *cname;
XX    };
XX
XXstruct LABEL  {
XX    struct LABEL *next;
XX    char *name;
XX    long pos;
XX    };
XX
XXextern long atol();
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[20];          /* 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
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_cd,     "cd",		/* change directory	    */
XX    cmd_sb,     "sb",		/* Send a break		    */
XX    cmd_baud,   "baud",		/* Set Baud Rate            */
XX    cmd_parity, "parity",	/* Set Parity		    */
XX    cmd_bt,     "bt",		/* Set Break Time	    */
XX    cmd_tm,     "tm",		/* Set KERMIT transfer mode */
XX    cmd_beep,	"beep",		/* Beep			    */
XX    cmd_echo,	"echo",		/* turn echo on or off	    */
XX    cmd_wrap,	"wrap",		/* turn wrap on or off	    */
XX    cmd_numkey,	"numkey",	/* turn numeric kpad on/off */
XX    cmd_appcur,	"appcur",	/* turn app. cursor on/off  */
XX    cmd_null,   NULL		/* mark the end of the list */
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    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 (strlen(file) == 0 || *file == '#') return(0);
XX    if ((sf = fopen(file, "r")) == NULL) {
XX        req("Can't open script file",file,0);
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    /* downcase the command */
XX    for (i=0; i<l; i++) p[i] |= ' ';    
XX
XX    /* now search for it */
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    req("Script - unknown command:",p,0);
XX    return(FALSE);
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
XXdo_script_cmd(stat)
XXint stat;
XX    {
XX    int len,l;
XX    char line[256];
XX    char *p;
XX
XX    /* if ON command is matched and we were     */
XX    /* doing a DELAY then abort the delay timer,*/
XX    /* except if on_cmd was just a SEND.        */
XX    if (stat == ONCOMMAND) {
XX        strcpy(line,on_cmd);
XX        p = next_wrd(line,&l);
XX	if (*p != 'S' && script_wait == WAIT_TIMER)  {
XX            AbortIO((char *) &Script_Timer);
XX            Wait (1L << Script_Timer_Port->mp_SigBit);
XX
XX	    /* script will proceed after on command    */
XX            script_wait = FALSE;
XX	    }
XX	exe_cmd(p,l);
XX        return(0);
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 *) 
XX			malloc(sizeof (struct LABEL));
XX		    }
XX		else {
XX		    labels->next = (struct LABEL *)
XX			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	    p = next_wrd(p+l+1, &l);
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) req("Script - label not found: ",golabel,0);
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    req("Script - terminated","",0);    
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 *s1,*s2;
XX
XX    s1 = ptr;
XX    if (*ptr == '"') {
XX        while(*ptr++  && *ptr != '"') ;
XX        if (*ptr == '"') {
XX            *ptr = '\0';  
XX            ptr = s2 = ++s1;
XX            while(*s2) {
XX		if	(*s2 != '^')	 *s1++ = *s2;
XX		else if (*(s2+1) == '^') *s1++ = *s2++;
XX		else			 *s1++ = ((*++s2)|' ')-96;
XX		s2++;
XX		}
XX	    *s1 = '\0';
XX            return(ptr);
XX	    }
XX	}
XX    if (*s1 == '^') {
XX        *s1 = (*(s1+1)|' ')-96;
XX        *(s1+1) = '\0';
XX        return(s1);
XX        }
XX    *(s1+1) = '\0';
XX    return(s1);
XX    }   
XX        
XX/***************************** SCRIPT COMMANDS ********************/
XX
XXvoid cmd_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
XXvoid cmd_send(str)
XXchar *str;
XX    {
XX    sendstring(tostring(str));
XX    }
XX
XXvoid cmd_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
XXvoid cmd_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
XXvoid cmd_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
XXvoid cmd_done(option)
XXchar *option;
XX    {
XX    char *p;
XX    int  l;
XX
XX    if (*option) {
XX	p = next_wrd(option,&l);
XX	*(p+l) = '\000';
XX	if  (strcmp(p,"vt100") == 0 || strcmp(p,"VT100") == 0)
XX	    cleanup("Exit vt100 from script",0);
XX	exit_script();
XX	script_start(p);
XX	}
XX    else exit_script();
XX    }
XX
XXvoid cmd_ks(file)
XXchar *file;
XX    {
XX    multi_xfer(file, doksend, 1);
XX    }
XX
XXvoid cmd_kr(file)
XXchar *file;
XX    {
XX    multi_xfer(file, dokreceive, 0);
XX    }
XX
XXvoid cmd_kg(file)
XXchar *file;
XX    {
XX    server = TRUE;
XX    multi_xfer(file, dokreceive, 0);
XX    }
XX
XXvoid cmd_kb()
XX    {
XX    saybye();
XX    }
XX
XXvoid cmd_xs(file)
XXchar *file;
XX    {
XX    multi_xfer(file, XMODEM_Send_File, 1);
XX    }
XX
XXvoid cmd_xr(file)
XXchar *file;
XX    {
XX    multi_xfer(file, XMODEM_Read_File, 1);
XX    }
XX
XXvoid cmd_cap(file)
XXchar *file;
XX    {
XX    do_capture(file);
XX    }
XX
XXvoid cmd_as(file)
XXchar *file;
XX    {
XX    do_send(file);
XX    }
XX
XXvoid cmd_cd(name)
XXchar *name;
XX    {
XX    set_dir(name);
XX    }
XX
XXvoid cmd_sb(str)
XXchar *str;
XX    {
XX    sendbreak();
XX    }
XX
XXvoid cmd_baud(rate)
XXchar *rate;
XX    {
XX    int i = atoi(rate);
XX
XX    switch( i )
XX	{
XX	case  300:
XX	case 1200:
XX	case 2400:
XX	case 4800:
XX	case 9600:
XX	setserbaud(i, TRUE);
XX	break;
XX
XX	default:
XX	req("Script - invalid baud rate: ",rate,0);
XX	break;
XX	}
XX    }
XX
XXvoid cmd_parity(par)
XXchar *par;
XX    {
XX    int i;
XX
XX    switch( *par|' ' )
XX	{
XX	case 'n': i =  0; break;
XX	case 'm': i =  1; break;
XX	case 's': i =  2; break;
XX	case 'e': i =  3; break;
XX	case 'o': i =  4; break;
XX
XX	default:
XX	req("Script - invalid parity: ",par,0);
XX	return;
XX	}
XX    p_parity = i;
XX    ClearMenuStrip( mywindow );         /* Remove old menu */
XX    InitCommItems();                    /* Re-do comm menu   */
XX    SetMenuStrip(mywindow,&menu[0]);    /* Re-display the menu */	
XX    }
XX
XXvoid cmd_bt(breaklength)
XXchar *breaklength;
XX    {
XX    long i = atol(breaklength);
XX    AbortIO(Read_Request);
XX    Read_Request->io_BrkTime = Write_Request->io_BrkTime = i;
XX    setparams();
XX    }
XX
XXvoid cmd_tm(tmode)
XXchar *tmode;
XX    {
XX    switch (*tmode|' ') {
XX	case 'i':
XX	p_mode = 0;
XX	break;
XX
XX	case 'c':
XX	p_mode = 1;
XX	break;
XX
XX	default:
XX	req("Script - invalid transfer mode: ",tmode,0);
XX	return;
XX	}
XX
XX    ClearMenuStrip(mywindow);
XX    InitCommItems();                    /* Re-do comm menu   */
XX    SetMenuStrip(mywindow,&menu[0]);
XX    }
XX
XXvoid cmd_beep(dummy)
XXchar	*dummy;
XX    {
XX    if (p_volume == 0) DisplayBeep(NULL);
XX    else {
XX	BeginIO(&Audio_Request);
XX	WaitIO(&Audio_Request);
XX	}
XX    }
XX
XXvoid cmd_echo(par)
XXchar	*par;
XX    {
XX    if ((par[1]|' ') == 'n') p_echo = 1;
XX    else		     p_echo = 0;
XX    redoutil();
XX    }
XX
XXvoid cmd_wrap(par)
XXchar	*par;
XX    {
XX    if ((par[1]|' ') == 'n') p_wrap = 1;
XX    else		     p_wrap = 0;
XX    redoutil();
XX    }
XX
XXvoid cmd_numkey(par)
XXchar	*par;
XX    {
XX    if ((par[1]|' ') == 'n') p_keyapp = 0;
XX    else		     p_keyapp = 1;
XX    redoutil();
XX    }
XX
XXvoid cmd_appcur(par)
XXchar	*par;
XX    {
XX    if ((par[1]|' ') == 'n') p_curapp = 1;
XX    else		     p_curapp = 0;
XX    redoutil();
XX    }
XX
XXvoid cmd_null(dummy)
XXchar *dummy;
XX    {
XX    }
XX
SHAR_EOF
if test 12281 -ne "`wc -c script.c`"
then
echo shar: error transmitting script.c '(should have been 12281 characters)'
fi
echo shar: extracting remote.c
sed 's/^XX//' << \SHAR_EOF > remote.c
XX/****************************************************
XX * vt100 emulator - remote character interpretation
XX *
XX *	v2.5 870214 DBW - more additions (see readme file)
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
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#include "vt100.h"
XX
XXstatic int    p[10];
XXstatic int    numpar;
XXstatic char   escseq[40];
XX
XX/************************************************
XX*  function to handle remote characters
XX*************************************************/
XXvoid doremote(c)
XXchar c;
XX    {
XX    if (c == 24) { inesc = 0; inctrl = 0; return; }
XX    if (c == 27 || (inesc >= 0 && c >= ' ')) { doesc(c); return; }
XX    if (inctrl >= 0 && c >= ' ') { 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
XX    /* Collect intermediates */
XX    if (c < '0') {escseq[inesc++] = c; return; }
XX
XX    /* by process of elimination, we have a final character.
XX       Put it in the buffer, and dispatch on the first character
XX       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	curmode = FS_NORMAL; p_keyapp = 0; p_curapp = 0;
XX	inesc = -1;
XX	a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
XX	redoutil();
XX	emit(12);
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      case '=':				/* set keypad application mode */
XX        p_keyapp = 1;
XX	redoutil();
XX        return;
XX        
XX      case '>':				/* reset application mode */
XX        p_keyapp = 0;
XX	redoutil();
XX        return;
XX        
XX      case 'Z':
XX	sendchar(27); sendstring("[?1;7c"); 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 
XX	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
XX	    /* Only allowed BEFORE parameters */
XX    	    if (inctrl == 0) private = c;
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 most private sequences right now,
XX	so just punt them */
XX
XX    if ((private != 0 && private != '?') || badseq != 0) return;
XX    if (private == '?' && escseq[0] != 'h' &&
XX	escseq[0] != 'l') 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 'L':				/* ANSI insert line */
XX      case 'M':				/* ANSI delete line */
XX	if (p[0] <= 0) p[0] = 1;
XX	ScrollRaster(mywindow->RPort,0L,
XX	    (long)((escseq[0] == 'M' ? 8L : -8L) * p[0]),
XX	    (long)MINX,(long)y-6,(long)(MAXX+7),(long)bot+1);
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  = FS_NORMAL;
XX		break;
XX
XX		case 1:
XX		curmode |= FSF_BOLD;
XX		break;
XX
XX		case 4:
XX		curmode |= FSF_UNDERLINED;
XX		break;
XX
XX		case 5:
XX		curmode |= FSF_ITALIC;
XX		break;
XX
XX		default:
XX		curmode |= FSF_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 (private == 0 && p[0] == 20)		nlmode = 1;
XX	else if (private == '?') {
XX	    if      (p[0] == 7)	p_wrap   = 1;
XX	    else if (p[0] == 1)	p_curapp = 1;
XX	    redoutil();
XX	    }
XX	return;
XX
XX      case 'l':				/* Reset parameter */
XX	if (private == 0 && p[0] == 20)		nlmode = 0;
XX	else if (private == '?') {
XX	    if      (p[0] == 7)	p_wrap   = 0;
XX	    else if (p[0] == 1) p_curapp = 0;
XX	    redoutil();
XX	    }
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;7c"); 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 'a':
XX	doline(0,-6,8,1);
XX	break;
XX
XX	case 'j':
XX	case 'm':
XX	case 'v':   doline(4,-6,4,-2);
XX	if      (c=='j')  doline(0,-2,4,-2);
XX	else if (c=='m')  doline(4,-2,8,-2);
XX	else              doline(0,-2,8,-2);
XX	break;
XX
XX	case 'k':
XX	case 'l':
XX	case 'w': doline(4,-2,4,1);
XX	if      (c=='k')  doline(0,-2,4,-2);
XX	else if (c=='l')  doline(4,-2,8,-2);
XX	else              doline(0,-2,8,-2);
XX	break;
XX
XX	case 'n':
XX	case 'q': doline(0,-2,8,-2);
XX	if      (c=='n')  doline(4,-6,4,2);
XX	break;
XX
XX	case 't':
XX	case 'u':
XX	case 'x':   doline(4,-6,4,1);
XX	if      (c=='t')  doline(4,-2,8,-2);
XX	else if (c=='u')  doline(0,-2,4,-2);
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 10028 -ne "`wc -c remote.c`"
then
echo shar: error transmitting remote.c '(should have been 10028 characters)'
fi
echo shar: extracting window.c
sed 's/^XX//' << \SHAR_EOF > window.c
XX/****************************************************
XX * vt100 emulator - window/keyboard support
XX *
XX *	v2.5 870214 DBW - more additions (see readme file)
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
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#include "vt100.h"
XX
XX/* keyboard definitions for toasc() */
XXstatic 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/*************************************************
XX*  function to get file name (via a requestor)
XX*************************************************/
XXvoid req(prmpt,name,getinp)
XXchar *prmpt,*name;
XXint  getinp;
XX    {
XX    ULONG class;
XX    unsigned int code, qual;
XX
XX    /* Make sure the prompt gets updated */
XX    if (numreqs == 1 && strcmp(Prompt,prmpt) != 0) {
XX	EndRequest(&myrequest,mywindow);
XX	numreqs = 0;
XX	}
XX
XX    /* copy in a prompt and a default */
XX    strcpy(Prompt,prmpt);
XX    strcpy(InpBuf,name);
XX
XX    /* If we want input, select the gadget */
XX    if (getinp) mystrgad.Flags |= SELECTED;
XX    else        mystrgad.Flags &= ~SELECTED;
XX
XX    /* If there is a requester... reuse it */
XX    if (numreqs == 1) RefreshGadgets(&mydonegad,mywindow,&myrequest);
XX
XX    /* otherwise create it */
XX    else {
XX	if (Request(&myrequest,mywindow) == 0) {
XX	    emits("ERROR - CAN'T CREATE REQUESTOR FOR:\n");
XX	    emits(Prompt); emit('\n');
XX	    emits(InpBuf); emit('\n');
XX	    return;
XX	    }
XX	else numreqs = 1;
XX	}
XX
XX    /* if we don't want input, we're done */
XX    if (getinp == 0) return;
XX
XX    /* wait for input to show up */
XX    while (1) {
XX	if ((NewMessage = (struct IntuiMessage *)
XX		GetMsg(mywindow->UserPort)) == FALSE) {
XX	    Wait(1L<<mywindow->UserPort->mp_SigBit);
XX	    continue;
XX	    }
XX	class = NewMessage->Class;
XX	code  = NewMessage->Code;
XX	qual  = NewMessage->Qualifier;
XX	ReplyMsg(NewMessage);
XX
XX	/* the requestor got terminated... yea!! */
XX	if (class == REQCLEAR) break;
XX
XX	/* maybe this is a menu item to handle */
XX	if (class == MENUPICK) handle_menupick(class,code);
XX	}
XX
XX    /* all done, so return the result */
XX    numreqs = 0;
XX    strcpy(name,InpBuf);
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    static char wrap_flag = 0;	/* are we at column 80? */
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	if (p_volume == 0) DisplayBeep(NULL);
XX	else {
XX	    BeginIO(&Audio_Request);
XX	    WaitIO(&Audio_Request);
XX	    }
XX	break;
XX
XX	default:
XX	if (c < ' ' || c > '~') break;
XX	if (p_wrap && wrap_flag && x >= MAXX) {
XX	    x = MINX;
XX	    y += 8;
XX	    if (y > MAXY) {
XX		y = MAXY;
XX		ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,
XX		    (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
XX		}
XX	    }
XX	Move(mywindow->RPort,(long)x,(long)y);
XX
XX	if (curmode&FSF_BOLD) {
XX	    if (p_depth > 1) {
XX		SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
XX		SetSoftStyle(mywindow->RPort,(long)curmode,253L);
XX		}
XX	    else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
XX	    }
XX	else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
XX
XX	if (curmode&FSF_REVERSE) {
XX	    SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID));
XX	    Text(mywindow->RPort,&c,1L);
XX	    SetDrMd(mywindow->RPort,(long)JAM2);
XX	    }
XX	else Text(mywindow->RPort,&c,1L);
XX
XX	if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L);
XX	x += 8;
XX	} /* end of switch */
XX
XX    if (y > MAXY) {
XX	y = MAXY;
XX	x = MINX;
XX	ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,
XX	    (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
XX	}
XX    if (x > MAXX) {
XX	wrap_flag = 1;
XX	x = MAXX;
XX	}
XX    else wrap_flag = 0;
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
XX    Move(mywindow->RPort,(long)x,(long)y);
XX    i = x / 8;
XX    if (i+la >= maxcol) {
XX	if (p_wrap == 0) la = maxcol - i;
XX	else {
XX	    lookahead[la] = 0;
XX	    emits(lookahead);
XX	    return;
XX	    }
XX	}
XX    if (curmode&FSF_BOLD) {
XX	if (p_depth > 1) {
XX	    SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
XX	    SetSoftStyle(mywindow->RPort,(long)curmode,253L);
XX	    }
XX	else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
XX	}
XX    else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
XX
XX    if (curmode&FSF_REVERSE) {
XX	SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID));
XX	Text(mywindow->RPort,lookahead,(long)la);
XX	SetDrMd(mywindow->RPort,(long)JAM2);
XX	}
XX    else Text(mywindow->RPort,lookahead,(long)la);
XX    if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L);
XX    x += (8 * la);
XX    }
XX
XX/******************************
XX* Manipulate cursor
XX******************************/
XXvoid cursorflip()
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,qual,local)
XXunsigned int code,qual;
XXint local;
XX    {
XX    unsigned int ctrl,shift,capsl,amiga,alt;
XX    char c = 0, keypad = 0;
XX    char *ptr;
XX
XX    ctrl    = qual & IEQUALIFIER_CONTROL;
XX    capsl   = qual & IEQUALIFIER_CAPSLOCK;
XX    amiga   = qual & (IEQUALIFIER_LCOMMAND | IEQUALIFIER_RCOMMAND);
XX    shift   = qual & (IEQUALIFIER_LSHIFT   | IEQUALIFIER_RSHIFT);
XX    alt	    = qual & (IEQUALIFIER_LALT     | IEQUALIFIER_RALT);
XX
XX    switch ( code )
XX	{
XX	case 98:
XX	case 226:
XX	case 99:
XX	case 227:
XX	case 96:
XX	case 97:
XX	case 224:
XX	case 225:
XX	case 100:
XX	case 101:
XX	case 228:
XX        case 229:
XX	case 102:
XX	case 103:
XX	case 230:
XX	case 231:   c = 0; break; /* ctrl, shift, capsl, amiga, or alt */
XX
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)	ptr = p_F[code - 0x50];
XX		    else	ptr = p_f[code - 0x50];
XX		    if (!script_on && *ptr == p_keyscript)
XX			    script_start(++ptr);
XX		    else    sendstring(ptr);
XX		    break;
XX	case 0x0f: c = (p_keyapp) ? 'p' : '0'; keypad = TRUE; break;
XX	case 0x1d: c = (p_keyapp) ? 'q' : '1'; keypad = TRUE; break;
XX	case 0x1e: c = (p_keyapp) ? 'r' : '2'; keypad = TRUE; break;
XX	case 0x1f: c = (p_keyapp) ? 's' : '3'; keypad = TRUE; break;
XX	case 0x2d: c = (p_keyapp) ? 't' : '4'; keypad = TRUE; break;
XX	case 0x2e: c = (p_keyapp) ? 'u' : '5'; keypad = TRUE; break;
XX	case 0x2f: c = (p_keyapp) ? 'v' : '6'; keypad = TRUE; break;
XX	case 0x3d: c = (p_keyapp) ? 'w' : '7'; keypad = TRUE; break;
XX	case 0x3e: c = (p_keyapp) ? 'x' : '8'; keypad = TRUE; break;
XX	case 0x3f: c = (p_keyapp) ? 'y' : '9'; keypad = TRUE; break;
XX	case 0x43: c = (p_keyapp) ? 'M' : 13 ; keypad = TRUE; break;
XX	case 0x4a: c = (p_keyapp) ? 'l' : '-'; keypad = TRUE; break;
XX	case 0x5f: sendstring("\033Om") ;break;
XX	case 0x3c: c = (p_keyapp) ? 'n' : '.'; keypad = TRUE; break;
XX	case 0x4c:
XX	case 0x4d: 
XX	case 0x4e: 
XX	case 0x4f: sendchar(27);            /* cursor keys */
XX		   if (p_curapp) sendchar('O');
XX		   else sendchar('[');
XX		   sendchar(code - 11);
XX		   break;
XX
XX	default:
XX	if (code < 75) c = keys[code];
XX	else c = 0;
XX	}
XX
XX    if (keypad) {
XX        if (p_keyapp) sendstring("\033O");
XX        sendchar(c);
XX        return(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	else if (c == '6') c = 30;
XX	else if (c == '-' || c == '?') c = 31;
XX	}
XX    if (ctrl && (c == '@' || c == '2' || c == ' ')) {
XX	if (!local) sendchar(alt?128:0);
XX	c = 0;
XX	}
XX    else if (c != 0 && (!local)) sendchar(alt?c+128:c);
XX    return((int)c);
XX    }
SHAR_EOF
if test 9827 -ne "`wc -c window.c`"
then
echo shar: error transmitting window.c '(should have been 9827 characters)'
fi
echo shar: extracting expand.c
sed 's/^XX//' << \SHAR_EOF > expand.c
XX/*************************************************************
XX * vt100 terminal emulator - Wild card and Directory support
XX *
XX *	v2.5 870214 DBW - more additions (see readme file)
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW	- new features (see README)
XX *           860830 Steve Drew Added Wild card support,
XX *		    features(expand.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 *      Much of the code from this module extracted from
XX *      Matt Dillons Shell program. (Thanxs Matt.)
XX *************************************************************/
XX
XX#include "vt100.h"
XX
XXstruct DPTR {                    /* Format of directory fetch ptr */
XX   struct FileLock *lock;        /* lock on directory   */
XX   struct FileInfoBlock *fib;    /* mod'd fib for entry */
XX};
XX
XX/*
XX * Disk directory routines
XX *
XX *
XX * dopen() returns a struct DPTR, or NULL if the given file does not
XX * exist.  stat will be set to 1 if the file is a directory.  If the
XX * name is "", then the current directory is openned.
XX *
XX * dnext() returns 1 until there are no more entries.  The **name and
XX * *stat are set.  *stat = 1 if the file is a directory.
XX *
XX * dclose() closes a directory channel.
XX *
XX */
XX
XXstruct DPTR *
XXdopen(name, stat)
XXchar *name;
XXint *stat;
XX{
XX   struct DPTR *dp;
XX   int namelen, endslash = 0;
XX   struct FileLock *MyLock;
XX   
XX   MyLock = (struct FileLock *)( (ULONG) ((struct Process *)
XX                                 (FindTask(NULL)))->pr_CurrentDir);
XX   namelen = strlen(name);
XX   if (namelen && name[namelen - 1] == '/') {
XX      name[namelen - 1] = '\0';
XX      endslash = 1;
XX   }
XX   *stat = 0;
XX   dp = (struct DPTR *)malloc(sizeof(struct DPTR));
XX   if (*name == '\0') 
XX      dp->lock = (struct FileLock *)DupLock (MyLock);
XX   else
XX      dp->lock = (struct FileLock *)Lock (name, ACCESS_READ);
XX   if (endslash)
XX      name[namelen - 1] = '/';
XX   if (dp->lock == NULL) {
XX      free (dp);
XX      return (NULL);
XX   }
XX   dp->fib = (struct FileInfoBlock *)
XX         AllocMem((long)sizeof(struct FileInfoBlock), MEMF_PUBLIC);
XX   if (!Examine (dp->lock, dp->fib)) {
XX      dclose (dp);
XX      return (NULL);
XX   }
XX   if (dp->fib->fib_DirEntryType >= 0)
XX      *stat = 1;
XX   return (dp);
XX}
XX
XXdnext(dp, pname, stat)
XXstruct DPTR *dp;
XXchar **pname;
XXint *stat;
XX{
XX   if (dp == NULL)
XX      return (0);
XX   if (ExNext (dp->lock, dp->fib)) {
XX      *stat = (dp->fib->fib_DirEntryType < 0) ? 0 : 1;
XX      *pname = dp->fib->fib_FileName;
XX      return (1);
XX   }
XX   return (0);
XX}
XX
XX
XXdclose(dp)
XXstruct DPTR *dp;
XX{
XX   if (dp == NULL)
XX      return (1);
XX   if (dp->fib)
XX      FreeMem (dp->fib, (long)sizeof(*dp->fib));
XX   if (dp->lock)
XX      UnLock (dp->lock);
XX   free (dp);
XX   return (1);
XX}
XX
XXfree_expand(av)
XXchar **av;
XX{
XX   char **base = av;
XX
XX   if (av) {
XX      while (*av) {
XX         free (*av);
XX         ++av;
XX      }
XX      free (base);
XX   }
XX}
XX
XX/*
XX * EXPAND(wild_name, pac)
XX *    wild_name      - char * (example: "df0:*.c")
XX *    pac            - int  *  will be set to # of arguments.
XX *
XX */
XX
XX
XXchar **
XXexpand(base, pac)
XXchar *base;
XXint *pac;
XX{
XX   char **eav = (char **)malloc (sizeof(char *));
XX   int  eleft, eac;
XX
XX   char *ptr, *name;
XX   char *bname, *ename, *tail;
XX   int stat, scr;
XX   struct DPTR *dp;
XX
XX   *pac = eleft = eac = 0;
XX   base = strcpy(malloc(strlen(base)+1), base);
XX   for (ptr = base; *ptr && *ptr != '?' && *ptr != '*'; ++ptr);
XX   for (; ptr >= base && !(*ptr == '/' || *ptr == ':'); --ptr);
XX   if (ptr < base) {
XX      bname = strcpy (malloc(1), "");
XX   } else {
XX      scr = ptr[1];
XX      ptr[1] = '\0';
XX      bname = strcpy (malloc(strlen(base)+1), base);
XX      ptr[1] = scr;
XX   }
XX   ename = ptr + 1;
XX   for (ptr = ename; *ptr && *ptr != '/'; ++ptr);
XX   scr = *ptr;
XX   *ptr = '\0';
XX   tail = (scr) ? ptr + 1 : NULL;
XX
XX   if ((dp = dopen (bname, &stat)) == NULL  ||  stat == 0) {
XX      free (bname);
XX      free (base);
XX      free (eav);
XX      req ("Could not open directory","",0);
XX      return (NULL);
XX   }
XX   while (dnext (dp, &name, &stat)) {
XX      if (compare_ok(ename, name)) {
XX         if (tail) {
XX            int alt_ac;
XX            char *search, **alt_av, **scrav;
XX            struct FileLock *lock;
XX
XX            if (!stat)      /* expect more dirs, but this not a dir */
XX               continue;
XX            lock = (struct FileLock *)CurrentDir (dp->lock);
XX            search = malloc(strlen(name)+strlen(tail)+2);
XX            strcpy (search, name);
XX            strcat (search, "/");
XX            strcat (search, tail);
XX            scrav = alt_av = expand (search, &alt_ac);
XX            CurrentDir (lock);
XX            if (scrav) {
XX               while (*scrav) {
XX                  if (eleft < 2) {
XX                     char **scrav = (char **)
XX			malloc(sizeof(char *) * (eac + 10));
XX                     movmem (eav, scrav, sizeof(char *) * (eac + 1));
XX                     free (eav);
XX                     eav = scrav;
XX                     eleft = 10;
XX                  }
XX                  eav[eac] = malloc(strlen(bname)+strlen(*scrav)+1);
XX                  strcpy(eav[eac], bname);
XX                  strcat(eav[eac], *scrav);
XX                  free (*scrav);
XX                  ++scrav;
XX                  --eleft, ++eac;
XX               }
XX               free (alt_av);
XX            }
XX         } else {
XX            if (eleft < 2) {
XX               char **scrav = (char **)
XX		    malloc(sizeof(char *) * (eac + 10));
XX               movmem (eav, scrav, sizeof(char *) * (eac + 1));
XX               free (eav);
XX               eav = scrav;
XX               eleft = 10;
XX            }
XX            eav[eac] = malloc (strlen(bname)+strlen(name)+1);
XX            eav[eac] = strcpy(eav[eac], bname);
XX            strcat(eav[eac], name);
XX            --eleft, ++eac;
XX         }
XX      }
XX   }
XX   dclose (dp);
XX   *pac = eac;
XX   eav[eac] = NULL;
XX   free (bname);
XX   free (base);
XX   if (eac)
XX      return (eav);
XX   free (eav);
XX   return (NULL);
XX}
XX
XX/*
XX * Compare a wild card name with a normal name
XX */
XX
XX#define MAXB   8
XX
XXcompare_ok(wild, name)
XXchar *wild, *name;
XX{
XX   char *w = wild;
XX   char *n = name;
XX   char *back[MAXB][2];
XX   int  bi = 0;
XX
XX   while (*n || *w) {
XX      switch (*w) {
XX      case '*':
XX         if (bi == MAXB) {
XX            req ("Too many levels of '*'","",0);
XX            return (0);
XX         }
XX         back[bi][0] = w;
XX         back[bi][1] = n;
XX         ++bi;
XX         ++w;
XX         continue;
XXgoback:
XX         --bi;
XX         while (bi >= 0 && *back[bi][1] == '\0')
XX            --bi;
XX         if (bi < 0)
XX            return (0);
XX         w = back[bi][0] + 1;
XX         n = ++back[bi][1];
XX         ++bi;
XX         continue;
XX      case '?':
XX         if (!*n) {
XX            if (bi)
XX               goto goback;
XX            return (0);
XX         }
XX         break;
XX      default:
XX         if (toupper(*n) != toupper(*w)) {
XX            if (bi)
XX               goto goback;
XX            return (0);
XX         }
XX         break;
XX      }
XX      if (*n)  ++n;
XX      if (*w)  ++w;
XX   }
XX   return (1);
XX}
XX
XXset_dir(new)
XXchar *new;
XX{
XX   register 	char 		*s;
XX   int   			i;
XX   struct 	FileLock 	*lock;
XX   char 			temp[60];
XX   struct       FileInfoBlock   *fib;
XX  
XX   if (*new != '\000') {
XX      strcpy(temp, MyDir);
XX      s = new;
XX      if (*s == '/') {
XX         s++;
XX         for (i=strlen(MyDir);
XX              MyDir[i] != '/' && MyDir[i] != ':';
XX              i--);
XX         MyDir[i+1] = '\0';
XX         strcat(MyDir, s);
XX         }
XX      else if (exists(s, ':') == 0) {
XX         if (MyDir[strlen(MyDir)-1] != ':')
XX            strcat(MyDir, "/");
XX         strcat(MyDir, s);
XX         }
XX      else
XX         strcpy(MyDir, s);
XX
XX      if ((lock = (struct FileLock *)Lock(MyDir, (long)ACCESS_READ)) == 0) {
XX         req("Directory not found:",MyDir,0);
XX         strcpy(MyDir, temp);
XX         }
XX      else {
XX	 fib = (struct FileInfoBlock *)AllocMem(
XX		(long)sizeof(struct FileInfoBlock), MEMF_PUBLIC);
XX	 if (fib) {
XX      	    if (Examine(lock, fib)) {
XX      		if (fib->fib_DirEntryType > 0) {
XX		    CurrentDir(lock);
XX		    if (MyDirLock != NULL) UnLock(MyDirLock);
XX		    MyDirLock = lock;
XX		    if (MyDir[strlen(MyDir)-1] == '/')
XX			MyDir[strlen(MyDir)-1] = '\000';
XX		    }
XX		else {
XX            	    req("Not a Directory:",MyDir,0);               
XX            	    strcpy(MyDir,temp);
XX		    }
XX		}
XX	    FreeMem(fib, (long)sizeof(struct FileInfoBlock));
XX	    }
XX	else {
XX	    req("Can't change directory... ","No free memory!",0);
XX	    strcpy(MyDir,temp);
XX	    }
XX	}
XX    }
XX}
XX
XXexists(s,c)
XXchar *s,c;
XX    {
XX    while (*s != '\000')
XX	if (*s++ == c) return(1);
XX    return(0);
XX    }
SHAR_EOF
if test 8633 -ne "`wc -c expand.c`"
then
echo shar: error transmitting expand.c '(should have been 8633 characters)'
fi
echo shar: extracting kermit.c
sed 's/^XX//' << \SHAR_EOF > kermit.c
XX/*************************************************************
XX * vt100 terminal emulator - KERMIT protocol support
XX *
XX *	v2.5 870214 DBW - more additions (see readme file)
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
XX *	     860901 ACS - Added eight bit quoting
XX *           860830 Steve Drew Wild card support, err recovry,bugs.
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#include "vt100.h"
XX
XX#define CONVERTNAME TRUE    /* file name to lower case for receive */
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 MYEBQ	 '&'	   /* 8th bit prefix character */
XX#define MYPAD      0       /* Number of padding charss 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   sendabort, /* flag for aborting send file  */
XX   rptflg,    /* are we doing repeat quoting */
XX   ebqflg,    /* are we doing 8th bit quoting */
XX   notfirst,  /* is this the first file received */
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   ebq,	      /* Quote character for 8th bit quoting */
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   sl1[] = "FILE            PKT NUM RETR BYTES",
XX   sl2[] = "%-15s  %c %4d  %2d %6ld %5s",
XX   sl3[50],
XX   mainmode[10];
XX
XXFILE *fp;     /* file for send/receive */
XX
XXchar *
XXgetfname(name)   /* returns ptr to start of file name from 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 amount, c, wild;
XX   char *p, **list = NULL;
XX
XX   if (!strcmp(file,"$")) { saybye(); return(2); }
XX   p = file;
XX   while(*p && *p != '*' && *p != '?') p++;
XX   if (*p) { 
XX       wild = TRUE;
XX       list = expand(file, &amount);
XX       if (list == NULL)  req("KERMIT","No wild card match",0);
XX       }
XX   else {
XX       wild = FALSE;
XX       amount = 1;
XX       }
XX   for (c = 0; c < amount; c++) {
XX       if (wild == TRUE) p = list[c];
XX         else  p = file;
XX       strcpy(filnam,getfname(p));
XX       ttime = TTIME_KERMIT;
XX       tp = retry = n = numtry = 0; totbytes = 0L;
XX       if ((fp = fopen(p,"r")) == NULL) {
XX           req("KERMIT: can't open send file:",p,0);
XX           continue;
XX           }
XX       strcpy(mainmode,"SEND");
XX       ClearBuffer();
XX       if (sendsw()) dostats(' ',"DONE");
XX       fclose(fp);
XX       } 
XX   free_expand(list);
XX   return TRUE;
XX   }
XX 
XXdokreceive(file,more)
XXchar *file;
XXint more;
XX   {
XX   int retval;
XX   
XX   ttime = TTIME_KERMIT;
XX   if (!strcmp(file,"$")) { saybye(); return(2); }
XX   strcpy(filnam, file);   
XX   if (server) strcpy(mainmode,"GET");
XX   else	       strcpy(mainmode,"RECV");
XX   tp =  retry = n =  numtry = notfirst = 0; totbytes = 0L;
XX   ClearBuffer();
XX   retval  = recsw();
XX   return(retval);
XX   }
XX
XXsendsw()
XX   {
XX   char sinit(), sfile(), sdata(), seof(), sbreak();
XX   sendabort = 0;
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':   if (sendabort) return FALSE;
XX                     else return TRUE;
XX         case 'E':   dostats('E',"ERROR");  /* so print the err and abort */
XX                     print_host_err(ackpkt);
XX                     return(FALSE);
XX         case 'A':   if (timeout == USERABORT) {
XX			 timeout = GOODREAD;
XX                         n = (n+1)%64;			 
XX                     	 sendabort = 1;
XX                     	 dostats('A',"ABORT");
XX                     	 strcpy(msgpkt, "D");
XX                     	 state = 'Z'; 
XX                     	 break;
XX                     	 }
XX                     if (timeout == TIMEOUT)  dostats('A',"TMOUT");
XX                     else { /* protocol error dectected by us */
XX			 dostats('A',"ERROR");
XX			 print_our_err();
XX			 }
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 = MYQUOTE;
XX                 numtry = 0;
XX                 retry--;
XX                 n = (n+1)%64;
XX                 return('F');
XX      case 'E':  return('E');
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('E');
XX      case FALSE: if (timeout == USERABORT) state = 'A';
XX                  return(state);
XX      default:
XX         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('E');
XX      case FALSE: if (timeout == USERABORT) state = 'A';
XX                  return(state);
XX      default:    
XX         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) {*/	/* tell host to discard file */
XX/*      timeout = GOODREAD;	*/
XX/*        spack('Z',n,1,"D");	*/
XX/*        }			*/
XX/*   else			*/
XX	spack('Z',n,sendabort,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('E');
XX      case FALSE: return(state);
XX      default:
XX         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('E');
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   dostats(' ',"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*/ 
XX
XX
XXrecsw()
XX   {
XX   char rinit(), rfile(), rdata();
XX
XX   state = 'R';
XX   
XX   while(TRUE) {
XX      switch(state) {
XX         case 'R':   state = rinit(); break;
XX         case 'Z':
XX         case 'F':   state = rfile(); break;
XX         case 'D':   state = rdata(); break;
XX         case 'C':   return(TRUE);
XX         case 'E':
XX         case 'A':   /* 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		    if (timeout == USERABORT){
XX			/* send an error packet back   */
XX                         dostats('A',"ABORT");
XX                         spack('E',n,12,"User aborted"); 
XX                     }
XX                     else if (timeout == TIMEOUT) {
XX			    /* we timed out waiting */
XX    			    /* will we need to spack here ?*/
XX			 dostats('A',"TMOUT");
XX			 }
XX			    /* must be 'E' from host or we
XX			     detected a protocol error */
XX                         else dostats('A',"ERROR");
XX
XX		     if (state == 'E') print_host_err(msgpkt);
XX
XX		     else if (timeout == GOODREAD) /* tell host why */
XX			print_our_err();
XX			   /* will this kill all files ?*/
XX                     do  {
XX                         ttime = 2;        
XX                         readchar();
XX                         }  while (timeout == GOODREAD);
XX                     fclose(fp);
XX                     sendstring("\r");
XX                     return(FALSE);
XX	 default:    return(FALSE);	
XX         }
XX      }
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('E');
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            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            return(state);
XX            }
XX         else return('A');
XX      case 'F':
XX         if (num != n) return('A');
XX	 strcpy(filnam,msgpkt);
XX         if (CONVERTNAME) {
XX             char *p;
XX	     p = &filnam[0];
XX             while (*p) { *p = tolower(*p); p++; }
XX             }
XX	 if (notfirst) { 
XX             totbytes = 0L;
XX             dostats('F',"RECV");
XX             }
XX	 /* is the first file so emit actual file name from host */
XX         else {
XX	     notfirst++;
XX	     }
XX         if ((fp = fopen(filnam,"w")) == NULL) {
XX	     req("KERMIT: Unable to create file:",filnam,0);
XX	     strcpy(msgpkt,"VT100 - Kermit - cannot create file: ");
XX	     strcat(msgpkt,filnam);
XX	     spack('E',n,strlen(msgpkt),msgpkt); /* let host know */
XX             dostats('E',"ERROR");
XX             return ('\0');       /* abort everything */
XX             }
XX         spack('Y',n,0,0);
XX         oldtry = numtry;
XX         numtry = 0;
XX         retry--;
XX         n = (n+1)%64;
XX         return('D');
XX
XX      /* totaly done server sending no more */
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('E');
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               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 'Z':
XX         if (num != n) return('A');
XX         spack('Y',n,0,0);
XX         n = (n+1)%64;
XX         retry--;
XX         dostats('Z',"DONE");
XX	 fclose(fp);
XX         return('Z');
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	     return(state);
XX             }
XX      case 'E':
XX         return('E');
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
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,mainmode);
XX   bufp = buffer;
XX   ClearBuffer();
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,mainmode);
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
XX   if (ebqflg && b8) {			/* Do 8th bit prefix if necessary. */
XX	msgpkt[size++] = ebq;
XX	a = a7;
XX	}
XX   
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
XX   if ((ebqflg) && (a7 == ebq))	/* Prefix the 8th bit prefix */
XX       msgpkt[size++] = quote;  /* if doing 8th-bit prefixes */
XX
XX   msgpkt[size++] = a;
XX   msgpkt[size] = '\0';
XX   }
XX
XXvoid decode()
XX   {
XX   USHORT  a, a7, b8;
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      b8 = 0;
XX      if (ebqflg) {                  /* 8th-bit prefixing? */
XX	  if (a == ebq) {            /* Yes, got an 8th-bit prefix? */
XX	      b8 = 0200;             /* Yes, remember this, */
XX	      a = *buf++;            /* and get the prefixed character. */
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      a |= b8;
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_KERMIT);
XX   data[2] = tochar(MYPAD);
XX   data[3] = ctl(MYPCHAR);
XX   data[4] = tochar(MYEOL);
XX   data[5] = MYQUOTE;
XX   if ((p_parity > 0) || ebqflg) {         /* 8-bit quoting... */
XX	data[6] = MYEBQ;          /* If parity or flag on, send &. */
XX	if ((ebq > 0040 && ebq < 0100) || /* If flag off, then turn it on  */
XX	   (ebq > 0140 && ebq < 0177) || /* if other side has asked us to */
XX	   (ebq == 'Y')) ebqflg = 1;
XX	}
XX    else				    /* Normally, */
XX       data[6] = 'Y';			    /* just say we're willing. */
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    ttime   = 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    ebqflg  = 0;
XX    if (data[6] == 0) return;
XX    ebq = data[6];
XX    if ((ebq > 040 && ebq < 0100) || 
XX	(ebq > 0140 && ebq < 0177)) ebqflg = 1;
XX    else if (((p_parity > 0) || ebqflg) && (ebq == 'Y')) {
XX	ebqflg = 1;
XX	ebq = '&';
XX	}
XX    else ebqflg = 0;
XX    if (data[7] == 0) return;
XX    if (data[8] == 0) return;
XX    rptq    = data[8];
XX    rptflg  = ((rptq > 040 && rptq < 0100) || 
XX	(rptq > 0140 && rptq < 0177));
XX    }
XX
XXsaybye()
XX  {
XX  int len,num;
XX  spack('G',n,1,"F");  /* shut down server no more files */
XX  rpack(&len,&num,ackpkt);
XX  }
XX
XXprint_our_err()
XX    {
XX    if (retry > MAXTRY || oldtry > MAXTRY) {
XX	req("KERMIT:","Too may retries for packet",0);
XX	strcpy(msgpkt,"VT100 KERMIT: Too many retries for packet");
XX	}
XX    else {
XX	req("KERMIT:","Protocol Error",0);
XX	strcpy(msgpkt,"VT100 KERMIT: Protocol Error");
XX	}
XX    spack('E',n,strlen(msgpkt));
XX    }
XX
XXprint_host_err(msg)
XX  char *msg;
XX  {
XX  req("KERMIT Host Error:",msg,0);
XX  }
XX
XXdostats(type,stat)
XXchar type,*stat;
XX    {
XX    if (type == 'Y' || type == 'N' || type == 'G') return;
XX    sprintf(sl3,sl2,filnam,type,n+(tp*64),retry-1,(long)totbytes,stat);
XX    if (n==63) tp++;
XX    req(sl1,sl3,0);
XX    }
XX
XXClearBuffer()
XX    {
XX    AbortIO(Read_Request);
XX    Read_Request->IOSer.io_Command = CMD_CLEAR;
XX    DoIO(Read_Request);
XX    Read_Request->IOSer.io_Command = CMD_READ;
XX    SendIO(Read_Request);
XX    }
XX
SHAR_EOF
if test 22034 -ne "`wc -c kermit.c`"
then
echo shar: error transmitting kermit.c '(should have been 22034 characters)'
fi
echo shar: extracting xmodem.c
sed 's/^XX//' << \SHAR_EOF > xmodem.c
XX/*************************************************************
XX * vt100 terminal emulator - XMODEM protocol support
XX *
XX *	v2.5 870214 DBW - more additions (see readme file)
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
XX *	     860901 ACS - Added Parity and Word Length and support code
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#include "vt100.h"
XX
XXint enablexon = TRUE;
XX
XXstatic unsigned long parity_settings[4] = {
XX    0x96696996,
XX    0x69969669,
XX    0x69969669,
XX    0x96696996 };
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    int doxon,i,j,k;
XX
XX    doxon = enablexon;
XX    if (doxon) No_XON();
XX    switch (p_parity) {
XX	case 0:	/* no parity */
XX	rs_out[0] = ch & 0xFF;
XX	break;
XX
XX	case 1: /* mark */
XX	rs_out[0] = (ch & 0x7F) | 0x80;
XX	break;
XX
XX	case 2: /* space */
XX	rs_out[0] = ch & 0x7F;
XX	break;
XX	
XX	case 3:	/* even */
XX	case 4: /* odd  */
XX        i     = (ch >> 5) & 0x3;
XX	j     = ch & 0x1F;
XX	k     = ((parity_settings[i] >> j) & 0x1) << 7;
XX	if (p_parity == 3)			/* even parity */
XX	    rs_out[0] = (ch & 0x7F) | k;
XX	else					/* odd parity */
XX	    rs_out[0] = (ch & 0x7F) | (k ^ 0x80);
XX	}
XX    DoIO(Write_Request);
XX    if (doxon) Do_XON();
XX    }
XX
XX/* send a break to the host */
XXvoid sendbreak() {
XX    AbortIO(Read_Request);
XX    Read_Request->IOSer.io_Command = SDCMD_BREAK;
XX    DoIO(Read_Request);
XX    Read_Request->IOSer.io_Command = CMD_READ;
XX    SendIO(Read_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	    SendIO(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	         req("ERROR:","User aborted transfer",0);
XX	         timeout = USERABORT;
XX                 return('\0');
XX	         }
XX            continue;
XX            }
XX        if (rd == FALSE && CheckIO(&Timer)) {
XX            req("ERROR","Timeout waiting for character",0);
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 & (p_parity == 0 ? 0xFF : 0x7F));
XX    }
XX
XXvoid No_XON() {
XX
XX    /* turn off XON/XOFF processing */
XX    enablexon = FALSE;
XX    Write_Request->io_SerFlags |= SERF_XDISABLED;
XX    Write_Request->IOSer.io_Command = SDCMD_SETPARAMS;
XX    DoIO(Write_Request);
XX    Write_Request->IOSer.io_Command = CMD_WRITE;
XX    }
XX
XXvoid Do_XON() {
XX    /* turn on XON/XOFF processing */
XX    enablexon = TRUE;
XX    Write_Request->io_SerFlags &= ~SERF_XDISABLED;
XX    Write_Request->IOSer.io_Command = SDCMD_SETPARAMS;
XX    DoIO(Write_Request);
XX    Write_Request->IOSer.io_Command = CMD_WRITE;
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 scrstr[40],scrstr2[40];
XX    bytes_xferred = 0L;
XX    ttime = TTIME_SHORT;
XX
XX    if ((fd = creat(file, 0)) < 0)
XX	{
XX	req("XMODEM Can't Open File:",file,0);
XX	return FALSE;
XX	}
XX    else
XX    strcpy(scrstr,"XMODEM Receive, <esc> to abort");
XX    req(scrstr,"",0);
XX
XX    sectnum = errors = bufptr = 0;
XX    sendchar(NAK);
XX    firstchar = 0;
XX    No_XON();
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		    Do_XON();
XX		    return FALSE;
XX		}
XX	    } while (firstchar != SOH && firstchar != EOT);
XX
XX	if  (firstchar == SOH)
XX	    {
XX	    sprintf(scrstr2,"Getting Block %4d...",sectnum);
XX	    req(scrstr,scrstr2,0);
XX	    sectcurr = readchar();
XX	    if (timeout != GOODREAD) { Do_XON(); return FALSE; }
XX	    sectcomp = readchar();
XX	    if (timeout != GOODREAD) { Do_XON(); 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) { Do_XON(); return FALSE; }
XX			checksum = (checksum + bufr[j]) & 0xff;
XX			}
XX		    if (checksum == readchar() && timeout == GOODREAD)
XX			{
XX			errors = 0;
XX			sprintf(scrstr2,"Block %4d verified",sectnum);
XX			sectnum++;
XX			bufptr += SECSIZ;
XX			bytes_xferred += SECSIZ;
XX			req(scrstr,scrstr2,0);
XX			if (bufptr == BufSize)
XX			    {
XX			    if (write(fd, bufr, BufSize-128) == EOF)
XX				{
XX				req(scrstr,"Error Writing File",0);
XX				Do_XON();
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) { Do_XON(); 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) {
XX			    Do_XON();
XX			    return FALSE;
XX			    }
XX			req(scrstr,"Received Duplicate Sector",0);
XX			sendchar(ACK);
XX			}
XX		    else errorflag = TRUE;
XX    		    }
XX		}
XX	    else errorflag = TRUE;
XX	    }
XX	if (errorflag == TRUE)
XX	    {
XX	    errors++;
XX	    req(scrstr,"Error",0);
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	Do_XON();
XX	return TRUE;
XX	}
XX    Do_XON();
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 scrstr[40],scrstr2[40];
XX    bytes_xferred = 0;
XX    ttime = TTIME_LONG;
XX
XX    if ((fd = open(file, 0)) < 0) {
XX	req("XMODEM","Cannot Open Send File",0);
XX	return FALSE;
XX	}
XX    else
XX    strcpy(scrstr,"XMODEM Send, <esc> to abort");
XX    req(scrstr,"",0);
XX    attempts = 0;
XX    sectnum = 1;
XX    No_XON();
XX    /* wait for sync char */
XX    j=1;
XX    while (((c = readchar()) != NAK) && (j++ < ERRORMAX))
XX	if (timeout == USERABORT) { Do_XON(); return(FALSE); }
XX    if (j >= (ERRORMAX))
XX	{
XX	req(scrstr,"Receiver not sending NAKs",0);
XX	Do_XON();
XX	return FALSE;
XX	}
XX
XX    while ((bytes_to_send = read(fd, bufr, BufSize)) && 
XX	    attempts != RETRYMAX)
XX	{
XX	if (bytes_to_send == EOF)
XX	    {
XX	    req(scrstr,"Error Reading File",0);
XX	    Do_XON();
XX	    return FALSE;
XX	    }
XX
XX	bufptr = 0;
XX	while (bytes_to_send > 0 && attempts != RETRYMAX)
XX	    {
XX	    attempts = 0;
XX	    sprintf(scrstr2,"Sending block %4d",sectnum);
XX	    do {
XX		req(scrstr,scrstr2,0);
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) {
XX		    req(scrstr,"ABORTED",0);
XX		    Do_XON();
XX		    return FALSE;
XX		    }
XX		} while ((c != ACK) && (attempts != RETRYMAX));
XX	    bufptr += size;
XX	    bytes_xferred += size;
XX	    sprintf(scrstr2,"Sent block %4d",sectnum);
XX	    req(scrstr,scrstr2,0);
XX	    sectnum++;
XX	    }
XX	}
XX    close(fd);
XX    if (attempts == RETRYMAX)
XX	{
XX	req(scrstr,"No Acknowledgment, ABORTING",0);
XX	Do_XON();
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	    req(scrstr,"NO END OF FILE",0);
XX	}
XX    Do_XON();
XX    return TRUE;
XX    }
XX
XX/* allow for multi file xfers separated by commas under
XX    kermit and XMODEM */
XX
XXvoid multi_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    if (name[0] == '$' && name[1] == '\0') {
XX	saybye();
XX	return;
XX	}
XX    p = name;
XX    while(*p == ' ') p++;
XX    while(*p && *p != ',' && *p != ' ') p++;
XX    if (*p == '\0')   done = TRUE;
XX    else	      multi = 1;
XX    *p = '\0';
XX
XX    status = ((*mode)(name, multi));
XX    if (status == FALSE) close(fd);
XX    if (!done && timeout != USERABORT) multi_xfer(++p, mode, do_send);
XX    else emit('\n');
XX    server = 0;
XX    multi = 0;
XX    }
XX
SHAR_EOF
if test 9802 -ne "`wc -c xmodem.c`"
then
echo shar: error transmitting xmodem.c '(should have been 9802 characters)'
fi
#	End of shell archive
exit 0

wecker@cookie.dec.com.UUCP (02/24/87)

#	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
#	newbindings.asm
# This archive created: Sun Feb 22 23:51:51 1987
echo shar: extracting readme
sed 's/^XX//' << \SHAR_EOF > readme
XXThis archive contains a vt100 emulator with KERMIT and XMODEM file
XXtransfer protocols by Dave Wecker (V2.6 DBW 870227).
XX
XXThanks:
XX-------
XX	To everyone who sent in code and suggestions!
XX
XXReleases:
XX---------
XX	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
XX	v2.5 870214 DBW - more additions (see readme file)
XX	v2.4 861214 DBW - lots of fixes/additions
XX	v2.3 861101 DBW - minor bug fixes
XX	v2.2 861012 DBW - more of the same
XX 	v2.1 860915 DBW - new features (see README)
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.6 870227 DBW - bug fixes for all the stuff in v2.5
XX	- Input requestors are now self selecting (ignore comment in 2.5)
XX	- Added a BS<->DEL menu item and startup option (SWAP ON/OFF)
XX	- Renamed dopen/dnext/dclose to diropen/dirnext/dirclose for LATTICE
XX	- Added a CONVERT option that tells whether KERMIT should downcase
XX	- MAJOR CHANGE: re write the INPUT/SCRIPT commands, see VT100.DOC
XX	- Fixed a major problem with Set Directory causing LOCK conflicts
XX	- Moved the Title up 1 pixel so that it doesn't get cut off anymore
XX
XXv2.5 870214 DBW - more additions (see readme file)
XX	- All prompting now done through a string requester/gadget.
XX	  NOTE: YOU MUST SELECT THE INPUT STRING OF THE REQUESTER BEFORE
XX		YOU CAN TYPE A RESPONSE.
XX	- Local echo mode added (half duplex for Carolyn)
XX	- BEEP command added to SCRIPT
XX	- New menu/init/script items:
XX		CLEAR SCREEN	- clears the screen
XX	 	ECHO		- turns on/off half duplex mode
XX		WRAP		- turns on/off autowrap on long lines
XX		NUMKEY		- turns on/off numeric keypad mode
XX		APPCUR		- turns on/off application cursor mode
XX	- Rewrote toasc() to use qualifier field (no more getting the
XX	  keyboard "stuck")
XX	- Fixed locking of directories (should now run under workbench ok)
XX	- Cleaned up VT100.H to really check includes on compile
XX	- Setting font explicitly to TOPAZ 8 (no more dumb assumptions)
XX
XXv2.4 861214 DBW - lots of fixes/additions
XX	- Beep should now work under Lattice
XX	- CreatePort now passes longs (as it should always have)
XX	- Nested comments in KERMIT.C removed
XX	- Beep volume of 0 (DisplayBeep) now works
XX	- snum[] declaration in KERMIT.C fixed
XX	- multi_xfer is now void and return fixed (in kermit)
XX	- "." can no longer get "stuck" as the break key
XX
XX	- RIGHT-AMIGA-keys have been added for most menu items
XX	- The ALT key is now an EIGHTth bit shifter
XX	- Control-@, Control-2, Control-space send the NULL character
XX	- Control-6 now sends Control-^
XX	- Control-- and Control-? now sends Control-_
XX	- Cursor application mode (<esc>[?1h and <esc>[?1l) now work
XX	- XMODEM now masks the eighth bit if parity is other than NONE
XX
XXv2.3 861101 DBW - minor bug fixes:
XX	- added p_wbcolors to allow workbench colors on custom screen
XX	  (In the init file you can specify WBCOLORS to be NO (use color
XX	   definitions in INIT FILE or VT100.H) or YES (use WORKBENCH
XX	   colors for everything)).
XX	- "$" now sends a kermit-bye (like it says in VT100.DOC).
XX	- made window/screen heights more reasonable
XX	- Added ANSI insert line and delete line (<csi><num>L and
XX	  <csi><num>M) to speed up various editors (like emacs).
XX	  NOTE: This is NOT a VT100 sequence (new extension).
XX	- ctrl-space now also sends a null (along with ^@ and ^`)
XX	- RAWKEY fixed in WINDOW.C
XX	- p_wrap fixed in WINDOW.C
XX	- removed WRDMAX from VT100.H
XX	- fixed exit with no params in SCRIPT.C
XX	- fixed parity comparisons in KERMIT.C
XX	- init file [n+1] changed to [nplus1] to make Lattice happy.
XX	- cursoron(), cursoroff() changed to one routine cursorflip().
XX	- long lines shortened to less than 80 characters (for gateways).
XX	- blanks following exit (or comments) now work in scripts.
XX
XXv2.2 861012 DBW - more of the same:
XX	- The INIT file "exit" can now chain to a script
XX	- The SCRIPT command "exit" can now chain to another script
XX	- Hangup menu item now works.
XX	- Autowrap can now be set from VT100.H, VT100.INIT (<esc>[?7h l)
XX	- Control-G is now handled with an audible beep
XX	- Script now used "^chr" to send control characters
XX	- The graphics "box" character (a) was added
XX	- Control-@ and Control-` now send the NULL character
XX	- Alternate color for BOLD has been re-instated by popular demand
XX	- Menus have been cleaned up.
XX	- Lattice compilation cleaned up.
XX	- No more wordsize parameter since PARITY takes care of all cases
XX	- Function keys can now call scripts
XX	- Double shift keys are now handled correctly.
XX	- Version has been added to the title bar (for bug reports).
XX
XXv2.1 860915 DBW - new features / bug fixes
XX	- Now identifies as a VT100 (including the response to <esc>Z)
XX	- Cursor color now gets read in as hex (instead of decimal)
XX	- REPORTMOUSE taken out of definitions (not needed)
XX	- XON/XOFF now being handled by the device driver instead of me
XX	- Literal escape characters have been replaced with \033
XX	- At init time the user can now specify the input BUFFER size
XX	  (typically between 512 and 2048 bytes) depending on baud rate
XX	- Script files are now case insensitive for commands
XX	- XMODEM now turns off the driver XON/XOFF during transfers
XX	- Graphic rendition now done by the OS instead of me.
XX	- Initialization files are now searched for in S: instead of C:
XX	- Forward GOTO bug fixed in the script package.
XX	- Keypad can now be used in both numeric and application mode
XX	- General purpose cleanup() routine added for all exits.
XX	- Utility menu added (sendbreak, hangup, change directory).
XX	  NOTE: hangup is not implemented yet.
XX	- Full wild card support in file transfers (see vt100.doc).
XX	- Kermit cleaned up with better filename handling (from host).
XX	- Script now has CD (changed directory) and SB (send break) commands
XX	- Added Parity and Wordsize choices in VT100.H, VT100.INIT, menu
XX	  and scripts. (Generates parity from a table).
XX	- Added 8th bit quoting in KERMIT when using 7 bit words (ODD or
XX	  EVEN parity).
XX	- Break time can be set from VT100.H, VT100.INIT or a script file.
XX	- Transfer mode (image or CRLF) can now be set from a script file.
XX	- Control characters in escape sequences now act like a true VT100.
XX	- F10 now works from init files.
XX	- Right (or Left) AMIGA with period (".") sends a BREAK to the host
XX	  from the keyboard.
XX	- XMODEM status kept down to one line for a file transfer.
XX
XXv2.0 860823 DBW	- Major rewrite:
XX	- Emulator now compiles under either MANX or LATTICE by defining
XX	  the appropriate compiler type in VT100.H.
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	- Added XON/XOFF generation so that characters should not get lost
XX	  any more at 9600 baud (when receiving clear text).
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	  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	- 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	- 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	- WORKBENCH colors are NEVER touched.
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	- 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	- File capture now no longer sends the filename to the host.
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	- UNDERLINE (<esc>[4m) has now been added.
XX	- The handling of remote (host) escape sequences has been completly
XX	  re-written (thanks to Dawn Banks for all the work).
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	- Cursor has no been reduced to the size of a normal character for
XX	  easier readability.
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	- KERMIT has been completely re-written and appears to work fine,
XX	  thanks to the efforts of Steve Drew.
XX	- New menu item allows script file support. Module written by
XX	  Steve Drew. See VT100.DOC for details.
XX
XXKnown problems:
XX---------------
XX	none
XX
XXSuggestions/bug fixes not implemented (as of yet):
XX--------------------------------------------------
XX	- Custom screen should use a borderless backdrop window
XX	- Quit from keyboard should be supported (for above)
XX	- Automatic maximum sizing of window should happen
XX	- Screen should be resizable
XX	- AT TIME should be implemented in scripts (besides DELAY)
XX	- Amiga keys for script execution/abort
XX	- Alternate execute of script files through the S: directory
XX	- Command line arguments to allow for scripts
XX	- Kermit toggle to leave file names alone
XX	- Kermit should create sub directories (when necessary)
XX	- Use the system keymap
XX	- Use a disk font for graphic character set
XX	- Allow the mouse to be sent to the host (for various EMACSs)
XX	- Kermit VM/CMS (IBM) protocol support
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
XX	REMEMBER: Set the correct compiler definition in VT100.H
XX
XXFiles:
XX------
XX	README		- this file
XX	vt100.doc	- documentation for the terminal emulator
XX	makefile	- make file for the emulator (under MANX AZTEC-C)
XX	vt100.h		- include file used by all other modules
XX	window.c	- manager for window and keyboard
XX	vt100.c		- main module, handles menus
XX	remote.c	- handle remote characters (vt100 emulation)
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	init.c		- startup code
XX	xmodem.c	- xmodem protocol that understands AMIGA binary and
XX			  text file formats (automatically).
XX	script.c	- script control package
XX	expand.c	- filename expansion (wildcards) and dir setting
XX
XXContact:
XX--------
XXPlease send bugs/comments/suggestions/praise 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 10834 -ne "`wc -c readme`"
then
echo shar: error transmitting readme '(should have been 10834 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.6 DBW 870227). Comments/suggestions/bugs/problems/praise
XXshould be 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
XXMANY pieces of code/suggestions have been sent in..
XX
XX	thanks to all!
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 the specified
XX		  "initfile", then VT100.INIT (in the current directory)
XX		  and finally S:VT100.INIT. The format for the init file
XX		  is described 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.C as variables,
XX		  beginning with "p_") are used.
XX
XX		- All commands are either menu or script based. Scripts
XX		  are described below.
XX
XXMenus (Commands in parenthesis are keyboard bindings: Right-Amiga-chr):
XX-----------------------------------------------------------------------
XXFile 	  			- file transfers
XX	Ascii Capture		- Begin/end a script of the current session
XX	Ascii Send		- Type a file to the host
XX	Xmodem Receive	(A-V)	- Receive a file using XMODEM protocol
XX	Xmodem Send	(A-^)	- Send    a file using XMODEM protocol
XX	Kermit Get	(A-G)	- Receive files from a host KERMIT SERVER
XX	Kermit Receive	(A-R)	- Receive files from a host KERMIT
XX	Kermit Send	(A-S)	- Send    files to   a host KERMIT [SERVER]
XX	Kermit Bye	(A-B)	- Terminate a host KERMIT SERVER
XXComm Setup			- Setup communications
XX	Baud Rate		- Set the terminal baud rate
XX		300, 
XX		1200,	(A-L)
XX		2400,	(A-H)
XX		4800,
XX		9600
XX	Parity			- Type of parity
XX		NONE, 	(A-X)
XX		MARK,
XX		SPACE,
XX		EVEN,	(A-E)
XX		ODD	(A-O)
XX	Xfer Mode
XX		Image	(A-I)	- Send files verbatim (for UNIX hosts or
XX				  binary files)
XX		Text	(A-T)	- Send CR LF as line terminator and strip
XX				  CR on received files (VMS text).
XX		Convert		- Should KERMIT convert fnames to lower case
XXScript 	  			- Script commands
XX	Execute file		- Start up an asynchronous script file
XX	Abort Execution		- Terminate a script file
XXUtility   			- Utility commands
XX	Send Break	(A-.)	- send a break to the host
XX	Hang Up			- close line (not implemented yet)
XX	Change Dir	(A-D)	- change the local directory (for transfers)
XX	Clear Scrn		- clear the screen (initial state)
XX	Echo			- turn on/off half duplex mode
XX	Wrap		(A-W)	- turn on/off long line wrapping mode
XX	Num Key		(A-K)	- turn on/off numeric keypad mode
XX	App Cur		(A-C)	- turn on/off application cursor mode
XX	BS<->DEL	(A-Z)	- swap backspace and delete keys
XX
XXKeypad mapping (in application keypad mode):
XX--------------------------------------------
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
XXNote:	Right AMIGA key in conjunction with a period (".")
XX	will send a break to the host.
XX
XX	CTRL in conjunction with an at-sign ("@") a two ("2") or a
XX	space (" ") will send a NULL to the host.
XX
XX	CTRL in conjunction with a six  ("6") will send a CTRL-^
XX	CTRL in conjunction with a dash ("-") or question mark ("?")
XX		will send a CTRL-_ to the host.
XX
XXMulti file Xfers:
XX-----------------
XXThe VT100 emulator supports multiple file transfers. This is
XXspecified by using a comma (",") between file names when using XMODEM
XXor KERMIT. (NOTE: host XMODEM's normally CANNOT support multiple file
XXtransfers).
XX
XXWhen specifying a file name to recieve by default the directory path
XXis stripped off of the filename when sent to the host but is kept for the
XXlocal file 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
XXnewfile.bin and put it on df1: (see explanation of "$" below). If you
XXdo a single file transfer you will get another prompt for the remote
XXname 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
XXthe desired directory.
XX
XXIn addition KERMIT supports wildcards:
XX    * = any number of characters
XX    ? = any single character
XXExamples:
XX	send:	*.c,*.h,*.doc
XX	get:	*.c,*.h,$
XX
XXKERMIT receive is now smart enough to use the host filename so no
XXfilename needs to be specified on the AMIGA's side (see the CONVERT option).
XX
XXInitialization and Script file operation:
XX-----------------------------------------
XXAn initialization file (as described in the "Program Startup" section)
XXmay contain any of the commands shown below that have the word INIT in
XXtheir description below. Commands that are available from scripts have
XXthe word SCRIPT in the descriptions below. All commands may be abbreviated
XXto 3 letters and are case insensitive.
XX
XXThe script file can be invoked by selecting 'execute file' from the
XXscript menu. At any time you can abort the script file by selecting
XX'Abort Execution'. You may also invoke a script from a function key if
XXthe first character of the function key definition is the KEYSCRIPT
XXcharacter (e.g., define F5 as "~df1:foo.script").
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
XXdesired if your script file is WAITing for a string or is DELAYing for
XXa period of time etc.
XX
XXInitialization and Script file Commands:
XX----------------------------------------
XX#	Commented line					(INIT,SCRIPT)
XX   Format:
XX	# This line is a comment
XX------------------------------------------------------------
XXAPPCUR	Set the application cursor mode			(INIT,SCRIPT)
XX   Format:
XX	APPCUR	ON/OFF or YES/NO
XX------------------------------------------------------------
XXASCII_SEND Send an ascii file to the host.		(SCRIPT)
XX   Format:
XX	(same format as CAPTURE)
XX------------------------------------------------------------
XXBACKGROUND Define a background color			(INIT)
XX   Format:
XX	BACKGROUND hex		three digit hex number
XX   Example:
XX	BACKGROUND F00		bright red background
XX------------------------------------------------------------
XXBAUD 	Set baud rate					(INIT,SCRIPT)
XX   Format:
XX	BAUD rate		Sets the baud rate for send/receive
XX   Example:
XX	BAUD 2400		Sets the baud rate at 2400 baud
XX------------------------------------------------------------
XXBEEP	Beep at the console				(SCRIPT)
XX   Format:
XX	BEEP
XX------------------------------------------------------------
XXBOLD 	Define a color for bold				(INIT)
XX   Format:
XX	(same as BACKGROUND)
XX------------------------------------------------------------
XXBREAK	Set the break time (for an SB command)		(INIT,SCRIPT)
XX   Format:
XX	BREAK value		Value is in micro-seconds
XX   Example:
XX	BREAK 750000
XX------------------------------------------------------------
XXBUFFER 	Set transmission buffer size			(INIT)
XX   Format:
XX	BUFFER n		Number of bytes to buffer
XX   Example:
XX	BUFFER 512
XX------------------------------------------------------------
XXCAPTURE	To start/stop ascii file capture.		(SCRIPT)
XX   Format:
XX	CAPTURE	file		Start ascii capturing
XX	CAPTURE			End ascii capturing
XX------------------------------------------------------------
XXCD 	To change the local directory			(SCRIPT)
XX   Format:
XX	CD	newdir		set a new directory for file transfers
XX   Example:
XX	CD	DF1:foo/bar	set the directory as specified
XX------------------------------------------------------------
XXCONVERT	Tell KERMIT whether or not to convert filenames	(INIT,SCRIPT)
XX   Format:
XX	CONVERT	ON/OFF or YES/NO
XX   Example:
XX	CONVERT	ON		Filenames will be down cased
XX------------------------------------------------------------
XXCURSOR 	Define a color for the cursor			(INIT)
XX   Format:
XX	(same as BACKGROUND)
XX------------------------------------------------------------
XXDELAY 	Suspends script file for a specified time	(SCRIPT)
XX   Format:        
XX        DELAY 	n		Suspends execution for n seconds
XX   Example:
XX	DELAY	2		Suspends for 2 seconds
XX------------------------------------------------------------
XXDEPTH 	Define the depth of the window/screen		(INIT)
XX   Format:
XX	DEPTH n		Number of planes in window/screen
XX   Example:
XX	DEPTH 1		Minimum depth
XX	DEPTH 2		Same as Workbench
XX------------------------------------------------------------
XXECHO	Turn on/off local echo				(INIT,SCRIPT)
XX   Format:
XX	ECHO	ON/OFF or YES/NO
XX   Example:
XX	ECHO	ON		Half duplex mode
XX------------------------------------------------------------
XXEXIT	Ends execution of the current script file.	(INIT,SCRIPT)
XX   Format:
XX	EXIT			Exit the current script/init file
XX	EXIT VT100		Exit vt100 program (from SCRIPT only)
XX	EXIT newscript		Exit this file and start up newscript
XX   Example:
XX	EXIT DF1:FOO.BAR	Exit the current file and start FOO.BAR
XX------------------------------------------------------------
XXF	Define a function key				(INIT,SCRIPT)
XX   Format:
XX	F n string		Define Function key n to be string
XX   Example:				(see SEND for string format)
XX	F 1 "dir^M"		Define F1 is the string dir<cr>
XX	F 11 "help"		Define Shifted F1 as the string help
XX	F 20 ^C			Define Shifted F10 as a control-C
XX------------------------------------------------------------
XXFOREGROUND Define a color for the foreground		(INIT)
XX   Format:
XX	(same as BACKGROUND)
XX------------------------------------------------------------
XXGOTO	Jumps to a different part of the script file.	(SCRIPT)
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	...
XX	GOTO FOO		Jumps to FOO
XX------------------------------------------------------------
XXINTERLACE Turn on/off interlace				(INIT)
XX   Format:
XX	INTERLACE ON/OFF or YES/NO
XX   Example:
XX	INTERLACE ON		Use interlacing
XX------------------------------------------------------------
XXKB  	Send a BYE packet to a host KERMIT server.	(SCRIPT)
XX   Format:
XX	KB 			Shut down server.
XX------------------------------------------------------------
XXKEYSCRIPT Define a new keyscript character		(INIT,SCRIPT)
XX   Format:
XX	KEYSCRIPT hex		New character in hex
XX   Example:
XX	KEYSCRIPT 7E		Use "~" as the new character
XX------------------------------------------------------------
XXKG  	Gets files from host.				(SCRIPT)
XX   Format:
XX	(same format as KS)	 Get from server
XX------------------------------------------------------------
XXKR  	Receives a file from kermit host.		(SCRIPT)
XX   Format:
XX	(same format as KS)	 Not from a server
XX------------------------------------------------------------
XXKS  	Sends files via kermit to the host.		(SCRIPT)
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------------------------------------------------------------
XXLINES	Define number of lines in the window		(INIT)
XX   Format:
XX	LINES n
XX   Example:
XX	LINES 24		Maximum for non-interlace
XX	LINES 48		Maximum for interlaced
XX------------------------------------------------------------
XXMODE	Set a transfer mode for KERMIT to use		(INIT,SCRIPT)
XX   Format:
XX	MODE type		type of transfers to perform
XX   Example:
XX	MODE IMAGE		image mode transfers
XX	MODE CRLF		<CR><LF> text transfers (VMS Kermit).
XX------------------------------------------------------------
XXNUMKEY	Numeric keypad mode				(INIT,SCRIPT)
XX   Format:
XX	NUMKEY	ON/OFF or YES/NO
XX   Example:
XX	NUMKEY	ON		Keypad is pure numbers
XX------------------------------------------------------------
XXON	Peforms a command every time string is received	(SCRIPT)
XX   Format:
XX        ON      "string"  cmd	Execute cmd when string is received.
XX				Only one ON string may be installed at a
XX				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------------------------------------------------------------
XXPARITY	Sets the parity					(INIT,SCRIPT)
XX   Format:
XX	PARITY	type		Set the parity type
XX   Example:
XX	PARITY	NONE		no parity
XX	PARITY	MARK		mark parity
XX	PARITY	SPACE		space parity
XX	PARITY	ODD		odd parity
XX	PARITY	EVEN		even parity
XX------------------------------------------------------------
XXSB	Sends a break character to the host		(SCRIPT)
XX   Format:			Note that any pending character to send
XX	SB				is aborted by this call
XX------------------------------------------------------------
XXSCREEN	Define the screen type				(INIT)
XX   Format:
XX	SCREEN type		type of screen to use
XX   Example:
XX	SCREEN WORKBENCH	use the workbench screen
XX	SCREEN CUSTOM		use a custom screen
XX------------------------------------------------------------
XXSEND 	Sends a string or character to the host.	(SCRIPT)
XX   Format:
XX	SEND    "string"	Sends a string to the host. Beginning and
XX				ending double quotes (") are required. A
XX				carat (^) may be used to send control chars.
XX				Two carats transmits a carat character.
XX        SEND    chr           	Sends a single character.
XX        SEND    ^chr   	    	Sends a single control character. The chr
XX				is NOT case sensitve
XX   Example:
XX	SEND	"mail"		Send the string mail
XX	SEND    "dir^M"		Send the string dir followed by a <CR>
XX	SEND	a		Send the letter a
XX	SEND	^C		Send a control C
XX	SEND	"abc^^def"	Send the string abc^def
XX	SEND	^^		Send a control-uparrow
XX	SEND	"		Send the '"' character
XX------------------------------------------------------------
XXSWAP 	Swap the meanings of backspace and delete keys	(INIT,SCRIPT)
XX   Format:
XX	SWAP ON/OFF or YES/NO
XX   Example:
XX	SWAP NO		Use standard definitions
XX------------------------------------------------------------
XXVOLUME	Set the BELL volume				(INIT)
XX   Format:
XX	VOLUME n
XX   Example:
XX	VOLUME 0		Use a visual bell
XX	VOLUME 64		Use a loud audible bell
XX------------------------------------------------------------
XXWAIT 	Suspends until a certain string is received.	(SCRIPT)
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 be aborted via the script menu.
XX   Example:
XX        WAIT    "User:"    	Waits for the string User:
XX------------------------------------------------------------
XXWBCOLORS Force usage of workbench colors		(INIT)
XX   Format:
XX	WBCOLORS ON/OFF or YES/NO
XX   Example:
XX	WBCOLORS YES		Workbebch colors will be used for all
XX------------------------------------------------------------
XXWRAP	Set long line wrapping				(INIT,SCRIPT)
XX   Format:
XX	WRAP	ON/OFF or YES/NO
XX   Example:
XX	WRAP	ON		Long lines will wrap
XX------------------------------------------------------------
XXXR  	Receives a file via XMODEM.			(SCRIPT)
XX   Format:
XX	(same format as KS)
XX------------------------------------------------------------
XXXS  	Sends a file via XMODEM.			(SCRIPT)
XX   Format:
XX	(same format as KS)
XX------------------------------------------------------------
XX
XX
XX----------------------------
XXInitialization file example:
XX----------------------------
XX
XX#####################################################################
XX#
XX#	VT100 sample initialization file
XX#	v2.6 870222 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.C
XX# (all variables in vt100.c have a "p_" prepended to them)
XX#
XX#####################################################################
XX#
XXAPPCUR		ON		# Application keypad mode is being used
XXBACKGROUND	000		# Colors are in hex RGB from 000 to FFF
XXBAUD		2400		# Anything after required fields is ignored
XXBOLD		a00		# Color for bold highlighting (in custom)
XXBREAK		750000		# Break time in micro-seconds
XXBUFFER		512		# 512 <= Input buffer size <= 2048
XXCONVERT		ON		# KERMIT should downcase host names
XXCURSOR		00a		# Color for cursor (in custom screen)
XXDEPTH		1		# number of bit planes to use (1 or 2)
XXECHO		OFF		# Full duplex mode in use
XXFOREGROUND	950		# Colors are only used on the custom screen
XXINTERLACE	ON		# ON for CUSTOM or interlaced workbench
XXKEYSCRIPT	7E		# Hex value for script introducer
XXLINES		48		# normal <= 24 interlaced <= 48
XXMODE		CRLF		# IMAGE or CRLF (for KERMIT transfers)
XXNUMKEY		ON		# The keypad should be numeric
XXPARITY		NONE		# NONE (= 8 bit), MARK, SPACE, ODD or EVEN
XXSCREEN		CUSTOM		# may be CUSTOM or WORKBENCH
XXSWAP		OFF		# Don't Swap the Back-space and Delete keys
XXVOLUME		64		# Beep Volume (0 = Visual Beep)
XXWBCOLORS	YES		# ignore custom colors and use defaults
XXWRAP		OFF		# Auto wrap ON or OFF
XX#
XX# Function bindings (strings to type when any of F1 - F10 are pressed)
XX#	f <num>		= function key
XX#	f <num>+10	= shifted function key
XX#
XX# The string specified must be the same format as the SEND command:
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# If the first character of the string is a script introducer
XX# (KEYSCRIPT) then the string is interpreted as a script filename
XX# to be executed when the key is pressed.
XX#
XX# Examples of bindings:
XX#
XXf 1	"^[OP"			# f1-f4 = PF1 - PF4 on a VT100
XXf 2	"^[OQ"
XXf 3	"^[OR"
XXf 4	"^[OS"
XX#
XX# f5,6,7 = scripts to execute (assuming that KEYSCRIPT = '~' = 0x7E)
XX#
XXf 5	"~df1:vt100_source/dialwork.script"
XXf 6	"~df1:vt100_source/sendvt100.script"
XXf 7	"~df1:vt100_source/getpics.script"
XX#
XXf 8	"MAIL^M"		# Reads my mail (note embedded <CR>)
XXf 9	"NOTE^M"		# Reads conferences
XXf 11	"$2400!"		# dials the phone to work
XXf 12	"$bbs1!"		# dials the phone to billboard 1
XXf 13	"$bbs2!"		# dials the phone to billboard 2
XXf 14	"$bbs3!"		# dials the phone to billboard 3
XX#
XX# all done with init, now execute script as startup sequence
XX#
XXexit df1:vt100_source/dialwork.script
XX
XX--------------------
XXScript file example:
XX--------------------
XX
XX###################################################################
XX# Script to dial work (dialwork.script)
XX#	v2.6	870222	DBW
XX###################################################################
XX#
XX# Make sure that we have all the parameters we want
XX#
XX	DELAY	2
XX	BAUD	2400
XX	PARITY	NONE
XX	MODE	CRLF
XX	BREAK	750000
XX	SB
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 ^M
XX	GOTO Login
XX#
XX# Now connect from the Gandalf to the terminal server (ts2):
XX# (when it asks for a password I need to type the password 
XX# manually here)
XX#
XXGandalf:
XX	DELAY 2
XX	SEND "ts2^M"
XX	WAIT "class start"
XX#
XX# Keep sending <CR>'s until the LAT prompts for a username:
XX#
XXWaitLat:
XX	DELAY 2
XX	ON "username>" GOTO Lat
XX	SEND ^M
XX	GOTO WaitLat
XX#
XX# Tell the LAT that it's me, and connect to the "cookie cluster"
XX# (my host systems). Tell the cluster my user name.
XX# (when it asks for a password I need to type the password
XX# manually here)
XX#
XXLat:
XX	SEND "wecker^M"
XX	DELAY 1
XX	SEND "connect cookie^M"
XX	WAIT "Username:"
XX	SEND "WECKER^M"
XX	WAIT "at home"
XX	SEND "^M^Mn^M"
XX#
XX# Got through all the LOGIN garbage, so let's do some work.
XX#
XX	WAIT "$ "
XX#
XX# All done so stop:
XX#
XX	EXIT
XX
SHAR_EOF
if test 19931 -ne "`wc -c vt100.doc`"
then
echo shar: error transmitting vt100.doc '(should have been 19931 characters)'
fi
echo shar: extracting makefile
sed 's/^XX//' << \SHAR_EOF > makefile
XX######################################################################
XX#
XX# Makefile to build vt100 terminal emulator
XX#
XX#	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
XX#	v2.5 870214 DBW - more additions (see readme file)
XX#	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX#	v2.3 861101 DBW - minor bug fixes
XX#	v2.2 861012 DBW	- more of the same
XX#	v2.1 860915 DBW - new features (see README)
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# Don't forget to define the right compiler (MANX or LATTICE) in VT100.H
XX#
XX######################################################################
XX
XXOBJS	= vt100.o init.o window.o xmodem.o remote.o \
XX	  kermit.o script.o expand.o newbindings.o
XX
XXvt100	: vt100.syms $(OBJS)
XX	ln -v -o vt100 $(OBJS) df0:lib/c.lib
XX
XXvt100.syms : vt100.h
XX	cc -A +Hvt100.syms vt100.h
XX
XXvt100.o	: vt100.c
XX	cc +Ivt100.syms vt100.c
XX
XXinit.o	: init.c
XX	cc +Ivt100.syms init.c
XX
XXwindow.o : window.c
XX	cc +Ivt100.syms window.c
XX
XXxmodem.o : xmodem.c
XX	cc +Ivt100.syms xmodem.c
XX
XXremote.o : remote.c
XX	cc +Ivt100.syms remote.c
XX
XXkermit.o : kermit.c
XX	cc +Ivt100.syms kermit.c
XX
XXscript.o : script.c
XX	cc +Ivt100.syms script.c
XX
XXexpand.o : expand.c
XX	cc +Ivt100.syms expand.c
XX
XXnewbindings.o : newbindings.asm
XX	as newbindings
XX
XX
SHAR_EOF
if test 1399 -ne "`wc -c makefile`"
then
echo shar: error transmitting makefile '(should have been 1399 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 *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
XX *	v2.5 870214 DBW - more additions (see readme file)
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
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/********* major version (used for title of terminal window) *********/
XX#define	VERSION	"VT100 (V2.6 DBW 860227) Terminal Window"
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 <devices/inputevent.h>
XX#include <devices/audio.h>
XX#include <hardware/blit.h>
XX
XX			/* for Lattice you may have to change these with: */
XX#include <stdio.h>	/* #include <lattice/stdio.h> and */
XX#include <ctype.h>	/* #include <lattice/ctype.h>	 */
XX
XX#include <libraries/dos.h>
XX#include <libraries/dosextens.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 TTIME_KERMIT 10	     /* number of seconds for KERMIT timeout*/
XX#define BufSize  0x200       /* Text buffer for XMODEM */
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 COMMAX 3     /* number of communication sub menus */
XX#define RSMAX 5      /* speed menu items */
XX#define PARMAX 5     /* parity items */
XX#define XFMAX 3      /* transfer mode items */
XX#define SCRIPTMAX 2  /* script menu items */
XX#define UTILMAX 9    /* utility menu */
XX#define MAXMENU 4    /* total number of menu entries */
XX
XX#define FSF_REVERSE 256	/* fake font style to flag INVERSVID mode */
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
XX/* things for 'beep' support */
XX#define BEEPSIZE    10L
XX#define BEEPFREQ    1000L
XX#define COLORCLOCK  3579545L
XX
XXextern struct	MsgPort *CreatePort();
XXextern char	*malloc(),*strcpy(),*fgets();
XXextern long	ftell();
XX
XXextern int	multi;		    /* flags multi file transfers */
XXextern int	server;
XXextern char	bufr[BufSize];
XXextern int	fd, timeout, ttime;
XXextern long	bytes_xferred;
XXextern char	MyDir[60];
XXextern struct	FileLock *MyDirLock;
XXextern struct	FileLock *StartLock;
XXextern struct	IntuitionBase *IntuitionBase;
XXextern struct	GfxBase *GfxBase;
XXextern struct	TextAttr myattr;
XXextern struct	TextFont *myfont;
XXextern struct	NewScreen NewScreen;
XXextern struct	NewWindow NewWindow;
XXextern struct	Screen *myscreen;
XXextern struct	Window *mywindow;
XXextern struct	ViewPort *myviewport;
XXextern struct	RastPort *myrastport;
XXextern struct	IntuiMessage *NewMessage;
XXextern struct	Preferences  *Prefs;
XXextern char	InpBuf[80],UndoBuf[80],Prompt[80];
XXextern struct	StringInfo mystrinfo;
XXextern struct	Gadget     mystrgad;
XXextern struct	IntuiText  donetxt;
XXextern struct	Gadget	   mydonegad;
XXextern struct	IntuiText  mystrtxt;
XXextern struct	Requester  myrequest;
XXextern int	numreqs;
XXextern struct	MenuItem FileItem[FILEMAX];
XXextern struct	IntuiText FileText[FILEMAX];
XXextern struct	MenuItem CommItem[COMMAX];
XXextern struct	IntuiText CommText[COMMAX];
XXextern struct	MenuItem RSItem[RSMAX];
XXextern struct	IntuiText RSText[RSMAX];
XXextern struct	MenuItem ParItem[PARMAX];
XXextern struct	IntuiText ParText[PARMAX];
XXextern struct	MenuItem XFItem[XFMAX];
XXextern struct	IntuiText XFText[XFMAX];
XXextern struct	MenuItem ScriptItem[SCRIPTMAX];
XXextern struct	IntuiText ScriptText[SCRIPTMAX];
XXextern struct	MenuItem UtilItem[UTILMAX];
XXextern struct	IntuiText UtilText[UTILMAX];
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;
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 struct	IOAudio Audio_Request;
XXextern struct	MsgPort *Audio_Port;
XXextern UBYTE	*BeepWave;
XXextern UBYTE	Audio_AllocMap[4];
XXextern int	p_baud,p_screen,p_interlace,p_depth,p_buffer,p_wbcolors;
XXextern int	p_foreground,p_background,p_bold,p_cursor,p_lines,p_mode;
XXextern int	p_parity,p_volume,p_wrap,p_echo,p_keyapp,p_curapp,p_bs_del;
XXextern int	p_convert;
XXextern char	p_keyscript;
XXextern long	p_break;
XXextern char	*p_f[10],*p_F[10];
XXextern int	script_on;
XXextern int	script_wait;
XXextern int	doing_init;
XX
XX/* vt100.c */
XXextern int  do_send(),do_capture(),cleanup();
XXextern void setserpar(), setserbaud(), setparams(), redoutil(), redocomm(),
XX	    handle_menupick();
XX
XX/* init.c */
XXextern void InitDevs(),InitFileItems(),InitCommItems(),
XX	 InitScriptItems(),InitUtilItems(),InitMenu();
XXextern char *InitDefaults();
XX
XX/* window.c */
XXextern	void swap_bs_del(),req(),emits(),emit(),emitbatch(),cursorflip();
XXextern	int  toasc();
XX
XX/* xmodem.c */
XXextern	void sendchar(),sendstring(),sendbreak(),multi_xfer(),
XX        No_XON(),Do_XON();
XXextern	int  readchar(),XMODEM_Read_File(),XMODEM_Send_File();
XX
XX/* remote.c */
XXextern	void doremote(),doindex(),doctrl(),doesc(),doerase();
XX
XX/* kermit.c */
XXextern	int	doksend(), dokreceive(), saybye();
XXextern	void	encode(), decode(), rpar(), spar();
XX
XX/* script.c */
XXextern int	script_start(), chk_script(), exit_script(),
XX		do_script_cmd();
XXextern char	*next_wrd(), *tostring();
XX
XX		/* init commands */
XXextern void	cmd_bkg(), cmd_bold(), cmd_buf(), cmd_cursor(), cmd_depth(),
XX		cmd_fore(), cmd_inter(), cmd_lines(), cmd_screen(),
XX		cmd_volume(), cmd_wb(), cmd_null(),
XX
XX		/* script commands */
XX		cmd_as(), cmd_beep(), cmd_cap(), cmd_cd(), cmd_delay(),
XX		cmd_goto(), cmd_goto(), cmd_kb(), cmd_kg(), cmd_kr(),
XX		cmd_ks(), cmd_on(), cmd_sb(), cmd_send(), cmd_wait(),
XX		cmd_xr(), cmd_xs(),
XX
XX		/* init and script commands */
XX		cmd_appcur(), cmd_baud(), cmd_bt(), cmd_conv(), cmd_echo(),
XX		cmd_exit(), cmd_fnc(), cmd_key(), cmd_mode(), cmd_numkey(),
XX		cmd_parity(), cmd_swap(), cmd_wrap();
XX
XX/* expand.c */
XXextern char **expand();
XXextern int  set_dir(), free_expand();
XX
SHAR_EOF
if test 7581 -ne "`wc -c vt100.h`"
then
echo shar: error transmitting vt100.h '(should have been 7581 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 *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
XX *	v2.5 870214 DBW - more additions (see readme file)
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
XX *	     860901 ACS - Added Parity and Word Length and support code
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#include "vt100.h"
XX
XX/**************************************************************/
XX/* here are all the global definitions that appear in vt100.h */
XX/**************************************************************/
XX
XXchar    bufr[BufSize];
XXint     fd, timeout = FALSE, ttime;
XXint	multi = FALSE, server;
XXlong    bytes_xferred;
XXchar	MyDir[60];
XXstruct	FileLock *MyDirLock = NULL;
XXstruct	FileLock *StartLock = NULL;
XXstruct	IntuitionBase *IntuitionBase;
XXstruct	GfxBase *GfxBase;
XX
XXstruct	TextAttr myattr = {
XX    (STRPTR) "topaz.font",
XX    8,
XX    0,
XX    0};
XXstruct	TextFont *myfont = NULL;
XXstruct NewScreen NewScreen = {
XX   0L,0L,640L,200L,1L,       /* left, top, width, height, depth */
XX   0,1,HIRES,    /* DetailPen, BlockPen, ViewModes */
XX   CUSTOMSCREEN,&myattr,   /* Type, Font */
XX   (UBYTE *)"VT100", /* Title */
XX   NULL,NULL };         /* Gadgets, Bitmap */
XXstruct NewWindow NewWindow = {
XX   0,0L,640L,200L,     /* left, top, width, height */
XX   0,1,              /* detailpen, blockpen */
XX   MENUPICK|CLOSEWINDOW|RAWKEY|REQCLEAR|REQSET|ACTIVEWINDOW|INACTIVEWINDOW,
XX   SMART_REFRESH|ACTIVATE|BORDERLESS|WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG,
XX   NULL,NULL,        /* FirstGadget, CheckMark */
XX   (UBYTE *)NULL,
XX   NULL,             /* set screen after open screen */
XX   NULL,             /* bitmap */
XX   640L, 200L, 640L, 200L,/* minw, minh, maxw, maxh */
XX   CUSTOMSCREEN      /* Type */
XX   };
XXstruct IntuiText MyTitle = {
XX    0,1,JAM2,26,0,	/* front pen, back pen, mode, left, top */
XX    &myattr,		/* font */
XX    (UBYTE *)VERSION,	/* title */
XX    NULL};		/* next text */
XXstruct Screen *myscreen = NULL;      /* ptr to applications screen */
XXstruct Window *mywindow = NULL;     /* ptr to applications window */
XXstruct ViewPort *myviewport;
XXstruct RastPort *myrastport;
XXstruct IntuiMessage *NewMessage;    /* msg structure for GetMsg() */
XXstruct Preferences  *Prefs;	    /* preferences from GetPrefs() */
XX
XX/**** String requester support ******/
XX
XXchar	InpBuf[80],UndoBuf[80],Prompt[80];
XXstruct IntuiText donetxt = {
XX    1,0,JAM2,0,0,	/* front pen, back pen, mode, left, top */
XX    &myattr,		/* font */
XX    (UBYTE *)"DONE",	/* question to ask */
XX    NULL};		/* next text */
XXstruct Gadget mydonegad = {
XX    NULL,290,2,40,10,/* next,left,top,width,height */
XX    GADGHCOMP|REQGADGET,/* flags */
XX    RELVERIFY|ENDGADGET,/* activation */
XX    BOOLGADGET,		/* gadget type */
XX    NULL,NULL,&donetxt,	/* gad render, sel render, gad text */
XX    0L,NULL,2,NULL};	/* mutual exclude, special, ID, user data */
XXstruct	StringInfo mystrinfo = {
XX    (UBYTE *)InpBuf,
XX    (UBYTE *)UndoBuf,
XX    0,80,0,0,0,0,	/* initial, max, disp, undo, #chrs, dsp chrs */
XX    0,0,NULL,0L,NULL};	/* left,top,layer,longint,keymap */
XXstruct Gadget mystrgad = {
XX    &mydonegad,10,12,320,10,	/* next,left,top,width,height */
XX    GADGHCOMP|REQGADGET,/* flags */
XX    ENDGADGET,STRGADGET,/* activation, type */
XX    NULL,NULL,NULL,	/* gad render, sel render, gad text */
XX    0L,			/* mutual exclude */
XX    (APTR)&mystrinfo,	/* special info */
XX    1,NULL};		/* gadget ID, user data */
XXstruct IntuiText mystrtxt = {
XX    0,1,JAM2,10,2,	/* front pen, back pen, mode, left, top */
XX    &myattr,		/* font */
XX    (UBYTE *)Prompt,	/* question to ask */
XX    NULL};		/* next text */
XXstruct Requester myrequest = {
XX    NULL,200,40,340,22,	/* older requester, left, top, width, height */
XX    0,0,&mystrgad,	/* relleft reltop, gadgets */
XX    NULL,		/* border */
XX    &mystrtxt,		/* text */
XX    NULL,1,NULL,	/* flags, back fill pen, layer */
XX    {0,0,0,0,0,0,0,0,
XX     0,0,0,0,0,0,0,0,
XX     0,0,0,0,0,0,0,0,
XX     0,0,0,0,0,0,0,0},	/* pad1 */
XX    NULL,NULL,		/* image bit map, rquest window */
XX    {0,0,0,0,0,0,0,0,0,
XX     0,0,0,0,0,0,0,0,0,
XX     0,0,0,0,0,0,0,0,0,
XX     0,0,0,0,0,0,0,0,0} /* pad2 */
XX    };
XXint numreqs = 0;	/* number of outstanding requestors */
XX
XX/***** menu structures *****/
XXstruct MenuItem FileItem[FILEMAX];
XXstruct IntuiText FileText[FILEMAX];
XXstruct MenuItem CommItem[COMMAX];
XXstruct IntuiText CommText[COMMAX];
XXstruct MenuItem RSItem[RSMAX];
XXstruct IntuiText RSText[RSMAX];
XXstruct MenuItem ParItem[PARMAX];
XXstruct IntuiText ParText[PARMAX];
XXstruct MenuItem XFItem[XFMAX];
XXstruct IntuiText XFText[XFMAX];
XXstruct MenuItem ScriptItem[SCRIPTMAX];
XXstruct IntuiText ScriptText[SCRIPTMAX];
XXstruct MenuItem UtilItem[UTILMAX];
XXstruct IntuiText UtilText[UTILMAX];
XXstruct Menu menu[MAXMENU];
XXstruct IOExtSer *Read_Request;
XXchar *rs_in;
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;
XXstruct IOAudio Audio_Request;
XXstruct MsgPort *Audio_Port = NULL;
XXUBYTE  *BeepWave;
XXUBYTE  Audio_AllocMap[4] = { 1, 8, 2, 4 };
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;
XXint  maxcol	= 79;
XX
XX/*************************** defaults *******************************/
XXint	p_baud	     = 2400;	    /* baud rate */
XXint	p_screen     = 1;	    /* 0 = WORKBENCH,	    1 = CUSTOM */
XXint	p_wbcolors   = 1;	    /* 0 = Custom, 1 = Workbench colors */
XXint	p_interlace  = 1;	    /* 0 = no interlace,    1 = interlace */
XXint	p_depth	     = 1;	    /* number of bit planes (1 or 2) */
XXint	p_foreground = 0x950;	    /* default foreground RGB color */
XXint	p_background = 0x000;	    /* default background RGB color */
XXint	p_bold	     = 0x900;	    /* default BOLD       RGB color */
XXint	p_cursor     = 0x009;	    /* default Cursor	  RGB color */
XXint	p_lines	     = 48;	    /* number of lines on the screen */
XXint	p_mode	     = 1;	    /* 0 = image, 1 = CRLF (for kermit) */
XXint	p_buffer     = 512;	    /* read buffer size (>= 512 bytes) */
XXint     p_parity     = 0;	    /* 0=none,1=mark,2=space,3=even,4=odd */
XXlong	p_break	     = 750000;	    /* break time (in micro seconds) */
XXint	p_volume     = 64;	    /* beep volume (0 = DisplayBeep) */
XXint	p_wrap	     = 0;	    /* 0 = truncate, 1 = wrap long lines */
XXint	p_keyapp     = 0;	    /* 0 = numeric, 1 = application keypad */
XXint	p_curapp     = 0;	    /* 0 = cursor, 1 = application cursor */
XXint	p_echo	     = 0;	    /* 0 = full duplex, 1 = half duplex */
XXint	p_bs_del     = 0;	    /* 0 = normal, 1 = swap bs and delete */
XXint	p_convert    = 1;	    /* 1 = convert filenames to lower case */
XXchar	p_keyscript  = 0x7E;	    /* function key script introducer = ~ */
XXchar	*p_f[10]     = {	    /* function key defaults */
XX    "\033OP","\033OQ","\033OR","\033OS",
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;
XXint doing_init = 0;
XX
XX/******************************************************/
XX/*                   Main Program                     */
XX/*                                                    */
XX/*      This is the main body of the program.         */
XX/******************************************************/
XX
XXchar lookahead[80];
XXFILE *tranr = NULL;
XXFILE *trans = NULL;
XXint capture,send;
XXchar name[80];
XXstruct MsgPort *mySerPort;
XX
XXmain(argc,argv)
XXint	argc;
XXchar	**argv;
XX    {
XX    ULONG class;
XX    unsigned int code, qual;
XX    int KeepGoing,i,la,dola,actual;
XX    char c,*ptr;
XX
XX    ptr = InitDefaults(argc,argv);
XX    InitDevs();
XX    InitFileItems();
XX    InitCommItems();
XX    InitScriptItems();
XX    InitUtilItems();
XX    InitMenu();
XX    SetMenuStrip(mywindow,&menu[0]);
XX    PrintIText(mywindow->RPort,&MyTitle,0L,0L);
XX
XX    MyDir[0]  =	    '\000';
XX    StartLock =	(struct FileLock *)((ULONG)((struct Process *)
XX		    (FindTask(NULL)))->pr_CurrentDir);
XX    MyDirLock = (struct FileLock *)DupLock(StartLock);
XX    KeepGoing =	    TRUE;
XX    capture   =	    FALSE;
XX    send      =	    FALSE;
XX    maxcol    =	    MAXX / 8;
XX    la	      =	    0;
XX    x	      =	    MINX ; 
XX    y	      =	    MINY; 
XX    curmode   =	    FS_NORMAL;
XX    script_on =     FALSE;
XX    script_wait=    TRUE;
XX    SetAPen(mywindow->RPort,1L);
XX    cursorflip();
XX    cursorflip();    
XX    emit(12);
XX    mySerPort = Read_Request->IOSer.io_Message.mn_ReplyPort;
XX    SendIO(Read_Request);
XX
XX    /* see if we had a startup script */
XX    if (ptr != NULL) script_start(ptr);
XX
XX    while( KeepGoing )
XX	    {
XX	    /* wait for window message or serial port message */
XX	    cursorflip();
XX	    if (script_wait)	/* if script ready dont wait here */
XX		Wait(
XX		 (1L << mySerPort->mp_SigBit) |
XX		 (1L << mywindow->UserPort->mp_SigBit) |
XX		 (1L << Script_Timer_Port->mp_SigBit));
XX	    cursorflip();
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		    req("File Sent","",0);
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		DoIO(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		    DoIO(Read_Request);
XX		    Read_Request->IOSer.io_Length = 1;
XX
XX		    for (i = 0; i < actual; i++) {
XX			c=rs_in[i] & 0x7f;
XX			if (script_on) chk_script(c);
XX
XX			if (dola == 1) {
XX			    if (c >= ' ' && c <= '~' && la < 80)
XX				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 (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		SendIO(Read_Request);
XX		}
XX
XX	    while((NewMessage = 
XX		    (struct IntuiMessage *)GetMsg(mywindow->UserPort))
XX			!= FALSE) {
XX		class = NewMessage->Class;
XX		code = NewMessage->Code;
XX		qual = NewMessage->Qualifier;
XX		ReplyMsg( NewMessage );
XX		switch( class )
XX		    {
XX		    case REQCLEAR:
XX		    numreqs = 0;
XX		    break;
XX
XX		    case CLOSEWINDOW:
XX		    KeepGoing = FALSE;
XX		    break;
XX
XX		    case RAWKEY:
XX		    c = toasc(code,qual,0);
XX		    if (p_echo) doremote(c);
XX		    break;
XX
XX		    case NEWSIZE:
XX		    emit(12);
XX		    break;
XX
XX		    case MENUPICK:
XX		    handle_menupick(class,code);
XX		    break;				    
XX
XX		    default:
XX		    PrintIText(mywindow->RPort,&MyTitle,0L,0L);
XX		    break;
XX		    }   /* end of switch (class) */
XX		}   /* end of while ( newmessage )*/
XX
XX            if (!script_wait || 
XX                 (CheckIO(&Script_Timer) && 
XX		    script_wait == WAIT_TIMER))
XX		do_script_cmd(NEXTCOMMAND);
XX	    }  /* end while ( keepgoing ) */
XX		
XX    /*   It must be time to quit, so we have to clean
XX    *   up and exit.
XX    */
XX
XX    cleanup("",0);
XX
XX    } /* end of main */
XX
XX/* cleanup code */
XX
XXcleanup(reason, fault)
XXchar *reason;
XXint fault;
XX    {
XX    switch(fault) {
XX	case 0:		/* quitting close everything */
XX	ClearMenuStrip( mywindow ); 
XX	CloseDevice(&Audio_Request);
XX	if (MyDirLock != NULL) UnLock(MyDirLock);
XX
XX	case 8:		/* error opening audio */
XX	DeletePort(Audio_Port);
XX	FreeMem(BeepWave,BEEPSIZE);
XX	CloseDevice(&Timer);
XX
XX	case 7:		/* error opening timer */
XX	DeletePort(Timer_Port);  
XX	CloseDevice(&Script_Timer);
XX	DeletePort(Script_Timer_Port);
XX
XX	case 6:		/* error opening write device */
XX	DeletePort(Write_Request->IOSer.io_Message.mn_ReplyPort);
XX	FreeMem(Write_Request,(long)sizeof(*Write_Request));
XX	CloseDevice(Read_Request);
XX
XX	case 5:		/* error opening read device */
XX	DeletePort(Read_Request->IOSer.io_Message.mn_ReplyPort);
XX	FreeMem(Read_Request,(long)sizeof(*Read_Request));
XX
XX	case 4:		/* error opening window */
XX	if (myfont   != NULL) CloseFont( myfont );
XX	if (mywindow != NULL) CloseWindow( mywindow );
XX	if (p_screen != 0) CloseScreen( myscreen );
XX
XX	case 3:		/* error opening screen */
XX	case 2:		/* error opening graphics library */
XX	case 1:		/* error opening intuition */
XX	default:
XX	if (*reason) puts (reason);
XX	}
XX    exit(fault);
XX    } 
XX
XXdo_capture(file)
XXchar *file;
XX    {
XX    if (capture == TRUE)
XX        {
XX        capture=FALSE;
XX        fclose(tranr);
XX        req("End File Capture","",0);
XX        }
XX    else
XX        {
XX        if (file == NULL) {
XX	    name[0] = '\000';
XX            req("Ascii Capture:",name,1);
XX	    } 
XX	else strcpy(name, file);
XX        if ((tranr=fopen(name,"w")) == 0) {
XX	    capture=FALSE;
XX	    req("Error Opening File","",0);
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        req("File Send Cancelled","",0);
XX        }
XX    else
XX        {
XX        if (file == NULL) {
XX	    name[0] = '\000';
XX            req("Ascii Send:",name,1);
XX            }
XX	else strcpy(name, file);
XX        if ((trans=fopen(name,"r")) == 0) {
XX   	    send=FALSE;
XX	    req("Error Opening File","",0);
XX	    return(FALSE);
XX	    }
XX	send=TRUE;
XX	}
XX    }
XX
XXvoid setparams()
XX    {
XX    Read_Request->IOSer.io_Command = 
XX	Write_Request->IOSer.io_Command = 
XX	    SDCMD_SETPARAMS;
XX    DoIO(Read_Request); DoIO(Write_Request);
XX    Read_Request->IOSer.io_Command = CMD_READ;
XX    SendIO(Read_Request);
XX    Write_Request->IOSer.io_Command = CMD_WRITE;
XX    }
XX
XXvoid hangup ()
XX    {
XX    AbortIO(Read_Request);
XX    CloseDevice (Read_Request);
XX    Timer.tr_time.tv_secs=0L;
XX    Timer.tr_time.tv_micro=750000L;
XX    DoIO((char *) &Timer.tr_node);
XX    OpenDevice (SERIALNAME,NULL,Read_Request,NULL);
XX    setparams();
XX    }
XX
XXvoid redocomm() {
XX    ClearMenuStrip( mywindow );         /* Remove old menu */
XX    InitCommItems();                    /* Re-do comm menu   */
XX    SetMenuStrip(mywindow,&menu[0]);    /* Re-display the menu */	
XX    }
XX
XXvoid setserbaud(baud, redomenu)
XXint baud;
XXLONG redomenu;
XX    {
XX    AbortIO(Read_Request);
XX    Write_Request->io_Baud = Read_Request->io_Baud = baud;
XX    setparams();
XX    p_baud = baud;
XX    if (redomenu) redocomm();
XX    }
XX
XXvoid redoutil() {
XX    ClearMenuStrip(mywindow);
XX    InitUtilItems();
XX    SetMenuStrip(mywindow,&menu[0]);
XX    }
XX
XXvoid handle_menupick(class, code)
XXULONG class;
XXunsigned int code;
XX    {
XX    unsigned int menunum, itemnum, subnum;
XX
XX    if (code == MENUNULL) return;
XX
XX    menunum = MENUNUM( code );
XX    itemnum = ITEMNUM( code );
XX    subnum  = SUBNUM( code );
XX    switch( menunum ) {
XX	case 0:
XX	switch( itemnum ) {
XX	    case 0:
XX	    do_capture(NULL);
XX	    break;
XX
XX	    case 1:
XX	    do_send(NULL);
XX	    break;
XX
XX	    case 2:
XX	    if (p_parity > 0) {
XX		req("Parity setting prevents this","",0);
XX		break;
XX		}
XX	    name[0] = '\000';
XX	    req("Xmodem Receive:",name,1);
XX	    multi_xfer(name,XMODEM_Read_File,0);
XX	    break;
XX
XX	    case 3:
XX	    if (p_parity > 0) {
XX		req("Parity setting prevents this","",0);
XX		break;
XX		}
XX	    name[0] = '\000';
XX	    req("Xmodem Send:",name,1);
XX	    multi_xfer(name,XMODEM_Send_File,1);
XX	    break;
XX
XX	    case 4:
XX	    server = TRUE;
XX	    name[0] = '\000';
XX	    req("Kermit GET remote file(s):",name,1);
XX	    multi_xfer(name,dokreceive,0);
XX            break;
XX
XX	    case 5:
XX	    multi_xfer("",dokreceive,0);
XX	    break;
XX
XX	    case 6:
XX	    server = TRUE;
XX	    name[0] = '\000';
XX	    req("Kermit Send local name:",name,1);
XX	    multi_xfer(name,doksend,1);
XX	    break;
XX
XX	    case 7:
XX	    saybye();
XX	    break;
XX	    }
XX	break;
XX
XX	case 1:
XX	switch( itemnum ) {
XX	    case 0:
XX	    switch( subnum ) {
XX		case 0:
XX		setserbaud(300, FALSE);
XX		break;
XX
XX		case 1:
XX		setserbaud(1200, FALSE);
XX		break;
XX
XX		case 2:
XX		setserbaud(2400, FALSE);
XX		break;
XX
XX		case 3:
XX		setserbaud(4800, FALSE);
XX		break;
XX
XX		case 4:
XX		setserbaud(9600, FALSE);
XX		break;
XX		}
XX	    break;	    
XX
XX	    case 1:
XX	    /* Set  Parity */
XX	    p_parity = subnum;
XX	    break;
XX
XX	    case 2:
XX	    /* set transfer mode */
XX	    if (subnum < 2) p_mode = subnum;
XX	    else {
XX		if (p_convert)	p_convert = 0;
XX		else		p_convert = 1;
XX		redocomm();
XX		}
XX	    break;
XX	    }
XX	break;
XX
XX	case 2:
XX	if (!itemnum && !script_on) {
XX	    name[0] = '\000';
XX	    req("Script file name:",name,1);
XX	    script_start(name);
XX	    }
XX	if (itemnum && script_on) exit_script();
XX	break;
XX
XX	case 3:
XX	switch( itemnum ) {
XX	    case 0:
XX	    sendbreak();
XX	    break;
XX
XX	    case 1:
XX	    hangup();
XX	    break;
XX
XX	    case 2:
XX	    strcpy(name,MyDir);
XX	    req("Directory:",name,1);
XX	    set_dir(name);
XX	    break;
XX
XX	    case 3:
XX	    top = MINY; bot = MAXY; savx = MINX; savy = MINY;
XX	    curmode = FS_NORMAL; inesc = -1;
XX	    a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
XX	    redoutil();
XX	    emit(12);
XX	    break;
XX
XX	    case 4:
XX	    if (p_echo) p_echo = 0;
XX	    else	p_echo = 1;
XX	    redoutil();
XX	    break;
XX
XX	    case 5:
XX	    if (p_wrap) p_wrap = 0;
XX	    else        p_wrap = 1;
XX	    redoutil();
XX	    break;
XX
XX	    case 6:
XX	    if (p_keyapp) p_keyapp = 0;
XX	    else          p_keyapp = 1;
XX	    redoutil();
XX	    break;
XX
XX	    case 7:
XX	    if (p_curapp) p_curapp = 0;
XX	    else          p_curapp = 1;
XX	    redoutil();
XX	    break;	    
XX
XX	    case 8:
XX	    swap_bs_del();
XX	    redoutil();
XX	    break;
XX	    }
XX
XX	break;
XX	} /* end of switch ( menunum ) */
XX    }
XX
SHAR_EOF
if test 18448 -ne "`wc -c vt100.c`"
then
echo shar: error transmitting vt100.c '(should have been 18448 characters)'
fi
echo shar: extracting init.c
sed 's/^XX//' << \SHAR_EOF > init.c
XX/***************************************************************
XX * vt100 - terminal emulator - initialization
XX *
XX *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
XX *	v2.5 870214 DBW - more additions (see readme file)
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
XX *	     860901 ACS	- Added Parity and Word Length and support code
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#include "vt100.h"
XX
XXchar line[256];
XXstatic char cmds[] = "V^GRSBLHXEOIT.DWKCZ";
XX
XXchar *InitDefaults(argc,argv)
XXint	argc;
XXchar	**argv;
XX    {
XX    FILE    *fd;
XX    char    *p;
XX    int	    l;
XX
XX    doing_init = 1;	/* make sure we only allow INIT script commands */
XX    if (((argc > 1) && (fd=fopen(argv[1],"r")) != 0) ||
XX	(fd=fopen("vt100.init","r")) != 0 ||
XX	(fd=fopen("s:vt100.init","r")) != 0) {
XX	while (fgets(line,256,fd) != 0) {
XX	    line[strlen(line)-1] = '\000';
XX	    p = next_wrd(&line[0],&l);
XX	    if (*p) {
XX		*p |= ' ';
XX		if (p[1]) p[1] |= ' ';
XX		if (*p == '#') continue;
XX		if (*p == 'e' && p[1] == 'x') break;
XX		exe_cmd(p,l);
XX		}
XX	    }
XX	fclose(fd);
XX	}
XX    doing_init = 0;
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   = 0L;
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)+16);
XX	if (p_interlace == 1)
XX	    NewScreen.TopEdge   = (long)(400 - NewScreen.Height);
XX	else
XX	    NewScreen.TopEdge   = (long)(208 - NewScreen.Height);
XX	}
XX    else {
XX	p_depth			= 2L;
XX	NewWindow.TopEdge	= 0L;
XX	NewWindow.Screen	= NULL;
XX	NewWindow.Type		= WBENCHSCREEN;
XX	}
XX    /* see if we exit with a startup script */
XX    if (*p == 'e') {
XX	p = next_wrd(p+l+1,&l);
XX	if (*p) return(p);
XX	}
XX    return(NULL);
XX    }
XX
XXvoid InitDevs()
XX{
XXUSHORT	colors[4];
XXint	i;
XXBYTE	*b,*c;
XX
XXIntuitionBase = (struct IntuitionBase *)
XX    OpenLibrary("intuition.library", INTUITION_REV);
XXif( IntuitionBase == NULL )
XX    cleanup("can't open intuition",1);
XX
XXGfxBase = (struct GfxBase *)
XX    OpenLibrary("graphics.library",GRAPHICS_REV);
XXif( GfxBase == NULL )
XX    cleanup("can't open graphics library",2);
XX
XXif (p_screen == 1) {
XX    if ((myscreen = (struct Screen *)OpenScreen(&NewScreen)) == NULL)
XX	cleanup("can't open screen",3);
XX    NewWindow.Screen = myscreen;
XX    }
XX
XXif ((mywindow = (struct Window *)OpenWindow(&NewWindow)) == NULL)
XX    cleanup("can't open window",4);
XXif ((myfont = (struct TextFont *)OpenFont(&myattr)) == NULL)
XX    cleanup("can't open font",4);
XX
XXmyviewport   = (struct ViewPort *)ViewPortAddress(mywindow);
XXmyrastport   = (struct RastPort *)mywindow->RPort;
XX
XXSetFont(myrastport,myfont);
XX
XXif (p_depth > 1) myrequest.BackFill = 2;
XXif (p_screen != 0 && p_wbcolors == 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 = 0L;
XXRead_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L);
XXif(OpenDevice(SERIALNAME,NULL,Read_Request,NULL))
XX    cleanup("Cant open Read device",5);
XXrs_in = malloc(p_buffer+1);
XXRead_Request->io_SerFlags = 0L;
XXRead_Request->io_Baud	  = p_baud;
XXRead_Request->io_ReadLen  = 8L;
XXRead_Request->io_WriteLen = 8L;
XXRead_Request->io_CtlChar  = 0x11130000L;
XXRead_Request->io_RBufLen  = p_buffer;
XXRead_Request->io_BrkTime  = p_break;
XXRead_Request->IOSer.io_Command = SDCMD_SETPARAMS;
XXDoIO(Read_Request);
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);
XXb = (BYTE *)Read_Request;
XXc = (BYTE *)Write_Request;
XXfor (i=0;i<sizeof(struct IOExtSer);i++) *c++ = *b++;
XXWrite_Request->IOSer.io_Message.mn_ReplyPort = CreatePort(0L,0L);
XXWrite_Request->IOSer.io_Command = CMD_WRITE;
XXWrite_Request->IOSer.io_Length  = 1;
XXWrite_Request->IOSer.io_Data    = (APTR) &rs_out[0];
XX
XXTimer_Port = CreatePort("Timer Port",0L);
XXScript_Timer_Port = CreatePort("Timer Port",0L);
XX
XXif (OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Timer, 0) ||
XX    OpenDevice(TIMERNAME, UNIT_VBLANK, (char *) &Script_Timer, 0)) 
XX	cleanup("can't open timer device",7);
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
XXBeepWave   = (UBYTE *)AllocMem(BEEPSIZE,(long)(MEMF_CHIP|MEMF_CLEAR));
XXif (BeepWave != 0) BeepWave[0] = 100;
XX
XXAudio_Port = CreatePort("Audio Port",0L);
XX
XXAudio_Request.ioa_Request.io_Message.mn_ReplyPort   = Audio_Port;
XXAudio_Request.ioa_Request.io_Message.mn_Node.ln_Pri = 85;
XXAudio_Request.ioa_Data		    = Audio_AllocMap;
XXAudio_Request.ioa_Length	    = (ULONG) sizeof(Audio_AllocMap);
XX
XXif (OpenDevice(AUDIONAME, NULL, (char *) &Audio_Request, NULL))
XX	cleanup("can't open audio device",8);
XX
XXAudio_Request.ioa_Request.io_Command	= CMD_WRITE;
XXAudio_Request.ioa_Request.io_Flags	= ADIOF_PERVOL;
XXAudio_Request.ioa_Data		= BeepWave;
XXAudio_Request.ioa_Length	= BEEPSIZE;
XXAudio_Request.ioa_Period	= COLORCLOCK / (BEEPSIZE * BEEPFREQ);
XXAudio_Request.ioa_Volume	= p_volume;
XXAudio_Request.ioa_Cycles	= 100;
XX}
XX
XX/*****************************************************************/
XX/*    The following function initializes the structure arrays    */
XX/*   needed to provide the File menu topic.                      */
XX/*****************************************************************/
XXvoid InitFileItems()
XX    {
XX    int	    n,nplus1;
XX
XX/* initialize each menu item and IntuiText with loop */
XXfor( n=0; n<FILEMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    FileItem[n].NextItem = &FileItem[nplus1];
XX    FileItem[n].LeftEdge = 0;
XX    FileItem[n].TopEdge = 10 * n;
XX    FileItem[n].Width = 120+40;
XX    FileItem[n].Height = 10;
XX    FileItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
XX    FileItem[n].MutualExclude = 0;
XX    FileItem[n].ItemFill = (APTR)&FileText[n];
XX    FileItem[n].SelectFill = NULL;
XX    if (n >= 2 && n <= 7) {
XX	FileItem[n].Command  = cmds[n-2];
XX	FileItem[n].Flags   |= COMMSEQ;
XX	}
XX    else 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 */
XX
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/*			Main Comm menu
XX/*		set up for Baud & Parity submenus
XX/******************************************************************/
XXvoid InitCommItems()
XX    {
XX    int	    n,nplus1;
XX
XX/* initialize each menu item and IntuiText with loop */
XXfor( n=0; n<COMMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    CommItem[n].NextItem = &CommItem[nplus1];
XX    CommItem[n].LeftEdge = 0;
XX    CommItem[n].TopEdge = 10 * n;
XX    CommItem[n].Width = 88;
XX    CommItem[n].Height = 10;
XX    CommItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP ;
XX    CommItem[n].MutualExclude = 0;
XX    CommItem[n].ItemFill = (APTR)&CommText[n];
XX    CommItem[n].SelectFill = NULL;
XX    CommItem[n].Command = 0;
XX    CommItem[n].NextSelect = 0;
XX
XX    CommText[n].FrontPen = 0;
XX    CommText[n].BackPen = 1;
XX    CommText[n].DrawMode = JAM2;    
XX    CommText[n].LeftEdge = 0;
XX    CommText[n].TopEdge = 1;
XX    CommText[n].ITextFont = NULL;
XX    CommText[n].NextText = NULL;
XX    }
XXCommItem[COMMAX-1].NextItem = NULL;
XX
XXCommText[0].IText = (UBYTE *)"Baud Rate";
XXCommText[1].IText = (UBYTE *)"Parity   ";
XXCommText[2].IText = (UBYTE *)"Xfer Mode";
XXCommItem[0].SubItem = RSItem;
XXCommItem[1].SubItem = ParItem;
XXCommItem[2].SubItem = XFItem;
XX
XX/*****************************************************************/
XX/*    The following initializes the structure arrays		 */
XX/*   needed to provide the BaudRate Submenu topic.               */
XX/*****************************************************************/
XX
XXfor( n=0; n<RSMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    RSItem[n].NextItem = &RSItem[nplus1];
XX    RSItem[n].LeftEdge = 75;
XX    RSItem[n].TopEdge = 10 * n;
XX    RSItem[n].Width = 56+40;
XX    RSItem[n].Height = 10;
XX    RSItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT;
XX    RSItem[n].MutualExclude = (~(1 << n));
XX    RSItem[n].ItemFill = (APTR)&RSText[n];
XX    RSItem[n].SelectFill = NULL;
XX    if (n >= 1 && n <= 2) {
XX	RSItem[n].Command    = cmds[n+5];
XX	RSItem[n].Flags	    |= COMMSEQ;
XX	}
XX    else 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
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 |= 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/*    The following initializes the structure arrays		 */
XX/*   needed to provide the Parity   Submenu topic.               */
XX/*****************************************************************/
XX
XXfor( n=0; n<PARMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    ParItem[n].NextItem = &ParItem[nplus1];
XX    ParItem[n].LeftEdge = 75;
XX    ParItem[n].TopEdge = 10 * n;
XX    ParItem[n].Width = 56+40;
XX    ParItem[n].Height = 10;
XX    ParItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT;
XX    ParItem[n].MutualExclude = (~(1 << n));
XX    ParItem[n].ItemFill = (APTR)&ParText[n];
XX    ParItem[n].SelectFill = NULL;
XX    if (n == 0 || n == 3 || n == 4) {
XX	ParItem[n].Command   = cmds[(n==0)?8:n+6];
XX	ParItem[n].Flags    |= COMMSEQ;
XX	}
XX    else ParItem[n].Command = 0;
XX    ParItem[n].SubItem = NULL;
XX    ParItem[n].NextSelect = 0;
XX
XX    ParText[n].FrontPen = 0;
XX    ParText[n].BackPen = 1;
XX    ParText[n].DrawMode = JAM2;/* render in fore and background */
XX    ParText[n].LeftEdge = 0;
XX    ParText[n].TopEdge = 1;
XX    ParText[n].ITextFont = NULL;
XX    ParText[n].NextText = NULL;
XX    }
XXParItem[PARMAX-1].NextItem = NULL;
XX
XX/* select parity item chekced */
XXParItem[p_parity].Flags |= CHECKED;
XX
XX/* initialize text for specific menu items */
XXParText[0].IText = (UBYTE *)"  None ";
XXParText[1].IText = (UBYTE *)"  Mark ";
XXParText[2].IText = (UBYTE *)"  Space";
XXParText[3].IText = (UBYTE *)"  Even ";
XXParText[4].IText = (UBYTE *)"  Odd  ";
XX
XX/*****************************************************************/
XX/*    The following initializes the structure arrays		 */
XX/*    needed to provide the Transfer Mode menu topic.            */
XX/*****************************************************************/
XX
XX/* initialize each menu item and IntuiText with loop */
XXfor( n=0; n<XFMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    XFItem[n].NextItem = &XFItem[nplus1];
XX    XFItem[n].LeftEdge = 75;
XX    XFItem[n].TopEdge = 10 * n;
XX    XFItem[n].Width = 80+40;
XX    XFItem[n].Height = 10;
XX    XFItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT;
XX    if (n < 2)  XFItem[n].MutualExclude = 2 - n;
XX    else	XFItem[n].MutualExclude = 0;
XX    XFItem[n].ItemFill = (APTR)&XFText[n];
XX    XFItem[n].SelectFill = NULL;
XX    if (n < 2) {
XX	XFItem[n].Command    = cmds[n+11];
XX	XFItem[n].Flags	    |= COMMSEQ;
XX	}
XX    else 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;
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 |= CHECKED;
XXif (p_convert)	XFItem[2].Flags |= CHECKED;
XX
XX/* initialize text for specific menu items */
XXXFText[0].IText = (UBYTE *)"  Image  ";
XXXFText[1].IText = (UBYTE *)"  Text   ";
XXXFText[2].IText = (UBYTE *)"  Convert";
XX
XX} /* end of InitCommItems() */
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,nplus1;
XX
XX/* initialize each menu item and IntuiText with loop */
XXfor( n=0; n<SCRIPTMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    ScriptItem[n].NextItem = &ScriptItem[nplus1];
XX    ScriptItem[n].LeftEdge = 0;
XX    ScriptItem[n].TopEdge = 10 * n;
XX    ScriptItem[n].Width = 128;
XX    ScriptItem[n].Height = 10;
XX    ScriptItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
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 structure arrays    */
XX/*   needed to provide the Util menu topic.                    */
XX/*****************************************************************/
XXvoid InitUtilItems()
XX    {
XX    int	    n,nplus1;
XX
XX/* initialize each menu item and IntuiText with loop */
XXfor( n=0; n<UTILMAX; n++ )
XX    {
XX    nplus1 = n + 1;
XX    UtilItem[n].NextItem = &UtilItem[nplus1];
XX    UtilItem[n].LeftEdge = 0;
XX    UtilItem[n].TopEdge = 10 * n;
XX    UtilItem[n].Width = 88+40;
XX    UtilItem[n].Height = 10;
XX    UtilItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
XX    if (n > 3) UtilItem[n].Flags |= CHECKIT;
XX    UtilItem[n].MutualExclude = 0;
XX    UtilItem[n].ItemFill = (APTR)&UtilText[n];
XX    UtilItem[n].SelectFill = NULL;
XX    if (n == 0 || n == 2) {
XX	UtilItem[n].Command   = cmds[(n==0)?13:14];
XX	UtilItem[n].Flags    |= COMMSEQ;
XX	}
XX    else if (n >= 5) {
XX	UtilItem[n].Command   = cmds[n+10];
XX	UtilItem[n].Flags    |= COMMSEQ;
XX	}
XX    else UtilItem[n].Command = 0;
XX    UtilItem[n].SubItem = NULL;
XX    UtilItem[n].NextSelect = 0;
XX
XX    UtilText[n].FrontPen = 0;
XX    UtilText[n].BackPen = 1;
XX    UtilText[n].DrawMode = JAM2;/* render in fore and background */
XX    UtilText[n].LeftEdge = 0;
XX    UtilText[n].TopEdge = 1;
XX    UtilText[n].ITextFont = NULL;
XX    UtilText[n].NextText = NULL;
XX    }
XXUtilItem[UTILMAX-1].NextItem = NULL;
XX
XXif (p_echo)	    UtilItem[4].Flags |= CHECKED;
XXif (p_wrap)	    UtilItem[5].Flags |= CHECKED;
XXif (p_keyapp == 0)  UtilItem[6].Flags |= CHECKED;
XXif (p_curapp)	    UtilItem[7].Flags |= CHECKED;
XXif (p_bs_del)	    UtilItem[8].Flags |= CHECKED;
XX
XX/* initialize text for specific menu items */
XXUtilText[0].IText = (UBYTE *)"Send Break";
XXUtilText[1].IText = (UBYTE *)"Hang Up";
XXUtilText[2].IText = (UBYTE *)"Change Dir";
XXUtilText[3].IText = (UBYTE *)"Clear Scrn";
XXUtilText[4].IText = (UBYTE *)"  Echo";
XXUtilText[5].IText = (UBYTE *)"  Wrap";
XXUtilText[6].IText = (UBYTE *)"  Num Key";
XXUtilText[7].IText = (UBYTE *)"  App Cur";
XXUtilText[8].IText = (UBYTE *)"  BS<->DEL";
XX}
XX
XX/****************************************************************/
XX/*   The following function inits the Menu structure array with */
XX/*  appropriate values for our simple menu.  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 = 40;
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 = 55;
XXmenu[1].TopEdge = 0;
XXmenu[1].Width = 88;
XXmenu[1].Height = 10;
XXmenu[1].Flags = MENUENABLED;
XXmenu[1].MenuName = "Comm Setup";   /* text for menu-bar display */
XXmenu[1].FirstItem = &CommItem[0];  /* pointer to first item in list */
XX
XXmenu[2].NextMenu = &menu[3];
XXmenu[2].LeftEdge = 153;
XXmenu[2].TopEdge = 0;
XXmenu[2].Width = 56;
XXmenu[2].Height = 10;
XXmenu[2].Flags = MENUENABLED;
XXmenu[2].MenuName = "Script";        /* text for menu-bar display */
XXmenu[2].FirstItem = &ScriptItem[0]; /* pointer to first item in list*/
XX
XXmenu[3].NextMenu = NULL;
XXmenu[3].LeftEdge = 225;
XXmenu[3].TopEdge = 0;
XXmenu[3].Width = 64;
XXmenu[3].Height = 10;
XXmenu[3].Flags = MENUENABLED;
XXmenu[3].MenuName = "Utility";      /* text for menu-bar display */
XXmenu[3].FirstItem = &UtilItem[0];  /* pointer to first item in list*/
XX}
XX
SHAR_EOF
if test 18744 -ne "`wc -c init.c`"
then
echo shar: error transmitting init.c '(should have been 18744 characters)'
fi
echo shar: extracting newbindings.asm
sed 's/^XX//' << \SHAR_EOF > newbindings.asm
XX************************************************************************
XX*	NewBindings.ASM
XX*
XX* This assembly file contains binding routines for the new gadget functions
XX* provided in V1.2 of AmigaDOS.  You can use these binding routines
XX* if you have an old version of C compiler, for instance Manx V3.20A
XX* ( Though with a couple minor changes it can be used with the old
XX*   MetaComco Assember and Lattice C V3.03 )
XX************************************************************************
XX
XXLIB_VERSION		equ	$14
XX
XX_LVOActivateGadget	equ	-$1CE
XX_LVOActivateWindow	equ	-$1C2
XX_LVOAddGList		equ	-$1B6
XX_LVORefreshGList	equ	-$1B0
XX_LVORemoveGList		equ	-$1BC
XX_LVOGetScreenData	equ	-$1AA
XX_LVOAreaEllipse		equ	-$BA
XX
XX	public	_ActivateGadget
XX	public	_ActivateWindow
XX	public	_AddGList
XX	public	_RefreshGList
XX	public	_RemoveGList
XX	public	_GetScreenData
XX	public	_AreaEllipse
XX	public	_IntuitionBase
XX	public	_GfxBase
XX
XX*************************************************************************
XX*	ActivateGadget(&gadget, p_window, p_requester);
XX*		BOOLEAN return true on sucess
XX*************************************************************************
XX_ActivateGadget:
XX	movem.l	A2/A6,-(sp)		* A6 isn't mandatory w/Manx
XX	movem.l	12(sp),A0-A2		* ( but if you toss, adjust to 8! )
XX	move.l	_IntuitionBase,A6
XX	cmp	#32,LIB_VERSION(A6)	* SPECIAL TEST FOR LEGIT V1.2
XX	ble	nicht1
XX	jsr	_LVOActivateGadget(A6)
XXnicht1:	movem.l	(sp)+,A2/A6
XX	rts
XX
XX************************************************************************
XX*	ActivateWindow(p_wind);
XX*
XX************************************************************************
XX_ActivateWindow:
XX	move.l	4(sp),A0
XX	move.l	A6,-(sp)		* Not necessary w/Manx
XX	move.l	_IntuitionBase,A6
XX	cmp	#32,LIB_VERSION(A6)	* SPECIAL TEST FOR LEGIT V1.2
XX	ble	nicht2
XX	jsr	_LVOActivateWindow(A6)
XXnicht2:	move.l	(sp)+,A6
XX	rts
XX
XX*************************************************************************
XX*	AddGList( &gad, p_wind, position, number)
XX*		Return value is actual position inserted
XX*************************************************************************
XX_AddGList:
XX	movem.l	4(sp),A0/A1
XX	movem.l	12(sp),D0/D1
XX	move.l	A6,-(sp)			* Nicht Manx
XX	move.l	_IntuitionBase,A6
XX	jsr	_LVOAddGList(A6)
XX	move.l	(sp)+,A6
XX	rts
XX
XX*************************************************************************
XX*	RefreshGList( &gad, p_wind, p_requester, number )
XX*
XX*************************************************************************
XX_RefreshGList:
XX	movem.l	A2/A6,-(sp)
XX	movem.l	12(sp),A0-A2
XX	move.l	$18(sp),D0
XX	move.l	_IntuitionBase,A6
XX	jsr	_LVORefreshGList(A6)
XX	movem.l	(sp)+,A2/A6
XX	rts
XX
XX*************************************************************************
XX*	RemoveGList( &gad, p_wind, number);
XX*************************************************************************
XX_RemoveGList:
XX	movem.l	4(sp),A0-A1
XX	move.l	12(sp),D0
XX	move.l	A6,-(sp)			* Toss w/Manx
XX	move.l	_IntuitionBase,A6
XX	jsr	_LVORemoveGList(A6)
XX	move.l	(sp)+,A6
XX	rts
XX
XX*************************************************************************
XX* AreaEllipse( p_rast, xcenter, ycenter, xdel, ydel);
XX*	(?) Returns 0 if no error a_la_AreaDraw()
XX*************************************************************************
XX_AreaEllipse:
XX	movem.l	D2/D3/A6,-(sp)
XX	move.l	16(sp),A1
XX	movem.l	20(sp),D0-D3
XX	move.l	_GfxBase,A6
XX	jsr	_LVOAreaEllipse(A6)
XX	movem.l	(sp)+,D2/D3/A6
XX	rts
XX	
XX*************************************************************************
XX*	GetScreenData( p_buffer, buffsize, type, p_somescreen);
XX*
XX*	Where p_buffer is a data area, sizeof(buffsize) which is
XX*	sizeof (struct Screen). type is WBENCHSCREEN or CUSTOMSCREEN
XX*	if type = CUSTOM, p_somescreen is the customscreen
XX*	Returns buffer containing a cloned_data for the screen requested
XX*************************************************************************
XX_GetScreenData
XX	move.l	4(sp),A0
XX	movem.l	8(sp),D0/D1/A1
XX	move.l	A6,-(sp)		* Gonzo Manx_a_mania
XX	move.l	_IntuitionBase,A6
XX	jsr	_LVOGetScreenData(A6)
XX	move.l	(sp)+,A6
XX	rts
XX
SHAR_EOF
if test 3929 -ne "`wc -c newbindings.asm`"
then
echo shar: error transmitting newbindings.asm '(should have been 3929 characters)'
fi
#	End of shell archive
exit 0

wecker@cookie.dec.com.UUCP (02/24/87)

#	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:
#	script.c
#	remote.c
#	window.c
#	expand.c
#	kermit.c
#	xmodem.c
# This archive created: Sun Feb 22 23:51:56 1987
echo shar: extracting script.c
sed 's/^XX//' << \SHAR_EOF > script.c
XX/*************************************************************
XX * vt100 terminal emulator - Script file support
XX *
XX *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
XX *	v2.5 870214 DBW - more additions (see readme file)
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
XX *	     860901 ACS - Added BAUD, PARITY and WORD commands & handling
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#include "vt100.h"
XX
XXstruct COMMAND {
XX    void (*func)();
XX    char *cname;
XX    };
XX
XXstruct LABEL  {
XX    struct LABEL *next;
XX    char *name;
XX    long pos;
XX    };
XX
XXextern long atol();
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[20];          /* 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
XX/********************** command tables *******************************/
XXstatic struct COMMAND inicmds[] = {	/* initialization commands */
XX    cmd_bkg,	"bac",		/* set background color	    */
XX    cmd_bold,	"bol",		/* set bold color 	    */
XX    cmd_buf,	"buf",		/* set buffer size 	    */
XX    cmd_cursor,	"cur",		/* set cursor color	    */
XX    cmd_depth,	"dep",		/* set screen depth 	    */
XX    cmd_fore,	"for",		/* set foreground color	    */
XX    cmd_inter,	"int",		/* interlace ON/OFF	    */
XX    cmd_lines,	"lin",		/* num lines 		    */
XX    cmd_screen,	"scr",		/* Screen WB/CUST 	    */
XX    cmd_volume,	"vol",		/* set volume		    */
XX    cmd_wb,	"wb",		/* use WB colors	    */
XX    cmd_null,   NULL		/* mark the end of the list */
XX    };
XXstatic struct COMMAND scrcmds[] = {	/* script only commands */
XX    cmd_as,     "asc",		/* ascii send               */
XX    cmd_beep,	"bee",		/* Beep			    */
XX    cmd_cap,    "cap",		/* ascii capture on/off     */
XX    cmd_cd,     "cd",		/* change directory	    */
XX    cmd_delay,  "del",		/* delay amount of seconds  */
XX    cmd_goto,   "got",		/* goto label               */
XX    cmd_kb,	"kb",		/* kermit bye (for server)  */
XX    cmd_kg,     "kg",           /* kermit get file          */
XX    cmd_kr,     "kr",           /* kermit receive file      */
XX    cmd_ks,     "ks",           /* kermit send file         */
XX    cmd_on,     "on", 		/* on a 'string' do a cmd   */
XX    cmd_sb,     "sb",		/* Send a break		    */
XX    cmd_send,   "send",         /* send string to host      */
XX    cmd_wait,   "wait",         /* wait for a host string   */
XX    cmd_xr,     "xr",           /* xmodem receive file      */
XX    cmd_xs,     "xs",           /* xmodem send file         */
XX    cmd_null,   NULL		/* mark the end of the list */
XX    };
XXstatic struct COMMAND commands[]= {	/* generally available commands */
XX    cmd_appcur,	"app",		/* turn app. cursor on/off  */
XX    cmd_baud,   "bau",		/* Set Baud Rate            */
XX    cmd_bt,     "bre",		/* Set Break Time	    */
XX    cmd_conv,	"con",		/* convert bs to del	    */
XX    cmd_echo,	"ech",		/* turn echo on or off	    */
XX    cmd_exit,   "exi",		/* exit script file         */
XX    cmd_fnc,	"f",		/* define function key	    */
XX    cmd_key,	"key",		/* keyscript character	    */
XX    cmd_mode,	"mod",		/* KERMIT transfer mode	    */
XX    cmd_numkey,	"numkey",	/* turn numeric kpad on/off */
XX    cmd_parity, "parity",	/* Set Parity		    */
XX    cmd_swap,	"swap",		/* Swap BS and DEL	    */
XX    cmd_wrap,	"wrap",		/* turn wrap on or off	    */
XX    cmd_null,   NULL		/* mark the end of the list */
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    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 (strlen(file) == 0 || *file == '#') return(0);
XX    if ((sf = fopen(file, "r")) == NULL) {
XX        req("Can't open script file",file,0);
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
XX    while(*s && (*s == ' ' || *s == '\t')) s++;
XX    p = s;
XX    while(*s && (*s != ' ' && *s != '\t')) s++;
XX    *l = s-p;
XX    return(p);
XX    }
XX
XXexe_cmd(p,l)
XXchar *p;
XXint l;
XX    {
XX    int i,l2;
XX
XX    /* downcase the command */
XX    for (i=0; i<l; i++) p[i] |= ' ';    
XX
XX    /* now search for it (first in the init command list) */
XX    if (doing_init)
XX	for (i=0; inicmds[i].func != cmd_null; ++i) {
XX	    l2 = strlen(inicmds[i].cname);
XX	    if (l >= l2 && strncmp(p, inicmds[i].cname, l2) == 0) {
XX		(*inicmds[i].func)(next_wrd(p+l, &l));
XX		return(TRUE);
XX		}
XX	    }
XX
XX    /* or the script command list */
XX    else
XX	for (i=0; scrcmds[i].func != cmd_null; ++i) {
XX	    l2 = strlen(scrcmds[i].cname);
XX	    if (l >= l2 && strncmp(p, scrcmds[i].cname, l2) == 0) {
XX		(*scrcmds[i].func)(next_wrd(p+l, &l));
XX		return(TRUE);
XX		}
XX	    }
XX
XX    /* now search for it (in the standard command list) */
XX    for (i=0; commands[i].func != cmd_null; ++i) {
XX	l2 = strlen(commands[i].cname);
XX        if (l >= l2 && strncmp(p, commands[i].cname, l2) == 0) {
XX            (*commands[i].func)(next_wrd(p+l, &l));
XX            return(TRUE);
XX	    }
XX	}
XX    if (doing_init) {
XX	puts("INIT - unknown command:");
XX	puts(p);
XX	}
XX    else req("Script - unknown command:",p,0);
XX
XX    return(FALSE);
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
XXdo_script_cmd(stat)
XXint stat;
XX    {
XX    int len,l;
XX    char line[256];
XX    char *p;
XX
XX    /* if ON command is matched and we were     */
XX    /* doing a DELAY then abort the delay timer,*/
XX    /* except if on_cmd was just a SEND.        */
XX    if (stat == ONCOMMAND) {
XX        strcpy(line,on_cmd);
XX        p = next_wrd(line,&l);
XX	if (*p != 'S' && script_wait == WAIT_TIMER)  {
XX            AbortIO((char *) &Script_Timer);
XX            Wait (1L << Script_Timer_Port->mp_SigBit);
XX
XX	    /* script will proceed after on command    */
XX            script_wait = FALSE;
XX	    }
XX	exe_cmd(p,l);
XX        return(0);
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 *) 
XX			malloc(sizeof (struct LABEL));
XX		    }
XX		else {
XX		    labels->next = (struct LABEL *)
XX			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	    p = next_wrd(p+l+1, &l);
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) req("Script - label not found: ",golabel,0);
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    req("Script - terminated","",0);    
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 *s1,*s2;
XX
XX    s1 = ptr;
XX    if (*ptr == '"') {
XX        while(*ptr++  && *ptr != '"') ;
XX        if (*ptr == '"') {
XX            *ptr = '\0';  
XX            ptr = s2 = ++s1;
XX            while(*s2) {
XX		if	(*s2 != '^')	 *s1++ = *s2;
XX		else if (*(s2+1) == '^') *s1++ = *s2++;
XX		else			 *s1++ = ((*++s2)|' ')-96;
XX		s2++;
XX		}
XX	    *s1 = '\0';
XX            return(ptr);
XX	    }
XX	}
XX    if (*s1 == '^') {
XX        *s1 = (*(s1+1)|' ')-96;
XX        *(s1+1) = '\0';
XX        return(s1);
XX        }
XX    *(s1+1) = '\0';
XX    return(s1);
XX    }   
XX
XX/***************************** SCRIPT COMMANDS ********************/
XX
XXvoid cmd_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
XXvoid cmd_send(str)
XXchar *str;
XX    {
XX    sendstring(tostring(str));
XX    }
XX
XXvoid cmd_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
XXvoid cmd_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
XXvoid cmd_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
XXvoid cmd_exit(option)
XXchar *option;
XX    {
XX    char *p;
XX    int  l;
XX
XX    if (doing_init) return;
XX
XX    if (*option) {
XX	p = next_wrd(option,&l);
XX	*(p+l) = '\000';
XX	if  (strcmp(p,"vt100") == 0 || strcmp(p,"VT100") == 0)
XX	    cleanup("Exit vt100 from script",0);
XX	exit_script();
XX	script_start(p);
XX	}
XX    else exit_script();
XX    }
XX
XXvoid cmd_ks(file)
XXchar *file;
XX    {
XX    multi_xfer(file, doksend, 1);
XX    }
XX
XXvoid cmd_kr(file)
XXchar *file;
XX    {
XX    multi_xfer(file, dokreceive, 0);
XX    }
XX
XXvoid cmd_kg(file)
XXchar *file;
XX    {
XX    server = TRUE;
XX    multi_xfer(file, dokreceive, 0);
XX    }
XX
XXvoid cmd_kb()
XX    {
XX    saybye();
XX    }
XX
XXvoid cmd_xs(file)
XXchar *file;
XX    {
XX    multi_xfer(file, XMODEM_Send_File, 1);
XX    }
XX
XXvoid cmd_xr(file)
XXchar *file;
XX    {
XX    multi_xfer(file, XMODEM_Read_File, 1);
XX    }
XX
XXvoid cmd_cap(file)
XXchar *file;
XX    {
XX    do_capture(file);
XX    }
XX
XXvoid cmd_as(file)
XXchar *file;
XX    {
XX    do_send(file);
XX    }
XX
XXvoid cmd_cd(name)
XXchar *name;
XX    {
XX    set_dir(name);
XX    }
XX
XXvoid cmd_sb(str)
XXchar *str;
XX    {
XX    sendbreak();
XX    }
XX
XXvoid cmd_baud(rate)
XXchar *rate;
XX    {
XX    int i = atoi(rate);
XX
XX    switch( i )
XX	{
XX	case  300:
XX	case 1200:
XX	case 2400:
XX	case 4800:
XX	case 9600:
XX	if (doing_init) p_baud = i;
XX	else	        setserbaud(i, TRUE);
XX	break;
XX
XX	default:
XX	if (doing_init) {
XX	    puts("INIT - invalid baud rate:");
XX	    puts(rate);
XX	    }
XX	else req("Script - invalid baud rate: ",rate,0);
XX	break;
XX	}
XX    }
XX
XXvoid cmd_parity(par)
XXchar *par;
XX    {
XX    int i;
XX
XX    switch( *par|' ' )
XX	{
XX	case 'n': i =  0; break;
XX	case 'm': i =  1; break;
XX	case 's': i =  2; break;
XX	case 'e': i =  3; break;
XX	case 'o': i =  4; break;
XX
XX	default:
XX	if (doing_init) {
XX	    puts("INIT - invalid parity:");
XX	    puts(par);
XX	    }
XX	else req("Script - invalid parity: ",par,0);
XX	return;
XX	}
XX    p_parity = i;
XX    if (doing_init) return;
XX
XX    ClearMenuStrip( mywindow );         /* Remove old menu */
XX    InitCommItems();                    /* Re-do comm menu   */
XX    SetMenuStrip(mywindow,&menu[0]);    /* Re-display the menu */	
XX    }
XX
XXvoid cmd_bt(breaklength)
XXchar *breaklength;
XX    {
XX    p_break = atol(breaklength);
XX    if (doing_init) return;
XX
XX    AbortIO(Read_Request);
XX    Read_Request->io_BrkTime = Write_Request->io_BrkTime = p_break;
XX    setparams();
XX    }
XX
XXvoid cmd_mode(tmode)
XXchar *tmode;
XX    {
XX    switch (*tmode|' ') {
XX	case 'i':
XX	p_mode = 0;
XX	break;
XX
XX	case 'c':
XX	p_mode = 1;
XX	break;
XX
XX	default:
XX	if (doing_init) {
XX	    puts("INIT - invalid transfer mode: ");
XX	    puts(tmode);
XX	    }
XX	else req("Script - invalid transfer mode: ",tmode,0);
XX	return;
XX	}
XX    if (doing_init) return;
XX
XX    ClearMenuStrip(mywindow);
XX    InitCommItems();                    /* Re-do comm menu   */
XX    SetMenuStrip(mywindow,&menu[0]);
XX    }
XX
XXvoid cmd_beep(dummy)
XXchar	*dummy;
XX    {
XX    if (p_volume == 0) DisplayBeep(NULL);
XX    else {
XX	BeginIO(&Audio_Request);
XX	WaitIO(&Audio_Request);
XX	}
XX    }
XX
XXvoid setvar(par,typ,var)
XXchar	*par;
XXint	typ,*var;
XX    {
XX    int	i;
XX
XX    switch (typ) {
XX	case 0: /* ON/OFF or YES/NO */
XX	case 1: /* not case */
XX	if ((par[1]|' ') == 'n' || (par[0]|' ') == 'y') *var = 1-typ;
XX	else						*var = typ;
XX	break;
XX
XX	case 2: /* read hex number */
XX	if (sscanf(par,"%x",&i) == 1) *var = i;
XX	    
XX	break;
XX
XX	case 3: /* read decimal number */
XX	if (sscanf(par,"%d",&i) == 1) *var = i;
XX	break;
XX	}
XX    }
XX
XXvoid cmd_echo(par)
XXchar	*par;
XX    {
XX    setvar(par,0,&p_echo);
XX    if (doing_init == 0) redoutil();
XX    }
XX
XXvoid cmd_wrap(par)
XXchar	*par;
XX    {
XX    setvar(par,0,&p_wrap);
XX    if (doing_init == 0) redoutil();
XX    }
XX
XXvoid cmd_numkey(par)
XXchar	*par;
XX    {
XX    setvar(par,1,&p_keyapp);
XX    if (doing_init == 0) redoutil();
XX    }
XX
XXvoid cmd_appcur(par)
XXchar	*par;
XX    {
XX    setvar(par,0,&p_curapp);
XX    if (doing_init == 0) redoutil();
XX    }
XX
XXvoid cmd_swap(par)
XXchar	*par;
XX    {
XX    setvar(par,0,&p_bs_del);
XX    if (doing_init == 0) redoutil();
XX    }
XX
XXvoid cmd_bkg(par)
XXchar	*par;
XX    {
XX    setvar(par,2,&p_background);
XX    }
XX
XXvoid cmd_bold(par)
XXchar	*par;
XX    {
XX    setvar(par,2,&p_bold);
XX    }
XX
XXvoid cmd_buf(par)
XXchar	*par;
XX    {
XX    setvar(par,3,&p_buffer);
XX    }
XX
XXvoid cmd_cursor(par)
XXchar	*par;
XX    {
XX    setvar(par,2,&p_cursor);
XX    }
XX
XXvoid cmd_depth(par)
XXchar	*par;
XX    {
XX    setvar(par,3,&p_depth);
XX    }
XX
XXvoid cmd_fore(par)
XXchar	*par;
XX    {
XX    setvar(par,2,&p_foreground);
XX    }
XX
XXvoid cmd_inter(par)
XXchar	*par;
XX    {
XX    setvar(par,0,&p_interlace);
XX    }
XX
XXvoid cmd_lines(par)
XXchar	*par;
XX    {
XX    setvar(par,3,&p_lines);
XX    }
XX
XXvoid cmd_screen(par)
XXchar	*par;
XX    {
XX    if ((par[0]|' ') == 'w') p_screen = 0;
XX    else		     p_screen = 1;
XX    }
XX
XXvoid cmd_wb(par)
XXchar	*par;
XX    {
XX    setvar(par,0,&p_wbcolors);
XX    }
XX
XXvoid cmd_key(par)
XXchar	*par;
XX    {
XX    int	i;
XX
XX    if (sscanf(par,"%x",&i) == 1) p_keyscript = (char)(i & 0x7f);
XX    }
XX
XXvoid cmd_volume(par)
XXchar	*par;
XX    {
XX    setvar(par,3,&p_volume);
XX    }
XX
XXvoid cmd_conv(par)
XXchar	*par;
XX    {
XX    setvar(par,0,&p_bs_del);
XX    if (doing_init == 0) redoutil();
XX    }
XX
XXvoid cmd_fnc(par)
XXchar	*par;
XX    {
XX    char    *s;
XX    int	    l;
XX    int	    i = atoi(par);
XX
XX    s = par;
XX    if (*s) s = next_wrd(s,&l);		/* skip key number */
XX    if (*s) s = next_wrd(s+l+1,&l);	/* point at desired string */
XX    if (*s) s = tostring(s);		/* convert the string */
XX    if (*s && i > 0 && i < 21) {
XX	if (i > 10) {
XX	    p_F[i-11] = malloc(strlen(s)+1);
XX	    strcpy(p_F[i-11],s);
XX	    }
XX	else {
XX	    p_f[i-1] = malloc(strlen(s)+1);
XX	    strcpy(p_f[i-1],s);
XX	    }
XX	}
XX    }
XX
XXvoid cmd_null(dummy)
XXchar *dummy;
XX    {
XX    }
XX
SHAR_EOF
if test 16463 -ne "`wc -c script.c`"
then
echo shar: error transmitting script.c '(should have been 16463 characters)'
fi
echo shar: extracting remote.c
sed 's/^XX//' << \SHAR_EOF > remote.c
XX/****************************************************
XX * vt100 emulator - remote character interpretation
XX *
XX *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
XX *	v2.5 870214 DBW - more additions (see readme file)
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
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#include "vt100.h"
XX
XXstatic int    p[10];
XXstatic int    numpar;
XXstatic char   escseq[40];
XX
XX/************************************************
XX*  function to handle remote characters
XX*************************************************/
XXvoid doremote(c)
XXchar c;
XX    {
XX    if (c == 24) { inesc = 0; inctrl = 0; return; }
XX    if (c == 27 || (inesc >= 0 && c >= ' ')) { doesc(c); return; }
XX    if (inctrl >= 0 && c >= ' ') { 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
XX    /* Collect intermediates */
XX    if (c < '0') {escseq[inesc++] = c; return; }
XX
XX    /* by process of elimination, we have a final character.
XX       Put it in the buffer, and dispatch on the first character
XX       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	curmode = FS_NORMAL; p_keyapp = 0; p_curapp = 0;
XX	inesc = -1;
XX	a[0] = 0; a[1] = 0; sa[0] = 0; sa[1] = 0;
XX	redoutil();
XX	emit(12);
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      case '=':				/* set keypad application mode */
XX        p_keyapp = 1;
XX	redoutil();
XX        return;
XX        
XX      case '>':				/* reset application mode */
XX        p_keyapp = 0;
XX	redoutil();
XX        return;
XX        
XX      case 'Z':
XX	sendchar(27); sendstring("[?1;7c"); 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 
XX	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
XX	    /* Only allowed BEFORE parameters */
XX    	    if (inctrl == 0) private = c;
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 most private sequences right now,
XX	so just punt them */
XX
XX    if ((private != 0 && private != '?') || badseq != 0) return;
XX    if (private == '?' && escseq[0] != 'h' &&
XX	escseq[0] != 'l') 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 'L':				/* ANSI insert line */
XX      case 'M':				/* ANSI delete line */
XX	if (p[0] <= 0) p[0] = 1;
XX	ScrollRaster(mywindow->RPort,0L,
XX	    (long)((escseq[0] == 'M' ? 8L : -8L) * p[0]),
XX	    (long)MINX,(long)y-6,(long)(MAXX+7),(long)bot+1);
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  = FS_NORMAL;
XX		break;
XX
XX		case 1:
XX		curmode |= FSF_BOLD;
XX		break;
XX
XX		case 4:
XX		curmode |= FSF_UNDERLINED;
XX		break;
XX
XX		case 5:
XX		curmode |= FSF_ITALIC;
XX		break;
XX
XX		default:
XX		curmode |= FSF_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 (private == 0 && p[0] == 20)		nlmode = 1;
XX	else if (private == '?') {
XX	    if      (p[0] == 7)	p_wrap   = 1;
XX	    else if (p[0] == 1)	p_curapp = 1;
XX	    redoutil();
XX	    }
XX	return;
XX
XX      case 'l':				/* Reset parameter */
XX	if (private == 0 && p[0] == 20)		nlmode = 0;
XX	else if (private == '?') {
XX	    if      (p[0] == 7)	p_wrap   = 0;
XX	    else if (p[0] == 1) p_curapp = 0;
XX	    redoutil();
XX	    }
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;7c"); 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 'a':
XX	doline(0,-6,8,1);
XX	break;
XX
XX	case 'j':
XX	case 'm':
XX	case 'v':   doline(4,-6,4,-2);
XX	if      (c=='j')  doline(0,-2,4,-2);
XX	else if (c=='m')  doline(4,-2,8,-2);
XX	else              doline(0,-2,8,-2);
XX	break;
XX
XX	case 'k':
XX	case 'l':
XX	case 'w': doline(4,-2,4,1);
XX	if      (c=='k')  doline(0,-2,4,-2);
XX	else if (c=='l')  doline(4,-2,8,-2);
XX	else              doline(0,-2,8,-2);
XX	break;
XX
XX	case 'n':
XX	case 'q': doline(0,-2,8,-2);
XX	if      (c=='n')  doline(4,-6,4,2);
XX	break;
XX
XX	case 't':
XX	case 'u':
XX	case 'x':   doline(4,-6,4,1);
XX	if      (c=='t')  doline(4,-2,8,-2);
XX	else if (c=='u')  doline(0,-2,4,-2);
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 10085 -ne "`wc -c remote.c`"
then
echo shar: error transmitting remote.c '(should have been 10085 characters)'
fi
echo shar: extracting window.c
sed 's/^XX//' << \SHAR_EOF > window.c
XX/****************************************************
XX * vt100 emulator - window/keyboard support
XX *
XX *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
XX *	v2.5 870214 DBW - more additions (see readme file)
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
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#include "vt100.h"
XX
XX/* keyboard definitions for toasc() */
XXstatic 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/***************************************************
XX *  function to swap the use of backspace and delete
XX ***************************************************/
XX
XXvoid swap_bs_del()
XX    {
XX    if (p_bs_del)   p_bs_del = 0;
XX    else	    p_bs_del = 1;
XX
XX    keys[0x41] =    p_bs_del ? 127 : 8;
XX    keys[0x46] =    p_bs_del ? 8 : 127;
XX    }
XX
XX/*************************************************
XX *  function to get file name (via a requestor)
XX *************************************************/
XXvoid req(prmpt,name,getinp)
XXchar *prmpt,*name;
XXint  getinp;
XX    {
XX    ULONG class;
XX    unsigned int code, qual;
XX    struct IntuiMessage *Msg;
XX
XX    /* Make sure the prompt gets updated */
XX    if (numreqs == 1 && strcmp(Prompt,prmpt) != 0) {
XX	EndRequest(&myrequest,mywindow);
XX	numreqs = 0;
XX	}
XX
XX    /* copy in a prompt and a default */
XX    strcpy(Prompt,prmpt);
XX    strcpy(InpBuf,name);
XX
XX    /* If there is a requester... reuse it */
XX    if (numreqs == 1) RefreshGadgets(&mystrgad,mywindow,&myrequest);
XX
XX    /* otherwise create it */
XX    else {
XX	if (Request(&myrequest,mywindow) == 0) {
XX	    emits("ERROR - CAN'T CREATE REQUESTOR FOR:\n");
XX	    emits(Prompt); emit('\n');
XX	    emits(InpBuf); emit('\n');
XX	    return;
XX	    }
XX	else numreqs = 1;
XX	}
XX
XX    /* if we don't want input, we're done */
XX    if (getinp == 0 || numreqs == 0) return;
XX
XX    /* throw away any extra messages */
XX    Wait(1L << mywindow->UserPort->mp_SigBit);
XX    while (Msg = (struct IntuiMessage *)GetMsg(mywindow->UserPort))
XX	ReplyMsg(Msg);
XX
XX    /* here is where we pre-select the gadget   */
XX    if (!ActivateGadget(&mystrgad,mywindow,&myrequest)) {
XX
XX	/* wait for his/her hands to get off the keyboard (Amiga-key) */
XX	Delay(20L);
XX	while (Msg = (struct IntuiMessage *)GetMsg(mywindow->UserPort))
XX	    ReplyMsg(Msg);
XX
XX	/* try once more before giving up... */
XX	ActivateGadget(&mystrgad,mywindow,&myrequest);
XX	}
XX
XX    /* wait for input to show up */
XX    while (1) {
XX	if ((NewMessage = (struct IntuiMessage *)
XX		GetMsg(mywindow->UserPort)) == FALSE) {
XX	    Wait(1L<<mywindow->UserPort->mp_SigBit);
XX	    continue;
XX	    }
XX	class = NewMessage->Class;
XX	code  = NewMessage->Code;
XX	qual  = NewMessage->Qualifier;
XX	ReplyMsg(NewMessage);
XX
XX	/* the requestor got terminated... yea!! */
XX	if (class == REQCLEAR) break;
XX
XX	/* maybe this is a menu item to handle */
XX	if (class == MENUPICK) handle_menupick(class,code);
XX	}
XX
XX    /* all done, so return the result */
XX    numreqs = 0;
XX    strcpy(name,InpBuf);
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    static char wrap_flag = 0;	/* are we at column 80? */
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	if (p_volume == 0) DisplayBeep(NULL);
XX	else {
XX	    BeginIO(&Audio_Request);
XX	    WaitIO(&Audio_Request);
XX	    }
XX	break;
XX
XX	default:
XX	if (c < ' ' || c > '~') break;
XX	if (p_wrap && wrap_flag && x >= MAXX) {
XX	    x = MINX;
XX	    y += 8;
XX	    if (y > MAXY) {
XX		y = MAXY;
XX		ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,
XX		    (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
XX		}
XX	    }
XX	Move(mywindow->RPort,(long)x,(long)y);
XX
XX	if (curmode&FSF_BOLD) {
XX	    if (p_depth > 1) {
XX		SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
XX		SetSoftStyle(mywindow->RPort,(long)curmode,253L);
XX		}
XX	    else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
XX	    }
XX	else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
XX
XX	if (curmode&FSF_REVERSE) {
XX	    SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID));
XX	    Text(mywindow->RPort,&c,1L);
XX	    SetDrMd(mywindow->RPort,(long)JAM2);
XX	    }
XX	else Text(mywindow->RPort,&c,1L);
XX
XX	if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L);
XX	x += 8;
XX	} /* end of switch */
XX
XX    if (y > MAXY) {
XX	y = MAXY;
XX	x = MINX;
XX	ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,
XX	    (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
XX	}
XX    if (x > MAXX) {
XX	wrap_flag = 1;
XX	x = MAXX;
XX	}
XX    else wrap_flag = 0;
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
XX    Move(mywindow->RPort,(long)x,(long)y);
XX    i = x / 8;
XX    if (i+la >= maxcol) {
XX	if (p_wrap == 0) la = maxcol - i;
XX	else {
XX	    lookahead[la] = 0;
XX	    emits(lookahead);
XX	    return;
XX	    }
XX	}
XX    if (curmode&FSF_BOLD) {
XX	if (p_depth > 1) {
XX	    SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
XX	    SetSoftStyle(mywindow->RPort,(long)curmode,253L);
XX	    }
XX	else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
XX	}
XX    else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
XX
XX    if (curmode&FSF_REVERSE) {
XX	SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID));
XX	Text(mywindow->RPort,lookahead,(long)la);
XX	SetDrMd(mywindow->RPort,(long)JAM2);
XX	}
XX    else Text(mywindow->RPort,lookahead,(long)la);
XX    if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L);
XX    x += (8 * la);
XX    }
XX
XX/******************************
XX* Manipulate cursor
XX******************************/
XXvoid cursorflip()
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,qual,local)
XXunsigned int code,qual;
XXint local;
XX    {
XX    unsigned int ctrl,shift,capsl,amiga,alt;
XX    char c = 0, keypad = 0;
XX    char *ptr;
XX
XX    ctrl    = qual & IEQUALIFIER_CONTROL;
XX    capsl   = qual & IEQUALIFIER_CAPSLOCK;
XX    amiga   = qual & (IEQUALIFIER_LCOMMAND | IEQUALIFIER_RCOMMAND);
XX    shift   = qual & (IEQUALIFIER_LSHIFT   | IEQUALIFIER_RSHIFT);
XX    alt	    = qual & (IEQUALIFIER_LALT     | IEQUALIFIER_RALT);
XX
XX    switch ( code )
XX	{
XX	case 98:
XX	case 226:
XX	case 99:
XX	case 227:
XX	case 96:
XX	case 97:
XX	case 224:
XX	case 225:
XX	case 100:
XX	case 101:
XX	case 228:
XX        case 229:
XX	case 102:
XX	case 103:
XX	case 230:
XX	case 231:   c = 0; break; /* ctrl, shift, capsl, amiga, or alt */
XX
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)	ptr = p_F[code - 0x50];
XX		    else	ptr = p_f[code - 0x50];
XX		    if (!script_on && *ptr == p_keyscript)
XX			    script_start(++ptr);
XX		    else    sendstring(ptr);
XX		    break;
XX	case 0x0f: c = (p_keyapp) ? 'p' : '0'; keypad = TRUE; break;
XX	case 0x1d: c = (p_keyapp) ? 'q' : '1'; keypad = TRUE; break;
XX	case 0x1e: c = (p_keyapp) ? 'r' : '2'; keypad = TRUE; break;
XX	case 0x1f: c = (p_keyapp) ? 's' : '3'; keypad = TRUE; break;
XX	case 0x2d: c = (p_keyapp) ? 't' : '4'; keypad = TRUE; break;
XX	case 0x2e: c = (p_keyapp) ? 'u' : '5'; keypad = TRUE; break;
XX	case 0x2f: c = (p_keyapp) ? 'v' : '6'; keypad = TRUE; break;
XX	case 0x3d: c = (p_keyapp) ? 'w' : '7'; keypad = TRUE; break;
XX	case 0x3e: c = (p_keyapp) ? 'x' : '8'; keypad = TRUE; break;
XX	case 0x3f: c = (p_keyapp) ? 'y' : '9'; keypad = TRUE; break;
XX	case 0x43: c = (p_keyapp) ? 'M' : 13 ; keypad = TRUE; break;
XX	case 0x4a: c = (p_keyapp) ? 'l' : '-'; keypad = TRUE; break;
XX	case 0x5f: sendstring("\033Om") ;break;
XX	case 0x3c: c = (p_keyapp) ? 'n' : '.'; keypad = TRUE; break;
XX	case 0x4c:
XX	case 0x4d: 
XX	case 0x4e: 
XX	case 0x4f: sendchar(27);            /* cursor keys */
XX		   if (p_curapp) sendchar('O');
XX		   else sendchar('[');
XX		   sendchar(code - 11);
XX		   break;
XX
XX	default:
XX	if (code < 75) c = keys[code];
XX	else c = 0;
XX	}
XX
XX    if (keypad) {
XX        if (p_keyapp) sendstring("\033O");
XX        sendchar(c);
XX        return(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	else if (c == '6') c = 30;
XX	else if (c == '-' || c == '?') c = 31;
XX	}
XX    if (ctrl && (c == '@' || c == '2' || c == ' ')) {
XX	if (!local) sendchar(alt?128:0);
XX	c = 0;
XX	}
XX    else if (c != 0 && (!local)) sendchar(alt?c+128:c);
XX    return((int)c);
XX    }
XX
SHAR_EOF
if test 10671 -ne "`wc -c window.c`"
then
echo shar: error transmitting window.c '(should have been 10671 characters)'
fi
echo shar: extracting expand.c
sed 's/^XX//' << \SHAR_EOF > expand.c
XX/*************************************************************
XX * vt100 terminal emulator - Wild card and Directory support
XX *
XX *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
XX *	v2.5 870214 DBW - more additions (see readme file)
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW	- new features (see README)
XX *           860830 Steve Drew Added Wild card support,
XX *		    features(expand.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 *      Much of the code from this module extracted from
XX *      Matt Dillons Shell program. (Thanxs Matt.)
XX *************************************************************/
XX
XX#include "vt100.h"
XX
XXstruct DPTR {                    /* Format of directory fetch ptr */
XX   struct FileLock *lock;        /* lock on directory   */
XX   struct FileInfoBlock *fib;    /* mod'd fib for entry */
XX};
XX
XX/*
XX * Disk directory routines
XX *
XX *
XX * diropen() returns a struct DPTR, or NULL if the given file does not
XX * exist.  stat will be set to 1 if the file is a directory.  If the
XX * name is "", then the current directory is openned.
XX *
XX * dirnext() returns 1 until there are no more entries.  The **name and
XX * *stat are set.  *stat = 1 if the file is a directory.
XX *
XX * dirclose() closes a directory channel.
XX *
XX */
XX
XXstruct DPTR *
XXdiropen(name, stat)
XXchar *name;
XXint *stat;
XX{
XX   struct DPTR *dp;
XX   int namelen, endslash = 0;
XX   struct FileLock *MyLock;
XX   
XX   MyLock = (struct FileLock *)( (ULONG) ((struct Process *)
XX                                 (FindTask(NULL)))->pr_CurrentDir);
XX   namelen = strlen(name);
XX   if (namelen && name[namelen - 1] == '/') {
XX      name[namelen - 1] = '\0';
XX      endslash = 1;
XX   }
XX   *stat = 0;
XX   dp = (struct DPTR *)malloc(sizeof(struct DPTR));
XX   if (*name == '\0') 
XX      dp->lock = (struct FileLock *)DupLock (MyLock);
XX   else
XX      dp->lock = (struct FileLock *)Lock (name, ACCESS_READ);
XX   if (endslash)
XX      name[namelen - 1] = '/';
XX   if (dp->lock == NULL) {
XX      free (dp);
XX      return (NULL);
XX   }
XX   dp->fib = (struct FileInfoBlock *)
XX         AllocMem((long)sizeof(struct FileInfoBlock), MEMF_PUBLIC);
XX   if (!Examine (dp->lock, dp->fib)) {
XX      dirclose (dp);
XX      return (NULL);
XX   }
XX   if (dp->fib->fib_DirEntryType >= 0)
XX      *stat = 1;
XX   return (dp);
XX}
XX
XXdirnext(dp, pname, stat)
XXstruct DPTR *dp;
XXchar **pname;
XXint *stat;
XX{
XX   if (dp == NULL)
XX      return (0);
XX   if (ExNext (dp->lock, dp->fib)) {
XX      *stat = (dp->fib->fib_DirEntryType < 0) ? 0 : 1;
XX      *pname = dp->fib->fib_FileName;
XX      return (1);
XX   }
XX   return (0);
XX}
XX
XX
XXdirclose(dp)
XXstruct DPTR *dp;
XX{
XX   if (dp == NULL)
XX      return (1);
XX   if (dp->fib)
XX      FreeMem (dp->fib, (long)sizeof(*dp->fib));
XX   if (dp->lock)
XX      UnLock (dp->lock);
XX   free (dp);
XX   return (1);
XX}
XX
XXfree_expand(av)
XXchar **av;
XX{
XX   char **base = av;
XX
XX   if (av) {
XX      while (*av) {
XX         free (*av);
XX         ++av;
XX      }
XX      free (base);
XX   }
XX}
XX
XX/*
XX * EXPAND(wild_name, pac)
XX *    wild_name      - char * (example: "df0:*.c")
XX *    pac            - int  *  will be set to # of arguments.
XX *
XX */
XX
XX
XXchar **
XXexpand(base, pac)
XXchar *base;
XXint *pac;
XX{
XX   char **eav = (char **)malloc (sizeof(char *));
XX   int  eleft, eac;
XX
XX   char *ptr, *name;
XX   char *bname, *ename, *tail;
XX   int stat, scr;
XX   struct DPTR *dp;
XX
XX   *pac = eleft = eac = 0;
XX   base = strcpy(malloc(strlen(base)+1), base);
XX   for (ptr = base; *ptr && *ptr != '?' && *ptr != '*'; ++ptr);
XX   for (; ptr >= base && !(*ptr == '/' || *ptr == ':'); --ptr);
XX   if (ptr < base) {
XX      bname = strcpy (malloc(1), "");
XX   } else {
XX      scr = ptr[1];
XX      ptr[1] = '\0';
XX      bname = strcpy (malloc(strlen(base)+1), base);
XX      ptr[1] = scr;
XX   }
XX   ename = ptr + 1;
XX   for (ptr = ename; *ptr && *ptr != '/'; ++ptr);
XX   scr = *ptr;
XX   *ptr = '\0';
XX   tail = (scr) ? ptr + 1 : NULL;
XX
XX   if ((dp = diropen (bname, &stat)) == NULL  ||  stat == 0) {
XX      free (bname);
XX      free (base);
XX      free (eav);
XX      req ("Could not open directory","",0);
XX      return (NULL);
XX   }
XX   while (dirnext (dp, &name, &stat)) {
XX      if (compare_ok(ename, name)) {
XX         if (tail) {
XX            int alt_ac;
XX            char *search, **alt_av, **scrav;
XX            struct FileLock *lock;
XX
XX            if (!stat)      /* expect more dirs, but this not a dir */
XX               continue;
XX            lock = (struct FileLock *)CurrentDir (dp->lock);
XX            search = malloc(strlen(name)+strlen(tail)+2);
XX            strcpy (search, name);
XX            strcat (search, "/");
XX            strcat (search, tail);
XX            scrav = alt_av = expand (search, &alt_ac);
XX            CurrentDir (lock);
XX            if (scrav) {
XX               while (*scrav) {
XX                  if (eleft < 2) {
XX                     char **scrav = (char **)
XX			malloc(sizeof(char *) * (eac + 10));
XX                     movmem (eav, scrav, sizeof(char *) * (eac + 1));
XX                     free (eav);
XX                     eav = scrav;
XX                     eleft = 10;
XX                  }
XX                  eav[eac] = malloc(strlen(bname)+strlen(*scrav)+1);
XX                  strcpy(eav[eac], bname);
XX                  strcat(eav[eac], *scrav);
XX                  free (*scrav);
XX                  ++scrav;
XX                  --eleft, ++eac;
XX               }
XX               free (alt_av);
XX            }
XX         } else {
XX            if (eleft < 2) {
XX               char **scrav = (char **)
XX		    malloc(sizeof(char *) * (eac + 10));
XX               movmem (eav, scrav, sizeof(char *) * (eac + 1));
XX               free (eav);
XX               eav = scrav;
XX               eleft = 10;
XX            }
XX            eav[eac] = malloc (strlen(bname)+strlen(name)+1);
XX            eav[eac] = strcpy(eav[eac], bname);
XX            strcat(eav[eac], name);
XX            --eleft, ++eac;
XX         }
XX      }
XX   }
XX   dirclose (dp);
XX   *pac = eac;
XX   eav[eac] = NULL;
XX   free (bname);
XX   free (base);
XX   if (eac)
XX      return (eav);
XX   free (eav);
XX   return (NULL);
XX}
XX
XX/*
XX * Compare a wild card name with a normal name
XX */
XX
XX#define MAXB   8
XX
XXcompare_ok(wild, name)
XXchar *wild, *name;
XX{
XX   char *w = wild;
XX   char *n = name;
XX   char *back[MAXB][2];
XX   int  bi = 0;
XX
XX   while (*n || *w) {
XX      switch (*w) {
XX      case '*':
XX         if (bi == MAXB) {
XX            req ("Too many levels of '*'","",0);
XX            return (0);
XX         }
XX         back[bi][0] = w;
XX         back[bi][1] = n;
XX         ++bi;
XX         ++w;
XX         continue;
XXgoback:
XX         --bi;
XX         while (bi >= 0 && *back[bi][1] == '\0')
XX            --bi;
XX         if (bi < 0)
XX            return (0);
XX         w = back[bi][0] + 1;
XX         n = ++back[bi][1];
XX         ++bi;
XX         continue;
XX      case '?':
XX         if (!*n) {
XX            if (bi)
XX               goto goback;
XX            return (0);
XX         }
XX         break;
XX      default:
XX         if (toupper(*n) != toupper(*w)) {
XX            if (bi)
XX               goto goback;
XX            return (0);
XX         }
XX         break;
XX      }
XX      if (*n)  ++n;
XX      if (*w)  ++w;
XX   }
XX   return (1);
XX}
XX
XXset_dir(new)
XXchar *new;
XX{
XX   register 	char 		*s;
XX   int   			i;
XX   struct 	FileLock 	*lock;
XX   char 			temp[60];
XX   struct       FileInfoBlock   *fib;
XX  
XX   if (*new != '\000') {
XX      strcpy(temp, MyDir);
XX      s = new;
XX      if (*s == '/') {
XX         s++;
XX         for (i=strlen(MyDir);
XX              MyDir[i] != '/' && MyDir[i] != ':';
XX              i--);
XX         MyDir[i+1] = '\0';
XX         strcat(MyDir, s);
XX         }
XX      else if (exists(s, ':') == 0) {
XX         if (MyDir[strlen(MyDir)-1] != ':')
XX            strcat(MyDir, "/");
XX         strcat(MyDir, s);
XX         }
XX      else
XX         strcpy(MyDir, s);
XX
XX      if ((lock = (struct FileLock *)Lock(MyDir, (long)ACCESS_READ)) == 0) {
XX         req("Directory not found:",MyDir,0);
XX         strcpy(MyDir, temp);
XX         }
XX      else {
XX	 fib = (struct FileInfoBlock *)AllocMem(
XX		(long)sizeof(struct FileInfoBlock), MEMF_PUBLIC);
XX	 if (fib) {
XX      	    if (Examine(lock, fib)) {
XX      		if (fib->fib_DirEntryType > 0) {
XX		    CurrentDir(lock);
XX		    if (MyDirLock != NULL) UnLock(MyDirLock);
XX		    MyDirLock = lock;
XX		    if (MyDir[strlen(MyDir)-1] == '/')
XX			MyDir[strlen(MyDir)-1] = '\000';
XX		    }
XX		else {
XX            	    req("Not a Directory:",MyDir,0);               
XX            	    strcpy(MyDir,temp);
XX		    }
XX		}
XX	    FreeMem(fib, (long)sizeof(struct FileInfoBlock));
XX	    }
XX	else {
XX	    req("Can't change directory... ","No free memory!",0);
XX	    strcpy(MyDir,temp);
XX	    }
XX	}
XX    }
XX}
XX
XXexists(s,c)
XXchar *s,c;
XX    {
XX    while (*s != '\000')
XX	if (*s++ == c) return(1);
XX    return(0);
XX    }
SHAR_EOF
if test 8710 -ne "`wc -c expand.c`"
then
echo shar: error transmitting expand.c '(should have been 8710 characters)'
fi
echo shar: extracting kermit.c
sed 's/^XX//' << \SHAR_EOF > kermit.c
XX/*************************************************************
XX * vt100 terminal emulator - KERMIT protocol support
XX *
XX *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
XX *	v2.5 870214 DBW - more additions (see readme file)
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
XX *	     860901 ACS - Added eight bit quoting
XX *           860830 Steve Drew Wild card support, err recovry,bugs.
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#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 MYEBQ	 '&'	   /* 8th bit prefix character */
XX#define MYPAD      0       /* Number of padding charss 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   sendabort, /* flag for aborting send file  */
XX   rptflg,    /* are we doing repeat quoting */
XX   ebqflg,    /* are we doing 8th bit quoting */
XX   notfirst,  /* is this the first file received */
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   ebq,	      /* Quote character for 8th bit quoting */
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   sl1[] = "FILE            PKT NUM RETR BYTES",
XX   sl2[] = "%-15s  %c %4d  %2d %6ld %5s",
XX   sl3[50],
XX   mainmode[10];
XX
XXFILE *fp;     /* file for send/receive */
XX
XXchar *
XXgetfname(name)   /* returns ptr to start of file name from 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 amount, c, wild;
XX   char *p, **list = NULL;
XX
XX   if (!strcmp(file,"$")) { saybye(); return(2); }
XX   p = file;
XX   while(*p && *p != '*' && *p != '?') p++;
XX   if (*p) { 
XX       wild = TRUE;
XX       list = expand(file, &amount);
XX       if (list == NULL)  req("KERMIT","No wild card match",0);
XX       }
XX   else {
XX       wild = FALSE;
XX       amount = 1;
XX       }
XX   for (c = 0; c < amount; c++) {
XX       if (wild == TRUE) p = list[c];
XX         else  p = file;
XX       strcpy(filnam,getfname(p));
XX       ttime = TTIME_KERMIT;
XX       tp = retry = n = numtry = 0; totbytes = 0L;
XX       if ((fp = fopen(p,"r")) == NULL) {
XX           req("KERMIT: can't open send file:",p,0);
XX           continue;
XX           }
XX       strcpy(mainmode,"SEND");
XX       ClearBuffer();
XX       if (sendsw()) dostats(' ',"DONE");
XX       fclose(fp);
XX       } 
XX   free_expand(list);
XX   return TRUE;
XX   }
XX 
XXdokreceive(file,more)
XXchar *file;
XXint more;
XX   {
XX   int retval;
XX   
XX   ttime = TTIME_KERMIT;
XX   if (!strcmp(file,"$")) { saybye(); return(2); }
XX   strcpy(filnam, file);   
XX   if (server) strcpy(mainmode,"GET");
XX   else	       strcpy(mainmode,"RECV");
XX   tp =  retry = n =  numtry = notfirst = 0; totbytes = 0L;
XX   ClearBuffer();
XX   retval  = recsw();
XX   return(retval);
XX   }
XX
XXsendsw()
XX   {
XX   char sinit(), sfile(), sdata(), seof(), sbreak();
XX   sendabort = 0;
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':   if (sendabort) return FALSE;
XX                     else return TRUE;
XX         case 'E':   dostats('E',"ERROR");  /* so print the err and abort */
XX                     print_host_err(ackpkt);
XX                     return(FALSE);
XX         case 'A':   if (timeout == USERABORT) {
XX			 timeout = GOODREAD;
XX                         n = (n+1)%64;			 
XX                     	 sendabort = 1;
XX                     	 dostats('A',"ABORT");
XX                     	 strcpy(msgpkt, "D");
XX                     	 state = 'Z'; 
XX                     	 break;
XX                     	 }
XX                     if (timeout == TIMEOUT)  dostats('A',"TMOUT");
XX                     else { /* protocol error dectected by us */
XX			 dostats('A',"ERROR");
XX			 print_our_err();
XX			 }
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 = MYQUOTE;
XX                 numtry = 0;
XX                 retry--;
XX                 n = (n+1)%64;
XX                 return('F');
XX      case 'E':  return('E');
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('E');
XX      case FALSE: if (timeout == USERABORT) state = 'A';
XX                  return(state);
XX      default:
XX         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('E');
XX      case FALSE: if (timeout == USERABORT) state = 'A';
XX                  return(state);
XX      default:    
XX         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) {*/	/* tell host to discard file */
XX/*      timeout = GOODREAD;	*/
XX/*        spack('Z',n,1,"D");	*/
XX/*        }			*/
XX/*   else			*/
XX	spack('Z',n,sendabort,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('E');
XX      case FALSE: return(state);
XX      default:
XX         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('E');
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   dostats(' ',"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*/ 
XX
XX
XXrecsw()
XX   {
XX   char rinit(), rfile(), rdata();
XX
XX   state = 'R';
XX   
XX   while(TRUE) {
XX      switch(state) {
XX         case 'R':   state = rinit(); break;
XX         case 'Z':
XX         case 'F':   state = rfile(); break;
XX         case 'D':   state = rdata(); break;
XX         case 'C':   return(TRUE);
XX         case 'E':
XX         case 'A':   /* 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		    if (timeout == USERABORT){
XX			/* send an error packet back   */
XX                         dostats('A',"ABORT");
XX                         spack('E',n,12,"User aborted"); 
XX                     }
XX                     else if (timeout == TIMEOUT) {
XX			    /* we timed out waiting */
XX    			    /* will we need to spack here ?*/
XX			 dostats('A',"TMOUT");
XX			 }
XX			    /* must be 'E' from host or we
XX			     detected a protocol error */
XX                         else dostats('A',"ERROR");
XX
XX		     if (state == 'E') print_host_err(msgpkt);
XX
XX		     else if (timeout == GOODREAD) /* tell host why */
XX			print_our_err();
XX			   /* will this kill all files ?*/
XX                     do  {
XX                         ttime = 2;        
XX                         readchar();
XX                         }  while (timeout == GOODREAD);
XX                     fclose(fp);
XX                     sendstring("\r");
XX                     return(FALSE);
XX	 default:    return(FALSE);	
XX         }
XX      }
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('E');
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            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            return(state);
XX            }
XX         else return('A');
XX      case 'F':
XX         if (num != n) return('A');
XX	 strcpy(filnam,msgpkt);
XX         if (p_convert) {
XX             char *p;
XX	     p = &filnam[0];
XX             while (*p) { *p = tolower(*p); p++; }
XX             }
XX	 if (notfirst) { 
XX             totbytes = 0L;
XX             dostats('F',"RECV");
XX             }
XX	 /* is the first file so emit actual file name from host */
XX         else {
XX	     notfirst++;
XX	     }
XX         if ((fp = fopen(filnam,"w")) == NULL) {
XX	     req("KERMIT: Unable to create file:",filnam,0);
XX	     strcpy(msgpkt,"VT100 - Kermit - cannot create file: ");
XX	     strcat(msgpkt,filnam);
XX	     spack('E',n,strlen(msgpkt),msgpkt); /* let host know */
XX             dostats('E',"ERROR");
XX             return ('\0');       /* abort everything */
XX             }
XX         spack('Y',n,0,0);
XX         oldtry = numtry;
XX         numtry = 0;
XX         retry--;
XX         n = (n+1)%64;
XX         return('D');
XX
XX      /* totaly done server sending no more */
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('E');
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               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 'Z':
XX         if (num != n) return('A');
XX         spack('Y',n,0,0);
XX         n = (n+1)%64;
XX         retry--;
XX         dostats('Z',"DONE");
XX	 fclose(fp);
XX         return('Z');
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	     return(state);
XX             }
XX      case 'E':
XX         return('E');
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
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,mainmode);
XX   bufp = buffer;
XX   ClearBuffer();
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,mainmode);
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
XX   if (ebqflg && b8) {			/* Do 8th bit prefix if necessary. */
XX	msgpkt[size++] = ebq;
XX	a = a7;
XX	}
XX   
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
XX   if ((ebqflg) && (a7 == ebq))	/* Prefix the 8th bit prefix */
XX       msgpkt[size++] = quote;  /* if doing 8th-bit prefixes */
XX
XX   msgpkt[size++] = a;
XX   msgpkt[size] = '\0';
XX   }
XX
XXvoid decode()
XX   {
XX   USHORT  a, a7, b8;
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      b8 = 0;
XX      if (ebqflg) {                  /* 8th-bit prefixing? */
XX	  if (a == ebq) {            /* Yes, got an 8th-bit prefix? */
XX	      b8 = 0200;             /* Yes, remember this, */
XX	      a = *buf++;            /* and get the prefixed character. */
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      a |= b8;
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_KERMIT);
XX   data[2] = tochar(MYPAD);
XX   data[3] = ctl(MYPCHAR);
XX   data[4] = tochar(MYEOL);
XX   data[5] = MYQUOTE;
XX   if ((p_parity > 0) || ebqflg) {         /* 8-bit quoting... */
XX	data[6] = MYEBQ;          /* If parity or flag on, send &. */
XX	if ((ebq > 0040 && ebq < 0100) || /* If flag off, then turn it on  */
XX	   (ebq > 0140 && ebq < 0177) || /* if other side has asked us to */
XX	   (ebq == 'Y')) ebqflg = 1;
XX	}
XX    else				    /* Normally, */
XX       data[6] = 'Y';			    /* just say we're willing. */
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    ttime   = 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    ebqflg  = 0;
XX    if (data[6] == 0) return;
XX    ebq = data[6];
XX    if ((ebq > 040 && ebq < 0100) || 
XX	(ebq > 0140 && ebq < 0177)) ebqflg = 1;
XX    else if (((p_parity > 0) || ebqflg) && (ebq == 'Y')) {
XX	ebqflg = 1;
XX	ebq = '&';
XX	}
XX    else ebqflg = 0;
XX    if (data[7] == 0) return;
XX    if (data[8] == 0) return;
XX    rptq    = data[8];
XX    rptflg  = ((rptq > 040 && rptq < 0100) || 
XX	(rptq > 0140 && rptq < 0177));
XX    }
XX
XXsaybye()
XX  {
XX  int len,num;
XX  spack('G',n,1,"F");  /* shut down server no more files */
XX  rpack(&len,&num,ackpkt);
XX  }
XX
XXprint_our_err()
XX    {
XX    if (retry > MAXTRY || oldtry > MAXTRY) {
XX	req("KERMIT:","Too may retries for packet",0);
XX	strcpy(msgpkt,"VT100 KERMIT: Too many retries for packet");
XX	}
XX    else {
XX	req("KERMIT:","Protocol Error",0);
XX	strcpy(msgpkt,"VT100 KERMIT: Protocol Error");
XX	}
XX    spack('E',n,strlen(msgpkt));
XX    }
XX
XXprint_host_err(msg)
XX  char *msg;
XX  {
XX  req("KERMIT Host Error:",msg,0);
XX  }
XX
XXdostats(type,stat)
XXchar type,*stat;
XX    {
XX    if (type == 'Y' || type == 'N' || type == 'G') return;
XX    sprintf(sl3,sl2,filnam,type,n+(tp*64),retry-1,(long)totbytes,stat);
XX    if (n==63) tp++;
XX    req(sl1,sl3,0);
XX    }
XX
XXClearBuffer()
XX    {
XX    AbortIO(Read_Request);
XX    Read_Request->IOSer.io_Command = CMD_CLEAR;
XX    DoIO(Read_Request);
XX    Read_Request->IOSer.io_Command = CMD_READ;
XX    SendIO(Read_Request);
XX    }
XX
SHAR_EOF
if test 22019 -ne "`wc -c kermit.c`"
then
echo shar: error transmitting kermit.c '(should have been 22019 characters)'
fi
echo shar: extracting xmodem.c
sed 's/^XX//' << \SHAR_EOF > xmodem.c
XX/*************************************************************
XX * vt100 terminal emulator - XMODEM protocol support
XX *
XX *	v2.6 870227 DBW - bug fixes for all the stuff in v2.5
XX *	v2.5 870214 DBW - more additions (see readme file)
XX *	v2.4 861214 DBW - lots of fixes/additions (see readme file)
XX *	v2.3 861101 DBW - minor bug fixes
XX *	v2.2 861012 DBW - more of the same
XX *	v2.1 860915 DBW - new features (see README)
XX *	     860901 ACS - Added Parity and Word Length and support code
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#include "vt100.h"
XX
XXint enablexon = TRUE;
XX
XXstatic unsigned long parity_settings[4] = {
XX    0x96696996,
XX    0x69969669,
XX    0x69969669,
XX    0x96696996 };
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    int doxon,i,j,k;
XX
XX    doxon = enablexon;
XX    if (doxon) No_XON();
XX    switch (p_parity) {
XX	case 0:	/* no parity */
XX	rs_out[0] = ch & 0xFF;
XX	break;
XX
XX	case 1: /* mark */
XX	rs_out[0] = (ch & 0x7F) | 0x80;
XX	break;
XX
XX	case 2: /* space */
XX	rs_out[0] = ch & 0x7F;
XX	break;
XX	
XX	case 3:	/* even */
XX	case 4: /* odd  */
XX        i     = (ch >> 5) & 0x3;
XX	j     = ch & 0x1F;
XX	k     = ((parity_settings[i] >> j) & 0x1) << 7;
XX	if (p_parity == 3)			/* even parity */
XX	    rs_out[0] = (ch & 0x7F) | k;
XX	else					/* odd parity */
XX	    rs_out[0] = (ch & 0x7F) | (k ^ 0x80);
XX	}
XX    DoIO(Write_Request);
XX    if (doxon) Do_XON();
XX    }
XX
XX/* send a break to the host */
XXvoid sendbreak() {
XX    AbortIO(Read_Request);
XX    Read_Request->IOSer.io_Command = SDCMD_BREAK;
XX    DoIO(Read_Request);
XX    Read_Request->IOSer.io_Command = CMD_READ;
XX    SendIO(Read_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	    SendIO(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	         req("ERROR:","User aborted transfer",0);
XX	         timeout = USERABORT;
XX                 return('\0');
XX	         }
XX            continue;
XX            }
XX        if (rd == FALSE && CheckIO(&Timer)) {
XX            req("ERROR","Timeout waiting for character",0);
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 & (p_parity == 0 ? 0xFF : 0x7F));
XX    }
XX
XXvoid No_XON() {
XX
XX    /* turn off XON/XOFF processing */
XX    enablexon = FALSE;
XX    Write_Request->io_SerFlags |= SERF_XDISABLED;
XX    Write_Request->IOSer.io_Command = SDCMD_SETPARAMS;
XX    DoIO(Write_Request);
XX    Write_Request->IOSer.io_Command = CMD_WRITE;
XX    }
XX
XXvoid Do_XON() {
XX    /* turn on XON/XOFF processing */
XX    enablexon = TRUE;
XX    Write_Request->io_SerFlags &= ~SERF_XDISABLED;
XX    Write_Request->IOSer.io_Command = SDCMD_SETPARAMS;
XX    DoIO(Write_Request);
XX    Write_Request->IOSer.io_Command = CMD_WRITE;
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 scrstr[40],scrstr2[40];
XX    bytes_xferred = 0L;
XX    ttime = TTIME_SHORT;
XX
XX    if ((fd = creat(file, 0)) < 0)
XX	{
XX	req("XMODEM Can't Open File:",file,0);
XX	return FALSE;
XX	}
XX    else
XX    strcpy(scrstr,"XMODEM Receive, <esc> to abort");
XX    req(scrstr,"",0);
XX
XX    sectnum = errors = bufptr = 0;
XX    sendchar(NAK);
XX    firstchar = 0;
XX    No_XON();
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		    Do_XON();
XX		    return FALSE;
XX		}
XX	    } while (firstchar != SOH && firstchar != EOT);
XX
XX	if  (firstchar == SOH)
XX	    {
XX	    sprintf(scrstr2,"Getting Block %4d...",sectnum);
XX	    req(scrstr,scrstr2,0);
XX	    sectcurr = readchar();
XX	    if (timeout != GOODREAD) { Do_XON(); return FALSE; }
XX	    sectcomp = readchar();
XX	    if (timeout != GOODREAD) { Do_XON(); 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) { Do_XON(); return FALSE; }
XX			checksum = (checksum + bufr[j]) & 0xff;
XX			}
XX		    if (checksum == readchar() && timeout == GOODREAD)
XX			{
XX			errors = 0;
XX			sprintf(scrstr2,"Block %4d verified",sectnum);
XX			sectnum++;
XX			bufptr += SECSIZ;
XX			bytes_xferred += SECSIZ;
XX			req(scrstr,scrstr2,0);
XX			if (bufptr == BufSize)
XX			    {
XX			    if (write(fd, bufr, BufSize-128) == EOF)
XX				{
XX				req(scrstr,"Error Writing File",0);
XX				Do_XON();
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) { Do_XON(); 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) {
XX			    Do_XON();
XX			    return FALSE;
XX			    }
XX			req(scrstr,"Received Duplicate Sector",0);
XX			sendchar(ACK);
XX			}
XX		    else errorflag = TRUE;
XX    		    }
XX		}
XX	    else errorflag = TRUE;
XX	    }
XX	if (errorflag == TRUE)
XX	    {
XX	    errors++;
XX	    req(scrstr,"Error",0);
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	Do_XON();
XX	return TRUE;
XX	}
XX    Do_XON();
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 scrstr[40],scrstr2[40];
XX    bytes_xferred = 0;
XX    ttime = TTIME_LONG;
XX
XX    if ((fd = open(file, 0)) < 0) {
XX	req("XMODEM","Cannot Open Send File",0);
XX	return FALSE;
XX	}
XX    else
XX    strcpy(scrstr,"XMODEM Send, <esc> to abort");
XX    req(scrstr,"",0);
XX    attempts = 0;
XX    sectnum = 1;
XX    No_XON();
XX    /* wait for sync char */
XX    j=1;
XX    while (((c = readchar()) != NAK) && (j++ < ERRORMAX))
XX	if (timeout == USERABORT) { Do_XON(); return(FALSE); }
XX    if (j >= (ERRORMAX))
XX	{
XX	req(scrstr,"Receiver not sending NAKs",0);
XX	Do_XON();
XX	return FALSE;
XX	}
XX
XX    while ((bytes_to_send = read(fd, bufr, BufSize)) && 
XX	    attempts != RETRYMAX)
XX	{
XX	if (bytes_to_send == EOF)
XX	    {
XX	    req(scrstr,"Error Reading File",0);
XX	    Do_XON();
XX	    return FALSE;
XX	    }
XX
XX	bufptr = 0;
XX	while (bytes_to_send > 0 && attempts != RETRYMAX)
XX	    {
XX	    attempts = 0;
XX	    sprintf(scrstr2,"Sending block %4d",sectnum);
XX	    do {
XX		req(scrstr,scrstr2,0);
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) {
XX		    req(scrstr,"ABORTED",0);
XX		    Do_XON();
XX		    return FALSE;
XX		    }
XX		} while ((c != ACK) && (attempts != RETRYMAX));
XX	    bufptr += size;
XX	    bytes_xferred += size;
XX	    sprintf(scrstr2,"Sent block %4d",sectnum);
XX	    req(scrstr,scrstr2,0);
XX	    sectnum++;
XX	    }
XX	}
XX    close(fd);
XX    if (attempts == RETRYMAX)
XX	{
XX	req(scrstr,"No Acknowledgment, ABORTING",0);
XX	Do_XON();
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	    req(scrstr,"NO END OF FILE",0);
XX	}
XX    Do_XON();
XX    return TRUE;
XX    }
XX
XX/* allow for multi file xfers separated by commas under
XX    kermit and XMODEM */
XX
XXvoid multi_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    if (name[0] == '$' && name[1] == '\0') {
XX	saybye();
XX	return;
XX	}
XX    p = name;
XX    while(*p == ' ') p++;
XX    while(*p && *p != ',' && *p != ' ') p++;
XX    if (*p == '\0')   done = TRUE;
XX    else	      multi = 1;
XX    *p = '\0';
XX
XX    status = ((*mode)(name, multi));
XX    if (status == FALSE) close(fd);
XX    if (!done && timeout != USERABORT) multi_xfer(++p, mode, do_send);
XX    else emit('\n');
XX    server = 0;
XX    multi = 0;
XX    }
XX
SHAR_EOF
if test 9859 -ne "`wc -c xmodem.c`"
then
echo shar: error transmitting xmodem.c '(should have been 9859 characters)'
fi
#	End of shell archive
exit 0

acs@amdahl.UUCP (02/26/87)

In browsing through script.c I noticed that there is no reference to
p_convert (the KERMIT filename case conversion variable).  I see two
routines (cmd_conv() and cmd_swap()) which manipulate the same variable
(p_bs_del).  Additionally, the command table entries for "con" and "swap"
have essentially the same comments (i.e. bs<->del conversion).  Methinks
that perhaps cmd_con() should conditionally set p_convert as follows:

line 695 was
    setvar(par,0,&p_bs_del);
and maybe should be
    setvar(par,0,&p_convert);

Additionally, I believe that the next line which reads:
    if (doing_init == 0) redoutil();
should perhaps be replaced with:
    if (doing_init) return;

    ClearMenuStrip(mywindow);
    InitCommItems();                    /* Re-do comm menu   */
    SetMenuStrip(mywindow,&menu[0]);

(if the above code looks familiar that's because it *is* -- I copied it
from cmd_mode()).

-- 
Tony Sumrall acs@amdahl.amdahl.com <=> ...!{ihnp4,hplabs,seismo}!amdahl!acs

[ Opinions expressed herein are the author's and should not be construed
  to reflect the views of Amdahl Corp. ]

ray@jimi.UUCP (03/02/87)

	After running the latest version of Dave Wecker's vt100
	emulator, I notice that a string requester pops up after
	my login script is finished.  Then I have to move the mouse
	over and click on the DONE box.  Is there any way to prevent
	this from happening?  It is rather annoying.  What even is 
	it's purpose?

	Thanks.
				--Ray Tripamer (ray@jimi.uucp)

) Seaman) (07/22/89)

bob@jacobs.CS.ORST.EDU (robert s. richardson) writes:
< I am looking for a VT100 program that supports smooth scrolling (you
< know, one pixel vertically at a time, just like the real thing.)
< 
< I really like VLT because it lets me use my own custom font, but
< smooth scrolling would A) make reading news a LOT easier on my eyes, and
< B) make for a nice effect in a science fiction TV program I am co-
< producing here at KBVR.
< 
< Thanks,
< | Bob Richardson     (or, for you UNIX buffs: bob@jacobs.cs.orst.edu) |

I've  never used VLT, so I can't address the differences between it and
Handshake, but Handshake does offer a very good VT100/VT220 emulator, and
supports smooth scrolling (I've never tried using alternate fonts, though).

It's also on the Fish disks, so it's easy to find.

-- 
Chris (Insert phrase here) Seaman |    /--\
crs@cpsc6a.att.com <or>           |   |    |         "This is as real as
...!att!cpsc6a!crs                |   |  \ |      your so-called 'Life' gets"
The Home of the Killer Smiley     |    \--X__

duncanj@umd5.umd.edu (James Duncan) (01/05/90)

  This question has more to do with XMODEM then vt100.
BTW, I do realize that I am using an old version of vt100 
but it has worked fine until now.  What I want to know is
how the XMODEM protocol works - nothing technical just
the basics. I have used Kermit and ASCII with no problem
but when I do XMODEM transfers I get garbage.  Does XMODEM
pack things so I need to unpack the file?  Is this a bug 
in vt100 or am I incorrectly using XMODEM?

  I tried downloading files from the Steve Jackson Games BBS
which supported the XMODEM and XMODEM/CRC protocols.  I selected
XMODEM for the transfer.  Should I have used XMODEM/CRC instead?


				Thanks for your assistance,

					Jim Duncan