.TITLE GETPRM - GET PARAMETERS FOR F11ACT .IDENT "0001" ; ; MODULE: FILES-11 ACTIVITY REPORTING TASK -- GET PARAMETER LIST ; ; VERSION: 0001 ; ; AUTHOR: ANDY PUTNINS ; ; DATE: 9-APR-79 ; ; PURPOSE: ; THIS ROUTINE READS AND PARSES A COMMAND LINE, AND SETS UP A LIST OF VALID ; DEVICES FOR WHICH THE USER WANTS FILE ACTIVITY STATISTICS. FINALLY, WE ; SET UP THE OUTPUT FDB WHICH EVENTUALLY WILL BE OPENED BY OUR CALLER. ; ; COMMAND LINE SYNTAX: ; ; [OUTFILE][/-APPEND][/SPOOL][/FILES][/PRIORITY:N] ; = [/ACP:XXXXXX] ; OR ; = [DEVICE[/FILES]],... ; ; /APPEND OPEN OUTFILE FOR APPEND (DEFAULT), ELSE CREATE OUTFILE ; /SPOOL SPOOL OUTFILE (DEFAULT IS /-SP) ; /FILES LIST ATTRIBUTES OF ALL FILES OPEN ON ALL DEVICES IF ; THIS SWITCH APPEARS ON OUTPUT SIDE OF COMMAND LINE; ; LIST ATTRIBUTES OF ALL FILES OPEN ON SPECIFIED DEVICE ; IF THIS SWITCH APPEARS ON INPUT SIDE ; (DEFAULT IS /-FI IN BOTH CASES). ; /PRIORITY:N ACP RUN PRIORITY IS N (DECIMAL) (DEFAULT IS 220.) ; /ACP:XXXXXX GATHER STATISTICS FOR ALL DEVICES SERVICED BY THE NAMED ; ACP. IF THIS SWITCH IS SPECIFIED ON THE INPUT SIDE, ; A DEVICE LIST MAY NOT BE SPECIFIED. ; ; AN EMPTY COMMAND LINE IS EQUIVALENT TO THE FOLLOWING DEFAULTS: ; ; F11ACT> TI:F11STATS.LST/APPEND/-SPOOL/-FILES/PRIORITY:220. ; ; INPUTS: ; DYNAMIC MEMORY INITIALIZED ; ; OUTPUTS: ; 'LH.SB' IS LISTHEAD OF EMPTY STATISTICS BLOCKS FOR DESIRED DEVICES ; 'SWMASK' INITIALIZED WITH COMMAND SWITCH MASK BITS FROM PARSE ; 'ACPPRI' CONTAINS (BINARY) ACP RUN PRIORITY ; 'OUTFDB' INITIALIZED ; CARRY SET IF NO MORE COMMANDS, OR IF I/O ERROR READING A COMMAND ; .PAGE .SBTTL GCL AND CSI CONTROL BLOCKS .MCALL GCMLB$,CSI$,CSI$SW,CSI$ND,CSI$SV ; ; GET COMMAND LINE AND COMMAND STRING INTERPRETER CONTROL BLOCKS ; .PSECT IMPURE,RW,D GCLBLK: GCMLB$ 3,F11,,CMDLUN ;ALLOW 3 LEVELS OF INDIRECTION CSI$ ;DEFINE OFFSETS CSIBLK: .BLKB C.SIZE ;ALLOCATE SPACE .PSECT PURE,RO,D PROMPT: .ASCII <15><12>'F11ACT> ' ;ALTERNATE PROMPT STRING FOR GCML$ PRMPTL=.-PROMPT ; ; COMMAND SWITCH MASK WORD AND BIT DEFINITIONS ; SW.NAP == 1 ;/-AP - DO NOT APPEND TO EXISTING FILE SW.SP == 2 ;/SP - SPOOL OUTPUT FILE SW.FI == 4 ;/FI - GATHER STATS ON OPEN FILES SW.PR == 10 ;/PR:N - ACP RUN PRIORITY SW.ACP == 20 ;/AC:X - GIVE STATS FOR ACP X .PSECT IMPURE,RW,D SWMASK:: .WORD 0 ; ; SWITCH VALUE WORDS FOR ACP NAME AND ACP RUN PRIORITY ; ACPNAM: .BLKB 3 .EVEN ACPPRI:: .BLKW ; ; SWITCH DESCRIPTOR TABLES FOR INPUT AND OUTPUT SIDES OF COMMAND LINE ; .PSECT PURE,RO,D INSW1: CSI$SW AC,SW.ACP,SWMASK,,,ACPSW CSI$SW FI,SW.FI,SWMASK CSI$ND ACPSW: CSI$SV ASCII,ACPNAM,3 CSI$ND INSW2: CSI$SW FI,SW.FI,SWMASK CSI$ND OUTSW: CSI$SW AP,SW.NAP,SWMASK,CLEAR,NEG CSI$SW SP,SW.SP,SWMASK,,NEG CSI$SW FI,SW.FI,SWMASK,,NEG CSI$SW PR,SW.PR,SWMASK,,,PRSW CSI$ND PRSW: CSI$SV DECIMAL,ACPPRI,1 CSI$ND .PAGE .SBTTL MESSAGE STRINGS .PSECT PURE,RO,D .NLIST BEX GCLMG1: .ASCIZ '%NF11ACT -- **** COMMAND INPUT ERROR CODE=%D,%D ****' GCLMG2: .ASCII 'F11ACT -- **** INDIRECT COMMAND FILENAME SYNTAX ERROR ****' GCLM2L=.-GCLMG2 GCLMG3: .ASCII 'F11ACT -- **** COMMAND LINE TOO LONG ****' GCLM3L=.-GCLMG3 GCLMG4: .ASCII 'F11ACT -- **** INDIRECT COMMAND FILES NESTED TOO DEEPLY ****' GCLM4L=.-GCLMG4 SYNMSG: .ASCIZ '%NF11ACT -- **** COMMAND SYNTAX ERROR: ****%N%VA' MEMMSG: .ASCII 'F11ACT -- **** INSUFFICIENT DYNAMIC MEMORY - ' .ASCII 'RERUN WITH A LARGER INCREMENT ****' MEMMGL=.-MEMMSG .LIST BEX .PAGE .SBTTL GET A COMMAND .MCALL GCML$,CSI$1,CSI$2,FDOP$R .PSECT GETPRM,RO,I GETPRM:: ; ; RELEASE ANY ALLOCATED STATISTICS BLOCK ENTRIES ; MOV #L.SB,R3 ;LENGTH OF STAT BLOCK MOV #LH.SB,R4 ;ADDR OF LISTHEAD CALL DELQ ;REMOVE AN ENTRY BCC GETPRM ;DO IT AGAIN IF SUCCESSFUL CLR NSFMEM ;RESET 'INSUFFICIENT DYNAMIC MEMORY' FLAG CLR SWMASK ;CLEAR SWITCH MASK ; ; GET A COMMAND LINE ; GCML$ #GCLBLK,#PROMPT,#PRMPTL ;GET A COMMAND LINE BCC 10$ JMP GCLERR ;ERROR - WRITE MESSAGE ; ; CHECK COMMAND SYNTAX ; 10$: MOV #CSIBLK,R0 ;CSI CONTROL BLOCK ADDR MOV GCLBLK+G.CMLD+2,C.CMLD+2(R0) ;COMMAND ADDRESS... MOV GCLBLK+G.CMLD,C.CMLD(R0) ;... AND LENGTH CSI$1 R0 ;CHECK COMMAND SYNTAX BCS 100$ ;ERROR - WRITE MESSAGE ; ; SEE IF USER WANTS STATISTICS FOR ALL DEVICES (NO DEVICE LIST OR ACP NAME) ; BITB #CS.EQU,C.STAT(R0) ;ANY INPUT SPECS IN COMMAND LINE? BNE 20$ ;YES - CONTINUE CLR R1 ;NO - INDICATE NO SPECIFIC ACP NAME JMP FINDEV ;FIND ALL DEVICES IN PUD ; ; SEE IF USER WANTS STATISTICS FOR ALL DEVICES SERVICED BY A GIVEN ACP ; 20$: CLR SWMASK ;RESET ALL SWITCH FLAGS CSI$2 R0,INPUT,#INSW1 ;PARSE FIRST INPUT SPEC BCS 100$ BIT #SW.ACP,SWMASK ;ACP SWITCH SPECIFIED? BEQ INPUT1 ;NO - CONTINUE MOV #ACPNAM,R0 ;ADDR OF ACP NAME STRING CLR R1 ;INDICATE STOP ON PERIOD CALL $CAT5 ;CONVERT NAME TO RAD50 (RESULT IN R1) JMP FINDEV ;GO SEARCH THE PUD 100$: JMP SYNERR ;BRANCH AID .PAGE .SBTTL INPUT - PARSE DEVICE LIST .ENABL LSB ; ; GET LIST OF DEVICES FROM INPUT SIDE OF COMMAND LINE ; INPUT: CLR SWMASK ;RESET ALL SWITCH FLAGS CSI$2 #CSIBLK,INPUT,#INSW2 ;GET NEXT DEVICE SPEC BCS 100$ INPUT1: BITB #CS.NMF!CS.DIF!CS.WLD,C.STAT(R0) ;ONLY DEVICE NAMES ALLOWED BNE 100$ ; ; CREATE STAT BLOCK, AND INSERT DEVICE NAME AND REDIRECTED PUD POINTER ; MOV #L.SB,R3 MOV #LH.SB,R4 CALL ADDQ BCC 5$ TIQIO #MEMMSG,#MEMMGL ;NO MORE DYNAMIC MEMORY - WRITE MESSAGE INC NSFMEM ;SET FLAG JMP GETPRM ;AND TRY ANOTHER COMMAND 5$: MOV CSIBLK+C.DEVD+2,R0 ;GET POINTER TO DEVICE NAME... MOV CSIBLK+C.DEVD,R1 ;... AND LENGTH MOV R5,R2 ;SET UP DEVICE NAME PTR IN STAT BLOCK ADD #.DNAM,R2 ;... MOV R2,P.DNAM(R5) ;... MOVB (R0)+,(R2)+ ;COPY 2 CHAR DEVICE NAME TO STAT BLOCK MOVB (R0)+,(R2)+ ;... CLR .DUNIT(R5) ;ASSUME UNIT #0 SUB #2,R1 ;ADJUST BYTE COUNT BEQ 10$ ;SKIP IF NO UNIT SPECIFIED BLT 100$ ;ERROR IF ONLY 1 CHAR STRING CALL $COTB ;CONVERT UNIT # TO BINARY CMPB #':,R2 ;TERMINATED BY COLON? BNE 100$ ;ERROR IF NOT MOV R1,.DUNIT(R5) ;SAVE UNIT # IN STAT BLOCK ; ; FIND GENUINE PUD ADDR FOR THIS DEVICE ; 10$: MOV .PUDBA,R0 ;START OF PUD BR 30$ 20$: ADD #U.SZ,R0 ;ADVANCE TO NEXT PUD ENTRY CMP R0,.PUDEA ;END OF LIST? BLOS 30$ ;NO - CONTINUE BIS #F.NSDV,.SBFLG(R5) ;YES - SET 'NO SUCH DEVICE' FLAG BR 60$ ;CONTINUE WITH NEXT DEVICE SPEC 30$: CMP .DNAM(R5),U.DN(R0) ;IS THIS THE RIGHT DEVICE NAME? BNE 20$ ;NO - KEEP LOOKING CMPB .DUNIT(R5),U.UN(R0) ;UNIT # MATCH? BNE 20$ ;NO 40$: CMP R0,U.RP(R0) ;IS THIS DEVICE REDIRECTED ELSEWHERE? BEQ 50$ ;NO - CONTINUE MOV U.RP(R0),R0 ;YES - FOLLOW POINTER... BR 40$ ;...AND LOOK AGAIN 50$: MOV R0,P.PUD(R5) ;SAVE PUD ADDRESS IN STAT BLOCK BIT #UC.DIR!UC.F11!UC.MNT,U.C1(R0) ;IS THIS A FILES-11 DEVICE? BNE 60$ ;YES - CONTINUE BIS #F.NF11,.SBFLG(R5) ;NO - SET FLAG IN STAT BLOCK 60$: BIT #SW.FI,SWMASK ;DOES USER WANT LIST OF OPEN FILES? BEQ 70$ ;NO - CONTINUE BIS #F.FI,.SBFLG(R5) ;YES - SET FLAG IN STAT BLOCK BIC #SW.FI,SWMASK ;RESET SWITCH MASK ; ; INITIALIZE ATTRIBUTE BLOCK LISTHEAD ; 70$: MOV R5,R2 ;POINT TO FILE ATTRIBUTE LISTHEAD ADD #LH.AB,R2 ;... MOV R2,(R2) ;INITIALIZE LISTHEAD MOV R2,2(R2) ;... ; ; ALL DONE WITH THIS DEVICE SPEC - SEE IF THERE IS ANOTHER ; BITB #CS.MOR,CSIBLK+C.STAT ;IS THERE MORE? BNE INPUT ;YES - PARSE IT JMP OUTPUT ;NO - DO OUTPUT SIDE OF COMMAND 100$: JMP SYNERR ;BRANCH AID .DSABL LSB .PAGE .SBTTL FINDEV - FIND ALL FILES-11 DEVICES IN SYSTEM ; ; COME HERE IF THE USER DID NOT SPECIFY AN EXPLICIT DEVICE LIST. ON ENTRY, ; R1 INDICATES WHETHER TO SEARCH THE PUD FOR ALL FILES-11 DEVICES (R1 CLEAR), ; OR ALL DEVICES SERVICED BY SOME ACP (R1 CONTAINS RAD50 NAME). AS WE SEARCH ; THE PUD, WE SET UP A STAT BLOCK ENTRY FOR EACH DEVICE WE FIND. ; FINDEV: MOV #L.SB,R3 ;LENGTH OF STAT BLOCK FOR ADDQ MOV #LH.SB,R4 ;LISTHEAD ADDR FOR ADDQ MOV .PUDBA,R0 ;START OF PUD BR 20$ 10$: ADD #U.SZ,R0 ;ADVANCE TO NEXT PUD ENTRY CMP R0,.PUDEA ;END OF LIST? BHI 50$ ;YES - ALL DONE 20$: BIT #UC.DIR!UC.F11!UC.MNT,U.C1(R0) ;IS THIS A FILES-11 DEVICE? BEQ 10$ ;NO - IGNORE IT CMP R0,U.RP(R0) ;IS THIS DEVICE REDIRECTED ELSEWHERE? BNE 10$ ;YES - IGNORE IT TST R1 ;ARE WE LOOKING FOR AN ACP MATCH? BEQ 30$ ;NO - GOOD ENOUGH CMP R1,@U.ACP(R0) ;YES - DOES OUR ACP SERVICE THIS GUY? BNE 10$ ;NO - KEEP LOOKING 30$: CALL ADDQ ;ALLOCATE & INITIALIZE STAT BLOCK BCC 40$ TIQIO #MEMMSG,#MEMMGL ;NO MORE SPACE - WRITE ERROR MESSAGE INC NSFMEM ;SET FLAG JMP GETPRM ;AND TRY ANOTHER COMMAND 40$: MOV R0,P.PUD(R5) ;SAVE PUD ADDRESS IN STAT BLOCK MOV R5,R2 ;POINT TO DEVICE NAME BUFFER ADD #.DNAM,R2 ;... MOV R2,P.DNAM(R5) ;SET UP DEVICE NAME PTR IN STAT BLOCK MOV U.DN(R0),(R2) ;DEVICE NAME TO STAT BLOCK MOVB U.UN(R0),.DUNIT(R5) ;AND UNIT # MOV R5,R2 ;POINT TO ATTRIBUTE LISTHEAD ADD #LH.AB,R2 ;... MOV R2,(R2) ;INITIALIZE LISTHEAD MOV R2,2(R2) ;... BR 10$ ;LOOP FOR NEXT DEVICE IN PUD 50$: JMP OUTPUT ;GO PARSE OUTPUT SIDE OF COMMAND .PAGE .SBTTL OUTPUT - PARSE OUTPUT FILESPEC ; ; COME HERE TO PARSE THE OUTPUT FILESPEC AND OPTION SWITCHES WHEN FINISHED ; SETTING UP THE STATISTICS BLOCK LIST. ; OUTPUT: CLR SWMASK ;RESET ALL SWITCH FLAGS MOV #ACPRIO,ACPPRI ;SET DEFAULT VALUE FOR /PRIORITY SWITCH CSI$2 #CSIBLK,OUTPUT,#OUTSW ;PARSE OUTPUT FILESPEC BCS 10$ BITB #CS.WLD!CS.MOR,C.STAT(R0) ;ONLY ONE OUTSPEC & NO WILDCARDS BEQ 20$ 10$: JMP SYNERR ;BRANCH AID 20$: FDOP$R #OUTFDB,,#CSIBLK+C.DSDS,,#FO.APD ;DEFAULT IS OPEN FOR APPEND BIT #SW.NAP,SWMASK ;IS THAT WHAT THE USER WANTS? BEQ NRET ;YES IF SWITCH FLAG CLEAR FDOP$R R0,,#CSIBLK+C.DSDS,,#FO.WRT ;NO - SET UP TO OPEN FOR WRITE ; ; NORMAL RETURN ; NRET: CLC RETURN ; ; ERROR RETURN ; ERRET: SEC RETURN .PAGE .SBTTL GCLERR - GET COMMAND LINE ERROR ROUTINE ; ; COME HERE IF AN ERROR IS DETECTED WHILE ATTEMPTING TO GET A COMMAND LINE. ; END OF FILE OR I/O ERROR WHILE READING FROM THE COMMAND INPUT LUN CAUSES ; A RETURN WITH CARRY SET. FOR ALL OTHER ERRORS, WE WRITE AN ERROR MESSAGE ; TO THE TERMINAL, AND LOOP FOR ANOTHER COMMAND. ; GCLERR: MOVB G.ERR(R0),R3 ;PICK UP ERROR CODE BIT #GE.EOF,R3 ;END OF FILE? BNE 5$ ;YES - RETURN TO MAINLINE ; ; I/O ERROR TRYING TO READ COMMAND LINE ; BIT #GE.IOR!GE.OPR,R3 ;I/O ERROR? BEQ 10$ ;NO - CHECK NEXT CASE MOVB F.ERR(R0),R3 ;EXPAND FCS ERROR CODES TO 1 WORD EACH MOV R3,TEMP MOVB F.ERR+1(R0),R3 MOV R3,TEMP+2 MOV #OUTBUF,R0 ;ADDR OF OUTPUT BUFFER MOV #GCLMG1,R1 ;ADDR OF MESSAGE STRING MOV #TEMP,R2 ;ADDR OF ARGUMENT BLOCK CALL $EDMSG ;FORMAT MESSAGE TIQIO #OUTBUF,R1 ;WRITE IT TO TERMINAL 5$: JMP ERRET ;GET OUT ; ; BAD INDIRECT FILE NAME ; 10$: BIT #GE.BIF,R3 BEQ 20$ TIQIO #GCLMG2,#GCLM2L JMP GETPRM ; ; COMMAND LINE TOO LONG ; 20$: BIT #GE.RBG,R3 BEQ 30$ TIQIO #GCLMG3,#GCLM3L JMP GETPRM ; ; INDIRECT COMMAND FILES NESTED TOO DEEPLY ; 30$: TIQIO #GCLMG4,#GCLM4L JMP GETPRM .PAGE .SBTTL SYNERR - SYNTAX ERROR ROUTINE ; ; COME HERE IF A SYNTAX ERROR IS DETECTED DURING COMMAND LINE PARSING. ; THE COMMAND STRING INTERPRETER LEAVES A SEGMENT DESCRIPTOR IN THE CSI ; CONTROL BLOCK WHICH DEFINES THE ADDRESS AND LENGTH OF THE BAD COMMAND ; LINE SEGMENT. WE WRITE AN ERROR MESSAGE AND THE BAD COMMAND LINE ; SEGMENT, AND LOOP FOR ANOTHER COMMAND. ; SYNERR: MOV #OUTBUF,R0 ;ADDR OF OUTPUT BUFFER MOV #SYNMSG,R1 ;ADDR OF MESSAGE STRING MOV #CSIBLK+C.FILD,R2 ;ADDR OF ARGUMENT BLOCK CALL $EDMSG ;FORMAT THE MESSAGE TIQIO #OUTBUF,R1 ;WRITE IT TO THE TERMINAL JMP GETPRM ;START ALL OVER WITH A NEW COMMAND .END