



     XCMALT(L)              Local (29 Oct 1988)              XCMALT(1L)



     NAME
          xcmalt - Xmodem communications program

***** NOTE *****

	By virtue of a restriction previously placed upon all code derivative
	from XCOMM, the XCMALT code and associated files may not be sold by
	anyone to anyone.  It's OK to transfer them for free.  By virtue of
	Larry Gensch's posting XCOMM on the CompuServe network, posting of
	XCMALT on this network is also OK.

Invoking XCMALT
---------------

The syntax for invoking XCMALT is

	xcmalt [-l /dev/linename] [-t] [-s scriptname]

The command-line options are:

	-l	Use the specified modem line, which must be a
		full pathname (e.g., "/dev/tty01").

	-t	Go directly to terminal mode.  The default is
		to go to command mode on program startup.  This
		switch is incompatible with the "-s" switch.

	-s	Execute the specified script file after program startup.

XCMALT starts up by reading the file ".xcmalt", if it is found in the current
directory, in your HOME directory, or in a default directory defined at compile
time. This startup file may contain any of the valid SET commands described
below. XCMALT then displays the current settings, and presents an "XCMALT>"
prompt, unless the -t or -s command line flag is present.

Two shell environment variables can affect XCMALT operation:

	If the environment contains a variable called "MODEM", then the value
	of that variable will be the default modem port.  The value must be a
	full pathname.  To set such a variable, in the Bourne shell, you might
	say

		MODEM=/dev/tty01; export MODEM

	or, in the C shell,

		setenv MODEM /dev/tty01

	If the environment contains a variable called "BYEttyxx", where "ttyxx"
	stands for the basename of the modem line selected either by the MODEM
	variable or by the "-l" command option, then the value of that variable
	will be sent to the modem when the program terminates.  This is useful
	for setting the modem back to some preselected state.  Example:

		BYEtty01="ATZ"

	Whatever string is contained in the "Byexxxxx" variable will be
	followed by a carriage-return/newline pair, also sent to the modem.

	Newer modems can be preset to revert to a predetermined state when the
	DTR signal of the computer is dropped, and so would not need to avail
	themselves of this feature.


XCMALT Command Summary
----------------------

The following commands are available at the "XCMALT>" command prompt:


	c	Initiate CIS QuickB File Transfer.  This command is used for
		both uploading and downloading from CompuServe.

	d	Enter the dial directory. Returns to the "XCMALT>" prompt if
		exited without dialing, but returns to terminal mode after
		dialing or running a script.

	s file	Execute the XCMALT script file "file".  Returns to terminal
		mode when the script is complete.

	rb file	(XMODEM binary receive)
	rt file	(XMODEM text receive)
		Receive the specified file from the remote system.

	sb file (XMODEM binary send)
	st file (Xmodem text send)
		Transmit the specified file to the remote system.

	set	Display or set the transmission parameters used by the XCMALT
		program.  Refer to the SET section of this document.

	t	Enter terminal mode.  Refer to the TERMINAL section of this
		document.

	exit
	 or
	x	Exit program.  Return to invoking program/shell.

	h	Hang-up the modem.

	! <cmd>	Execute the specified command as a child process.  If <cmd> is
		ommitted, execute a local interactive shell. (A space is
		required between the '!' and the command.)

	!!	Re-execute the last shell command string.

	$	Execute a shell command with stdin and stdout redirected to the
		modem port.  This effectively puts the computer into a "host"
		mode.

	%p local_name [remote_name]  Transmit a file (put) to a remote Unix system.
		This command uses standard Unix utilities on the other end.
		'remote_name' defaults to the same pathname as 'local_name' if not
		otherwise specified.

	%t remote_name [local_name] Receive a file (take) from a remote Unix system.
		This command uses standard Unix utilities on the other end.
		'local_name' defaults to the same pathname as 'remote_name' if not
		otherwise specified.

	help
	 or
	?	Displays a brief summary of XCMALT commands, "set" options, and
		terminal-escape commands.



File Transfers - Text and Binary Modes
--------------------------------------

	When transferring files using the XMODEM protocol, the file mode is
	specified in the upload/download command.  A "Text" file transfer
	enables special translation of the transmitted or received file to
	support CP/M and MS-DOS end of line characters.  When transmitting a
	file using text mode, all newlines are converted to carriage-return,
	newline sequences.  When receiving a file using text mode, all
	carriage return, newline sequences are converted to a single newline.
	A "binary" file transfer transmits the file "as is" without any
	conversion.

	When transferring files using CompuServe QuickB protocol, the format of
	the file is specified by the host.  An "ascii" file will force XCMALT
	to perform text-mode translation; a "binary" file will turn off any
	translation.


Using the SET Command
---------------------

The SET command is used to display and set/reset XCMALT's tunable parameters.
Any of these commands may be placed in the ".xcmalt" file which is read upon
starting up XCMALT.  The usage is shown below:

	(1)	set

		Display XCMALT's current parameters.


	(2)	set 7bit  on|off
		set crc   on|off
		set term  on|off
		set cmd   on|off
		set nl    on|off
		set cis   on|off
		set mung  on|off
		set purge on|off
		set xoff  on|off
		set halfdplx on|off
		set baud  <value>
		set cfile name
		set pfile name


		7bit	Modem high-bit masking.  All characters received from
			the modem are masked so their values are between 0 and
			127.  This is useful for remote systems that transmit
			parity characters (the parity is ignored).  If this
			option is set "off", received characters are not
			masked.

		crc	Set XMODEM CRC protocol.  All transferred blocks use a
			16-bit block check, which is more reliable than the
			older "checksum" block check.  If this option is set
			"off", checksum protocol is used.  Note that in almost
			all cases the program on either side will use checksum
			protocol if the other side doesn't support CRC, so
			there's no real reason not to leave this option always
			"on".

		term	Set auto-jumpback to terminal mode after all file
			transfers.

		nl	Set literal-newline mode (in terminal mode, all
			newlines are sent as newlines; carriage returns are
			sent as carriage returns.)  If this option is set
			"off", then newlines are sent as carriage returns.

		cis	Set CompuServe <ENQ> file transfer requests.  An "on"
			value specifies that when in terminal mode, an <ENQ>
			character will perform an automatic CIS QuickB protocol
			transfer.  This parameter should be set "off" when not
			connected to CompuServe, as phone line noise may cause
			a bogus file transfer request.

		mung	Set file overwrite flag.  If "on", files may be
			overwritten when receiving data files.  If "off", files
			will not be overwritten (will cause an error message to
			be displayed).

		purge	Set Bad Telephone Line Purge mode.  If "on", removes
			spurious characters received through the phone line due
			to noise before listening for an acknowledgement.  This
			increases the amount of time spent transmitting each
			block, but can improve throughput overall by reducing
			the number of block retransmissions.

		xoff	Set XON/XOFF flow control flag.  If "on", the program
			will honor the XOFF control character and wait until an
			XON character is received before transmitting any more
			information.  If "off", the program will ignore
			XOFF/XON requests.

		halfdplx  Sets the half-duplex flag.  If this flag is set, then
			all characters typed at the keyboard while in terminal
			mode will be echoed to the screen as well as sent to
			the modem line.  Useful for remote systems that don't
			echo characters.

		baud	Set the desired baud rate.  Supported baud rates are
			300, 1200, 2400, 4800, 9600, 19200 and 38400 baud.

		cfile	Set the name of the capture file to "name".

		pfile	Set the name of the phonelist file to "name".


TERMINAL Mode operation
-----------------------

In terminal mode, all characters typed at the keyboard are sent to the
modem; all characters received from the modem are displayed on the local
terminal screen.

Newline characters (0x0A) are translated to carriage returns (0x0D) when
literal-newline mode is "off".

The header file "xcmalt.h" contains a #define for ESCAPE_CHR.  This
value is the key that will, when typed in terminal mode, introduce an
XCMALT "escape" command.  The default definition for ESCAPE_CHR is ASCII
01, or control-A; you may change it if you please by changing the header
file.  Below, the ESCAPE_CHR is referred to as the "ESC" key.  Don't
confuse this with the <ESCAPE> key.

When the "ESC" key is typed in terminal mode, the program will examine the
next key pressed.  If it is a special command function, that function will
be performed; otherwise, the second character is sent to the modem.  Thus,
to send an "ESC" character through the modem, it is necessary to press the
key TWICE.

Supported ESC commands:

ESC b	BREAK		Send a BREAK signal (a sustained null) to the modem.

ESC d	Dial		Select a phone number and dial it.

ESC f	send File	Send a file through the modem (ascii transfer).  An
			option is available for waiting after each line is
			sent to avoid overrunning the remote systems input
			buffer.

ESC g	script (GO)	Execute a script file.

ESC h	Hangup		Disconnect from the remote system.

ESC t	Toggle capture	Toggle capture file - If the file is not open, it is
			opened in APPEND mode (text receive accumulates at
			the end of the file).  If the file is already open,
			it is closed, instead.

ESC x	eXit		Exit terminal mode back to XCMALT command mode.


Format of the PHONELIST file:
-----------------------------

1.	The .phonelist must exist with the file name ".phonelist" either in the
	current directory, in your home directory as defined by the $HOME
	environment variable, or in the LIBDIR as defined in xcmalt.h.
	The name of the phonelist file can be changed using the SET PFILE
	command.

2.	The .phonelist file is ASCII text (lines of text separated by newlines).
	It can be created and maintained using emacs, vi, or even ed.

3.	The first field of data in each line (after any whitespace and up to
	the next occurance of whitespace) is assumed to be a phone number in a
	valid format for the modem being dialed.

4.	Descriptive text may follow the phone number.

5.	The following three definitions may then follow in any order:

	BITS=x		(x=7|8) Set the terminal mode mask to 7/8 bits.

	BAUD=nnnn	(n=300|1200|2400|4800|9600|19200|38400) Set the baud
			rate to the specified value.

	SCRIPT=file	Immediately after sending the autodial string, execute
			the script file specified. (Note that the specified
			filename is CASE SENSITIVE!)

6.	The following definition, if used, must be the LAST field on the line.

	PREFIX=xxxxxxxx (e.g., PREFIX=ATs110=0s111=0

			The PREFIX="string" allows you send your modem a
			different setup string for each caller (default: no
			special setup).  This is helpful for MNP and Telebit
			modems which require special attention for contacting
			non-MNP modems and other Telebits.



The XCMALT Enhanced Script Language
====================================

The script language in XCMALT is a total rewrite of the script language found
in XCOMM version 2 by Larry Gensch.  Scripts written for XCOMM probably
won't work properly under XCMALT; there are some superficial similarities,
because the same sorts of telecommunication operations are involved, but
these will be misleading more often than not.

The XCMALT script language is intended to be closely similar to the Unix
Bourne shell language.  Unfortunately, it isn't identical to the Bourne
shell, so it has the same problem that the 'awk' program does for those
experienced in the C language: an 'awk' script LOOKS like C, but it isn't,
really; and in the same way, an XCMALT script LOOKS like a Bourne shell
script, but isn't.  So the operation of the Bourne shell, if you're familiar
with it, is useful as an analogy in understanding the XCMALT script language,
but only as an analogy.


Fundamental Concepts
=====================

An XCMALT script consists of lists of commands.  Commands are set off from
each other within a list by either a newline ('\n') or a semicolon (;), as is
the case with the Bourne shell.  The semicolon and the newline have identical
effect as command separators, so (anticipating a bit here) you could say
either

	if counter morethan 5
	then
		transmit "bye^M"
		quit
	endif

or

	if counter morethan 5; then transmit "bye^M"; quit; endif

and the result will be the same either way.  The newline and the semicolon
are treated the same way as in the Bourne shell, except that a newline cannot
be quoted so as to remove its interpretation as a command terminator (in
other words, a quoted string cannot contain a newline).

Commands are composed of words separated by spaces or tab characters, and
a word can be one of the following:

     *  One of the XCMALT script language keywords, which are listed
	below, with appropriate explanations;

     *  A number, meaning a sequence consisting only of digits, with
	an optional leading minus sign to indicate a negative number;

     *  A literal string of characters surrounded by double-quotation
	marks ('"'); such a string can be no longer than 80 characters.
	A double-quotation mark can be imbedded within the string by
	preceding it with a backslash ('\"'); when the string is
	interpreted, the backslash is disregarded and the double-quotation
	mark is treated as part of the string.  Mismatched quotation
	marks result in a syntax error.

     *  The name of a user variable, which can have either a string or
	a numeric value.  The name of a user variable must begin with
	an alphabetic character.

     *  The name of a shell environment variable, preceded by a dollar
	sign ('$').  The XCMALT script language examines the Unix
	environment for the specified variable and, if such a variable
	exists, substitutes the value of that variable.  The result is
	treated as if it were a quoted literal string, and, therefore,
	should not be more than 80 characters long, or else it will be
	truncated to its first 80 characters.  Similarly, such an
	environment variable should not contain a newline.

     *  An expression surrounded by back-quotation marks ('`').  This
	sort of expression operates similarly to the Bourne shell's
	command-substitution mechanism: the contents of the back-quotes
	are passed to the Bourne shell, and the standard output of the
	back-quoted command is treated as if it were a quoted literal
	string.  Therefore, the command's output should not be more than
	80 characters long, nor contain a newline.  Also, the contents
	of the back-quotes cannot be longer than 80 characters, nor
	contain a newline.

     *  An expression introduced by a pound-sign (or number-sign: '#'),
	which is treated as a comment.  All characters from the '#'
	until the end of the physical line are ignored.  This comment
	mechanism is the same as in the Bourne shell.

Quoted literal strings (and the two other mechanisms that act like quoted
literal strings, shell environment variables and back-quoted shell commands)
may be up to 80 characters long.  All other words must be no longer than 8
characters, and are treated case-independently (which is to say, uppercase
is the same as lowercase); note, though, that the names of shell environment
variables are case-dependent (uppercase must match uppercase and lowercase
must match lowercase), because they are case-dependent in the shell.

Any word not recognizable within the foregoing categories is treated as the
name of a new user variable.  Such a word, if longer than 8 characters, is
considered to be a syntax error.

User variables are created with the 'assign' script keyword, and may have
either numeric or string values.  The type of a user variable is determined
by how it's created; if it's assigned to a string, it's a string variable,
and if it's assigned to a number, it's a numeric variable.  The value of any
user variable can be changed with another 'assign' command, and numeric
variables can be changed to string variables and vice-versa.  Shell
environment variables cannot be changed within an XCMALT script, but the
value of a shell environment variable can be assigned to a user variable, and
the value of the user variable can thereafter be changed.

Scripts are contained in ASCII text disk files, one script to a file.  A
script can invoke another script as a subroutine with the 'call' keyword; up
to 5 scripts can be nested in this way at any single time.

With all this said, the following list of XCMALT script language commands
should be comprehensible.  The format "<something>" means that a token,
or word-type, of the "something" type is meant rather than the literal
sequence 'something'.


XCMALT Script Language Commands
================================

affirm
	Syntax: affirm

	Reads a string from the terminal, and returns TRUE if the
	string begins with 'y' or 'Y'; otherwise, returns FALSE.
	Used in evaluating conditional expressions.  The string
	must be terminated by a newline or carriage return.

	Example:

		echo -n "Continue (y/n)? "
		if affirm
		then
			continue
		else
			break
		endif

assign
	Syntax: assign <varname> eq <number>
	        assign <varname> eq "string"
		assign <varname1> eq <varname2>
		assign <varname> eq <script-command>

	Assigns to user variable <varname> the value following "eq";
	if that value is a number, then <varname> becomes a numeric
	user variable; if that value is a string, then <varname>
	becomes a string user variable.  If <varname> does not already
	exist as a user variable, it is created.  Variable space is
	allocated dynamically, but running out of memory space for
	variables is unlikely.  All variables are global across scripts
	that run at the same time via the 'call' keyword, and all
	variables vanish when a script, called directly from XCMALT
	as opposed to called from another script, exits.  In other
	words, variable values are not static except during 'call'
	execution.  Variable names cannot be longer than 8 characters.
	Successive 'assigns' are permissible, and the type of the
	variable changes according to the type of the value following
	"eq".  A user variable is destroyed with the 'unassign' keyword.

	If a variable is assigned the value of a script command, then
	it becomes a numeric variable with value TRUE or FALSE, depending
	on the status returned by the script command.  If a variable
	is assigned the value of a back-quoted command, it becomes a
	string variable with the value of the first 80 characters of
	the back-quoted command.  If a variable is assigned equal to
	an envionment variable, it becomes a string variable with the
	value of the first 80 characters of the value of the environment
	variable.

	Examples:

		assign numvar eq 5
		assign strvar eq "This variable is a string"
		assign mydir eq $HOME
		assign numvar2 eq numvar
		assign strvar2 eq strvar
		assign numvar eq true
		assign today eq `date`; echo "today is " today

beep

	Syntax: beep

	Sends a control-G to the terminal.  Useful for alerting the
	user that some event has occurred, for example a CONNECT after
	a lengthy redialing session.

break
	Syntax: break

	Exits from the immediately enclosing 'while' loop.  Identical
	to the C-language 'break', and to the Bourne shell 'break' except
	that the XCMALT script-language 'break' does not take a numeric
	argument.  Don't confuse this with the script keyword 'xmitbrk',
	which sends a BREAK signal to the modem port.

call
	Syntax: call "scriptname"

	Suspends execution of the current script, and attempts to load
	and run the specified scriptname.  The scriptname must be a
	quoted literal string.  There is no XCMALT analogue
	of the Bourne shell "exec" command; all subscripts in XCMALT
	are treated as subroutines.  All variables are global across
	subscripts, so if a subscript changes the value of a variable,
	then that change will remain in effect after return to the
	parent script.  Shell environment variables cannot be changed
	within any XCMALT script.

capture
	Syntax: capture "on"
		capture "off"

	Turns the file-capture function on or off.  Note that the
	arguments must be quoted literal strings.  Note also that
	when the script exits into terminal mode, the file-capture
	function is turned off again, so if you want to continue
	capturing after going into terminal mode, you must use the
	Ctrl-A T sequence to turn the capture function on again.


continue
	Syntax: continue

	Resumes execution at the top of the immediately enclosing
	'while' loop.  Identical to the C language 'continue'
	instruction, and to the Bourne shell 'continue' command
	except that no numeric argument is accepted.

debug
	Syntax: debug "on"
		debug "off"

	If the 'debug' option is on, then XCMALT will make many
	parenthetical comments about what it's doing while it runs
	the script.  These comments can sometimes be helpful in
	debugging script logic.  Note that the argument must be
	a quoted literal string.

decr
	Syntax: decr <numeric-variable>

	Decrements the value of the specified numeric user variable
	by 1.  Useful in controlling loop execution.  If the specified
	variable isn't numeric, or doesn't exist, a syntax error results.

dial
	Syntax: dial "number-string"

	Dials the specified number, assuming Hayes dialing protocol.

echo
	Syntax: echo "string" <variable> ...
		echo -n "string" <variable> ...

	Don't confuse this with the XCOMM "echo" script command.  This
	one is more like the Bourne shell "echo": it sends its arguments
	to the user's terminal.  The number of arguments is optional,
	except that the total result may not exceed 80 characters.  Variables
	and back-quoted shell commands are expanded as necessary.

	If the "-n" switch is present, then no carriage-return/newline
	sequence is appended to the output.

	Examples:

		echo "The time and date are now " `date`
		echo "My terminal type is " $TERM
		echo "My terminal type is " $TERM " today."

	Note that whitespace isn't echoed unless it's part of a quoted
	literal string.

exit
	Syntax: exit

	Terminates execution of the current script.  If a script reaches
	its end, it exits automatically, so 'exit' is useful mainly to
	terminate a script prematurely.

false
	Syntax: false

	Same as the Unix 'false' command.  Does nothing, but returns a
	FALSE status value.  Useful within conditional expressions.

	Example:

		if waitfor "CONNECT" 30 eq false
		then
			quit
		endif

	Note that the special modifier "!" could also be used in the
	above example:

		if ! waitfor "CONNECT" 30
		then
			quit
		endif

	and note too that the "!" must be separated from its argument
	by whitespace, unlike the usage of the XCOMM script language.

file
	Syntax: file <script-command>

	The standard output of the specified script command is sent
	to the current capture file.  If the "capture" option is not
	set, then an error message is displayed, but script execution
	continues.

	Examples:

		file echo "--------- CUT HERE ----------"

			sends the output of the 'echo' command to
			the current capture file, provided that
			the "capture" option is now "on".

		file echo `date`

			Sends a timestamp to the current capture file,
			provided that the "capture" option is now "on".
			The same thing could have been done with

				file shell "date"

if
	Syntax: if <list1>; then <list2>; [ else <list3>; ] endif

	If <list1> evaluates as true, performs <list2>;
	otherwise, if <list3> is specified, performs  <list3>;
	then resumes execution immediately following 'endif'.
	To accommodate those whose minds wander while writing
	scripts, "fi" is an acceptable synonym for "endif".

	Each list may consist of any number of script commands
	separated by semicolons or newlines. The value of <list1>
	is determined by inclusively OR'ing the value of each
	directive in the list, so that if any of the directives
	in <list1> evaluates as true, then so will <list1>.
	<list1> is performed in its entirety regardless of the
	value of any of its component commands.

	The keywords 'then', 'else', and 'endif' (or 'fi') must
	be immediately preceded by command separators, either
	a semicolon or a newline, just as is the case in the Bourne
	shell.

	For conditional evaluation in 'if' and 'while'
	constructions, the following comparators are available in
	addition to the script directives mentioned elsewhere:

	<varname1> eq "string"
	<varname1> eq <number>
	<varname1> eq <varname2>
	<varname1>
	"string"

		evaluates as true if the value of
		user variable <varname1> is the same
		as that of a specified string or numeric
		constant or of a specified second variable
		name.  If the variable name <varname1> is not
		followed by anything else, then the expression
		evaluates as true if the variable is numeric
		and has a non-zero value, or if the variable is
		a string variable and has a non-zero length;
		otherwise, the expression evaluates as false.
		Comparing a string variable to a numeric
		variable, or vice-versa, causes a syntax error.

		If a conditional expression consists only of
		a quoted literal string, the expression evaluates
		as TRUE if the string's length is non-zero, and
		otherwise evaluates to FALSE.  Because environment
		variables and back-quoted shell commands are treated
		as if their output/value were quoted literal strings,
		this allows direct testing of a shell command or
		of an environment for non-zero length.  Nonexistent
		environment variables are treated as if they exist
		with the value "" (a string of zero length).

	<varname1> neq "string"
	<varname1> neq <number>
	<varname1> neq <varname2>

		evaluates as true if the value of
		user variable <varname1> is not
		equal to that of a specified string or
		numeric constant or of a specified second
		variable name.  Comparing a string variable to a
		numeric variable, or vice-versa, causes a syntax
		error.

	<varname1> lessthan "string"
	<varname1> lessthan <number>
	<varname1> lessthan <varname2>

		evaluates as true if the value of
		user variable <varname1> is less
		than that of a specified string or numeric
		constant or of a specified second variable
		name.  String variables are compared lexically
		according to ASCII value.

	<varname1> morethan "string"
	<varname1> morethan <number>
	<varname1> morethan <varname2>

		Operates identically to 'lessthan', except
		in reverse.

	The value of any conditional expression may be negated
	by preceding it with an exclamation point followed by
	a space or tab.

	Examples:

		if counter eq 0; then break; endif;
		if var1 eq var2; then echo "identical"; endif
		if counter morethan 20; then break; endif;
		if counter lessthan 0; then break; endif;
		if ! counter; then echo "counter is " counter; endif

		To perform a list if any of a set of conditions
		exist:

			if counter morethan 5;
				   counter eq brkvalue;    # a second comparator
			then break;
			endif;

		i.e., perform the 'break' directive if the value of
		numeric user variable 'counter' is greater than the
		numeric constant 5, or if the value of 'counter' is
		equal to that of the user numeric variable
		'brkvalue'.

incr
	Syntax: incr <numeric-variable>

	Increments the value of the specified numeric user variable
	by one.  The opposite of 'decr'.


linked
	Syntax: linked

	'linked' is a pseudo-function that evaluates as TRUE if
	the current script has been invoked from the dialing
	directory, and as FALSE otherwise.

	Example:

		if ! linked; then
			dial "5551212"
		endif

pause
	Syntax: pause <number>

	Suspends execution for the specified number of seconds.
	Identical to Unix "sleep."

pipe
	Syntax: pipe "<shell-command>"

	The standard input and standard output of the specified SHELL
	COMMAND are connected to the modem port, and the command is
	executed.  This is the equivalent of the command mode "$"
	command.

	Examples:

		To send a DELETE character to the modem:

			pipe "echo \"\177\""

		To perform a file receive via Zmodem, assuming
		that Chuck Forsberg's 'rz'/'sz program resides
		on your system:

			pipe "rz"

portname
	Syntax: portname

	This isn't a command, but a synonym for the current modem
	terminal device, treated as if it were a quoted string.
	Useful if modems of differing types are attached to different
	terminal lines and need different dialing or initialization
	sequences.  To compare the value of 'portname' to some other
	string, you must first assign a user variable equal to
	'portname'.  Examples:

		assign myport eq portname
		if myport eq "/dev/tty01"
		then
			transmit "AT&E0^M"
		endif

quit
	Syntax: quit

	Exits the script and terminates XCMALT entirely.  Any LCKfile
	will be removed if possible and the user's terminal will be
	restored to the state it was in when XCMALT was invoked.

read
	Syntax: read <variable-name>

	Takes a string from the user's keyboard and places it into
	the specified user variable.  Any previous value of the
	specified variable is discarded.

redial
	Syntax: redial

	Redials the number most recently dialed with the 'dial' command.

seen
	Syntax: seen "string" <number>

	Evaluates as true if "string" has occurred within the last
	<number> characters received during the most recent 'waitfor'
	command.  Only up to 1024 characters are remembered at any one
	time during 'waitfor' processing.  If no <number> is specified,
	then all the characters received during the most recent 'waitfor'
	command are examined, up to a maximum of 1024.  The 'seen' buffer
	is reset at the beginning of each 'waitfor' command.  This is
	useful to tell whether which of several strings has been received.
	Example:

		if waitfor "string1" 20
		then
			echo "Received 'string1'."
		else
			if seen "string2"
			then
				echo "Received 'string2' instead."
			endif
		endif


set
	set <XCMALT-set-option> <value>

	This command is the same as the command-mode XCMALT 'set' command,
	such as "set baud 1200", "set cis on", and so forth, except that
	a string <value> must be enclosed within double-quotation marks.

	Examples:

		set cis "on"
		set cfile "newfilename"
		set baud 2400

shell
	Syntax: shell "<shell-command>"

	The shell command enclosed within the double-quotation marks is
	executed.  This is similar to the XCMALT command-mode "!" command.
	Remember that if the shell command contains double-quotation marks,
	they must be escaped with backslashes.

timeout
	Syntax: timeout <number>

	If <number> is greater than zero, starts a timer which will
	cause the MOST DEEPLY NESTED script to exit when <number>
	MINUTES expire.  If <number> is zero, then any pending timeout
	is cancelled.  If <number> is negative, nothing happens.

	Expiration of the specified timeout causes the most
	deeply nested script to exit, not to quit the program.
	To cause the program to quit if a timeout expires, use a
	subscript.  Example:

	    'script1' contains:

		call "script2"
		if expired
		then
			quit
		endif
		# more commands


	    'script2' contains:

		assign expired eq 1
		timeout 5			# limit of 5 minutes
		while ! waitfor "login:" 30
		do
			xmitbrk
		done
		assign expired eq 0
		exit

	When 'script2' exits, the numeric variable 'expired' will be
	set to 1 if 'script2' timed out, and will be 0 otherwise.
	'script1' can act on this information accordingly.

transmit
	Syntax: transmit "<string>"

	Sends a string to the modem.  This is Larry Gensch's original
	"transmit" script command.  The string is sent with brief pauses
	between characters, to accommodate modems that cannot accept
	rapid command input, and within the string, any alphabetic character
	preceded by a caret (^) is translated to the corresponding control
	character.

	Example:

		transmit "ATDT 5551212^M"

		sends the string "ATDT 5551212" to the modem, followed
		by a carriage return character.

true
	Syntax: true

	Does nothing, but always evaluates as TRUE.  Useful in conditional
	expressions.  The opposite of 'false'.

tty
	Syntax: tty "on"
	        tty "off"

	Ordinarily, during script execution, characters received from the
	modem port are echoed to the user's terminal screen.  This happens
	only during 'waitfor' and 'type' execution, so it may be a bit
	choppy.  This echoing can be turned off with

		tty "off"

	and turned back on with

		tty "on"

	Note that "on" and "off" must be enclosed in quotation marks.

type
	Syntax: type "<filename>"

	Sends the specified ASCII file to the modem port.  This is the
	same as the XCMALT terminal-mode "send ASCII file" escape.

unassign
	Syntax: unassign <variablename>

	Erases the specified user variable.  The variable may be either
	numeric or string type.  The variable name must not be enclosed
	in quotation marks, because variable names are considered to be
	XCMALT script keywords, and not literal strings.

waitfor
	Syntax: waitfor "<string>" <number>

	Scans input from the modem port for an occurrence of the specified
	string, which must be enclosed in quotation marks.  The scanning
	continues for the specified number of seconds or until the specified
	string is identified in the modem input stream, whichever comes
	first.  This command evaluates as TRUE if the specified string
	is found, and as FALSE if the specified number of seconds elapses
	and the string isn't found within that time.  The default time, if
	no <number> is specified, is roughly 30 seconds.

	Example:

		assign counter eq 1
		while ! waitfor "login:" 15
		do
			xmitbrk; incr counter; if counter morethan 5
			then
				quit
			endif
		done

	If the 'cis' option has been set to "on", either in the '.xcmalt'
	startup script, or by a direct 'set' command from command mode,
	or with

			set cis "on"

	within a current script, and if during 'waitfor' processing a
	CIS B-protocol file transfer request is received, then the B-protocol
	transfer is performed, the <number> argument is reset to its original
	value, and 'waitfor' processing continues.  This allows automatic
	B-protocol file transfers from within a script.

while
	Syntax: while <list1>; do <list2>; done

	Operates similarly to the 'if' command, except that <list2> is
	executed repeatedly so long as <list1> evaluates as TRUE.  All
	the conditional comparators and rules for comparisons that apply
	for the 'if' command also apply to 'while'.  (Note that 'while'
	loops can be nested within 'if' commands and vice-versa.)

xmitbrk
	Syntax: xmitbrk

	Sends a BREAK signal to the modem port.


A note on script-driven protocol file transfers
================================================

Script-driven file transfers using the Compuserve B-protocol is more or less
built into the XCMALT script language, since during 'waitfor' processing, a
file transfer request from the modem port will trigger a B-protocol transfer
if the "cis" mode is set.  The difficulty in performing such transfers isn't
in the transfer itself, but rather in the manuvering required to get into
position to transfer the correct file, and is something that probably only
experienced script writers should wrestle with.  However, if we assume that
in the midst of a script, you've reached a point where you can issue a
"download" command to Compuserve, for instance a "Disposition" prompt during
a File Library "BROWSE" command, and you want to download the present file,
which is XCALL.C on Compuserve, you'd use the following sequence of script
commands to do it:

	set cis on	# can't do auto file Quick-B transfer otherwise
	transmit "dow^M"
	pause 2		# wait for CIS to display protocol menu
	transmit "6^M"	# Quick-B is number 6 on that menu
	transmit "xcall.c^M" 	# "file name for your computer:"
	waitfor "Disposition"

During the final "waitfor" processing, the Compuserve ENQ character will
be recognized and the transfer will proceed automatically.  Then 'waitfor'
will continue waiting for the "Disposition" prompt, after which your script
can proceed.  The same sort of thing can be done with file uploads, but once
again, the difficulty isn't with the transfer, but rather with setting things
up so that the transfer will be requested at the correct place.

For Xmodem, Ymodem, and Zmodem transfers via scripts, there's no mechanism
built into the XCMALT script language to use the built-in, 128-byte-packet
Xmodem in XCMALT.  Instead, I strongly recommend that you obtain Chuck
Forsberg's excellent, public-domain utility called "RZSZ", which can handle
Xmodem, Xmodem-1K, Ymodem, and Zmodem transfers and which can be used from
within XCMALT with the 'pipe' command, or from command mode with the "$"
command.
