.MCALL SUPER,UCBDF$,TCBDF$,LCBDF$,DIR$,GMCR$,QIOW$,EXIT$S .MCALL DCBDF$,GTSK$C SUPER DCBDF$ UCBDF$ TCBDF$ LCBDF$ .MACRO PRNT ADDR,LEN MOV #PRTLOG,R0 MOV #'ADDR',Q.IOPL(R0) MOV #'LEN',Q.IOPL+2(R0) DIR$ R0 .ENDM ;THIS PROGRAM ALLOWS ANY USER TO CHANGE THEIR SY ASSIGNMENT ;AND/OR THEIR UIC ASSIGNMENT WITHOUT THE COMPLICATED SYNTAX ;OF THE SET AND ASN COMMANDS. ;ANY DEVICE NAME, WITH OR WITHOUT A COLON, ON THE MCR LINE ;WILL BE USED TO CHANGE THE SY LOGICAL ASSIGNMENT. THE ;POSITION ON THE LINE IS NOT IMPORTANT. ;ANY TWO OCTAL NUMBERS, NOT COUNTING A DEVICE UNIT NUMBER, ;ANYWHERE ON THE MCR LINE WILL BE USED AS THE GROUP AND ;USER NUMBER FOR CHANGING THE UIC. IF THERE IS ONLY ONE ;NUMBER, IT IS USED TO CHANGE THE USER NUMBER, AND THE ;GROUP NUMBER STAYS THE SAME. TO CHANGE THE GROUP NUMBER ;WITHOUT CHANGES YOU USE AN ASTERISK IN PLACE OF THE ;USER NUMBER. EXAMPLE: LOG 50,* LOG:: LET R0 := #MCRLIN DIR$ R0 ;GET LINE FROM MCR ON.NOERROR LET R0 := R0 + #G.MCRB ;FIND THE BEGENING OF THE LINE LET R1 := R0 + $DSW ;CALCULATE ADDRESS OF END LET (R1)+ :B= #0 ;MAKE SURE IT ENDS IN A NUL LET (R1)+ :B= #0 ;TERMINATE IT TWICE FOR LUCK SCALL PARSE ;PARSE THE DEV AND UIC OUT OF THE LINE SCALL FNDEV ;FIND THE UCB OF THE DEVICE MENTIONED SCALL FNDTI ;FIND THE TI UCB FOR THIS TERMINAL SCALL FNDASN ;FIND THE SY LOGICAL ASSIGNMENT FOR THIS TERMINAL ;DEPENDING ON WHAT THE PARSE ROUTINE FOUND, ;EITHER THE CURRENT ASSIGNMENT IS PRINTED, ;OR THE DEV OR UIC ARE CHANGED IF FLAG EQ #0 ;FLAG=0 MEANS PRINT CURRENT ASSNMENT LET R2 := #ARGBLK ;ARGUMENT BLOCK FOR EDMSG ROUTINE LET R0 := LCBADR ;LOOK UP THE ASSIGNED UCB ADDRESS IN LET R0 := L.ASG(R0) ;THE LCB. LET (R2) :B= U.UNIT(R0) ;GET THE UNIT NUMBER. LET R0 := U.DCB(R0) ;FIND THE DCB ADDRESS. LET ASNDEV := D.NAM(R0) ;PUT THE GENERIC NAME IN THE OUTPUT. LET R3 :B= D.UNIT(R0) ;CORRECT UNIT NUMBER FOR MULTIPLE LET (R2) := (R2) + R3 ;CONTROLERS BY ADDING LOWEST UNIT NUMBER. LET R0 := TIUCB ;GET TI UCB. LET 2(R2) :B= U.UIC+1(R0) ;CONVERT THE UIC TO TWO WORDS TO MAKE LET 4(R2) :B= U.UIC(R0) ;IT EASYER TO CONVERT TO ASCII OCTAL. LET R0 := #OUTPUT ;SET UP ALL THE REST OF THE REGESTERS LET R1 := #FORMAT ;FOR THE EDMSG ROUTINE. CALL $EDMSG ;CONVERT NUMBERS TO OCTAL. LET R1 := R1 + #WHOL ;CALCULATE THE LENGTH OF THE OUTPUT STRING. LET R0 := #PRTLOG ;PRINT THE STRING ON THE LET Q.IOPL(R0) := #WHOAMI ;TERMINAL. LET Q.IOPL+2(R0) := R1 DIR$ R0 ELSE ;FLAG <> 0 MEANS CHANGE DEV AND/OR UIC IF DEV NE #0 ;IF DEV=0, DON'T CHANGE SY ASSIGNMENT LET R0 := LCBADR ;GET LCB ENTRY ADDRESS LET L.ASG(R0) := DEVUCB ;CHANGE UIC IN LCB. END LET R0 := TIUCB ;GET TI UCB IFB UIC NE #0 ;A ZERO USER NUMBER MEANS DON'T CHANGE USER LET U.UIC(R0) :B= UIC ;CHANGE USER. END IFB UIC+1 NE #0 ;A ZERO GROUP CODE MEANNS DON'T CHANGE IT. LET U.UIC+1(R0) :B= UIC+1 ;CHANGE GOUP CODE END END END EXIT$S .PAGE ; ; ; SUBROUTINES ; ; ;PARSE THE INPUT LINE FOR DEVICE AND UIC ; PARSE:: REPEAT LET R1 :B= (R0)+ ;SKIP CHARACTERS UNTILB RESULT IS EQ ORB R1 EQ #40 ;UNTIL A NUL OR A SPACE IFB R1 NE #0 ;EXIT IF THAT'S ALL THERE IS REPEAT ;LOOP FOR ALL CHARS LET R1 :B= (R0)+ IF RESULT IS EQ THEN RETURN ;QUIT ON THE FIRST NUL IFB R1 GE #'A ANDB R1 LE #'Z ;IF IT STARTS WITH AN ALPHA, LET DEV :B= R1 ;THEN IT MUST BE A DEVICE. LET DEV+1 :B= (R0)+ ;TRUST THE 2ND CHAR TO BE ALPHA IF RESULT IS EQ THEN RETURN ;UNLESS ITS A NUL LET FLAG := . +1 ;SET FLAG FOR FOUND SOMETHING LET R1 :B= (R0)+ ;GET NEXT CHAR, AND CHECK TO IF RESULT IS EQ THEN RETURN ;SEE IF IT IS A NUMERIC CHARACTER IFB R1 GE #'0 ANDB R1 LE #'9 ;IF IT IS, THEN IT IS A LET R1 := . - #'0 ;UNIT NUMBER. CONVERT TO BINARY. LET UNIT := R1 ;NOTE THAT UNIT NUMBERS CAN GO UP TO 9 DECIMAL END ELSE IF R1 GE #'0 ANDB R1 LT #'8 ;ANYTHING STARTING WITH A NUMERIC LET R3 := #0 ;MUST BE A GROUP OR USER NUMBER REPEAT ;SO CONVERT IT TO BINARY LET R3 := R3 L.SHIFT 3 LET R3 := R3 + R1 - #'0 LET R1 :B= (R0)+ ;GET NEXT INPUT CHARACTER ;KEEP GOING UNTIL THE STRING ;RUNS OUT, OR YOU FIND A NON- ;OCTAL CHARACTER. UNTIL RESULT IS EQ ORB R1 LT #'0 ORB R1 GT #'7 IF R3 GT #377 OR R3 LE #0 ;CHECK FOR BAD NUMBERS PUSH R0 ;PRINT A MESSAGE IF SOMEONE PRNT ILGUIC,ILGL ;ENTERS AN ILLEGAL GROUP OR POP R0 ;USER NUMBER. LET R3 := #0 ;ZERO THE NUMBER TO SIGNIFY "NO CHANGE" END LET UIC+1 :B= UIC ;CYCLE THROUGH THE USER NUMBER LET UIC :B= R3 ;SO THAT SINGLE NUMBERS CHANGE LET FLAG := . +1 ;IT ONLY. SET FLAG TO INDICATE YOU FOUND SOMETHING ELSE IFB R1 EQ #'* ;THE STAR MEANS LEAVE THE LET UIC+1 :B= UIC ;CORRESPONDING NUMBER EXACTLY LET UIC :B= #0 ;AS IT IS. LET FLAG := . +1 ;SET FLAG TO SIGNAL YOU FOUND SOMETHING END END END END END RETURN .PAGE ; ;IF THERE IS A DEVICE IN THE COMMAND LINE, HUNT ;THROUGH THE DCB AND UCB LISTS AND LOOK UP THE ;UCB ADDRESS OF THE DEVICE ;PROCEDURE FNDEV FNDEV:: IF DEV NE #0 LET R0 := $DEVHD ;GET POINTER TO FIRST DEVICE REPEAT IF D.NAM(R0) EQ DEV ;IS THIS THE RIGHT DEVICE? LET R1 :B= D.UNIT(R0) ;CHECK TO SEE IF THIS DCB LET R2 :B= D.UNIT+1(R0) ;COVERS THE UNIT NUMBER I AM IF R1 LE UNIT AND R2 GE UNIT ;LOOKING FOR. LET R2 := D.UCB(R0) ;GET POINTER TO FIRST UCB COVERED LET R3 := UNIT - R1 ;CALCULATE NUMBER OF UCBS TO SKIP IF RESULT IS GT ;DONT SKIP ANY IF YOU DONT HAVE TO THRU R3 LET R2 := R2 + D.UCBL(R0) ;SKIP TO NEXT UCB END END LET DEVUCB := R2 ;R2 NOW POINTS TO CORRECT UCB RETURN END END LET R0 := @R0 ;LINK TO NEXT DCB UNTIL YOU FIND UNTIL RESULT IS EQ ;IT, OR YOU RUN OUT OF DCB'S PRNT NODEV,DEVL ;IF YOU RUN OUT, PRINT AN ERROR LET DEV := #0 ;AND SET DEV SO NO DEVICE CHANGES WILL END ;BE MADE. RETURN ;ENDPROCEDURE FNDEV .PAGE ; ;FIND THE UCB FOR THE CURRENT TI BY HUNTING FOR ;YOURSELF IN THE TASK LIST. ;PROCEDURE FNDTI FNDTI:: GTSK$C TSKNAM ;WHAT IS MY NAME? LET R0 := $TSKHD ;GET POINTER TO FIRST TASK REPEAT ;REPEAT FOR ALL TASKS ;IS THIS ME? IF TSKNAM EQ T.NAM(R0) AND TSKNAM+2 EQ T.NAM+2(R0) LET TIUCB := T.UCB(R0) ;YES, THEN HERE'S MY TI UCB RETURN END LET R0 := T.TCBL(R0) ;LINK TO NEXT TCB UNTIL RESULT IS EQ ;IF I DONT FIND ME, THEN SOMETHING PRNT BADTSK,BADL ;IS REALLY ROTTEN IN THE STATE OF RSX! EXIT$S ;PRINT AN ERROR AND EXIT. ;ENDPROCEDURE FNDTI .PAGE ; ;HUNT THROUGH THE LOGICAL ASSIGNMENT LIST AND ;FIND THIS TERMINALS CURRENT SY ASSIGNMENT ;PROCEDURE FNDASN FNDASN:: LET R0 := $LOGHD ;GET POINTER TO FIRST ASSIGNMENT REPEAT ;LOOP FOR ALL ASSIGNMENTS IFB L.TYPE(R0) NE #0 ;IGNORE GLOBAL ASSIGNMENTS IF L.UCB(R0) EQ TIUCB ;IS IT MY ASSIGNMENT? ;IS IT AN SY0 ASSIGNMENT? IF L.NAM(R0) EQ #"SY ANDB L.UNIT(R0) EQ #0 IFB L.TYPE(R0) GT #0 ;CHECK FOR LOCAL ASN LET LCBADR := R0 ;GET THE ASSIGNED UCB ELSE LET LOGUCB := R0 ;GET THE LOGIN ONE IN CASE YOU NEED IT END END END END LET R0 := @R0 ;LINK TO NEXT LCB UNTIL RESULT IS EQ ;UNTIL YOUVE SEEN THEM ALL IF LCBADR EQ #0 ;DO I HAVE ANY LOCAL ASNMENTS? LET LCBADR := LOGUCB ;NO, SO USE THE LOGIN ONE IF RESULT IS EQ ;BY THE WAY, DID I HAVE A LOCAL ONE? PRNT NOASN,ASNL ;IF NO, THIS PROGRAM IS TOO DUMB TO ALLOCATE A NEW EXIT$S ;ASSIGNMENT IF YOU DONT HAVE ONE, SO IT JUST END END ;PRINTS A NASTY MESSAGE AND EXITS. RETURN ;ENDPROCEDURE FNDASN .PAGE ; ; DATA AREA ; MCRLIN:: GMCR$ PRTLOG:: QIOW$ IO.WVB,1,1,,,, DEV:: .WORD 0 ;DEVICE PARSED FROM MCR LINE UNIT:: .WORD 0 ;UNIT NUMBER FROM SAME UIC:: .WORD 0 ;UIC PARSED FROM MCR LINE FLAG:: .WORD 0 ;FLAG INDICATING IF ANY OF THE ABOVE ARE PRESENT DEVUCB:: .WORD 0 ;UCB OF THE ABOVE DEVICE TIUCB:: .WORD 0 ;UIC OF THE ISSUING TI LCBADR:: .WORD 0 ;ADDRESS OF THE SY LOCAL ASSIGNMENT LCB LOGUCB:: .WORD 0 ;ADDRESS OF THE SY LOGIN ASSIGNMENT LCB TSKNAM:: .BLKW 16. ;BUFFER FOR GTSK$C ARGBLK:: .BLKW 3 ;ARGUMENT LIST FOR EDMSG ROUTINE .NLIST BEX FORMAT:: .ASCIZ /%O:[%O,%O]/ ;FORMAT STRING FOR EDMSG WHOAMI:: .ASCII /CURRENT ASSIGNMENT IS: / ASNDEV:: .WORD 0 ;2 BYTES FOR GENERIC DEVIDE NAME WHOL=.-WHOAMI OUTPUT:: .BLKB 14 ;OUTPUT FOR EDMSG ILGUIC: .ASCII /ILLEGAL GROUP OR USER NUMBER IN UIC!/ ILGL=.-ILGUIC NODEV:: .ASCII /THERE IS NO SUCH DEVICE ON THE SYSTEM!/ DEVL=.-NODEV BADTSK:: .ASCII /BAD TASK LIST! CALL SYSTEM PROGRAMMER./ BADL=.-BADTSK NOASN:: .ASCII /YOU DO NOT HAVE ANY LOCAL ASIGNMENTS!?/ ASNL=.-NOASN .END LOG