🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: mod.amiga.sources
1 messages
1 total messages Started by doc Tue, 14 Oct 1986 18:02
VT100 (V2.2 861012 DBW) Part 1 of 3
#48
Author: doc
Date: Tue, 14 Oct 1986 18:02
1665 lines
48883 bytes
This is the "official" release of V2.2

Major items of interest include:

	- You can now define an INIT file that chains to any number of SCRIPT
	  files and then exits (if desired). Great for having the program wake
	  up at 3am, dial your favorite BBS and download the world.

	- Hangup, Break, Null, Autowrap, Audible Beep, Function Key Scripts,
	  Every Parity type, all implemented.

	- Menus, Lattice compile, BOLD, Graphics "box", Double Shift, Title bar
	  all cleaned up (or fixed).

	- Script and init files now use the same control character sequences.

*** NOTICE ***

	- Any bug reports MUST specify the version of the software being used.

	- The ONLY bugs I will respond to are from this version (V2.2) as of
	  today (10/12/86).

	- Do not expect another major version for awhile (unless there is a 
	  MAJOR problem). I am starting a new project (3d graphics editor,
	  display system) and will be pretty well tied up.


#	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
#	window.c
#	xmodem.c
# This archive created: Tue Oct 14 12:57:23 1986
# By:	Craig Norborg (Purdue University Computing Center)
cat << \SHAR_EOF > readme
This archive contains a vt100 emulator with KERMIT and XMODEM file transfer
protocols by Dave Wecker (V2.2 DBW 861012).

Thanks:
-------
	To everyone who sent in code and suggestions!

Releases:
---------
	v2.2 861012 DBW - more of the same
 	v2.1 860915 DBW - new features (see README)
	v2.0 860823 DBW - Major rewrite
	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
	v1.0 860712 DBW	- First version released

Usage:
------
	Please read VT100.DOC for usage information and examples.

Release Notes:
--------------
v2.2 861012 DBW - more of the same:

	- The INIT file "exit" command can now take an optional argument
	  which is the name of a script to execute after initialization
	  is complete.

	- The SCRIPT command "exit" takes an optional paramater which may
	  be either the pathname of the next script to execute or the
	  string "VT100" (which causes the emulator to exit completely).

	- Hangup menu item now works.

	- Autowrap can now be set from VT100.H, VT100.INIT and the standard
	  escape sequence (<ESC>[?7h - set, <ESC>[?7l - reset)

	- Control-G is now handled with an audible beep (volume set with the
	  VOLUME parameter in VT100.H and VT100.INIT). If the volume is set
	  to 0, a visual beep (DisplayBeep) will be used instead.

	- Script now used "^chr" to send control characters instead of
	  "|" (which was screwing up U**X users). See VT100.DOC for details.

	- The graphics "box" character (a) was added so bar charts now work
	  in line drawing mode (e.g., monitor system on VMS).

	- Control-@ and Control-` now send the NULL character

	- Alternate color for BOLD has been re-instated by popular demand
	  (instead of using SetSoftStyle) when there is more than 1 bit-
	  plane. With one bit-plane, SetSoftStyle is used.

	- Menus have been cleaned up.

	- Lattice compilation cleaned up.

	- No more wordsize parameter since PARITY takes care of all cases
	  (NONE=8bit, MARK, SPACE, EVEN ODD).

	- Any function key definition that begins with a KEYSCRIPT
	  introducer will invoke a script from the function key: e.g.,
	  "~df1:foo/script.txt" (if KEYSCRIPT = 0x7E = "~")

	- Double shift keys are now handled correctly.

	- Version has been added to the title bar (for bug reports).

v2.1 860915 DBW - new features / bug fixes

	- Now identifies as a VT100 (including the response to <esc>Z)
	- Cursor color now gets read in as hex (instead of decimal)
	- REPORTMOUSE taken out of definitions (not needed)
	- XON/XOFF now being handled by the device driver instead of me
	- Literal escape characters have been replaced with \033
	- At init time the user can now specify the input BUFFER size
	  (typically between 512 and 2048 bytes) depending on baud rate
	- Script files are now case insensitive for commands
	- XMODEM now turns off the driver XON/XOFF during transfers
	- Graphic rendition now done by the OS instead of me.
	- Initialization files are now searched for in S: instead of C:
	- Forward GOTO bug fixed in the script package.
	- Keypad can now be used in both numeric and application mode
	- General purpose cleanup() routine added for all exits.
	- Utility menu added (sendbreak, hangup, change directory).
	  NOTE: hangup is not implemented yet.
	- Full wild card support in file transfers (see vt100.doc).
	- Kermit cleaned up with better filename handling (from host).
	- Script now has CD (changed directory) and SB (send break) commands
	- Added Parity and Wordsize choices in VT100.H, VT100.INIT, menu
	  and scripts. (Generates parity from a table).
	- Added 8th bit quoting in KERMIT when using 7 bit words (ODD or
	  EVEN parity).
	- Break time can be set from VT100.H, VT100.INIT or a script file.
	- Transfer mode (image or CRLF) can now be set from a script file.
	- Control characters in escape sequences now act like a true VT100.
	- F10 now works from init files.
	- Right (or Left) AMIGA with period (".") sends a BREAK to the host
	  from the keyboard.
	- XMODEM status kept down to one line for a file transfer.

v2.0 860823 DBW	- Major rewrite:

	- Emulator now compiles under either MANX or LATTICE by defining
	  the appropriate compiler type in VT100.H.
	- Sped up code to an effective baud rate of (about) 8k. This means
	  that clear text at 4800 baud should be no problem.
	- Added XON/XOFF generation so that characters should not get lost
	  any more at 9600 baud (when receiving clear text).
	- Got rid of all command line switches and environment variables.
	  Instead upon invocation the program searches first for any file
	  named on the command line, then looks for VT100.INIT in the
	  current directory and finally searches for C:VT100.INIT.
	  All parameters can be set in the init file, and a sample VT100.INIT
	  is provided in VT100.DOC that shows all possible options.
	- All parameters that are set by VT100.INIT are defined in VT100.H
	  (variables starting with "p_"). This allows you to compile your
	  own defaults into the code.
	- You can now set the number of lines (for all you EMACS freaks :-).
	  On an interlaced screen this gives you upto a 48 line terminal.
	- WORKBENCH colors are NEVER touched.
	- In an attempt to keep the size down, the color palette menu item
	  has been removed (current). Code is about 36K in size with a
	  run time image (using workbench screen) of about 88k.
	- Many bugs fixed including reverse scrolling with descenders,
	  reverse video at end of line, clearing with scrolling regions,
		... and 20 or more others.
	- File capture now no longer sends the filename to the host.
	- BOLD (<esc>[1m) has now been added by using an additional color
	  when you specify a depth of 2 (instead of 1) bitplane.
	- UNDERLINE (<esc>[4m) has now been added.
	- The handling of remote (host) escape sequences has been completly
	  re-written (thanks to Dawn Banks for all the work).
	- Function keys (and shifted function keys) can now be bound to
	  arbitrary strings (Jim Ravan gets his macros). See VT100.DOC
	  for details.
	- Cursor has no been reduced to the size of a normal character for
	  easier readability.
	- XMODEM has been improved (by Steve Drew) to use a timer device
	  (for timeouts) and to abort immediately if the user types <ESC>.
	- KERMIT has been completely re-written and appears to work fine,
	  thanks to the efforts of Steve Drew.
	- New menu item allows script file support. Module written by
	  Steve Drew. See VT100.DOC for details.

Known problems:
---------------

	- none reported yet.

Suggestions not implemented:
----------------------------

	- "ASCII capture uses synchronous I/O so capture of game playing
	  is jerky"

	  This change MAY be made if someone else wants to write the code.

	- "Beep should be in stereo"

	  I am trying to use as FEW system resources as possible, therefore
	  beep only ties up 1 of the 4 possible channels.

Installation:
-------------
	The files in this archive may be extracted by the bourne shell
	(/bin/sh) or the shar program using the "unshar switch (-u)",
	contact me if you need a copy of this version of shar.

	REMEMBER: Set the correct compiler definition in VT100.H

Files:
------
	README		- this file

	vt100.doc	- documentation for the terminal emulator

	makefile	- make file for the emulator (under MANX AZTEC-C)

	vt100.h		- include file used by all other modules

	window.c	- manager for window and keyboard

	vt100.c		- main module, handles menus

	remote.c	- handle remote characters (vt100 emulation)

	kermit.c	- kermit protocol (to transfer text files on VMS
			  select the CRLF option on the transfer mode menu,
			  otherwise use image mode).

	init.c		- startup code

	xmodem.c	- xmodem protocol that understands AMIGA binary and
			  text file formats (automatically).

	script.c	- script control package

	expand.c	- filename expansion (wildcards) and dir setting

Contact:
--------
Please send bugs/comments/suggestions to:

	Dave Wecker at	ENET:	COOKIE::WECKER
			ARPA:	wecker%cookie.dec.com@decwrl.dec.com
			USENET:	{decvax|decwrl}!cookie.dec.com!wecker
			SNAIL:	Dave Wecker
				115 Palm Springs Drive
				Colorado Springs, CO  80908
SHAR_EOF
cat << \SHAR_EOF > vt100.doc
This is the documentation file for the VT100 terminal emulator by Dave
Wecker (V2.2 DBW 861012). Comments/suggestions/bugs/problems/praise should
be sent to:

	Dave Wecker at	ENET:	COOKIE::WECKER
			ARPA:	wecker%cookie.dec.com@decwrl.dec.com
			USENET:	{decvax|decwrl}!cookie.dec.com!wecker
			SNAIL:	Dave Wecker
				115 Palm Springs Drive
				Colorado Springs, CO  80908

Multi-file transfer, the new version of KERMIT and script support were
contributed by Steve Drew (Aug 20 1986). If you wish to thank Steve
directly he can be contacted through:

    	Steve Drew at	ENET:    CGFSV1::DREW
    			ARPA:    drew%cfgsv1.dec.com@decwrl.dec.com
    			USENET:  decvax!decwrl!cgfsv1.dec.com!drew    

Many other pieces of code/suggestions have been sent in.. thanks to all!

Program startup:
----------------
	1> vt100 [initfile]

		- At startup, the program will search for an initialization
		  file to execute. It will first look for the specified
		  "initfile", then VT100.INIT (in the current directory)
		  and finally S:VT100.INIT. The format for the init file
		  is described later in this document.

		- The init file controls the setting of initial defaults
		  and screen and macro definitions.

		- If none of the files (listed above) are found, the
		  built-in defaults (defined in VT100.H as variables,
		  beginning with "p_") are used.

		- All commands are either menu or script based. Scripts
		  are described below.

Menus:
------
File 	  			- file transfers
	Ascii Capture		- Begin/end a script of the current session
	Ascii Send		- Type a file to the host
	Xmodem Receive		- Receive a file using XMODEM protocol
	Xmodem Send		- Send    a file using XMODEM protocol
	Kermit Get		- Receive files from a host KERMIT SERVER
	Kermit Receive		- Receive files from a host KERMIT
	Kermit Send		- Send    files to   a host KERMIT [SERVER]
	Kermit Bye		- Terminate a host KERMIT SERVER
Comm Setup			- Setup communications
	Baud Rate		- Set the terminal baud rate
		300, 1200, 2400,
		4800, 9600
	Parity
		NONE, MARK, SACE,
		EVEN, ODD	- Type of parity
	Xfer Mode
		image		- Send files verbatim (for UNIX hosts or
				  binary files)
		CR LF		- Send CR LF as line terminator and strip
				  CR on received files (VMS text).
Script 	  			- Script commands
	Execute file		- Start up an asynchronous script file
	Abort Execution		- Terminate a script file
Utility   			- Utility commands
	Send Break		- send a break to the host
	Hang Up			- close line (not implemented yet)
	Change Dir		- change the local directory (for transfers)

Keypad mapping (in application mode):
-------------------------------------

		AMIGA		VT100		comments
		-------		-------		---------------------------
		0-9	==	0-9
		.	==	.
		ENTER	==	ENTER		(basically, flip the bottom
		-	==	,		 2 keys up to get a VT100)
		HELP	==	-		(only free key around)
		f1-f4	==	PF1-PF4		(or any rebinding you do)
		arrows	==	arrows

Note:	Right (or Left) AMIGA key in conjunction with a period (".") will
	send a break to the host.

	CTRL in conjunction with either an at-sign ("@") or a backquote ("`")
	will send a NULL to the host.

Initialization file example:
----------------------------
Here is a (hopefully) self-explanatory VT100.INIT file with all options
used:

#######################################################################
#
#	VT100 sample initialization file
#	v2.2 861012 DBW	- Dave Wecker standard defaults
#
# Hash mark at the beginning of a line denotes a comment.
# White space (space(s) or tab(s)) delimit fields.
# Case ignored except for function key bindings.
#
# All items in this file overide variables of the same name in VT100.H
# (all variables in vt100.h have a "p_" prepended to them)
#
##########################################################################
#
BAUD		2400		# Anything after required fields is ignored
SCREEN		CUSTOM		# may be CUSTOM or WORKBENCH
INTERLACE	ON		# ON for CUSTOM or interlaced workbench
DEPTH		1		# number of bit planes to use (1 or 2)
FOREGROUND	950		# Colors are only used on the custom screen
BACKGROUND	000		# Colors are in hex RGB from 000 to FFF
BOLD		a00		# Color for bold highlighting (in custom)
CURSOR		00a		# Color for cursor (in custom screen)
LINES		48		# normal <= 24 interlaced <= 48
MODE		CRLF		# IMAGE or CRLF (for KERMIT transfers)
BUFFER		512		# 512 <= Input buffer size <= 2048
PARITY		NONE		# NONE (= 8 bit), MARK, SPACE, ODD or EVEN
BREAK		750000		# Length for break key in microseconds
VOLUME		64		# Beep Volume (0 = Visual Beep)
WRAP		OFF		# Auto wrap ON or OFF
KEYSCRIPT	7E		# Hex value for script introducer
#
# Function bindings (strings to type when any of F1 through F10 are pressed)
#	f<num>	= function key
#	F<num>	= shifted function key
#
# The string specified must be delimited and uses one special character:
#	^	= control next character
#	^^	= up arrow
#
# Sample control characters:
#	^[	= escape	^M	= carriage return
#	^J	= line feed	^L	= form feed
#
# If the first character of the string is a script introducer (KEYSCRIPT)
# then the string is interpreted as a script filename to be executed when
# the key is pressed.
#
# Examples of bindings:
#
f1	"^[OP"			# f1-f4 = PF1 - PF4 on a VT100
f2	"^[OQ"
f3	"^[OR"
f4	"^[OS"
#
# f5,6,7 = scripts to execute (assuming that KEYSCRIPT = '~' = 0x7E)
#
f5	"~df1:vt100_source/dialwork.script"
f6	"~df1:vt100_source/sendvt100.script"
f7	"~df1:vt100_source/getpics.script"
#
f8	"MAIL^M"		# Reads my mail (note embedded <CR>)
f9	"NOTE^M"		# Reads conferences
F1	"$2400!"		# dials the phone to work
F2	"$bbs1!"		# dials the phone to billboard 1
F3	"$bbs2!"		# dials the phone to billboard 2
F4	"$bbs3!"		# dials the phone to billboard 3
#
# all done with init, now execute script as startup sequence
#
exit df1:vt100_source/dialwork.script

Multi file Xfers:
-----------------
The VT100 emulator now supports multiple file transfers. This is specified
by using a comma (",") between file names when using XMODEM or KERMIT.
(NOTE: host XMODEM's normally CANNOT support multiple file transfers).

When specifying a file name to recieve by default the directory path is
stripped of the filename when sent to the host but is kept for the local
file spec. eg:

        receive file: ram:file.txt,df1:newfile.bin,$

will ask the server for file.txt and put it in ram:, and get newfile.bin
and put it on df1: (see explanation of "$" below). If you do a single file
transfer you will get another prompt for the remote name e.g.:

        receive file: ram:file.txt
        remote file name[file.txt] userdisk1:wantfile.txt

The same rules apply to sending multiple files therefore if you are
doing multi file transfers make sure the host server is connected to the
desired directory.

In addition KERMIT now supports wildcards (* = any number of characters,
? = any single character). Examples:

	send:	*.c,*.h,*.doc
	get:	*.c,*.h,$

KERMIT receive is now smart enough to use the host filename so no filename
needs to be specified on the AMIGA's side.

Script file operation:
----------------------
The script file can be invoked by selecting 'execute file' from the script 
menu. At any time you can abort the script file by selecting
'Abort Execution'.

During the time script file is running the terminal emulation is still
active and you may type simulataneous to the script file. This may be desired
if your script file is WAITing for a string or is DELAYing for a period of
time etc.

Script file Commands (case insensitive):
------------------------------------------------------------
#	Commented line
   Format:
	# comment		 may not be on same line as a command.
   Example:
	# this is a comment
------------------------------------------------------------
ASCII_SEND Send an ascii file to the host.
   Format:
	(same format as CAPTURE)
------------------------------------------------------------
BAUD 	Set baud rate
   Format:
	BAUD rate		Sets the baud rate for send/receive
   Example:
	BAUD 2400		Sets the baud rate at 2400 baud
------------------------------------------------------------
BT	Set the break time (for an SB command)
   Format:
	BT value		Value is in micro-seconds
   Example:
	BT 750000
------------------------------------------------------------
CAPTURE	To start/stop ascii file capture.
   Format:
	CAPTURE	file		Start ascii capturing
	CAPTURE			End ascii capturing
   Example:
	CAPTURE foo.bar		Starts capture of file foo.bar
	CAPTURE			Ends ascii capture of file foo.bar
------------------------------------------------------------
CD 	To change the local directory
   Format:
	CD	newdir		set a new directory for file transfers
   Example:
	CD	DF1:foo/bar	set the directory as specified
------------------------------------------------------------
DELAY 	Suspends script file for a specified time
   Format:        
        DELAY 	n		Suspends execution for n seconds
   Example:
	DELAY	2		Suspends for 2 seconds
------------------------------------------------------------
EXIT	Ends execution of the current script file.
   Format:
	EXIT			Exit the current script
	EXIT VT100		Exit vt100 program
	EXIT newscript		Exit this script and start up newscript
   Example:
	EXIT DF1:FOO.BAR	Exit the current script and start FOO.BAR
------------------------------------------------------------
GOTO	Jumps to a different part of the script file.
   Format:
	GOTO label		Jumps to a line beginning with label:
				Jumps may be forward or backward.
   Example:
	FOO:			Sets up a label
	GOTO FOO		Jumps to FOO
------------------------------------------------------------
KB  	Send a BYE packet to a host KERMIT server (shut down server).
   Format:
	KB
------------------------------------------------------------
KG  	Gets files from host. (which is running as a server).
   Format:
	(same format as KS)
------------------------------------------------------------
KR  	Receives a file from kermit host (not running as server)
   Format:
	(same format as KS)
------------------------------------------------------------
KS  	Sends files via kermit to the host.
   Format:
	KS file			Send one file
	KS file1,file2,...	Send multiple files
	KS file1,file2,...,$	Send multiple files and shut down server
   Example:
	KS foo.bar		sends foo.bar (note no quoting is used)
	KS foo1,foo2,foo3	sends three files
	KS foo1,foo2,foo3,$	sends three files and shuts down server
------------------------------------------------------------
ON	Peforms a command every time a string is received
   Format:
        ON      "string"  cmd	Execute cmd when string is received. Only
				one ON string may be installed at a time.

  				If cmd is a GOTO and we were previously
				WAITing for a string the WAIT is aborted and
				execution resumes at the new label.

              			If cmd is not SEND and we were previously
				DELAYing, then the DELAY is aborted and the
				cmd is executed, followed by the next command
				after the DELAY.

				If cmd is a SEND and we were previously
				DELAYing, then the DELAY is continued.
   Example:
        ON  "LOSS CARRIER" GOTO RESTART
				If modem drops carrier, try to redial
        ON  "--more--" SEND " "
				Send a space every time --more-- is received
------------------------------------------------------------
PARITY	Sets the parity
   Format:
	PARITY	type		Set the parity type
   Example:
	PARITY	NONE		no parity
	PARITY	MARK		mark parity
	PARITY	SPACE		space parity
	PARITY	ODD		odd parity
	PARITY	EVEN		even parity
------------------------------------------------------------
SEND 	Sends a string or character to the host.
   Format:
	SEND    "string"	Sends a string to the host. Beginning and
				ending double quotes (") are required. A
				carat (^) may be used to send control chars.
				Two carats transmits a carat character.
        SEND    chr           	Sends a single character.
        SEND    ^chr   	    	Sends a single control character. The chr
				is NOT case sensitve
   Example:
	SEND	"mail"		Send the string mail
	SEND    "dir^M"		Send the string dir followed by a <CR>
	SEND	a		Send the letter a
	SEND	^C		Send a control C
	SEND	"abc^^def"	Send the string abc^def
	SEND	^^		Send a control-uparrow
	SEND	"		Send the '"' character
------------------------------------------------------------
SB	Sends a break character to the host
   Format:
	SB			Note that any pending character to send
   Example:				is aborted by this call
	SB
------------------------------------------------------------
TM	Set a transfer mode for KERMIT to use
   Format:
	TM type			type of transfers to perform
   Example:
	TM IMAGE		image mode transfers
	TM CRLF			<CR><LF> text transfers (VMS Kermit).
------------------------------------------------------------
WAIT 	Suspends the script file until a certain string is received.
   Format:
	WAIT	"string"	Same rules for string as SEND
	WAIT			Enter an endless wait. Usually used after
				some "ON" commands have been set up. Can
				still aborted via the script menu.
   Example:
        WAIT    "User:"    	Waits for the string User:
        WAIT               	Waits forever
------------------------------------------------------------
XR  	Receives a file via XMODEM.
   Format:
	(same format as KS)
------------------------------------------------------------
XS  	Sends a file via XMODEM.
   Format:
	(same format as KS)
------------------------------------------------------------


Script file examples:
--------------------
#########################################################################
# Script to dial work (dialwork.script)
#	v2.2	861012	DBW
#########################################################################
#
# Make sure that we have all the parameters we want
#
	DELAY	2
	BAUD	2400
	PARITY	NONE
	TM	CRLF
	BT	750000
	SB
#
# First get the modem's attention:
#
Start:
	DELAY 1
	ON "Ready" GOTO Dial
	SEND ^B
	DELAY 2
	GOTO Start
#
# Now dial the 2400 baud line to work:
#
Dial:
	ON "Attached" GOTO Login
	SEND "$2400!"
	DELAY 30
	GOTO Start
#
# We got attached, so keep hitting return until the Gandalf terminal
# handler wakes up:
#
Login:
	ON "enter" GOTO Gandalf
	DELAY 1
	SEND ^M
	GOTO Login
#
# Now connect from the Gandalf to the terminal server (ts1):
# (when it asks for a password I need to type the password manually here)
#
Gandalf:
	DELAY 2
	SEND "ts1^M"
	WAIT "class start"
#
# Keep sending <CR>'s until the LAT prompts for a username:
#
WaitLat:
	DELAY 2
	ON "username>" GOTO Lat
	SEND ^M
	GOTO WaitLat
#
# Tell the LAT that it's me, and connect to the "cookie cluster" (my host
# systems). Tell the cluster my user name.
# (when it asks for a password I need to type the password manually here)
#
Lat:
	SEND "wecker^M"
	DELAY 1
	SEND "connect cookie^M"
	WAIT "Username:"
	SEND "WECKER^M"
	WAIT "at home"
	SEND "^M^M^M"
#
# Got through all the LOGIN garbage, so let's do some work.
#
	WAIT "$ "
#
# Now go back to the LAT and connect to my workstation
#
	SEND "^]connect child^M"
	WAIT "login:"
	SEND "wecker^M"
	WAIT "at home"
	SEND "^M^M^M"
#
# Leave us on VMS
#
	SEND ^^
	DELAY 2
#
# Go run the next script
#
	EXIT df1:vt100_source/sendvt100.script

#########################################################################
# Script to upload the terminal emulator sources (sendvt100.script)
#	v2.2	861012	DBW
#########################################################################
#
# Make sure that we have all the parameters we want
#
	DELAY	2
	PARITY	NONE
	TM	IMAGE
#
# Get into the right directory and upload to my U**X workstation
#
	CD df1:vt100_source
	SEND ^^
	SEND "cd ~/amiga/vt100^M"
	SEND "rm -f *^M"
	WAIT "% "
	DELAY 2
#
# Send the readme file for the terminal emulator via XMODEM:
#
	SEND "xmodem -r readme^M"
	DELAY 3
	XS readme
	WAIT "% "
#
# Send the other terminal emulator files via KERMIT:
#
	DELAY 1
	SEND "kermit -x^M"
	DELAY 3
	KS vt100.doc,makefile,vt100.h,*.c
	DELAY 2
	KB
	WAIT "% "
#
# We popped out of server mode, so send the compiled code
#
	DELAY 1
	SEND "kermit -i -x^M"
	DELAY 3
	KS vt100
	DELAY 2
	KB
	WAIT "% "
#
# Now build the target shar files
#
	SEND "shar -a readme vt100.doc makefile vt100.h vt100.c init.c "
	SEND "> vt100_22a.shar^M"
	SEND "shar -a script.c remote.c window.c expand.c kermit.c xmodem.c "
	SEND "> vt100_22b.shar^M"
#
# Time to pull copies over to VMS
#
	SEND ^^
	SEND "swi [wecker.amiga]^M"
	SEND "cop child::"
	SEND "
	SEND "/staff/wecker/amiga/vt100/vt100_22a.shar"
	SEND "
	SEND " []vt100_22a.shar^M"
	WAIT "$ "
	SEND "cop child::"
	SEND "
	SEND "/staff/wecker/amiga/vt100/vt100_22b.shar"
	SEND "
	SEND " []vt100_22b.shar^M"
	WAIT "$ "
	SEND "cop child::"
	SEND "
	SEND "/staff/wecker/amiga/vt100/vt100"
	SEND "
	SEND " []vt100_22.bin^M"
	WAIT "$ "
#
# Make them available to the world
#
	SEND "pub vt100_22*.*^M"
	WAIT "$ "
#
# All done so go to the next script
#
	EXIT df1:vt100_source/getpics.script

#########################################################################
# Script to download images (getpics.script)
#	v2.2	861012	DBW
#########################################################################
#
# Make sure that we have all the parameters we want
#
	DELAY	2
	PARITY	NONE
	TM	CRLF
#
# Get into the right directory and download
#
	CD RAY:
	SEND "swi [wecker.render]^M"
	SEND "kermit server^M"
	DELAY 3
	KG *.img
	DELAY 2
	KB
	WAIT "$ "
#
# Now get out of the emulator
#
	EXIT VT100

SHAR_EOF
cat << \SHAR_EOF > makefile
######################################################################
#
# Makefile to build vt100 terminal emulator
#
#	v2.2 861012 DBW	- more of the same
#	v2.1 860915 DBW - new features (see README)
#	     860823 DBW - Integrated and rewrote lots of code
#	v2.0 860809 DBW	- Major release.. LOTS of changes
# 	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
# 	v1.0 860712 DBW	- First version released
#
#
# Don't forget to define the right compiler (MANX or LATTICE) in VT100.H
#
######################################################################

OBJS	= vt100.o init.o window.o xmodem.o remote.o \
	  kermit.o script.o expand.o

INCL	= vt100.h
#INCL	= 

vt100	: $(OBJS)
	copy df0:lib/c.lib ram:
	ln -v -o vt100 $(OBJS) ram:c.lib
	delete ram:#?.lib

vt100.o	: vt100.c $(INCL)
	cc -b +Hvt100.syms vt100.c

init.o	: init.c $(INCL)
	cc -b +Ivt100.syms init.c

window.o : window.c $(INCL)
	cc -b +Ivt100.syms window.c

xmodem.o : xmodem.c $(INCL)
	cc -b +Ivt100.syms xmodem.c

remote.o : remote.c $(INCL)
	cc -b +Ivt100.syms remote.c

kermit.o : kermit.c $(INCL)
	cc -b +Ivt100.syms kermit.c

script.o : script.c $(INCL)
	cc -b +Ivt100.syms script.c

expand.o : expand.c $(INCL)
	cc -b +Ivt100.syms expand.c


SHAR_EOF
cat << \SHAR_EOF > window.c
/****************************************************
 * vt100 emulator - window/keyboard support
 *
 *	v2.2 861012 DBW - more of the same
 *	v2.1 860915 DBW - new features (see README)
 *	     860823 DBW - Integrated and rewrote lots of code
 *	v2.0 860809 DBW - Major rewrite
 *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
 *	v1.0 860712 DBW	- First version released
 *
 ****************************************************/

#define MODULE_WINDOW 1
#include "vt100.h"

/* keyboard definitions for toasc() */
static char keys[75] = {
    '`','1','2','3','4','5','6','7','8','9','0','-' ,
    '=','\\', 0, '0','q','w','e','r','t','y','u','i','o' ,
    'p','[',']', 0, '1','2','3','a','s','d','f','g','h' ,
    'j','k','l',';','\'', 0, 0, '4','5','6', 0, 'z','x','c','v',
    'b','n','m',44,'.','/', 0, '.','7','8','9',' ',8,
    '\t',13,13,27,127,0,0,0,'-' } ;

/* forward declarations for LATTICE */
void filename();
void emits();
void emit();
void emitbatch();
void cursoroff();
void cursoron();

/*************************************************
*  function to get file name
*************************************************/
void filename(name)
char name[];
    {
    char c;
    ULONG class;
    unsigned int code;
    int keepgoing,i;
    keepgoing = TRUE;
    i=0;
    while (keepgoing) {
	while( NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort) )
	    {
	    class = NewMessage->Class;
	    code = NewMessage->Code;
	    ReplyMsg( NewMessage );
	    if (class=RAWKEY)
		{
		c = toasc(code,1);
		name[i]=c;
		if (name[i] != 0)
		    {
		    if (name[i] == 13)
			{
			name[i]=0;
			keepgoing = FALSE;
			}
		    else
			{
			if (name[i] == 8 || name[i] == 127)
			    {
			    i -= 2;
			    if (i < -1)  i = -1;
			    else {
				if (x == MINX) { y -= 8; x = MAXX; }
				emit(8);
				emit(32);
				emit(8);
				}
			    }
			else
			emit(c);
			if (x == MAXX) emits("\n");
			}
		    i += 1;
		    }
		}
	    } /* end of new message loop */
	}   /* end of god knows what */
    emit(13);
    emit(10);
    } /* end of function */


/*************************************************
*  function to print a string
*************************************************/
void emits(string)
char string[];
    {
    int i;
    char c;

    i=0;
    while (string[i] != 0)
	{
	c=string[i];
	if (c == 10) emit(13);
	emit(c);
	i += 1;
	}
    }

/*************************************************
*  function to output ascii chars to window
*************************************************/
void emit(c)
char c;
    {
    static char wrap_flag = 0;	/* are we at column 80? */

    c &= 0x7F;
    switch( c )
	{
	case '\t':
	x += 64 - ((x-MINX) % 64);
	break;

	case 10:  /* lf */
	y += 8;
	break;

	case 13:  /* cr */
	x = MINX;
	break;

	case 8:   /* backspace */
	x -= 8;
	if (x < MINX) x = MINX;
	break;

	case 12:     /* page */
	x = MINX;
	y = MINY;
	SetAPen(mywindow->RPort,0L);
	RectFill(mywindow->RPort,(long)MINX,
	    (long)(MINY-7),(long)(MAXX+7),(long)(MAXY+1));
	SetAPen(mywindow->RPort,1L);
	break;

	case 7:     /* bell */
	if (p_volume == 0) DisplayBeep(NULL);
	else {
	    BeginIO(&Audio_Request);
	    WaitIO(&Audio_Request);
	    }
	break;

	default:
	if (c < ' ' || c > '~') break;
	if (p_wrap && wrap_flag) {
	    x = MINX;
	    y += 8;
	    if (y > MAXY) {
		y = MAXY;
		ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,
		    (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
		}
	    }
	Move(mywindow->RPort,(long)x,(long)y);

	if (curmode&FSF_BOLD) {
	    if (p_depth > 1) {
		SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
		SetSoftStyle(mywindow->RPort,(long)curmode,253L);
		}
	    else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
	    }
	else SetSoftStyle(mywindow->RPort,(long)curmode,255L);

	if (curmode&FSF_REVERSE) {
	    SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID));
	    Text(mywindow->RPort,&c,1L);
	    SetDrMd(mywindow->RPort,(long)JAM2);
	    }
	else Text(mywindow->RPort,&c,1L);

	if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L);
	x += 8;
	} /* end of switch */

    if (y > MAXY) {
	y = MAXY;
	x = MINX;
	ScrollRaster(mywindow->RPort,0L,8L,(long)MINX,
	    (long)(MINY-6),(long)(MAXX+7),(long)(MAXY+1));
	}
    if (x > MAXX) {
	wrap_flag = 1;
	x = MAXX;
	}
    else wrap_flag = 0;
    }

/*************************************************
*  function to output ascii chars to window (batched)
*************************************************/
void emitbatch(la,lookahead)
int la;
char *lookahead;
    {
    int i;	

    Move(mywindow->RPort,(long)x,(long)y);
    i = x / 8;
    if (i+la >= maxcol) {
	if (p_wrap == 0) la = maxcol - i;
	else {
	    lookahead[la] = 0;
	    emits(lookahead);
	    return;
	    }
	}
    if (curmode&FSF_BOLD) {
	if (p_depth > 1) {
	    SetAPen(mywindow->RPort,(long)(2+(1^p_screen)));
	    SetSoftStyle(mywindow->RPort,(long)curmode,253L);
	    }
	else SetSoftStyle(mywindow->RPort,(long)curmode,255L);
	}
    else SetSoftStyle(mywindow->RPort,(long)curmode,255L);

    if (curmode&FSF_REVERSE) {
	SetDrMd(mywindow->RPort,(long)(JAM2+INVERSVID));
	Text(mywindow->RPort,lookahead,(long)la);
	SetDrMd(mywindow->RPort,(long)JAM2);
	}
    else Text(mywindow->RPort,lookahead,(long)la);
    if (curmode&FSF_BOLD) SetAPen(mywindow->RPort,1L);
    x += (8 * la);
    }

/******************************
* Manipulate cursor
******************************/
void cursoroff()
    {
    SetDrMd(mywindow->RPort,(long)COMPLEMENT);
    SetAPen(mywindow->RPort,3L);
    RectFill(mywindow->RPort,
	(long)(x-1),(long)(y-6),(long)(x+8),(long)(y+1));
    SetAPen(mywindow->RPort,1L);
    SetDrMd(mywindow->RPort,(long)JAM2);
    }

void cursoron()
    {
    SetDrMd(mywindow->RPort,(long)COMPLEMENT);
    SetAPen(mywindow->RPort,3L);
    RectFill(mywindow->RPort,
	(long)(x-1),(long)(y-6),(long)(x+8),(long)(y+1));
    SetAPen(mywindow->RPort,1L);
    SetDrMd(mywindow->RPort,(long)JAM2);
    }

/************************************************
*  function to take raw key data and convert it 
*  into ascii chars
**************************************************/
int toasc(code,local)
unsigned int code;
int local;
    {
    static int ctrl = 0;
    static int shift = 0;
    static int capsl = 0;
    static int amiga = 0;
    char c = 0, keypad = 0;
    char *ptr;

    switch ( code )
	{
	case 98:   capsl = 1; c = 0;break;
	case 226:  capsl = 0; c = 0;break;
	case 99:   ctrl  = 1; c = 0;break;
	case 227:  ctrl  = 0; c = 0;break;
	case 96:
	case 97:   if(++shift > 2) shift = 0; c = 0; break;
	case 224:
	case 225:  if (--shift < 0) shift = 0; c = 0;break;
	case 102:
	case 103:  if (++amiga > 2) amiga = 0; c = 0; break;
	case 230:
	case 231:  if (--amiga < 0) amiga = 0; c = 0; break;
	case 0x50: 
	case 0x51: 
	case 0x52: 
	case 0x53: 
	case 0x54: 
	case 0x55: 
	case 0x56: 
	case 0x57: 
	case 0x58: 
	case 0x59:  c = 0;
		    if (shift)	ptr = p_F[code - 0x50];
		    else	ptr = p_f[code - 0x50];
		    if (!script_on && *ptr == p_keyscript)
			    script_start(++ptr);
		    else    sendstring(ptr);
		    break;
	case 0x0f: c = (keyapp) ? 'p' : '0'; keypad = TRUE; break;
	case 0x1d: c = (keyapp) ? 'q' : '1'; keypad = TRUE; break;
	case 0x1e: c = (keyapp) ? 'r' : '2'; keypad = TRUE; break;
	case 0x1f: c = (keyapp) ? 's' : '3'; keypad = TRUE; break;
	case 0x2d: c = (keyapp) ? 't' : '4'; keypad = TRUE; break;
	case 0x2e: c = (keyapp) ? 'u' : '5'; keypad = TRUE; break;
	case 0x2f: c = (keyapp) ? 'v' : '6'; keypad = TRUE; break;
	case 0x3d: c = (keyapp) ? 'w' : '7'; keypad = TRUE; break;
	case 0x3e: c = (keyapp) ? 'x' : '8'; keypad = TRUE; break;
	case 0x3f: c = (keyapp) ? 'y' : '9'; keypad = TRUE; break;
	case 0x43: c = (keyapp) ? 'M' : 13 ; keypad = TRUE; break;
	case 0x4a: c = (keyapp) ? 'l' : '-'; keypad = TRUE; break;
	case 0x5f: sendstring("\033Om") ;break;
	case 0x3c: c = (keyapp) ? 'n' : '.'; keypad = TRUE; break;
	case 0x4c:
	case 0x4d: 
	case 0x4e: 
	case 0x4f: sendchar(27);            /* cursor keys */
		   if (keyapp) sendchar('O');
		   else sendchar('[');
		   sendchar(code - 11);
		   break;

	default:
	if (code < 75) c = keys[code];
	else c = 0;
	}

    if (keypad) {
        if (keyapp) sendstring("\033O");
        sendchar(c);
        return(0);
	}
        
    /* add modifiers to the keys */

    if (c != 0) {
	if (shift) {
	    if ((c <= 'z') && (c >= 'a')) c -= 32;
	    else
	    switch( c ) {
		case '[':  c = '{'; break;
		case ']':  c = '}'; break;
		case '\\': c = '|'; break;
		case '\'': c = '"'; break;
		case ';':  c = ':'; break;
		case '/':  c = '?'; break;
		case '.':  c = '>'; break;
		case ',':  c = '<'; break;
		case '`':  c = '~'; break;
		case '=':  c = '+'; break;
		case '-':  c = '_'; break;
		case '1':  c = '!'; break;
		case '2':  c = '@'; break;
		case '3':  c = '#'; break;
		case '4':  c = '$'; break;
		case '5':  c = '%'; break;
		case '6':  c = '^'; break;
		case '7':  c = '&'; break;
		case '8':  c = '*'; break;
		case '9':  c = '('; break;
		case '0':  c = ')'; break;
		default:            break;
		}
	    }
	else if (capsl && (c <= 'z') && (c >= 'a')) c -= 32;
	}
    if (ctrl) {
	if (c > '`' && c <= 127) c -= 96;
	else if (c > '@' && c <= '_') c -= 64;
	}
    if (amiga && c == '.') {
	if (!local) sendbreak();
	c = 0;
	}
    else if (ctrl && (c == '@' || c == '`')) {
	if (!local) sendchar(0);
	c = 0;
	}
    else if (c != 0 && (!local)) sendchar(c);
    return((int)c);
    }

SHAR_EOF
cat << \SHAR_EOF > xmodem.c
/*************************************************************
 * vt100 terminal emulator - XMODEM protocol support
 *
 *	v2.2 861012 DBW - more of the same
 *	v2.1 860915 DBW - new features (see README)
 *	     860901 ACS - Added Parity and Word Length and support code
 *	     860823 DBW - Integrated and rewrote lots of code
 *	     860815 Steve Drew: readchar inproved with real timeouts
 *	v2.0 860809 DBW - Major rewrite
 *	v1.1 860720 DBW	- Switches, 80 cols, colors, bug fixes
 *	v1.0 860712 DBW	- First version released
 *
 *************************************************************/

#define MODULE_XMODEM 1
#include "vt100.h"

int enablexon = TRUE;

/* forward declarations for LATTICE */
void sendstring();
void sendchar();
void sendbreak();
void No_XON();
void Do_XON();

static unsigned long parity_settings[4] = {
    0x96696996,
    0x69969669,
    0x69969669,
    0x96696996 };

/************************************************************
* Send a string (using sendchar below)
************************************************************/

void sendstring(s)
char *s;
    {
    char c;

    while ((c = *s++) != '\000') sendchar(c);
    }

/**************************************************************/
/* send char and read char functions for the xmodem function */
/************************************************************/
void sendchar(ch)
int ch;
    {
    int doxon,i,j,k;

    doxon = enablexon;
    if (doxon) No_XON();
    switch (p_parity) {
	case 0:	/* no parity */
	rs_out[0] = ch & 0xFF;
	break;

	case 1: /* mark */
	rs_out[0] = (ch & 0x7F) | 0x80;
	break;

	case 2: /* space */
	rs_out[0] = ch & 0x7F;
	break;
	
	case 3:	/* even */
	case 4: /* odd  */
        i     = (ch >> 5) & 0x3;
	j     = ch & 0x1F;
	k     = ((parity_settings[i] >> j) & 0x1) << 7;
	if (p_parity == 3)			/* even parity */
	    rs_out[0] = (ch & 0x7F) | k;
	else					/* odd parity */
	    rs_out[0] = (ch & 0x7F) | (k ^ 0x80);
	}
    DoIO(Write_Request);
    if (doxon) Do_XON();
    }

/* send a break to the host */
void sendbreak() {
    AbortIO(Read_Request);
    Read_Request->IOSer.io_Command = SDCMD_BREAK;
    DoIO(Read_Request);
    Read_Request->IOSer.io_Command = CMD_READ;
    SendIO(Read_Request);
    }

int readchar()
    {
    int rd,ch;

    Timer.tr_time.tv_secs = ttime;
    Timer.tr_time.tv_micro = 0;
    SendIO((char *) &Timer.tr_node);
    
    rd = FALSE;
    while (rd == FALSE)  
        {	
	Wait((1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) |
            ( 1L << mywindow->UserPort->mp_SigBit) |
            ( 1L << Timer_Port->mp_SigBit));
	if (CheckIO(Read_Request))
            {
	    WaitIO(Read_Request);
	    ch=rs_in[0];
	    rd = TRUE;
	    SendIO(Read_Request);
	    }
	if (NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort)) {
	   if ((NewMessage->Class == RAWKEY) && (NewMessage->Code == 69))
	         {
                 AbortIO((char *) &Timer);
                 Wait (1L << Timer_Port->mp_SigBit);
	         if (want_message) 
	           emits("\nUser aborted transfer\n");
	         timeout = USERABORT;
                 return('\0');
	         }
            continue;
            }
        if (rd == FALSE && CheckIO(&Timer)) {
            if (want_message)
              emits("\nTimeout waiting for character\n");
            timeout = TIMEOUT;
            return('\0');
            }
	}     /* end while */
    AbortIO((char *) &Timer);
    Wait (1L << Timer_Port->mp_SigBit);
    timeout = GOODREAD;
    return(ch & 0xFF);
    }

void No_XON() {

    /* turn off XON/XOFF processing */
    enablexon = FALSE;
    Write_Request->io_SerFlags |= SERF_XDISABLED;
    Write_Request->IOSer.io_Command = SDCMD_SETPARAMS;
    DoIO(Write_Request);
    Write_Request->IOSer.io_Command = CMD_WRITE;
    }

void Do_XON() {
    /* turn on XON/XOFF processing */
    enablexon = TRUE;
    Write_Request->io_SerFlags &= ~SERF_XDISABLED;
    Write_Request->IOSer.io_Command = SDCMD_SETPARAMS;
    DoIO(Write_Request);
    Write_Request->IOSer.io_Command = CMD_WRITE;
    }

/**************************************/
/* xmodem send and recieve functions */
/************************************/

int XMODEM_Read_File(file)
char *file;
    {
    int firstchar, sectnum, sectcurr, sectcomp, errors, errorflag;
    unsigned int checksum, j, bufptr;
    char numb[10];
    bytes_xferred = 0L;
    ttime = TTIME_SHORT;
    want_message = TRUE; /* tell readchar to print any error msgs */

    if ((fd = creat(file, 0)) < 0)
	{
	emits("Cannot Open File\n");
	return FALSE;
	}
    else
    emits("Receiving File\n\nType <ESC> to abort transfer\n");

    sectnum = errors = bufptr = 0;
    sendchar(NAK);
    firstchar = 0;
    No_XON();
    while (firstchar != EOT && errors != ERRORMAX)
	{
	errorflag = FALSE;

	do {                                    /* get sync char */
	    firstchar = readchar();
	    if (timeout != GOODREAD) {
		if (timeout == USERABORT || errors++ == ERRORMAX)
		    Do_XON();
		    return FALSE;
		}
	    } while (firstchar != SOH && firstchar != EOT);

	if  (firstchar == SOH)
	    {
	    emits(blanks);
	    emits("\rGetting Block ");
	    sprintf(numb, "%d", sectnum);
	    emits(numb);
	    emits("...");
	    sectcurr = readchar();
	    if (timeout != GOODREAD) { Do_XON(); return FALSE; }
	    sectcomp = readchar();
	    if (timeout != GOODREAD) { Do_XON(); return FALSE; }
	    if ((sectcurr + sectcomp) == 255)
		{
		if (sectcurr == ((sectnum + 1) & 0xff))
		    {
		    checksum = 0;
		    for (j = bufptr; j < (bufptr + SECSIZ); j++)
			{
			bufr[j] = readchar();
			if (timeout != GOODREAD) { Do_XON(); return FALSE; }
			checksum = (checksum + bufr[j]) & 0xff;
			}
		    if (checksum == readchar() && timeout == GOODREAD)
			{
			errors = 0;
			sectnum++;
			bufptr += SECSIZ;
			bytes_xferred += SECSIZ;
			emits("verified\r");
			if (bufptr == BufSize)
			    {
			    if (write(fd, bufr, BufSize-128) == EOF)
				{
				emits("\nError Writing File\n");
				Do_XON();
				return FALSE;
				}
			    bufptr = 128;
			    for (j = 0; j < 128; j++)
				bufr[j] = bufr[(BufSize-128)+j];
			    }
			sendchar(ACK);
			}
		    else
			{
			errorflag = TRUE;
			if (timeout == USERABORT) { Do_XON(); return FALSE; }
			}
		    }
		else
		    {
		    /* got a duplicate sector */	
		    if (sectcurr == (sectnum & 0xff))
			{
			/* wait until we time out for 5secs */
			do {
			    readchar();
			    } while (timeout == GOODREAD);
			if (timeout == USERABORT) {
			    Do_XON();
			    return FALSE;
			    }
			emits("\nReceived Duplicate Sector\n");
			sendchar(ACK);
			}
		    else errorflag = TRUE;
    		    }
		}
	    else errorflag = TRUE;
	    }
	if (errorflag == TRUE)
	    {
	    errors++;
	    emits("\nError\n");
	    sendchar(NAK);
	    }
	}        /* end while */
    if ((firstchar == EOT) && (errors < ERRORMAX))
	{
	sendchar(ACK);
	while (bufptr > 0 && (bufr[--bufptr] == 0x00 ||
			      bufr[bufptr]   == 0x1A)) ;
	write(fd, bufr, ++bufptr);
	close(fd);
	Do_XON();
	return TRUE;
	}
    Do_XON();
    return FALSE;
    }

int XMODEM_Send_File(file)
char *file;
    {
    int sectnum, bytes_to_send, size, attempts, c;
    unsigned checksum, j, bufptr;
    char numb[10];
    bytes_xferred = 0;
    ttime = TTIME_LONG;
    want_message = TRUE; /* tell readchar to print any error msgs */

    if ((fd = open(file, 0)) < 0) {
	emits("Cannot Open Send File\n");
	return FALSE;
	}
    else
    emits("Sending File\n\nType <ESC> to abort transfer\n");
    attempts = 0;
    sectnum = 1;
    No_XON();
    /* wait for sync char */
    j=1;
    while (((c = readchar()) != NAK) && (j++ < ERRORMAX))
	if (timeout == USERABORT) { Do_XON(); return(FALSE); }
    if (j >= (ERRORMAX))
	{
	emits("\nReceiver not sending NAKs\n");
	Do_XON();
	return FALSE;
	}

    while ((bytes_to_send = read(fd, bufr, BufSize)) && attempts != RETRYMAX)
	{
	if (bytes_to_send == EOF)
	    {
	    emits("\nError Reading File\n");
	    Do_XON();
	    return FALSE;
	    }

	bufptr = 0;
	while (bytes_to_send > 0 && attempts != RETRYMAX)
	    {
	    attempts = 0;
	    emits(blanks);
	    emits("\rBlock ");
	    sprintf(numb, "%d ", sectnum);
	    emits(numb);
	    do {
		emits(".");    
		sendchar(SOH);
		sendchar(sectnum);
		sendchar(~sectnum);
		checksum = 0;
		size = SECSIZ <= bytes_to_send ? SECSIZ : bytes_to_send;
		bytes_to_send -= size;
		for (j = bufptr; j < (bufptr + SECSIZ); j++)
		if (j < (bufptr + size)) {
		    sendchar(bufr[j]);
		    checksum += bufr[j];
		    }
		else sendchar(0);
		sendchar(checksum);
		attempts++;
		c = readchar();
		if (timeout == USERABORT) {
		    emits("\n");
		    Do_XON();
		    return FALSE;
		    }
		} while ((c != ACK) && (attempts != RETRYMAX));
	    bufptr += size;
	    bytes_xferred += size;
	    emits(" sent\r");
	    sectnum++;
	    }
	}
    close(fd);
    if (attempts == RETRYMAX)
	{
	emits("\nNo Acknowledgment Of Sector, Aborting\n");
	Do_XON();
	return FALSE;
	}
    else
	{
	attempts = 0;
	do {
	    sendchar(EOT);
	    attempts++;
	    } while ((readchar() != ACK) &&
		     (attempts != RETRYMAX) &&
		     (timeout != USERABORT)) ;
	if (attempts == RETRYMAX)
	    emits("\nNo Acknowledgment Of End Of File\n");
	}
    Do_XON();
    return TRUE;
    }

SHAR_EOF
#	End of shell archive
exit 0
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads