.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