QTPI v1.50 and later supports a scripting language. The scripting language is fully featured, rich and structured. It's also very easy to learn. It's called Basic or 'C', or even both.
QTPI scripting is implemented using the 'Client-Server Manager' Thing (CSM) that allows robust messaging between applications. CSM supports a BASIC and 'C' interface, allowing scripts for QTPI (or any CSM compliant server) to be written in either language.
QTPI v1.50 offers a "Run Script" or "Run External" menu option. This can invoked a compiled script program (which may have either Basic or 'C' source); if you have a recent Minerva (tm) ROM, thanks to those clever 'men from the minnys-try', QTPI will hook into the Multi-BASIC vector to interpret an uncompiled BASIC script for you.
QTPI v1.55 and later can invoke SMS2 command files on SMS2 systems and invoke uncompiled BASIC programs using the SBASIC thing under SMSQ/E.
To use CSM functionality with QTPI , you must have loaded the CSM thing.
LRESPR srvthg_rext
srvthg_rext adds some new KEYWORDS to BASIC (see the CSM documentation for full details). The KEYWORDS relevant to QTPI clients are:
CLIENT 'QTPI' : REMark Declare a program to be a QTPI Client REQUEST 'QTPI',act$,result$ : REMark Make a QTPI request FREECLIENT 'QTPI' : REMark Stop being a QTPI client
The following example script requests QTPI to display a dialogue box with a title "File(s) to upload" and the input field preloaded with the text "flp1_*". If the user returns a valid string (i.e. not ESC or and empty string), then QTPI is requested to upload the files. The result of the script (either ESC from the dialogue box or an upload) is reported in the QTPI status line.
100 CLIENT 'QTPI' 110 REQUEST 'QTPI','ASKT Files to upload'&CHR$(0)&'flp1_*',a$ 120 IF CODE(a$(1)) <> 7 THEN 130 REQUEST 'QTPI','UPLOAD '&a$,b$ 135 REQUEST 'QTPI','STSMSG Upload of '&a$&' returned '&b$,b$ 137 ELSE 138 REQUEST 'QTPI','STSMSG "ASKT" REQUEST gave "'&a$(2 TO)&'"',b$ 140 END IF 150 FREECLIENT 'QTPI' 160 STOP
QTPI error responses always start with chr$(7), so you only need to check the first character to see if the request succeeded.
QTPI supports the following REQUESTS.
|
The ASCSEND request sends or cancels an ASCII file transmission (cf SF1/Send Text).
Responses will be "OK", chr$(7) & "Not found" or "Canceled" (this is not an error).
100 CLIENT 'QTPI' 110 REQUEST 'QTPI','ASCSEND flp1_boot',r$ 120 REQUEST 'QTPI','SEND \e007How was that then ? \er\en',s$ 130 PRINT : PRINT 'Client ';r$;' ';s$ 140 STOP
The ASKN request gives the user a number of choices
(cf the "Save|Don't Save|Go Back" requester).
The format of the command is "title&chr$(0)&choices". The choices are delimited by the vertical bar (|) character
Responses will the offset of the option or chr$(7) & "ESC".
Example:
100 CLIENT 'qtpi' 105 req$ = 'Really quit this script ?'&CHR$(0)&'Yes|No|Perhaps|Soon' 110 REQUEST 'qtpi','ASKN '&req$,a$ 120 IF CODE(a$(1)) = 7 THEN 130 PRINT 'You EScaped' 140 ELSE 150 a = a$ : REMark well basic must be good for something 160 SELECT ON a 170 ON a = 0 180 PRINT "Bye bye then" 190 ON a = 1 200 PRINT "Glad you could stay" 210 ON a = 2 220 PRINT "Please make up your mind" 230 ON a = 3 240 PRINT "Procrastination is the thief of time" 250 END SELECT 260 ENDIF 270 FREECLIENT 'QTPI' : REMark lets be legal nowThe above example would create a dialogue box on the QTPI screen.
Selection amy be made by mouse, cursor key of first letter (if unique). Note that the offset starts at zero (as it's an offset ).'C' programmers will think this was too obvious to note.
The ASKT request presents a dialogue box asking for a text response. The script may preset a default response.
The format of the command is "title & chr$(0) & preset". The preset part need not be given.
Responses will the entered text or chr$(7) & "ESC".
Example
100 CLIENT 'QTPI' 110 REQUEST 'QTPI','ASKT File(s) to upload'&CHR$(0)&'flp1_*',a$ 120 IF CODE(a$(1)) <> 7 THEN 130 REQUEST 'QTPI','UPLOAD '&a$,b$ 135 REQUEST 'QTPI','STSMSG Upload of '&a$&' returned '&b$,b$ 137 ELSE 138 REQUEST 'QTPI','STSMSG "ASKT" REQUEST gave "'&a$(2 TO)&'"',b$ 140 END IF 160 STOP
The above example would create a dialogue box on the QTPI screen.
The CAPTURE command opens (or if already open), closes a text capture log.
Responses will be "OK" (even if the open fails) or "Canceled".
Example
CLIENT 'QTPI' REQUEST 'QTPI',CAPTURE ram2_mylog_log', a$ IF a$ <> "OK" : PRINT "A log was already open" FREECLIENT QTPI
The config command loads the specified configuration file. This name becomes the default configuration file.
Responses are "OK" or chr$(7) & "Error".
Example
CLIENT "qtpi" REQUEST "qtpi","config win1_QTPI_ser2_dat", a$ IF a$ <> "OK" THEN PRINT #15,"The config load failed" ENDIF
The CONVERSE command sends a string to the serial port and waits for a response. The wait period is defined by the current TIMEOUT setting (default 20 seconds).
Responses will be chr$(7) & "Timeout" or the remote response. The inverse of CONVERSE maybe done using WAIT and SEND.
The format of the command is "prompt & chr$(0) & term-string". term-string is a sequence of characters that will terminate remote input.
Example:
CLIENT 'qtpi' REMark Let the remote see what they type REQUEST 'qtpi','echo on',a$ REMark prompt and wait for string terminated with CR REQUEST 'qtpi','CONVERSE Enter your name ? '&CHR$(0)&"\er",b$ REQUEST 'qtpi','echo off',a$ IF b$ <> "Fred" THEN REQUEST 'qtpi',"SEND You're not welcome here\er",a$ REQUEST 'qtpi', "HANGUP",a$ ELSE REQUEST 'qtpi',"SEND Hi Fred, welcome to QTPI scripting\er",a$ ENDIFSee also WAIT, SEND, TIMEOUT, ECHO
The DIAL command dials either a phone book entry or a number. If the name or number given matches an entry in the phone book, then QTPI will invoke the phone book options (protocol, baud, EOL codes, parity etc) before dialing the number. If the number does not match a phone book entry, it is dialed directly.
Response is the modem return from dialing (CCONNECT 14400, BUSY etc).
Example
100 CLIENT 'qtpi' 110 REMark or REQUEST 'qtpi','DIAL 4th Dimension',a$ 120 REQUEST 'qtpi','DIAL 0-1202-770515',a$ 130 IF "CONNECT" INSTR a$ THEN 140 REQUEST 'qtpi', 'WAIT Please enter your first and last name:',a$ 150 IF 'name:' INSTR a$ THEN 160 REQUEST 'QTPI','SEND \eu',b$ : \eu sends LOGIN string 170 ELSE ...
The DOWNLOAD command downloads a file (or files, depending on protocol).
Response is always "OK", even when it isn't.
Example
110 CLIENT 'qtpi' 120 REQUEST 'qtpi','download',a$ : REMark SEAlink/ZMODEM :-) 130 REQUEST 'qtpi','download ram2_x_zip',a$ : REMark XMODEM :-(
See also PROTOCOL
The ECHO commands defines if text entered remotely is echoed back to the remote. Normally this would be off. If you were using QTPI and a script as a mini-BBS, then you might want to use this.
Response "OK" or chr$(7) & "Error" if not "on" or "off".
Example
REQUEST 'qtpi','echo on',a$ REMark prompt and wait for string terminated with CR REQUEST 'qtpi','CONVERSE Enter your name ? '&CHR$(0)&"\er",n$ REQUEST 'qtpi','echo off',a$ REMark no echo for password REQUEST 'qtpi','CONVERSE Enter your password : '&CHR$(0)&"\er",p$ IF VerifyUser(n$, p$) THEN ...
The EXITPARAM commands defines a text string that is passed to a QTPI shutdown script.
Response is "OK".
Example
REMark if we've detected QFAX at startup, we can suspend it REMark so it gives up the serial port for our use. : CLIENT 'QFAX' REQUEST 'QFAX','SUSPEND' FREECLIENT 'QFAX' CLIENT 'QTPI' REQUEST 'QTPI','EXITPARAM REQUEST QFAX RESUME' FREECLIENT 'QTPI' :
In the shutdown script, CMD$ is REQUEST QFAX RESUME.
GET returns the current value of a QTPI config value (i.e. anything you can set from the SF3 menu. The value required is specified using the name text string from the Config screen (or qtpi_dat), and is case independent.
Response is the value or chr$(7) & "Error".
Example
CLIENT 'qtpi' REQUEST 'QTPI','GET baud',a$ IF a$ = '9600' THEN REMark We can go faster than a speeding snail ..... REQUEST 'QTPI','SET BAUD=19200',a$ ENDIF REQUEST 'QTPI','GET xpr protocol',a$ IF a$ <> 'ZMODEM' THEN REMark Let's use a real one :-) REQUEST 'QTPI','SET xpr protocol=zmodem',a$ REMark same as REQUEST 'QTPI','PROTOCOL ZMODEM',a$ ENDIF
See also SET, PROTOCOL
Sends the Disconnect command to the modem, sets QTPI to its disconnected state.
Response is always "OK", even when it isn't.
Example
REMark Do we really need one (exercise for reader) CLIENT 'QTPI' REQUEST 'QTPI','HANGUP',a$ : REMark average QUANTA member could almost IF a$ == "OK" THEN : REMark have worked that one out :-).
The ICONIFY request iconifies QTPI .
Response is always "OK", even when it isn't.
Example
CLIENT 'QTPI' REQUEST 'QTPI','ICONIFY',a$
QTPI offers a ICONIC mode where by it will run as a button and may only be controlled by CSM commands. This mode is entered by either:
QTPI may only be restored to full screen from ICONIC mode by the CSM command 'IWAKE'; a normal wake or mouse click has no effect.
QTPI may be restored to a 'normal' button (one that you can hit) with the CSM 'IFREE' command.
For example:
CLIENT 'qtpi' REQUEST 'qtpi','ISLAVE',a$ REQUEST 'qtpi','send sz /var/spool/uucppublic/test.zip',a$ REM This loop just checks the QTPI status until the file is received stat% = 0 : cnt% = 0 REPeat loop PAUSE 100 REQUEST 'qtpi','status',a$ IF 'RZ' INSTR a$ THEN IF stat% = 0 : stat% = 1 PRINT a$ cnt% = 0 ELSE IF stat% : EXIT loop cnt% = cnt% + 1 IF cnt% = 15 : EXIT loop END IF END REPeat loop REQUEST 'qtpi','IWAKE'
All CSM commands, other than those that require screen input (ASKT,ASKN) are honoured in this mode.
The QUIT request will work, but it does not ask for any confirmation (to save changed settings etc).
The config command loads the specified phone book file. This name becomes the default phone book file.
Responses are "OK" or chr$(7) & "Error".
Example
CLIENT "qtpi" REQUEST "qtpi","loadphone win1_QBook_USA_dat", a$ IF a$ <> "OK" THEN PRINT #15,"The phone book load failed" ENDIF
Changes the file transfer protocol.
Response is "OK" or chr$(7) & "Error".
Example
CLIENT 'qtpi' REQUEST 'QTPI','GET xpr protocol',a$ IF a$ <> 'ZMODEM' THEN REMark Let's use a real one :-) REQUEST 'QTPI','PROTOCOL ZMODEM',a$ ENDIFSee also GET, SET
The QUIT command quits QTPI . No "Save" requesters are displayed for unsaved data. All other normal shutdown activities are performed (reset of switch character, baud rate, hot keys etc).
Response is always "OK".
Example
CLIENT 'QTPI' REQUEST 'QTPI','QUIT',a$
Resumes a QTPI session after the SUSPEND request. Reopens the serial port.
Response is always "OK".
Example
CLIENT 'QTPI' REQUEST 'QTPI','RESUME'
The SAVECONF command saves the current configuration. If no file name is given the current configuration file is used.
Response is always "OK", even if it strictly isn't.
Example
CLIENT 'qtpi' REQUEST 'qtpi','SAVECONF win9_bad-drive_dat',a$ IF a$ = "OK" : PRINT "Somewhat economical with fidelity"
Sends a string to the serial port. Note that strings may contain the usual QTPI escape sequences.
Response is always "OK".
Example
CLIENT 'qtpi' REQUEST 'qtpi', 'SEND \e007Ring your bell\e007\er', a$
SET sets a a QTPI config value (i.e. anything you can set from the SF3 menu. The value required is specified using the name text from the Config screen (or qtpi_dat), and is case independent.
Response is the value or chr$(7) & "Error".
Example
CLIENT 'qtpi' REQUEST 'QTPI','GET baud',a$ IF a$ = '9600' THEN REMark We can go faster than a speeding snail ..... REQUEST 'QTPI','SET BAUD=19200',a$ ENDIF REQUEST 'QTPI','GET xpr protocol',a$ IF a$ <> 'ZMODEM' THEN REMark Let's use a real one :-) REQUEST 'QTPI','SET xpr protocol=zmodem',a$ ENDIFSee also GET, PROTOCOL
The REQUEST 'SPAWN' runs a compiled program from within QTPI , that may use the QTPI screen and serial channels.
The REQUEST will return "OK" or a 007 string describing a SMS/QDOS error condition.
Note that QTPI is effectively suspended while the SPAWNed program is run and will not read mouse, keyboard or serial port. This is achived by temporarily zeroing job priorities. The user should not change these.
The format is
SPAWN prog[,ch1,ch2,ch3][;parameters]
Some pseudo-channels are defined as
#s - QTPI serial channel #c - QTPI console channel
Otherwise, filenames may be given.
Examples
c$ = 'SPAWN flp2_qfax,#s,#c,#c;-v -z jrh jh_fax' REQUEST 'QTPI', c$ ,z$
The above sends a fax from with QTPI , with output to the QTPI console window. Note this requires QFAX v2.6 or better for -z.
c$ = 'SPAWN flp2_qfax,#s,ram2_qfax_log,nul;-v -z jrh jh_fax' REQUEST 'QTPI', c$, z$ 100 CLIENT 'qtpi' 105 REMark Need CSM v1.16 for two parameter (don't care) requests. 110 REQUEST 'qtpi','wake' 120 REQUEST 'qtpi','askt Fax to send'&CHR$(0)&'flp2__fax',a$ 130 REQUEST 'qtpi','askt Respondent',b$ 140 req$ = 'flp2_qfax,#s,#c,#c;-v -z '&b$&' '&a$ 150 REQUEST 'qtpi','spawn '&req$,x$ 160 FREECLIENT 'qtpi'An example with no channels
100 : 110 CLIENT 'qtpi' 120 REQUEST 'qtpi','wake' 130 REQUEST 'qtpi','spawn flp1_qed;flp1_qtpi_dat',try$ 140 IF try$ == 'OK' : REQUEST 'qtpi','config flp1_qtpi_dat' 150 FREECLIENT 'qtpi'
Returns QTPI status. The reply may take a number of forms.
For example:
SZ ram2_test_zip 58% 1573 0
Example
CLIENT 'QTPI' REQUEST 'QTPI','STATUS', a$
This command writes a text message to the QTPI status line. The text should NOT contain QTPI \escape sequences.
Response is always "OK".
Example
CLIENT 'QTPI' REQUEST 'QTPI','STSMSG Please phone home ....', a$
Suspends a QTPI session. QTPI closes the serial port and does not read the mouse or keyboard until a RESUME (or QUIT).
Response is always "OK".
Example
CLIENT 'QTPI' REQUEST 'QTPI','SUSPEND'
Sets the timeout for any subsequent WAIT or CONVERSE commands. The time is assumed to be in seconds, unless it is followed by the text "MIN" in which case it's assumed to be minutes.
Response is either "OK" or chr$(7) & "Bad Timeout".
Example
CLIENT 'QTPI' REQUEST 'QTPI','TIMEOUT 60', a$ REMark or even REQUEST 'QTPI','TIMEOUT 1 MIN', a$
This command requests the upload of file(s).
Response is always "OK".
The upload is asynchonous of the command (i.e. the command merely requests that QTPI starts the transfer, the status of the transfer may be followed usuing the STATUS command.
Example
100 CLIENT 'QTPI' 110 REQUEST 'QTPI','ASKT Files to upload'&CHR$(0)&'flp1_*',a$ 120 IF CODE(a$(1)) <> 7 THEN 130 REQUEST 'QTPI','UPLOAD '&a$,b$ 135 REQUEST 'QTPI','STSMSG Upload of '&a$&' returned '&b$,b$ 137 ELSE 138 REQUEST 'QTPI','STSMSG "ASKT" REQUEST gave "'&a$(2 TO)&'"',b$ 140 END IF 150 FREECLIENT 'QTPI' 160 STOP
This command waits for either the timeout period (defined by TIMEOUT) to expire or a string from the serial port terminated by a specified character or group of characters.
Response is either chr$(7) & "Timeout" or the response from the serial port.
Example
CLIENT 'qtpi' REMark WAIT for QBOX login string REQUEST 'qtpi', 'WAIT Please enter your first and last name:',a$ IF 'name:' INSTR a$ THEN REQUEST 'QTPI','SEND \eu',b$ : \eu sends LOGIN string ELSE
This command WAKES QTPI . If QTPI is iconified it will be made full size, if it is hidden it will be 'picked' to the front.
Response is "OK".
Example
CLIENT 'qtpi' REQUEST 'qtpi', 'WAKE',a$
If QTPI detects the CSM Thing on your system, the "Run External" option is available in the Files (Shift F1) menu.
QTPI will run executable scripts (actually any executable (type 1) program) on all O/S variants, and on Minerva systems, will run interpreted BASIC scripts from files that end _bas. SMS2 system can automatically invoke command files, SMSQ/E systems can automatically invoke _bas files.
When scripts are invoked from the QTPI menu, they are started with two channels on the stack, a nul channel for stdin and the file/device defined by the configuration item "Script Log" as stdout.
If the "Script Log" file name has a 'C' printf style numeric format string embedded, than a new log file will be started for each script.
Script Log=ram2_script%3d_log ram2_script001_log ram2_script002_log
If the "Script Log" does not contain numeric formating information, then script output is appended to the given file.
The name of a script that is run or interpreted at QTPI startup. Note that at this stage, QTPI has parsed its configuration file but has not yet opened the serial port.
The name of a script that is run or interpreted at QTPI shutdown. The command line passed to this script (CMD$, argv[1] ...argv[n]) is set by the QTPI REQUEST 'EXITPARAM'.
A number of example scripts are available, including:
QTPI and QTPI scripting was written by Jonathan Hudson jrhudson@bigfoot.com
Jonathan Hudson,
Southampton,
England.
This document was generated using the LaTeX2HTML translator Version 98.1p1 release (March 2nd, 1998)
Copyright © 1993, 1994, 1995, 1996, 1997, Nikos Drakos, Computer Based Learning Unit, University of Leeds.
The command line arguments were:
latex2html -no_subdir -split 0 -local_icons qtpiscript.tex.
The translation was initiated by Jonathan Hudson on 1999-11-11