.TITLE OSIT$CMD_EXECUTOR Read a command and execute it
.IDENT /1.0-001/
;
;****************************************************************************
;* *
;* COPYRIGHT (c) 1987, 1988 BY *
;* DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS. *
;* ALL RIGHTS RESERVED. *
;* *
;* THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED *
;* ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE *
;* INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER *
;* COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY *
;* OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY *
;* TRANSFERRED. *
;* *
;* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE *
;* AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT *
;* CORPORATION. *
;* *
;* DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS *
;* SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL. *
;* *
;* *
;****************************************************************************
;
;++
; FACILITY: VOTS example program. to communicate with another example
; program called OSIT$CMD_SOURCE
;
; FUNCTIONAL DESCRIPTION:
;
; Demonstrate task-to-task communication in MACRO. Read a command from
; the remote task, OSIT$CMD_SOURCE. Execute the command and send back
; the output. The command output is written to a file, which is read
; and sent to osit$cmd_source line by line.
;
; ENVIRONMENT: user mode
;
; AUTHOR: S.T. CREATION-DATE: December 8, 1987
;
; MODIFIED BY:
;
; HOW TO ASSEMBLE AND LINK
;
; macro/list=osit$cmd_executor/object=osit$cmd_executor -
; sys$library:osit+
osit$cmd_executor
;
; For '' substitute the directory to which you have copied
; the files.
;
; link osit$cmd_executor
;
; REQUIRED FILES AND COMMANDS:
;
; See osit$cmd_source for more information.
;
;--
;
.SUBTITLE DECLARATIONS
;+
; Include system macros
;-
$DSCDEF
$IODEF
$LNMDEF
$RMSDEF
$SSDEF
;+
; Include the VOTS specific macros
;-
$osit$constants
$osit$itemdef
;+
; Macros
;-
;
; Push the arguments in reverse order and call lib$spawn
; to execute a command line
;
.MACRO LIB_SPAWN CMD_DSC RSPFILE_DSC FLAGS IOSB
PUSHL #0 ; no cli arg addr
PUSHL #0 ; no prompt dsc
PUSHL #0 ; no astarg
PUSHL #0 ; no ast addr
PUSHL #0 ; no efn addr
PUSHAQ IOSB ; completion status
PUSHL #0 ; no process id descriptor
PUSHL #0 ; no process name descriptor
PUSHAL FLAGS ; flags address
PUSHAQ RSPFILE_DSC ; output file descriptor
PUSHL #0 ; no input file descriptor
PUSHAQ CMD_DSC ; Command string descriptor
CALLS #12,G^LIB$SPAWN; Spawn the command
.ENDM LIB_SPAWN
;
; Push the argument and call lib$stop to exit and report an error
;
.MACRO LIB_STOP
PUSHL R0
CALLS #1,G^LIB$STOP
.ENDM LIB_STOP
;
; Push the arguments and call lib$stop to exit and report RMS errors
;
.MACRO LIB_STOP_FAB FAB_NAME
PUSHL FAB_NAME + FAB$L_STV
PUSHL FAB_NAME + FAB$L_STS
CALLS #2,G^LIB$STOP
.ENDM LIB_STOP_FAB
;
; Push the arguments and call lib$stop to exit and report RMS errors
;
.MACRO LIB_STOP_RAB RAB_NAME
PUSHL RAB_NAME + RAB$L_STV
PUSHL RAB_NAME + RAB$L_STS
CALLS #2,G^LIB$STOP
.ENDM LIB_STOP_RAB
;+
; Local definitions
;-
HDR_SIZE = 4 ; Application Header size
HDR_W_STATUS = 0 ; Application status field
IOSB_W_LENGTH = 2 ; Length field in I/O status block
MAX_CMD = 256 ; Limit command length
MAX_CMDHDR = MAX_CMD + HDR_SIZE ; Command plus header length
MAX_RSP = 256 ; Limit response line length
MAX_RSPHDR = MAX_RSP + HDR_SIZE ; Response plus header length
;+
; Declare external routines and variables
;-
.EXTRN LIB$SPAWN,- ; Spawn a command
LIB$PUT_OUTPUT,- ; write to sys$output
LIB$STOP ; Stop and report an error
;+
; Read only data
;-
.SBTTL RO_DATA - read only data
.PSECT RO_DATA RD,NOWRT,EXE,LONG
;
; Descriptors
;
OSITDEV_DSC: .ASCID /OSIT$DEVICE/
SYS_NET_DSC: .ASCID /SYS$NET/ ; Logical equated to NCB
RSPFILE_DSC: .ASCID /OSIT$CMD_OUTPUT.TMP/
TOOSHORT_DSC: .ASCID /OSIT$CMD_SOURCE sent a message which was too short./
TRN_TABNAM: .ASCID /LNM$PROCESS_TABLE/
;+
; Read write data
;-
.SBTTL RW_DATA RD,WRT,EXE,LONG
.PSECT RW_DATA RD,WRT,EXE,LONG
;
; Buffer and dsc for command
;
CMDHDR: .BLKB HDR_SIZE ; Reserved for application header
CMD: .BLKB MAX_CMD ; Start of command
CMD_DSC: .WORD MAX_CMD ; Length
.BYTE DSC$K_DTYPE_T ; Text
.BYTE DSC$K_CLASS_S ; String, pointer
.ADDRESS CMD ; pointer
CMD_LEN: .BLKL 1 ; Length of command
FLAGS: .LONG 0 ; Flags for lib$spawn call
IOSB: .BLKQ 1 ; iosb, completion status
;
; Buffer and dsc for the NCB. The NCB is obtained by
; translating the logical name sys$net.
;
NCB: .BLKB OSIT$K_MAX_NCB
NCB_DSC: .WORD 0 ; Length
.BYTE DSC$K_DTYPE_T ; Text
.BYTE DSC$K_CLASS_S ; String
.ADDRESS NCB ; Pointer
;
; RMS data structures used to access the file which contains
; the command output.
;
.ALIGN LONG
RSPFILE_FAB: ; FAB for command-output file
$FAB -
FNM = ,-
FAC = ,-
SHR = ,-
RAT =
RSPFILE_RAB: ; RAB for command-output file
$RAB -
FAB = RSPFILE_FAB,-
UBF = RSP,- ; Read line into RSP buffer
USZ = MAX_RSP,- ; Limit size of line read
RAC = ; use sequential access
;
; Buffer for lines of command output
;
RSPHDR: .BLKB HDR_SIZE ; Reserved for the application header
RSP: .BLKB MAX_RSP ; Start of line of command output
TC_CHAN: .BLKW 1 ; Connection channel (Only a word)
;
; item list for call to $trnlnm
;
TRN_ITMLST: .WORD OSIT$K_MAX_NCB ; max. size of equivalence name
.WORD LNM$_STRING ; get equivalence name
.ADDRESS NCB ; and store it in NCB
.ADDRESS NCB_DSC
.LONG 0 ; terminate item list
;+
; Start of program
;-
.SBTTL CODE - Start of program
.PSECT CODE RD,NOWRT,EXE
.ENTRY CMD_EXECUTOR 0
$TRNLNM_S - ; Get the NCB by translating SYS$NET
LOGNAM = SYS_NET_DSC,-
ITMLST = TRN_ITMLST,-
TABNAM = TRN_TABNAM
BLBS R0,5$
JMP R0_ERROR
5$: $ASSIGN_S - ; Assign a channel to osit$device
CHAN = TC_CHAN,-
DEVNAM = OSITDEV_DSC ;
BLBS R0,6$ ; On failure, goto r0_error
JMP R0_ERROR
;
; IMPORTANT: The P2 parameter is treated as a value (PUSHL), so
; make sure to put a '#' in front of it.
;
6$: $QIOW_S - ; Accept the connection
CHAN = TC_CHAN,- ; and wait for the connection
FUNC = #IO$_ACCESS,- ; to be set up.
IOSB = IOSB,- ;
P2 = #NCB_DSC ; Don't forget the #!
BLBS R0,7$
JMP R0_ERROR
7$: MOVZWL IOSB,R0 ; Get the status of the connect request
BLBS R0,READ_CMD ; On failure, goto iosb_error or r0_error
JMP IOSB_ERROR
;
; The connection has been established. Read the command to execute.
;
READ_CMD:
$QIOW_S - ; Read the command from osit$cmd_source
CHAN = TC_CHAN,-
FUNC = #IO$_READVBLK,-
IOSB = IOSB,-
P1 = CMDHDR,-
P2 = #MAX_CMDHDR
BLBS R0,10$
JMP R0_ERROR
10$: MOVZWL IOSB,R0 ; Get the status of the connect request
BLBS R0,15$ ; On failure, goto iosb_error or r0_error
JMP IOSB_ERROR
;
; The command has been read. Make sure there is an application header.
; If there is only an application header, then exit.
;
15$:
MOVZWL IOSB + IOSB_W_LENGTH,- ; R4 is the length of the line+header
R4
CMPW R4,#HDR_SIZE ; Make sure there is a header
BGEQU 16$
JMP APPL_ERROR ; If not, goto appl_error
16$: SUBL2 #HDR_SIZE,R4 ; R4 is the length of the line
BNEQ 17$
JMP LEAVE ; If r4 is zero, there is no command, exit
;
; There is a command to execute.
; Call lib$spawn and write the command output to a file.
;
17$: MOVW R4,- ; Set the command length
CMD_DSC + DSC$W_LENGTH
LIB_SPAWN -
CMD_DSC RSPFILE_DSC FLAGS IOSB
BLBS R0,20$ ; Continue if success
LIB_STOP ; Print error and stop otherwise
;
; Open the file which contains the command output.
; (r0 and r1 are not preserved)
;
20$: $OPEN FAB = RSPFILE_FAB
BLBS R0,25$
LIB_STOP_FAB RSPFILE_FAB ; Stop and report an RMS error
25$: MOVAL RSPFILE_RAB,R7
$CONNECT -
RAB = (R7)
;
; Read lines of output until endoffile in encountered
;
READ_LINE:
$GET RAB = (R7) ; The rsp buffer contains the record
BLBS R0,40$ ; rsphdr precedes rsp
CMPL #RMS$_EOF,R0 ; End of file?
BEQL 50$ ; Yes, send an endoffile indication.
LIB_STOP_RAB RSPFILE_RAB ; Stop and report an RMS error
40$: MOVW #SS$_NORMAL,-
RSPHDR + HDR_W_STATUS ; Indicate success
MOVW RAB$W_RSZ(R7),-
R4 ; R4 is the line length
ADDL2 #HDR_SIZE,R4 ; R4 is the line plus header length
$QIOW_S - ; Send the line to osit$cmd_source
CHAN = TC_CHAN,-
FUNC = #IO$_WRITEVBLK,-
IOSB = IOSB,-
P1 = RSPHDR,-
P2 = R4
BLBS R0,10$
JMP R0_ERROR
10$: MOVZWL IOSB,R0 ; Get the status of the request
BLBS R0,15$ ; On failure, goto iosb_error or r0_error
JMP IOSB_ERROR
15$: BRW READ_LINE ; Read the next line
;
; The end-of-file has been reached. Return a header with
; ss$_endoffile to indicate this.
; Also, close the output file and delete it.
;
50$:
$CLOSE FAB = RSPFILE_FAB ; Close the file
$ERASE FAB = RSPFILE_FAB ; Delete the file
MOVW #SS$_ENDOFFILE,- ; Set endoffile status
RSPHDR + HDR_W_STATUS
$QIOW_S - ; Send endoffile indication
CHAN = TC_CHAN,-
FUNC = #IO$_WRITEVBLK,-
IOSB = IOSB,-
P1 = RSPHDR,-
P2 = #HDR_SIZE
BLBS R0,60$
JMP R0_ERROR
60$: MOVZWL IOSB,R0 ; Get the status of the request
BLBS R0,70$ ; On failure, goto iosb_error or r0_error
JMP IOSB_ERROR
70$: JMP READ_CMD ; Loop back to get another command
;
; The sender is done. Disconnect the transport connection and exit.
;
LEAVE:
$QIOW_S - ; Disconnect the transport connection
CHAN = TC_CHAN,-
FUNC = #IO$_DEACCESS
BLBS R0,10$
JMP R0_ERROR
10$: RET ; Exit with success
;
; If the process was started by a .COM procedure, these error
; messages will be written to the .LOG file.
;
; Report an R0 error
;
R0_ERROR:
PUSHL R0 ; Argument for lib$stop
CALLS #1,G^LIB$STOP ; Exit and report the error
;
; Report an I/O Status block error
;
IOSB_ERROR:
PUSHL IOSB+4 ; report iost2
PUSHL #0 ; Arg 2 is 0 (FAO count)
PUSHL R0 ; Arg 1 is r0
CALLS #3,G^LIB$STOP ; Exit and report the error
;
; Report an application error
;
APPL_ERROR:
PUSHAQ TOOSHORT_DSC ;
CALLS #1,G^LIB$PUT_OUTPUT ; Display the error message
MOVL #SS$_ABORT,R0
$EXIT_S ; Exit with ss$_abort status
.END CMD_EXECUTOR