.TITLE STF -- MCR COMMAND STUFFER .IDENT -000000- .SBTTL TITLE PAGE ;+ ; ABSTRACT: STF ; ; THIS PROGRAM IS USED TO FORCE A COMMAND TO BE EXECUTED ; ON A SPECIFIED TERMINAL. THIS IS USEFUL WHEN IT IS ; NECESSARY TO FORCE SOMETHING THROUGH A TERMINAL, ; SAY TO LOG A USER OUT. ; ; OPERATING PROCEDURES: ; ; THIS PROGRAM IS RUN AS AN MCR COMMAND. THE SYNTAX IS ; ; MCR>STF TTNN: COMMAND ; ; WHERE TTNN: IS THE DEVICE WHICH IS TO HAVE THE COMMAND ; RUN ON IT AND "COMMAND" IS THE COMMAND. IF THE COMMMAND ; IS TERMINATED WITH RETURN, THE COMMAND STRING IS ECHOED ; ON THE DESTINATION TERMINAL; IF IT IS TERMINATED WITH ; AN ESCAPE IT IS NOT ECHOED. ; ; LIMITATIONS: ; ; THE INVOKING USER MUST BE PRIVILEGED TO RUN THIS ; FUNCTION. ; ; WRITTEN: 14-JAN-78, -0.0.0-, BRUCE C. WRIGHT ; MODIFIED: ; VERIFIED: ;- .SBTTL MACRO CALLS .MCALL GMCR$,DIR$,QIOW$,EXIT$S,RQST$ ; .MACRO ERROR STRING .NCHR N, JSR R0,ERROR .WORD N .ASCII "STRING" .EVEN .ENDM ; .SBTTL MAIN LINE CODE ; STF:: DIR$ #GMCR ;GET MCR COMMAND LINE. BCC 1$ ;SKIP IF OK. ERROR 1$: MOV @#$DSW,R0 ;GET LENGTH OF MCR LINE ADD #GMCR+G.MCRB,R0 ;GET THE TERMINATING CHAR MOVB (R0),TERMCH ;SAVE IT FOR LATER. MOV .CRTSK,R1 ;GET OUR ATL NODE. MOV A.TI(R1),R1 ;GET OUR PUD ADDRESS MOV R1,PUD ;SAVE PUD ADDRESS BITB #UT.PR,U.TF(R1) ;ARE WE PRIVILEGED? BNE 10$ ;YES -- CONTINUE. ERROR 10$: MOV #1,R1 ;SET .TPARS OPTIONS WORD ;THIS MEANS THAT KEYWORDS ;CANNOT BE ABBREVIATED AND ;BLANKS ARE SIGNIFICANT. MOV #KEYTBL,R2 ;GET ADDRESS OF KEYWORD TABLE MOV @#$DSW,R3 ;GET CHARACTER COUNT. MOV #GMCR+G.MCRB,R4 ;GET ADDRESS OF DATA STRING MOV #START,R5 ;GET ADDRESS OF FIRST STATE. CALL .TPARS ;CALL .TPARS TO PARSE STRING. BCC 20$ ;CONTINUE IF NO ERROR ERROR 20$: CMP UNIT,#77 ;UNIT TOO BIG? BLOS 21$ ;NO ERROR 21$: MOV .PUDBA,R1 ;GET PUD BEGINNING ADDRESS 25$: CMP U.DN(R1),DEV ;IS THIS OUR DEVICE TYPE? BNE 26$ ;NO CMPB U.UN(R1),UNIT ;IS THIS OUR UNIT NUMBER? BEQ 27$ ;NO 26$: ADD #U.SZ,R1 ;ADD IN LENGTH OF PUD ENTRY CMP R1,.PUDEA ;IS THIS THE END OF THE PUD? BLO 25$ ;NO -- CONTINUE. ERROR 27$: BIT #UC.TTY,U.C1(R1) ;IS THIS A TTY DEVICE? BNE 28$ ;YES -- OK ERROR 28$: MOV R1,-(SP) ;SAVE PUD ADDRESS MOV R3,R5 ;GET THE REMAINING LEN IN R5 BNE 29$ ;SKIP IF NON-ZERO ERROR 29$: MOV R4,R2 ;ADDR INTO R2 30$: CMPB (R2),#'A+40 ;IS IT ABOVE LOWER CASE A? BLO 31$ ;NO CMPB (R2),#'Z+40 ;IS IT LOWER CASE? BHI 31$ ;NO BICB #40,(R2) ;MAKE IT UPPER CASE FOR $CAT5 31$: INC R2 ;POINT TO NEXT CHAR. SOB R5,30$ ;AND LOOP. MOV R4,R0 ;POINT TO THE START OF THE STRING MOV #^RAT.,R1 ;ASSUME THAT THIS IS ...AT. CMPB (R0),#'@ ;IS THE FIRST CHARACTER AN @? BEQ 32$ ;YES -- NO RAD50. CALL $CAT5 ;CONVERT FIRST CHARS TO RADIX-50. 32$: MOV #MFTFNS,R2 ;GET THE MFT FUNCTIONS MOV #MFTNUM,R0 ;AND THEIR NUMBER 33$: CMP R1,(R2)+ ;IS THIS ONE OF THEM? BEQ 34$ ;YES -- FIX IT. SOB R0,33$ ;LOOP OVER MFT FUNCTIONS. BR 35$ ;SKIP MFT MOVE 34$: MOV #^RMFT,R1 ;GET ....MFT REQUEST. 35$: MOV R1,RQST+R.QSTN+2 ;SAVE TASK IN RQST DPB. MOV (SP)+,R1 ;RECOVER PUD ADDRESS MOV R4,-(SP) ;SAVE CURRENT ADDRESS MOV R3,-(SP) ;SAVE REMAINING LENGTH. MOV R1,-(SP) ;SAVE PUD ADDRESS. MOV #6,R3 ;GET NUMBER OF NODES TO PICK CALL ..PICV ;PICK NODES FOR MCR COMMAND BUFFER BCC 38$ ;SKIP IF OK ERROR 38$: MOV (SP)+,R0 ;RECOVER PUD ADDRESS MOV R0,M.TI(R4) ;SET THE TI ADDRESS IN NODE MOV .CRTSK,R1 ;GET OUR ATL NODE MOV R0,A.TI(R1) ;SET US ONTO THIS TERMINAL. MOV RQST+R.QSTN+2,M.TN(R4) ;SAVE THE TASK NAME. MOV (SP)+,R2 ;RECOVER LENGTH REMAINING MOV R2,QIO+Q.IOPL+2 ;REMEMBER LENGTH FOR ECHO. MOV (SP)+,R1 ;RECOVER ADDRESS MOV U.UI(R0),RQST+R.QSPC ;MOVE IN REQUESTOR. MOV R4,R5 ;MOVE BUFFER ADDRESS INTO R5 ADD #M.BF,R5 ;POINT TO BEGINNING OF BUFFER MOV R5,QIO+Q.IOPL ;REMEMBER ADDRESS. MOV R2,M.BC(R4) ;SAVE BYTE COUNT. 40$: MOVB (R1)+,(R5)+ ;MOVE IN THE CHARACTERS. SOB R2,40$ ;LOOP OVER ENTIRE REMAINING STRING MOVB #ESC,(R5)+ ;TERMINATE THE LINE WITH CMPB TERMCH,#CR ;WAS TERMINATING CHARACTER ? BNE 45$ ;NO -- DON'T ECHO. MOV #QIO,-(SP) ;TRY TO ECHO TO TERMINAL. CALL .DIRDL BCC 44$ ;OK -- PROCEED. 43$: MOV .CRTSK,R0 ;GET OUR ATL NODE. MOV PUD,A.TI(R0) ;PUT US BACK ON ORIGINATOR TERM. MOV #6,R3 ;GET NODE LENGTH. CALL ..NADV ;RETURN THE NODE. ERROR 44$: TSTB @#$DSW ;DID DSW FAIL? BMI 43$ ;YES TSTB IOST ;DID IOST FAIL? BMI 43$ ;YES 45$: MOV R4,R1 ;GET NODE ADDRESS INTO R1 MOV #.MCRLH,R4 ;GET MCR LISTHEAD. MOV @#PS.EXP,-(SP) ;SAVE PSW. BIS #140,@#PS.EXP ;DISABLE CONTEXT SWITCHING. MOV #RQST,-(SP) ;REQUEST TASK. CALL .DIRDL BCS 50$ ;BAD -- SEND MESSAGE. CALL ..NADD ;ADD THIS NODE TO HIS LIST. CALL ..ENB0 ;ENABLE CONTEXT SWITCHING. MOV .CRTSK,R1 ;GET OUR ATL NODE MOV PUD,A.TI(R1) ;RESET IT TO THE ORIGINAL TERMINAL EXIT$S ;AND EXIT. 50$: CALL ..ENB0 ;ENABLE CONTEXT SWITCHING. MOV #6,R3 ;GET THE LENGTH OF THE BUFFER CALL ..NADV ;RETURN THE BUFFER TO THE POOL. MOV .CRTSK,R1 ;GET OUR ATL NODE MOV PUD,A.TI(R1) ;GET BACK TO THE ORIGINAL TERMINAL CMP #-1,@#$DSW ;INSUFFICIENT POOL? BNE 102$ ;NO ERROR 102$: CMP #-2,@#$DSW ;TASK NOT INSTALLED? BNE 103$ ;NO ERROR 103$: CMP #-3,@#$DSW ;PARTITION TOO SMALL? BNE 106$ ;NO ERROR 106$: CMP #-6,@#$DSW ;HANDLER NOT RESIDENT? BNE 107$ ;NO ERROR 107$: CMP #-7,@#$DSW ;TASK ALREADY ACTIVE? BNE 108$ ;NO ERROR 108$: CMP #-8.,@#$DSW ;TASK DISABLED? BNE 180$ ;NO ERROR 180$: CMP #-80.,@#$DSW ;ISSUED BY BACKGROUND TASK? BNE 191$ ;NO ERROR 191$: CMP #-91.,@#$DSW ;INVALID UIC? BNE 194$ ;NO ERROR 194$: CMP #-94.,@#$DSW ;PARTITION NOT IN SYSTEM? BNE 195$ ;NO ERROR 195$: CMP #-95.,@#$DSW ;INVALID PRIORITY? BNE 198$ ;NO ERROR 198$: ERROR .SBTTL COMMAND LINE PARSE TABLES .MCALL ISTAT$,STATE$,TRAN$ ; ; INITIALISE STATE TABLES ; ISTAT$ STATBL,KEYTBL ; ; SKIP OVER COMMAND NAME ; STATE$ START TRAN$ "STF" STATE$ TRAN$ $BLANK ; ; READ DEVICE AND UNIT NUMBER ; STATE$ TRAN$ $ANY,,SETDV1 STATE$ TRAN$ $ANY,,SETDV2 STATE$ TRAN$ $NUMBR,DEV1,SETUNT TRAN$ $LAMDA STATE$ DEV1 TRAN$ ': ; ; SKIP TO NEXT NON-BLANK ; STATE$ TRAN$ $BLANK,$EXIT TRAN$ $LAMDA,$EXIT STATE$ .SBTTL COMMAND LINE PARSE ACTION ROUTINES ; ; ACTION ROUTINES ; ; GET DEVICE NAME CHARACTER 1 ; SETDV1: MOVB .PCHAR,DEV RETURN ; ; GET DEVICE NAME CHARACTER 2 ; SETDV2: MOVB .PCHAR,DEV+1 RETURN ; ; GET UNIT NUMBER ; SETUNT: MOV .PNUMB,UNIT RETURN .SBTTL SUBROUTINE TO PRINT ERROR MESSAGES ; ; THIS SUBROUTINE IS INVOKED BY THE "ERROR" MACRO. IT ; PRINTS THE ARGUMENT GENERATED BY THE "ERROR" MACRO ON ; THE USER'S TERMINAL. ; ; CALLING SEQUENCE: ; ; JSR R0,ERROR ; .WORD STRINGLENGTH ; .ASCII "STRING" ; ; THE SUBROUTINE WILL NEVER RETURN TO THE CALLER. ; ERROR: MOV (R0)+,QIO+Q.IOPL+2 ;MOVE IN QIO LENGTH MOV R0,QIO+Q.IOPL ;GET THE QIO ADDRESS MOV #QIO,-(SP) ;AND PRINT ERROR MESSAGE CALL .DIRDL EXIT$S ;AND EXIT. .SBTTL DATA AREA ; ; RESULTS FROM PARSE OF COMMAND STRING ; DEV: .ASCII / / ;ASCII DEVICE NAME UNIT: .WORD 0 ;UNIT NUMBER ; ; MFT COMMANDS ; MFTFNS: .RAD50 /ABOALTCANDISENAFIXLOARESUNF/ MFTNUM = <.-MFTFNS>/2 ; ; MISCELLANEOUS DATA AREAS ; PUD: .WORD 0 ;PUD ADDRESS OF INVOKING TERMINAL TERMCH: .WORD 0 ;TERMINATING CHARACTER CR = 15 ;CARRIAGE RETURN FOR TERMCH ESC = 33 ;ESCAPE FOR TERMCH IOST: .WORD 0,0 ;I/O STATUS BLOCK ; ; DIRECTIVE PARAMETER BLOCKS ; QIO: QIOW$ IO.WVB,1,1,,IOST,,<,,40> RQST: RQST$ ...MCR GMCR: GMCR$ .END STF