701 lines
22 KiB
Plaintext
701 lines
22 KiB
Plaintext
.he Fido/FidoNet/FidoTerm Script Language Copyright Tom Jennings #
|
||
|
||
Tom Jennings
|
||
Fido Software
|
||
164 Shipley
|
||
San Francisco CA 94107
|
||
|
||
|
||
SCRIPT LANGUAGE MACHINE MODEL
|
||
|
||
Fido/FidoNet's script language is a machine language, and like all<6C>
|
||
machine languages, there is an underlying "model" machine that<61>
|
||
the script instructions manipulate. The buckets and Beetles, that<61>
|
||
is.
|
||
|
||
The script machine model has the following components at your<75>
|
||
disposal:
|
||
|
||
NAME DESCRIPTION
|
||
|
||
&A The numeric "accumulator", values 0 - 65535
|
||
&C The "clock", counts up, in seconds
|
||
&T The "trap register", 0 or 1 - 65535 seconds
|
||
&E The "error register", either 0 or 1
|
||
|
||
&R The general purpose Recognizer
|
||
&S The "shift register", 20 characters,
|
||
&1 - &8 General purpose registers
|
||
stack 10 levels of data stack
|
||
|
||
|
||
&A: The "accumulator" (such a quaint word) is a simple<6C>
|
||
register for storing or manipulating numbers. It can be set to<74>
|
||
any value from 0 to 65535. It can be stored into any other<65>
|
||
register. There are instructions to test when the accumulator is<69>
|
||
zero.
|
||
|
||
&T: The "trap register" is part of a mechanism to break<61>
|
||
endless loops; the "TRAP" instruction is used to set a failsafe<66>
|
||
if a script or part of a script takes too long to execute.
|
||
|
||
&E: The "error register" can be either 0 or 1, with 1<>
|
||
generally indicating an error condition. There are instructions<6E>
|
||
to set and test the error register.
|
||
|
||
&R: The Recognizer can be used to store text or numbers.
|
||
|
||
&1 - &8: These are general purpose registers, and can hold<6C>
|
||
numbers or text. They are used to pass parameters to subroutines.<2E>
|
||
Each subroutine level has it's own set of these registers. When a<>
|
||
subroutine is called, the initial values are those of the calling<6E>
|
||
routine.
|
||
|
||
&S: The "shift register" is a special register that contains<6E>
|
||
the last 20 characters received from the modem, and is what<61>
|
||
patterns are matched against. Characters are shifted in from the<68>
|
||
right, and the left most character "falls off" the end. You can<61>
|
||
also store text in &S and use the "IF" instruction to do string<6E>
|
||
comparisons.
|
||
|
||
&1 through &8 are "local variables"; they are not shared amongst<73>
|
||
all subroutine levels. When a CALL is executed, the called script<70>
|
||
"inherits" the calling scripts initial values for these<73>
|
||
registers, but any changes made are lost upon RETURN.
|
||
|
||
|
||
The stack is a general purpose "push down" stack; you PUSH items<6D>
|
||
onto the stack, and POP them off. Items can only be accessed from<6F>
|
||
the top of the stack. There is room for up to ten items on the<68>
|
||
stack. If there are (for instance) five items on the stack, to<74>
|
||
get at the first one pushed (the "bottom" of the stack) you must<73>
|
||
first pop off the four on "top" of it.
|
||
.pa
|
||
|
||
INSTRUCTION SYNTAX
|
||
|
||
All instructions are of the form:
|
||
|
||
|
||
INSTRUCTION OPERAND OPERAND
|
||
|
||
Blank lines or lines beginning with a semicolon are ignored.<2E>
|
||
Lines beginning with a colon (label statements) are ignored when<65>
|
||
processing instructions.
|
||
|
||
Operands are usually text strings, and all strings should be<62>
|
||
quoted.
|
||
|
||
|
||
INSTRUCTION PROCESSING
|
||
|
||
The script processor is basically a text processor. The macro<72>
|
||
language applies to all commands at all times. Anything to the<68>
|
||
right of the instruction itself is expanded by the macro<72>
|
||
processor.
|
||
|
||
Macros are expanded from left to right, once. There are two<77>
|
||
special tokens the macro processor understands:
|
||
|
||
&(one letter register name)
|
||
\(special text character)
|
||
|
||
The language chosen allows just about every disgusting trick<63>
|
||
possible with machine language; self-modifying code, computer<65>
|
||
GOTOs, etc. I'll dispense with the formality, and show some<6D>
|
||
generalized examples and leave it at that:
|
||
|
||
Message "This is a string"
|
||
|
||
The MESSAGE command merely displays what it's given on the<68>
|
||
command status line. It makes for a simple example. In this case,<2C>
|
||
centered in the status line you'd see:
|
||
|
||
This is a string
|
||
|
||
If the recognizer (&R) contained the string "HELLO DUDE" the<68>
|
||
instruction:
|
||
|
||
Message "The recognizer contains &R"
|
||
|
||
Would display:
|
||
|
||
The recognizer contains HELLO DUDE
|
||
|
||
To display the same thing, but with quotes surrounding the<68>
|
||
contents of the recognizer, you would use:
|
||
|
||
|
||
Message "The recognizer contains \"&R\""
|
||
|
||
Displayed as:
|
||
|
||
The recognizer contains "HELLO DUDE"
|
||
|
||
|
||
Note the \ before the quote character merely quotes what follows.<2E>
|
||
There are some convenient exceptions:
|
||
|
||
\r carriage return, 13 decimal
|
||
\n line feed, 10 decimal
|
||
\e escape, 27 decimal
|
||
\b backspace, 8 decimal
|
||
\c etx (Control-C), 3 decimal
|
||
\1 SOH character, decimal 1
|
||
\127 DEL character, decimal 127
|
||
... ...
|
||
|
||
If you don't like that, ("C" programmers will like it though) you<6F>
|
||
can enter control characters like so:
|
||
|
||
^A 1 decimal, ASCII SOH
|
||
^M carriage return, 13 decimal
|
||
^J linefeed, 10 decimal
|
||
... ...
|
||
|
||
|
||
The ADD instruction adds a value to the accumulator. For example:
|
||
|
||
ADD 27
|
||
|
||
Would add 27 to the accumulator; if it had contained 3, it would<6C>
|
||
now contain 30. If the &2 register contained "34", the following:
|
||
|
||
ADD &2
|
||
|
||
Would add the numeric value 34 to &A. If &2 contained "ABRACADAB"<22>
|
||
then it would add zero to &A.
|
||
|
||
Here are some further examples. Assume first:
|
||
|
||
&A contains 20
|
||
&R contains "Text"
|
||
&1 contains "764-1629"
|
||
&2 contains 300
|
||
|
||
INSTRUCTION OPERAND EXPANDED
|
||
message "sample text" sample text
|
||
message &R 20
|
||
message "pattern is &r, OK?" pattern is 20, OK?
|
||
message "&A&R&A" 20Text20
|
||
message "Dialing &1 at &2 baud" Dialing 764-1629 at 300 baud
|
||
|
||
|
||
You can take this to absurd extremes. The instruction JMP <label><3E>
|
||
passes execution to the line following the line containing<6E>
|
||
:<label>. You can take advantage of this by using a "computed<65>
|
||
goto". The command:
|
||
|
||
jmp "&R"
|
||
|
||
Would attempt to jump to a line:
|
||
|
||
:TEXT
|
||
.pa
|
||
.sh Pattern Matching
|
||
PATTERN MATCHING
|
||
|
||
The main purpose of Fido/FidoNet's script language is pattern<72>
|
||
matching; looking for particular strings of characters received<65>
|
||
from the modem. All of the script language instructions are<72>
|
||
intended to work together to do this.
|
||
|
||
The single most important component of the script machine is the<68>
|
||
Shift Register. The shift register contains the last 20<32>
|
||
characters received from the modem, and works like this:
|
||
|
||
Assume that with your modem and Fido/FidoNet, you just called into<74>
|
||
and connected with some bulletin board system, and are about to<74>
|
||
be asked to log in.
|
||
|
||
As characters are received they are put into the right hand end<6E>
|
||
of the shift register; the character on the left edge of the<68>
|
||
shift register is lost. For example, if the bulletin board signon<6F>
|
||
message you'd see on your screen was:
|
||
|
||
WELCOME TO THE ACME HOG THROWERS BBS
|
||
|
||
AT THE PROMPT ENTER YOUR NAME AND PASSWORD:
|
||
|
||
|
||
Lots of times a simple "wait until the word XYZ" will do exactly<6C>
|
||
what you want. This sort of thing is easy to write scripts for,<2C>
|
||
and even in complex scripts is a very useful function.
|
||
|
||
The problems start when you need to base different actions on a<>
|
||
number of possible patterns, not just one. A simple "MATCH"<22>
|
||
instruction just won't do it, and brute force techniques of<6F>
|
||
searching through a screenful of text ("rummaging") has serious<75>
|
||
limitations.
|
||
|
||
|
||
In Fido/FidoNet the technique used involves a 20 character array<61>
|
||
called the "shift register", referred to as "&S" in the script<70>
|
||
language.
|
||
|
||
The shift register changes after each character received from the<68>
|
||
modem; in the example above, W, E, L, C, O, M, E, etc. Part way<61>
|
||
through the above message being displayed, the shift register<65>
|
||
would look like:
|
||
|
||
....
|
||
&S " WEL"
|
||
&S " WELC"
|
||
&S " WELCO"
|
||
&S " WELCOM"
|
||
....
|
||
&S "LCOME TO THE HOG THRO"
|
||
....
|
||
|
||
Fido/FidoNet compares patterns you specify against the right hand end<6E>
|
||
of the shift register; this means that for each character<65>
|
||
received (therefore a new string each time) you can look for any<6E>
|
||
reasonable number of possible patterns. ("Reasonable" will be<62>
|
||
discussed later ...)
|
||
|
||
|
||
|
||
In this example, to do an automatic login, once we see the word<72>
|
||
"PASSWORD:", we can output thename and password. This is a common<6F>
|
||
and simple case. The instruction "MATCH" will do the job.
|
||
|
||
"MATCH" compares text you specify against the contents of the<68>
|
||
shift register. For this example we'd use "WORD:". A string match<63>
|
||
is used, so you only need to use enough characters to make it<69>
|
||
unique; the string "WORD:" does not appear anywhere else in the<68>
|
||
initial signon message. (Actually, ":" will work fine here, but<75>
|
||
it's a good idea to use at least a couple of characters; "RD:"<22>
|
||
would be even better.)
|
||
|
||
MATCH "WORD:"
|
||
|
||
To continue the example above, as characters come in from the<68>
|
||
modem they shift through the shift register. Fido/FidoNet is<69>
|
||
executing the "MATCH" instruction above, and the shift register<65>
|
||
looks like:
|
||
|
||
....
|
||
match WORD:
|
||
&S= "OUR NAME AND PASSWOR"
|
||
|
||
match WORD:
|
||
&S= "UR NAME AND PASSWORD"
|
||
|
||
match WORD:
|
||
&S= "R NAME AND PASSWORD:"
|
||
|
||
For each character received, the "MATCH" instruction is comparing<6E>
|
||
it's pattern ("WORD:") against the contents of the shift<66>
|
||
register. When the patterns match, the next line of the script<70>
|
||
file is executed, which in this case could be an instruction to<74>
|
||
output your name and password.
|
||
.pa
|
||
COMPLEX PATTERN MATCHING
|
||
|
||
You don't need to understand the how and whys of the shift<66>
|
||
register to use the "MATCH" command, and for most casual script<70>
|
||
writers that will be all you need.
|
||
|
||
A good example of the limitations of such a simple system is a<>
|
||
script that dials phone numbers with a Hayes modem using "AT"<22>
|
||
commands, and responding to the many possible "result codes".<2E>
|
||
(This example assumes a basic understanding of Hayes modem<65>
|
||
commands.)
|
||
|
||
The dialing part is easy; you just issue the ATDT command and the<68>
|
||
phone number. The problem arises when you try to interpret the<68>
|
||
results of that command, such as busy, no answer, connecting at<61>
|
||
various baud rates, errors, etc. A simple "MATCH" instruction<6F>
|
||
just won't work.
|
||
|
||
For example the US Robotics Courier HST has about a dozen<65>
|
||
possible responses to a simple dial command; any script you write<74>
|
||
must be able to handle them all. That's what we'll do here.
|
||
|
||
Dialing a US Robotics Courier HST
|
||
|
||
The command we'll use, for simplicity, is:
|
||
|
||
"AT DT 764 1629\r"
|
||
|
||
("\r" means "carriage return, CR, decimal 13)
|
||
|
||
The modem can respond with any of the following result words:
|
||
|
||
CONNECT (300 baud)
|
||
RING (incoming call)
|
||
NO CARRIER (failed to connect)
|
||
ERROR (bad command given)
|
||
CONNECT 1200
|
||
NO DIAL TONE
|
||
BUSY
|
||
NO ANSWER
|
||
CONNECT 2400
|
||
RINGING
|
||
VOICE
|
||
CONNECT 9600
|
||
|
||
This is where you take advantage of the shift register. The<68>
|
||
script fragment below handles the problem at hand and is<69>
|
||
explained below. You will be using this SAMPLE ... IF ... GOTO<54>
|
||
loop to do most complex string compares.
|
||
|
||
|
||
&T= 60
|
||
&C= 0
|
||
TRAP dial-failed
|
||
output "ATDT 764-1629\r"
|
||
:get-result
|
||
sample
|
||
if "NO" dial-failed
|
||
if "ERR" dial-failed
|
||
if "12" conn-1200
|
||
if "24" conn-2400
|
||
if "96" conn-9600
|
||
if "ECT\r" conn-300
|
||
if "BU" redial
|
||
if "VO" dial-failed
|
||
if "RING\r" dial-failed
|
||
goto getresult
|
||
|
||
:dial-failed
|
||
&A= 0
|
||
return 1
|
||
|
||
:conn-300
|
||
&A= 300
|
||
goto connect
|
||
|
||
:conn-1200
|
||
&A= 1200
|
||
goto connect
|
||
|
||
:conn-2400
|
||
&A= 2400
|
||
goto connect
|
||
|
||
:conn-9600
|
||
&A= 9600
|
||
:connect
|
||
$$ "b &A\r"
|
||
message "connected at &a baud"
|
||
return 0
|
||
|
||
|
||
"SAMPLE" is a special instruction for use in SAMPLE/IF/JMP loops,<2C>
|
||
and causes one character to shift into the shift register. (The<68>
|
||
"MATCH" instruction and most others do this automatically, but<75>
|
||
"IF" doesn't.) You should have one, and only one, "SAMPLE"<22>
|
||
instruction before each set of "IF" instructions; if you have<76>
|
||
none, the shift register will not ever change, and if you have<76>
|
||
more than one you will miss patterns.
|
||
|
||
"IF" compares the given pattern against the current contents of<6F>
|
||
the shift register, and branches to the specified label if a<>
|
||
match is made.
|
||
|
||
The patterns searched for by the "IF" instructions need to be<62>
|
||
mentioned. You could search for the entire modem response<73>
|
||
("CONNECT 1200" instead of just "12") but the script will run<75>
|
||
faster is short strings are used. Use as few as possible is the<68>
|
||
general rule. The "NO" pattern will match any of the following,<2C>
|
||
which all mean no connection: NO CARRIER, NO DIAL TONE, NO<4E>
|
||
ANSWER. The 300 baud connection result code is "CONNECT", hard to<74>
|
||
distinguish from "CONNECT 1200" because the "IF" will match<63>
|
||
"CONNECT" without waiting for the "1200" or whatever follows. The<68>
|
||
"ECT\r" means that it will only match that word at the end of a<>
|
||
line, that is, followed by a CR character.
|
||
|
||
A loop of this length will run pretty slowly. It really should<6C>
|
||
have a "timeout" check, using the &C clock, to limit the dialing<6E>
|
||
attempt to a minute or so, and this will slow it further.
|
||
|
||
To accomodate this, Fido/FidoNet has rather huge buffers, and using<6E>
|
||
the explicit "SAMPLE" instruction means that characters won't<>
|
||
speed through the shift register faster than you can test them.
|
||
|
||
With a loop of approximately this size, it would take a few<65>
|
||
thousand characters at continuous 9600 baud to cause character<65>
|
||
loss. In the example above, speed is not a problem; the modem<65>
|
||
issues very little text.
|
||
|
||
SAMPLE/IF/JMP loops should be as tight as possible. This is<69>
|
||
interpreted, so keep that in mind; keep comments out of loops,<2C>
|
||
keep labels and operands short. Use as few "IF"s as possible.
|
||
|
||
If you need to do such a series of compares through a large<67>
|
||
amount of text at high speed, it is best to cut down the search,<2C>
|
||
for example by issuing commands to reach some intermediate point<6E>
|
||
from which you can do your multiple compares.
|
||
.pa
|
||
FURTHER NOTES ON PATTERN MATCHING
|
||
|
||
The strings you provide to the "MATCH" and "IF" instructions have<76>
|
||
some characteristics that make for easier comparisons.
|
||
|
||
All searches are case IN-sensitive. "ANC" matches "anc", etc. You<6F>
|
||
can specify it in your script in either way.
|
||
|
||
"?" is a wildcard character; it mean match any character.<2E>
|
||
"CONNECT ??00" will match "CONNECT 1200", "CONNECT 2400", etc.
|
||
|
||
Control characters are treated just as any other character. "End<6E>
|
||
of line" characters will vary with the bulletin board program or<6F>
|
||
whatever it is you call; Fido for instance is like most BBSs, and<6E>
|
||
uses a CR/LF sequence (decimal 13, decimal 10). You can search<63>
|
||
for "\r" or "\13" or for "\r\n" or "\13\10", but keep in mind<6E>
|
||
that other systems could use LF/CR, or other combination.
|
||
|
||
HINT: You can store strings directly in to the Shift Register and<6E>
|
||
then test it with the "IF" command. For instance, user input from<6F>
|
||
the "INPUT" command copied into &S could be tested for a<>
|
||
particular value.
|
||
|
||
.pa
|
||
.sh Register and Arithmetic Instructions
|
||
|
||
These are the most basic instructions to change the contents of<6F>
|
||
the various registers. Please note that the space after the "="<22>
|
||
is signifigant.
|
||
|
||
&S= text
|
||
&1= text or number
|
||
&2= text or number
|
||
&3= text or number
|
||
...
|
||
&8= text or number
|
||
Set the specified register. Numbers are really text<78>
|
||
strings, but you can treat them either way. The string must be<62>
|
||
under 20 characters.
|
||
|
||
&A= value
|
||
Set the accumulator to the specified value. The<68>
|
||
accumulator is numeric only.
|
||
|
||
&B= value
|
||
Set the baud rate register to the specified value; if the<68>
|
||
value is not a valid baud rate then the &B register will not<6F>
|
||
change.
|
||
|
||
&C= value
|
||
Set the free-running clock to an initial value. The clock<63>
|
||
counts up continuously every second.
|
||
|
||
&T= value
|
||
Set the trap register to the specified value. Setting it<69>
|
||
to zero disables the trap.
|
||
|
||
ADD value
|
||
SUB value
|
||
Add or subtract the value to the accumulator.
|
||
|
||
PUSH text
|
||
Puts the text onto the top of data stack. There are only<6C>
|
||
10 levels so watch out. Anything can be pushed onto the stack.
|
||
|
||
POP register
|
||
Take the top item off the stack and place it in the<68>
|
||
specified register. If you try to put non-numeric text into a<>
|
||
numeric register it becomes "0". You cannot POP items not PUSHed.
|
||
|
||
.pa
|
||
.sh Flow Control Instructions
|
||
|
||
TRAP label
|
||
This instruction is used to set a time limit on script<70>
|
||
execution, usually loops searching for a pattern. The trap uses<65>
|
||
the &C clock.
|
||
|
||
The &T trap register is set to the specified number of seconds,<2C>
|
||
and the &C clock is reset. Before each script instruction is<69>
|
||
executed, the clock is compared against the trap time; if the<68>
|
||
time limit is exceeded, the script branches to the specified<65>
|
||
label in the script file that initially set the trap; therefore<72>
|
||
the trap can even abort scripts running many subroutine calls<6C>
|
||
deep. Setting the &T trap register to zero disables the trap.
|
||
|
||
&T= 0
|
||
&C= 0
|
||
TRAP label
|
||
....
|
||
|
||
If at any time during script execution the &C clock<63>
|
||
reaches or exceeds the &T trap register, script execution<6F>
|
||
proceeds from the specified label in the current script file.
|
||
|
||
|
||
JMP label
|
||
Branch to the specified label unconditionally.
|
||
|
||
JZ label
|
||
JNZ label
|
||
Branch to the specified label in the current script file<6C>
|
||
if the accumulator is zero (JZ) or not zero (JNZ). This is used<65>
|
||
to test previous arithmetic instructions.
|
||
|
||
DJNZ label
|
||
A basic looping instruction: "Decrement and Jump if Not<6F>
|
||
Zero". Subtracts 1 from &A, and if the result is not zero,<2C>
|
||
branches to the specified label.
|
||
|
||
JERROR label
|
||
Branches if the &E error register is not zero. &E is<69>
|
||
generally set by the MATCH instruction failing, the RETURN (from<6F>
|
||
subroutine) instruction.
|
||
|
||
CALL scriptfile parameters ...
|
||
Execute the script file as a subroutine. The filename is<69>
|
||
"scriptfile.SCR". The called script file can in turn call other<65>
|
||
scripts, and each executes until the end of the script file or a<>
|
||
RETURN instruction is executed.
|
||
|
||
Each subroutine has it's own set of registers, &1 to &8.<2E>
|
||
Parameters can be passed to the called routine, which set the<68>
|
||
initial value of the local registers. The contents of the local<61>
|
||
registers are lost when the subroutine returns.
|
||
|
||
|
||
RETURN value
|
||
Return to the calling subroutine (if any) and optionally<6C>
|
||
set the error register to the specified value.
|
||
.pa
|
||
.sh String Comparison Instructions
|
||
|
||
MATCH pattern limit
|
||
Wait until the pattern is found in the incoming character<65>
|
||
stream before executing the next instruction in the script. The<68>
|
||
pattern can contain "?" wildcard characters. There is an implicit<69>
|
||
limit of 60 seconds; if a match is not found with the time limit<69>
|
||
the error register is set and the next instruction executed.<2E>
|
||
(Presumably a JERROR ... instruction.) Optionally a time limit,<2C>
|
||
in seconds can be specified.
|
||
|
||
SAMPLE
|
||
Shifts one character into the shift register; to be used<65>
|
||
in SAMPLE/IF/GOTO loops.
|
||
|
||
IF pattern label
|
||
Compares the pattern against the contents of the shift register, and branches to the specified label if it matches. The pattern can contain "?" wildcard characters.
|
||
.pa
|
||
.sh Character Output Instructions
|
||
|
||
OUTPUT string
|
||
Queue the string for output to the modem, simulating<6E>
|
||
manual keyboard entry. The speed with which characters are output
|
||
is determined by the THROTTLE setting.
|
||
|
||
COPY string
|
||
Output the string directly to the modem at maximum speed.
|
||
|
||
THROTTLE n (0 - 500)
|
||
This controls the maximum speed that Fido/FidoNet will output<75>
|
||
characters queued up by the OUTPUT command. The speed is<69>
|
||
specified in a minimum wait between characters, in milliseconds.<2E>
|
||
The default is 20 milliseconds.
|
||
.pa
|
||
.sh File I/O Instructions
|
||
|
||
Fido/FidoNet's file system is very simple; there can only be one file<6C>
|
||
open at a time. It is not a cooincidence that the file format is<69>
|
||
compatible with most BASICs; each record in a Fido/FidoNet file<6C>
|
||
contains 8 fields, each field is a quoted string seperated by<62>
|
||
commas. Each record is delimited with a CR/LF. There is no<6E>
|
||
Control-Z or other end of file terminator.
|
||
|
||
FOPEN filename
|
||
Opens a file for reading or writing. The script is<69>
|
||
aborted if the file cannot be found, or if "UNATTENDED" is set,<2C>
|
||
then the error register &E is set. The file must be FCLOSEd when<65>
|
||
not needed.
|
||
|
||
FNEW filename
|
||
Creates a new file of the specified name. The script is<69>
|
||
aborted if the file cannot be created. The file will be empty<74>
|
||
after creation.
|
||
|
||
FREAD
|
||
Reads one record from the file, and deposits the contents<74>
|
||
of the record into the eight registers &1 to &8. Each record can<61>
|
||
contain any number of items, but only the first 8 will be used.<2E>
|
||
Each should be an argument as described elsewhere, preferably<6C>
|
||
quoted.
|
||
|
||
Lines are read from the file one per FREAD instruction,<2C>
|
||
starting with the first line in the file, until the last line is<69>
|
||
read; all FREADs after the last line will leave all registers<72>
|
||
empty and set the error register &E.
|
||
|
||
FWRITE
|
||
A new record is added to the end of the open file, that<61>
|
||
contains the contents of the eight registers &1 to &8. Each is<69>
|
||
"quoted". The script is aborted if the disk becomes full, or if<69>
|
||
"UNATTENDED" is set, then the error register &E is set.
|
||
th
|
||
|
||
FCLOSE
|
||
This closes the current file and allows the FOPENing of<6F>
|
||
another file. If any FWRITEs were done, they are written out to<74>
|
||
disk at this time.
|
||
|
||
.pa
|
||
.sh User Input Instructions
|
||
KEYBD char
|
||
Temporarily suspend script file operation until the user<65>
|
||
types the specified key; CR if none specified. All characters the<68>
|
||
user types, including the terminating one, are outout to the<68>
|
||
modem. This allows the user to manually enter something such as<61>
|
||
password.
|
||
|
||
INPUT prompt
|
||
The prompt is displayed and the user enters a line of<6F>
|
||
text, which is parsed into variables &1 through &8. Any extra<72>
|
||
text is ignored.
|
||
|
||
ASK question
|
||
The question is displayed and Y or N is input as a<>
|
||
response, with &E set true if the answer is Y.
|
||
|
||
PAUSE prompt
|
||
The prompt is displayed and the user must hit any key to<74>
|
||
continue.
|
||
|
||
MESSAGE message
|
||
Output the message to the command status line.
|
||
|
||
.pa
|
||
.sh Special Instructions
|
||
|
||
These instructions generally take one operand and perform some<6D>
|
||
hopefully useful instruction. They are generally high level<65>
|
||
functions to perform common functions.
|
||
|
||
|
||
IOPORT n (1 - 2)
|
||
Select the serial port to do business with; the default<6C>
|
||
is the first port, on a pclone COM1.
|
||
|
||
CD-BIT (1,2,4,8,16,32,64,128)
|
||
Set the Carrier Detect (CD) mask bit for proper operation<6F>
|
||
of the on-screen "ONLINE/OFFLINE" display.
|
||
|
||
TIME hh:mm (00:00 - 23:59)
|
||
Wait until the specified time of day before executing the<68>
|
||
next line in the script file.
|
||
|
||
FILES filespec
|
||
Sets &A to the number of files matching the file<6C>
|
||
specification.
|
||
|
||
DELAY milliseconds (1 - 65000)
|
||
Delay execution of the script until time elapsed.
|
||
|
||
QUIET milliseconds (1 - 65000)
|
||
Wait for no input from the modem for the specified time.
|
||
|
||
DTR
|
||
Lowers the modem control line Data Terminal Ready (DTR)<29>
|
||
for 1/2 second.
|
||
|
||
BREAK
|
||
Causes a 1/2 second line break.
|