.TITLE RESET .IDENT /2.4/ ; ; WRITTEN BY: ; JAMES G. DOWNWARD ; KMS FUSION, INC ; 3941 RESEARCH PARK DR ; ANN ARBOR, MICH. 48104 ; (313)769-8500 ; ; THIS PROGRAM IS TO MODIFY VALUES IN THE KMS FUSION ; MODIFIED ACCOUNT FILE. ; ; IF THE TASK IS INSTALLED AS ...RSE (FOR RESET ACCOUNT FILE) ; IT SUPPORTS THE FOLLOWING SYNTAX ; ; RSET "COMMAND NAME" ; ; WHERE "COMMAND NAME" IS ONE OF ; ; FLAGS - RESET ALL ACCOUNT BUSY FLAGS(TTN) ; LOGINS - RESET ALL # OF LOGINS ENTRIES ; TIME - RESET ALL ACCUMULATED LOGON TIME ENTRIES ; ALL - RESET BUSY FLAG, # OF LOGINS, AND LOGON TIME ; ENTRIES FOR ALL ACCOUNTS. ; USER - RESET INDIVIDUAL ACCOUNT ENTRIES ; ; ONE SPACE MUST BE LEFT BETWEEN RSET AND THE START OF THE ; COMMAND NAME. ONLY THE FIRST TWO LETTERS OF THE COMMAND NAME ARE ; CHECKED FOR SYNTAX. ; ; ; TO USE THE PROGRAM INSTALL IT AS ...RSE. ALSO ALL LOGINS ; SHOULD BE DISABLED AND EVERYONE EXCEPT THE SYSTEM OPERATOR ; MUST BE LOGGED OFF. ONCE , A COMMAND OF RSET TIME, OR RSET LOGINS ; OR RSET ALL IS GIVEN ALL PAST RECORD OF THE ACCOUNT FILE IS LOST ; SO IT IS A GOOD IDEA TO GET AN UPTODATE COPY OF THE ACCOUNT FILE ; BY RUNNING ACCLOG FIRST. ; ; ; AN ALTERNATE COMMAND FORM IS USED TO SET/CLEAR THE PRIVILEGE MASK, ; THE OPTIONAL RUNNABLE TASK, THE TERMINAL FLAG, AND THE ALLOWED NUMBER ; OF DISK BLOCKS THE USER MAY HAVE ; ; ; RSET USER=NAME:PASSWORD/TASK=XXXXXX/PRV=NNNNNN/FLAG ; ; ; EACH KEYWORD (TASK,PRV,FLAG) ARE OPTIONAL. ; ONLY THE FIRST TWO CHARACTERS ARE CHECKED FOR SPELLING. ; FLAG -- RESET USER'S ACCOUNT BUSY FLAG ; TASK=XXXXXX -- INSERT UP TO A 6 CHARACTER TASK NAME ; OR CLEAR TASK NAME IF NOTHING FOLLOWS THE "=" ; PRV=NNNNNN -- INSERT A 6 DIGIT OCTAL WORD WHERE ; NNNNNN ARE UP TO 6 OCTAL DIGITS. IF ; NOTHING FOLLOWS THE "=" SIGN, ZERO ; THE PRIVLEGE MASK WORD. ; BLKS=NNNNNN -- INSERT A 6 DIGIT DECIMAL WORD, WHERE ; NNNNNN ARE UP TO 6 OCTAL DIGITS. THIS ; VALUE BECOMES THE ALLOWED NUMBER OF BLOCKS ; A USER MAY USE BEFORE THE SYSTEM STARTS ; REQUESTING THE USER TO DELETE FILES. ; ; Error returns: ; Under certain very ambiguous conditions an error return of 177772 ; (IE.SPC -- Illegal user buffer) will cause the write error message to ; appear. This seems associated with the total length of the account ; file. I have so far been able to work around the problem by changing ; the size of the account file (copy with PIP, and extend size with /BL:NN). ; An additional error message (illegal user buffer) has been added to ; warn you that the account file size is causing problems. To date ; I do not understand what the error means and how (if at all) the code is ; screwing up. In three years this program only produced the error ; once, when the account file size was changed to 12. blocks. Increasing ; the size to 13. blocks made the problem go away. ; ; 4/27/79 ; Dave Kelly found the answer to this problem (I think), in that IO.WVB ; does not like to write out a block with zero bytes in it. On the off ; chance that other wierd errors might still crop up, i am not only ; including Dave Kelly's SLP patch, but am also leaving in the ; illegal user buffer error message. Finally, if a write error ; of unknown type occurs, a BPT is executed after the account file ; is closed with iosb, iosb+2 in R0 and R1 respectively. ; ; ; ; ; TASKBUILD AS FOLLOWS ; RESET/MM,TI:=RESET,MCR.OLB/LB:ACTFIL ; MCR.OLB/LB,LB:[1,54]RSX11M.STB,[1,1]EXELIB/LB ; / ; PAR=GEN ; ASG=TI:1 ; ASG=SY:2 ; STACK=64 ; TASK=...RSE ; PRI=75 ; LIBR=FCSRES:RO:6 ; IF SYSTEM HAS RESIDENT FCS LIBRARY ; // ; ; ; ; JAMES G. DOWNWARD 7/27/77 ; MODIFIED: ; 08-MAR-79 ERROR MESSAGES FOR ILLEGAL USER BUFFER ; ; 24-APR-79 DSK01 DAVID S. KELLY ; CHANGE TO SKIP FINAL WRITE IF EOF ; NOTED AT START OF BLOCK. ; ; 29-MAY-79 JGD02 ZERO CPU TIME ENTRY WHILE ZEROING ; CONNECT TIME ; ; 11-Feb-83 JGD03 Lower case error messages ; ; .MCALL QIO$,DIR$,WTSE$S,OPEN$U,CLOSE$,READ$ .MCALL EXIT$S,GTIM$S,MRKT$,GMCR$ ; ; CONSTANTS ; LUN1 = 1 ; TI: LUN LUN2 = 2 ; ACCOUNT FILE LUN EFN1 = 1 ; EVENT FLAG FOR ALL I/O EFN2 = 2 ; EVENT FLAG FOR MARK TIME ; ; LOCAL DATA -- MESSAGES AND ERROR MESSAGES ; .NLIST BEX .ENABLE LC ; ; ER1: .ASCIZ <15>/RESET -- Account file write error/ ER2: .ASCIZ <15>/RESET -- Account file read error/ ER3: .ASCIZ <15>/RESET -- Account file busy or wrong LB:/ ER4: .ASCIZ <15>/RESET -- Command syntax error/ ER5: .ASCIZ <15>/RESET -- Invalid account/ ; THIS MAY BE USED LATER ER6: .ASCIZ <15>/RESET -- Command error/ ER7: .ASCIZ <15>/RESET -- Command word not recognized/ ER8: .ASCIZ <15>/RESET -- Illegal octal value/ ER9: .ASCIZ <15>/RESET -- Missing password/ ER10: .ASCIZ <15>/RESET -- Illegal decimal number/ ER11: .ASCIZ <15>/RESET -- Illegal user buffer, increase size of RSX11.SYS/ ER12: .ASCIZ <15>/RESET -- Unknown write error, IOSB, IOSB+2 in R0, R1/ ; ; MSG1: .ASCIZ <15>/RESET -- All account busy flags reset/ MSG2: .ASCIZ <15>/RESET -- All total login time entries zeroed/ MSG3: .ASCIZ <15>/RESET -- All # of logins entries zeroed/ .LIST BEX .EVEN ; ; FILE DPB'S ; ODPB: QIO$ IO.WVB,LUN1,EFN1,,,, ; TI: OUTPUT DPB FDPB: QIO$ IO.RVB,LUN2,EFN1,,IOSB,,<$ACTBF,$BFLEN,,,1> ; DBP FOR [0,0]RSX11.SYS IOSB: .BLKW 2 ; I/O STATUS BLOCK MKT: MRKT$ EFN2,100.,1 ; WAIT 100 TICKS ; ; GMCR: GMCR$ BUF=GMCR+2 ; BUFFER FOR ALL TI: I/O ; ; VARIABLES ; EOF: .WORD 0 ; END OF FILE FLAG SO WE ARE SURE OF WRITING BACK THE LAST BLOCK COUNT: .WORD 0 ; NUMBER OF BYTES IN ACCOUNT FILE BUFFER TEMP: .WORD 0 ; TEMPORARY STORAGE FOR FILE DPB FILOPN: .WORD 0 ; FILE OPEN FLAG ENTRY: .WORD 0 ; CURRENT ENTRY POINT TO ACCOUNT OPNERR: .WORD 0 ; ERROR FLAG FOR OPEN ACCOUNT REDERR: .WORD 0 ; ERROR FLAG SET IF ACCOUNT READ ERROR WRTERR: .WORD 0 ; ERROR FLAG SET IF ERROR WRITING ACCOUNT RSTFLG: .WORD 0 ; RESET ALL ACCOUNT BUSY FLAGS IF <>0/ LGNFLG: .WORD 0 ; RESET # OF LOGINS IF <>0 TIMFLG: .WORD 0 ; RESET ALL CONNECT TIME ENTRIES IF <>0 USRFLG: .WORD 0 ; ONLY THE SPECIFIED USERS ACCOUNT IS TO BE RESET TSKFLG: .WORD 0 ; THE TASK IS TO BE SET IN THE ACCOUNT FILE PRVFLG: .WORD 0 ; THE PRIVLEGE MASK IS TO BE SET IN THE ACCOUNT FILE FLGFLG: .WORD 0 ; RESET THE ACCNT BUSY FLAG IN ONLY THE USER'S ACCOUNT BLKFLG: .WORD 0 ; ENTER A NEW VALUE INTO THE ALLOWED NUMBER OF DISK BLOCKS DECFLG: .WORD 0 ; A ASCII TO DECIMAL CONVERSION IS TO BE DONE(NOT OCTAL) TASK: .WORD 0 ; RESERVE THREE WORDS OF STORAGE FOR TASK NAME .WORD 0 ; .WORD 0 ; .EVEN PSWD: .ASCII / / ; THE USER'S PASSWORD(UP TO 6 CHARACTERS) NAME: .ASCII / / ; THE USER'S NAME (UP TO 12 CHARACTERS) PRIV1: .ASCII / / ; ALLOW 6 CHARACTER SPACES FOR THE ASCII PRIVLEGE MASK BLOCKS: .ASCII / / ; ALLOW 6 CHARACTER SPACES FOR THE ASCII NUMBER OF DISK BLOCKS(OCTAL) .EVEN PRIV: .WORD 0 ; THE PRIVLEGE MASK WORD BLK: .WORD 0 ; THE ALLOWED NUMBER OF BLOCKS ; ; .SBTTL MAIN LINE CODE ; + ; ; $SETEP - ACCOUNT FILE MAINTENANCE PROGRAM ; ; - $SETEP: DIR$ #GMCR ; GET MCR COMMAND LINE BCC 10$ ; IF CC OK NO ERROR SO PROCEED MOV #ER6,R0 ; PRINT ERROR MESSAGE CALL WRIT ; SYNTAX ERROR JMP EXIT ; AND EXIT ; ; ; FIND OUT WHICH FUNCTION TO BE DONE ; ;+ $GNBLK - GET NEXT NON BLANK CHARACTER ; THIS ROUTINE IS PULLED IN FROM MCR.OLB ; INPUTS - R0 - THE INPUT BUFFER ADDRESS ; AFTER EACH CALL R0 POINTS TO THE NEXT BUFFER ADDRESS ; OUTPUTS - R1 - EQUALS 0 IF NO BLANKS PASSED OVER ; EQUALS THE NUMBER OF BLANKS IF ANY FOUND ; R2 - HAS THE OUTPUT CHARACTER(IF ANY) ; 10$: MOV #BUF,R0 ; GET ADRESS OF INPUT BUFFER ADD #2.,R0 ; POINT TO WHERE WE EXPECT SPACE 14$: CALL $GNBLK ; GET FIRST NON BLANK CHARACTER BCS 15$ ; EOL FOUND, SYNTAX ERROR TST R1 ; ANY SPACES FOUND BEQ 14$ ; NO, SINCE A SPACE MUST SEPERATE RSE[T] FROM A ; COMMAND WORD, LETS LOOP AND TRY AND PASS A SPACE BR 20$ ; WE'RE PAST THE SPACE SO THE FIRST LETTER OF THE ; COMMAND WORD IS IN R2 15$: MOV #ER4,R0 ; NO, SYNTAX ERROR CALL WRIT ; SO PRINT ERROR MESSAGE AND EXIT CALL EXIT ; AND EXIT 20$: CMPB R2,#'F ; IS THE COMMAND "RESET FLAGS"? BNE 30$ ; NO, CHECK TO SEE IF OTHER COMMAND CALL $GNBLK ; GET ANOTHER CHARACTER BCS 15$ ; AN EOL IS INAPPROPRIATE HERE CMPB R2,#'L ; IS IT AN "L"? BNE 15$ ; NO, EXIT SYNTAX ERROR INC RSTFLG ; YES, SO SET RESET ACCOUNT USE FLAG BR 50$ ; GO OPEN FILE AND EXECUTE COMMAND 30$: CMPB R2,#'T ; SHOULD WE RESET THE LOGON TIME VALUES? BNE 35$ ; NO, CHECK TO SEE IF SOMETHING ELSE CALL $GNBLK ; GET ANOTHER CHARACTER BCS 15$ ; AN EOL HERE IS WRONG CMPB R2,#'I ; IS IT AN "I"? BNE 15$ ; NO, EXIT SYNTAX ERROR INC TIMFLG ; SET THE FLAG TO INDICATE WE WILL ZERO LOGIN TIMES BR 50$ ; GO OPEN ACCOUNT FILE AND EXECUTE COMMAND 35$: CMPB R2,#'L ; SHOULD WE RESET THE NUMBER OF LOGINS BNE 40$ ; NO, CHECK TO SEE IF MORE CALL $GNBLK ; GET NEXT CHARACTER BCS 15$ ; AN EOL IS WRONG HERE CMPB R2,#'O ; IS IT AN "O"? BNE 15$ ; NO, SYNTAX ERROR INC LGNFLG ; SET THE FLAG TO ZERO THE NUMBER OF LOGINS BR 50$ ; GO OPEN ACCOUNT FILE AND ZERO THE NUMBER OF LOGINS 40$: CMPB R2,#'A ; SHOULD WE RESET EVERYTHING? BNE USER ; CHECK TO SEE IF USER= SYNTAX CALL $GNBLK ; GET NEXT NON BLANK BCS EXIT2 ; AN EOL HERE IS BAD CMPB R2,#'L ; IS IN AN "L" BNE EXIT2 ; NO, A SYNTAX ERROR INC LGNFLG ; THE NUMBER OF LOGINS ENTRY WILL BE ZEROED INC TIMFLG ; THE TOTAL LOGIN TIME ENTRY WILL BE ZEROED INC RSTFLG ; THE ACCOUNT FILE IN USE FLAG WILL BE ZEROED ; ; OPEN ACCOUNT FILE ; 50$: CALL OPEN ; TRY AND OPEN ACCOUNT FILE(A RETURN MEANS SUCCESS) ; ; OPEN SUCCESFUL, SO PROCEED TO ZERO ENTRIES ; 60$: CALL RESET ; GO ZERO [0,0]RSX11.SYS FILE ENTRIES BCC 64$ ; NO READ/WRITE ERRORS FOUND SO SKIP AROUND TST REDERR ; WAS IT A READ ERROR? BEQ 62$ ; NO, SO SKIP AROUND MOV #ER2,R0 ; PRINT MESSAGE SAYING IT IS A READ ERROR CALL WRIT ; AND PRINT IT 62$: TST WRTERR ; IS IT A WRITE ERROR? BEQ 64$ ; NO, MY GOD! WHAT HAPPENED? MOV #ER1,R0 ; ITS A WRIT ERROR, QUEUE A MESSAGE CALL WRIT ; AND PRINT IT CMPB IOSB,#372 ; IS THIS THE 'ILLEGAL USER BUFFER' PROBLEM BNE 64$ ; NO MOV #ER11,R0 ; YES, SO PRINT WARNING MESSAGE CALL WRIT ; WRITE IT OUT CLR WRTERR ; RESET FLAG SO WON'T DUMP REGISTERS LATER 64$: TST RSTFLG ; SHOULD WE PRINT MESSAGE SAYING LOGIN FLAGS RESET BEQ 65$ ; NO, CHECK SOME MORE MOV #MSG1,R0 ; YES,PRINT MESSAGE SAYING "ACCOUNT BUSY FLAGS RESET" CALL WRIT ; WRITE IT OUT 65$: TST LGNFLG ; SHOULD WE PRINT MESSAGE SAYING # LOGINS ZEROED BEQ 70$ ; NO, CHECK SOME MORE MOV #MSG3,R0 ; YES , PRINT MESSAGE " ALL NUMBER OF LOGINS ZEROED" CALL WRIT ; PRINT IT 70$: TST TIMFLG ; PRINT MESSAGE SAYING TIME ENTRIES ZEROED? BEQ 75$ ; NO, SO EXIT MOV #MSG2,R0 ; YES, PRINT "ALL TOTAL LOGIN TIME ENTRIES ZEROED" CALL WRIT ; AND PRINT IT ON TI: 75$: JMP EXIT ; ALL DONE, GOODBY EXIT2: JMP EXIT1 ; EXIT AND PRINT ERROR MESSAGE ; ;+ ; USER -- PARSE THE COMMAND STRING AND SET THE APPROPRIATE ; FLAGS FOR A LATER SEARCH OF THE ACCOUNT FILE ; THE SYNTAX ; USER=NAME:PASSWORD/TASK=XXXXXX/PRIV=NNNNN ; IS BEING SCANNED FOR. ONLY THE FIRST TWO LETTERS OF ; EACH KEYWORD COUNT. TO ZERO OUT AN ENTRY, USE EITHER ; PRIV=0, OR TASK = (A SPACE FOLLOWS THE EQUAL SIGN). ; ;- USER: CMPB R2,#'U ; DOES THE COMMAND WORD START WITH U BNE EXIT3 ; EXIT, THE COMMAND IS NOT RECOGNIZED CALL $GNBLK ; GET THE NEXT NON BLANK CHARACTER BCS EXIT3 ; AN EOL HERE IS AN ERROR CMPB R2,#'S ; IS THE SECOND LETTER AN S? BNE EXIT3 ; NO, EXIT, ILLEGAL OR UNKNOWN COMMAND WORD INC USRFLG ; SET USRFLG, THE COMMAND WORD SEEMS TO BE USER 10$: CALL $GNBLK ; START SCAN TO FIND AN = SIGN BCS EXIT3 ; ANY EOL AT THIS POINT IS BAD SYNTAX CMPB R2,#'= ; IS IT AN EQUAL SIGN BNE 10$ ; TRY AGAIN MOV #NAME,R3 ; WE FOUND AN EQUAL SIGN, SO WE WILL START STUFFING MOV #12.,R4 ; CHARACTERS INTO NAME. 12 CHARACTERS MAX 20$: CALL $GNBLK ; GET NEXT NON BLANK CHARACTER BCS EXIT3 ; AN EOL IS NOT LEGAL HERE CMPB R2,#': ; IS THE CHARACTER A COLON, IF SO EXIT LOOP BEQ 30$ ; AND GET PASSWORD CMPB R2,#'/ ; A / IS ILLEGAL BEQ EXIT4 ; SO EXIT MOVB R2,(R3)+ ; MOVE CHARACTER INTO NAME DEC R4 ; DECREASE CHARACTER COUNT TST R4 ; IF R4=0,12 CHARACTERS STUFFED BEQ 25$ ; SO GO GET A COLON BR 20$ ; GET ANOTHER CHARACTER 25$: CALL $GNBLK ; GET A CHARACTER BCS EXIT3 ; EXIT, EOL FOUND CMPB R2,#': ; IS IT A COLON BNE EXIT4 ; A COLON MUST FOLLOW NAME OR ELSE EXIT 30$: MOV #6.,R4 ; ONLY 6 CHARACTERS ALLOWED IN PASSWORD MOV #PSWD,R3 ; GET ADDRESS OF PASSWORD STORAGE 35$: CALL $GNBLK ; GET CHARACTER BCS EXIT3 ; EOL NOT ALLOWED HERE CMPB R2,#'/ ; A / MEANS WE SCANNED OVER A PASSWORD BEQ KEY ; GO SEE WHAT TO SET MOVB R2,(R3)+ ; MOVE CHARACTER INTO PSWD DEC R4 ; DECREASE CHARACTER COUNT BEQ 40$ ; GO CHECK FOR A / BR 35$ ; LOOP SOME MORE 40$: CALL $GNBLK ; GET A CHARACTER BCS EXIT3 ; AN EOL IS ILLEGAL HERE STILL CMPB R2,#'/ ; IT BETTER BE A / BNE EXIT3 ; EXIT COMMAND SYNTAX ERROR KEY: CALL $GNBLK ; GET A CHARACTER BCS EXIT3 ; END OF LINE NOT ALLOWED CMPB R2,#'T ; IF A T IS FOUND CHECK TO SEE IF "TASK" IS KEYWORD BEQ TSKCK ; GO CHECK CMPB R2,#'P ; IS THE KEYWORD "PRIV"? BEQ PRVCK ; GO SEE CMPB R2,#'F ; IF A F IS FOUND CHECK TO SEE IF "FLAG" IS KEYWORD BEQ FLGCK ; GO CHECK CMPB R2,#'B ; IS THE KEYWORD "BLKS"? BEQ BLKCK ; GO SEE KEY1: CLR R4 ; CLEAR FOR TEST ADD TSKFLG,R4 ; WE ONLY WILL CONTINUE IF EITHER TSKFLG,FLGFLG,PRVFLG ADD FLGFLG,R4 ; OR BLKFLG IS SET ADD BLKFLG,R4 ; ADD PRVFLG,R4 ; SO SUM THE THREE FLAGS AND TEST FOR >0 TST R4 ; IF EQ ZERO ERROR BEQ EXIT3 ; SYNTAX ERROR MOV #PRIV1,R0 ; SET UP TO CONVERT PRIVLEGE MASK WORD TO OCTAL MOV #PRIV,R3 ; AND PUT IN IN PRIV CALL ASCOCT ; CONVERT PRIVLEGE WORD FROM ASCII TO OCTAL MOV #BLOCKS,R0 ; SET UP TO CONVERT NUMBER OF BLOCKS TO OCTAL MOV #BLK,R3 ; AND PUT IN IN BLK INC DECFLG ; SET DECIMAL CONVERSION FLAG CALL ASCOCT ; CONVERT ASCII BLOCKS TO OCTAL NUMBER CALL OPEN ; TRY AND OPEN [0,0]RSX11.SYS . A RETURN MEANS OPEN A SUCCESS CALL FIND ; GO TRY AND MATCH NAME/PASSWORD AND RESET THE ACCOUNT JMP EXIT ; EXIT WHEN DONE EXIT3: JMP EXIT1 ; EXIT AND PRINT ERROR MESSAGE EXIT4: MOV #ER9,R0 ; PRINT MESSAGE THAT PASSWORD'S MISSING CALL WRIT ; JMP EXIT1 ; EXIT AND PRINT SYNTAX ERROR MESSAGE SCAN: CALL $GNBLK ; WE ALREADY FOUND WTHE FIRST LETTER, LETS FIND THE SECOND BCS EXIT3 ; EOL NOT ALLOWED HERE CMPB R2,R4 ; IS SECOND LETTER OK BNE EXIT3 ; SYNTAX ERROR 10$: CALL $GNBLK ; SCAN FOR AN "=" BCS EXIT3 ; EOL NOT ALLOWED CMPB R2,#'/ ; SHOULD NOT FIND IN FRONT OF =SIGN BEQ EXIT3 ; SO EXIT CMPB R2,#'= ; AN "=" YET? BNE 10$ ; TRY AGAIN MOV #6.,R4 ; ONLY 6 CHARACTERS ALLOWED 20$: CALL $GNBLK ; GET A CHARACTER BCS KEY1 ; AN EOL HERE JUST MEANS END OF COMMAND CMPB R2,#'/ ; A "/" MEANS CHECK FOR ANOTHER KEYWORD BEQ 35$ ; SO GO AND LOOK FOR IT MOVB R2,(R3)+ ; OTHERWISE MOVE A CHARACTER INTO BUFFER TST R4 ; IF ALL SIX CHARACTERS PUT IN, EXIT LOOP BEQ 30$ ; EXIT LOOP BR 20$ ; LOOP 30$: CALL $GNBLK ; GET A CHARACTER BCS KEY1 ; AN EOL MEANS END OF COMMAND STRING DEC R0 ; BACK UP A CHARACTER AND 35$: JMP KEY ; LOOK FOR ANOTHER COMMAND STRING ; ; COMMON EXIT POINT ; ; EXIT1: MOV #ER4,R0 ; PRINT ERROR MESSAGE SAYING CALL WRIT ; COMMAND NOT IMPLEMENTED EXIT: TST FILOPN ; IS THE ACCOUNT FILE OPEN? BEQ 10$ ; NO , SO EXIT CLOSE$ #$ACTFL ; YES, SO CLOSE IT TST WRTERR ; IF THERE IS NO WRITE ERROR WE DON'T WANT TO DUMP BEQ 10$ ; IOSB, IOSB+2 MOV #ER12,R0 ; WARN USER OF REGISTER DUMP CALL WRIT ; MOV IOSB,R0 ; THERE IS A WRITE ERROR MOV IOSB+2,R1 ; SO R0, AND R1 WILL CONTAIN THE IO STATUS BOCK BPT ; THIS IS THE EASIEST WAY TO GET AN ERROR MESSAGE 10$: EXIT$S ; AND EXIT ; ; ROUTINES TO PROCESS THE KEYWORDS, TASK, PRIV,FLAG ; TSKCK: MOV #'A,R4 ; SET UP TO TEST FOR SECOND LETTER ="A" MOV #TASK,R3 ; AND TO PUT DATA INTO TASK NAME INC TSKFLG ; AND SET TASK FLAG BR SCAN ; NOW GO PARSE LINE BLKCK: MOV #'L,R4 ; SET UP TO TEST FOR SECOND LETTER = "L"? MOV #BLOCKS,R3 ; AND TO PUT DATA INTO BLOCKS INC BLKFLG ; ANS SET BLOCK FLAG BR SCAN PRVCK: MOV #'R,R4 ; SET UP TO TEST FOR SECOND LETTER ="R" MOV #PRIV1,R3 ; AND TO PUT DATA INTO THE ASCII PRIVLEGE MASK WORD INC PRVFLG ; AND SET PRIV MASK KEYWORD FLAG BR SCAN FLGCK: CALL $GNBLK ; GET A CHARACTER BCS EXIT3 ; AN EOL HERE IS BAD CMPB R2,#'L ; IS SECOND LETTER AN L? BNE EXIT3 ; SYNTAX ERROR INC FLGFLG ; WE FOUND AN L, SET THE RESET ACCOUNT IN USE FLAG 10$: CALL $GNBLK ; GET ANOTHER CHARACTER BCC 20$ ; CARRY CLEAR SO NO EOL, SCAN LINE JMP KEY1 ; EOL, SO PROCESS COMMAND LINE 20$: CMPB R2,#'/ ; GOT A "/" ? BNE 10$ ; NO, LOOP AGAIN JMP KEY ; YES, GET ANOTHER KEYWORD .SBTTL SUBROUTINES ;+ ; OPEN -- OPEN [0,0]RSX11.SYS FOR UPDATE ; AN ATTEMPT WILL BE MADE TO OPEN FILE UP TO FIVE TIMES ; (IN CASE FILE IN USE). ; ;- OPEN: CLR OPNERR ; INDICATE NO ERRORS TO START WITH 10$: OPEN$U #$ACTFL,,,#FD.RWM ; TRY AND OPEN FILE FOR UPDATE BCC 40$ ; IF NO ERRORS EXIT SUBROUTINE CMP OPNERR,#5. ; OTHERWISE CHECK THE NUMBER OF TIMES TRIED TO OPEN FILE BLT 20$ ; IF LESS THAN OR EQUAL 5 TIMES,WAIT 1 SEC AND TRY AGAIN MOV #ER3,R0 ; IF TRIED 5 TIMES, PRINT ERROR MESSAGE AND EXIT CALL WRIT ; PRINT OUT MESSAGE JMP EXIT ; AND EXIT 20$: DIR$ #MKT ; LET'S WAIT ONE SECOND AND TRY AGAIN WTSE$S #2 ; WAIT ON EVENT FLAG 2 INC OPNERR ; INCREMENT THE NUMBER OF TIMES TRIED TO OPEN FILE BR 10$ ; GO BACK AND TRY ABAIN 40$: INC FILOPN ; SET FILE OPEN FLAG CLR OPNERR ; SET NO ERROR RETURN ; GO BACK TO MAINLINE CODE ;+ ; *** - WRIT - WRITE TERMINAL MESSAGE ; ; INPUT: ; R0 - MESSAGE ADDRESS ; ;- WRIT: MOV R0,R1 ; COPY BUFFER ADDRESS 10$: TSTB (R1)+ ; END OF MESSAGE? BNE 10$ ; NO, LOOP TILL END SUB R0,R1 ; COMPUTE LENGTH MOV #ODPB,R4 ; GET OUTPUT DPB ADDRESS MOV R0,Q.IOPL(R4) ; SET BUFFER ADDRESS MOV R1,Q.IOPL+2(R4) ; SET BUFFER LENGTH CALLR QIO ; WRITE IT OUT ;+ ; *** - QIO - ISSUE QIO ; ; INPUT: ; R4 - DPB ADDRESS ;- QIO: DIR$ R4 ; ISSUE QIO BCS 10$ ; ERROR MOVB Q.IOEF(R4),R5 ; GET EVENT FLAG TO WAIT ON WTSE$S R5 ; AND WAIT 10$: RETURN ; ;+ ; ASCOCT -- ROUTINE TO TAKE UP TO 6 CHARACTERS AND CONVERT THEM INTO A OCTAL ONE ; WORD NUMBER. TRAILING SPACES ARE THROWN AWAY AND ONLY NUMBERS 0-7 ALLOWED. ; THE ROUTINE USES THE SYSLIB ROUTINE .ODCVT TO CONVERT ASCII TO OCTAL ; R3 = ADDRESS OF RESULT WORD ; R4 = LENGTH OF ASCII STRING ; R5 = ADDRESS OF ASCII STRING ; AS SOON AS A TRAILING SPACE IS FOUND THE SCAN TO FIND THE NUMBER OF CHARACTERS ; STOPS. THE ROUTINE $GNBLK INSURES THAT NO INTERNAL SPACES EXIST IN THE ASCII ; NUMBER ; ;- ASCOCT: MOV R0,R5 ; SAVE ADDRESS OF STRING CLR R4 ; CLEAR R4 WHICH IS TO CONTAIN THE NUMBER OF CHARACTERS ; POSSIBBLY TRAILING SPACES 10$: CMPB #40,(R0)+ ; IS IT A SPACE? BEQ 50$ ; FOUND FIRST TRAILING SPACE,SO GO AND CONVERT NUMBER INC R4 ; ONE CHARACTER FOUND, BUMP COUNTER UP 1 CMPB #6.,R4 ; SIX CHARACTERS YET? BEQ 50$ ; YES, GO CONVERT TO OCTAL BR 10$ ; NO, SCAN ANOTHER CHARACTER 50$: TST R4 ; ARE ANY CHARACTERS TO BE CONVERTED? BEQ 100$ ; NO, JUST RETURN, THE VALUE TO BE CONVERTED IS ZERO TST DECFLG ; SHOULD THIS REALLY BE A DECIMAL CONVERSION? BNE 60$ ; YES , SKIP AROUND CALL .ODCVT ; NO, CONVERT STRING TO OCTAL WORD BCS OCTERR ; IF CARRY SET FOUND AN ILLEGAL CHARACTER BR 100$ ; AND RETURN 60$: CALL .DCCVT ; CONVERT TO DECIMAL NUMBER BCS DECERR ; IF CARRY SET, A NON NUMERIC CHARACTER FOUND 100$: RETURN ; ALL DONE , RETURN OCTERR: MOV #ER8,R0 ; OCTAL CONVERSION ERROR CALL WRIT ; PRINT OUT MESSAGE JMP EXIT ; AND EXIT DECERR: MOV #ER10,R0 ; DECIMAL CONVERSION ERROR CALL WRIT ; PRINT OUT MESSAGE JMP EXIT ; AND EXIT ;+ ; ***RESET - READ ACCOUNT INFORMATION INTO THE BUFFER AND ; ZERO THE APPROPRIATE ENTRIES ; EACH BUFFER(ACTBF) IS 512 BYTES LONG AND CONTAINS 4 ; USER ACCOUNT BLOCKS ; ;- RESET: MOV #FDPB,R4 ; GET FILE DPB ADDRESS MOV R4,TEMP ; SAVE R4 FOR LATER MOV #1,Q.IOPL+10(R4) ; SET TO START AT VBN 1 CLR Q.IOPL+6(R4) ; 5$: CALL QIO ; READ IN THE BLOCK MOV IOSB+2,COUNT ; GET COUNT OF WORDS READ BEQ 75$ ; IF ZERO WORDS READ, TEST FOR END OF FILE ; DSK01 MOV #$ACTBF,R0 ; GET BUFFER ADDRESS ;**-1 10$: MOV R0,ENTRY ; SAVE ENTRY ADRESS FOR LATER, WE'LL NEED IT CALL ZERO ; WE ARE AT THE START OF A 128 BYTE ACCOUNT BLOCK ; GO AND PRINT THE INFORMATION MOV ENTRY,R0 ; RESTORE ENTRY, SO WE CAN STEP THROUGH THE ACCOUNT ; BUFFER. ADD #A.LEN,R0 ; POINT TO NEXT ENTRY SUB #A.LEN,COUNT ; COMPUTE WORDS LEFT IN BUFFER BHI 10$ ; IF STILL MORE TO PROCESS IN THIS BUFFER ; LOOP BACK AND PRINT SOME MORE 50$: CMPB #IE.EOF,IOSB ; OTHERWISE CHECK FOR END OF FILE BNE 52$ ; SKIP OVER IF EOF NOT FOUND INC EOF ; IF END OF FILE FOUND, SET EOF FLAG BR 53$ ; EOF FOUND, WRITE OUT FILE FOR LAST TIME 52$: TSTB IOSB ; BE SURE WE DON'T HAVE ANY READ ERRORS BMI 54$ ; A READ ERROR FOUND, SET CARRY BEFORE EXITING 53$: MOV TEMP,R4 ; RESTORE R4 MOV #IO.WVB,2(R4) ; NOW GET SET TO WRITE OUT THE BLOCK WE JUST READ IN MOV IOSB+2,Q.IOPL+2(R4) ; SET COUNT OF BYTES TO WRITE BACK OUT CALL QIO ; WRITE OUT THE BLOCK TSTB IOSB ; ANY ERRORS BMI 70$ ; OH SHIT!!, SET CARRY, EXIT AND SALVAGE FILE IF POSSIBLE MOV #IO.RVB,2(R4) ; RESET FDB FOR READ VIRTUAL BLOCK ADD #$BFLEN/512.,Q.IOPL+10(R4) ; NO ERRORS, SO POINT TO NEXT VBN ADC Q.IOPL+6(R4) ; TST EOF ; WAS END OF FILE FOUND, IF YES, DON'T READ IN ANOTHER BLOCK ; BNE 60$ ; YES , EOF FOUND SO EXIT BNE 72$ ; YES , EOF FOUND SO EXIT ; JGD01 BR 5$ ; READ IN A NEW BUFFER ;**-1 54$: INC REDERR ; LET THE MAINLINE CODE KNOW ITS A READ ERROR 55$: SEC ; SET CARRY AS AN ERROR FLAG 60$: RETURN ; 70$: INC WRTERR ; LET THE MAINLINE CODE KNOW ITS A WRITE ERROR BR 55$ ; SET CARRY AND EXIT 72$: CLC ; CLEAR CARRY TO SHOW SUCCESS ; DSK01 RETURN ; RETURN, ALL IS WELL ; DSK01 75$: CMPB #IE.EOF,IOSB ; EOF FOUND? ; DSK01 BNE 52$ ; NO - CHECK FOR READ ERROR ; DSK01 INC EOF ; YES - SET FLAG ; DSK01 BR 60$ ; BUT SKIP FINAL WRITE ; DSK01 ;**-2 ;+ ; ***FIND - READ ACCOUNT INFORMATION INTO THE BUFFER AND ; SEE IF PASSWORD AND NAME MATCH ; EACH BUFFER(ACTBF) IS 512 BYTES LONG AND CONTAINS 4 ; USER ACCOUNT BLOCKS ; ;- FIND: MOV #FDPB,R4 ; GET FILE DPB ADDRESS MOV R4,TEMP ; SAVE R4 FOR LATER MOV #1,Q.IOPL+10(R4) ; SET TO START AT VBN 1 CLR Q.IOPL+6(R4) ; 5$: CALL QIO ; READ IN THE BLOCK MOV IOSB+2,COUNT ; GET COUNT OF WORDS READ BEQ 50$ ; IF ZERO WORDS READ, TEST FOR END OF FILE MOV #$ACTBF,R0 ; GET BUFFER ADDRESS 10$: MOV R0,ENTRY ; SAVE ENTRY ADRESS FOR LATER, WE'LL NEED IT CALL MATCH ; DO NAME AND PASSWORD MATCH? TST USRFLG ; IF MATCH FOUND, USRFLG=0 BEQ 100$ ; YES, MATCH FOUND, GO WRITE OUT BLOCK MOV ENTRY,R0 ; RESTORE ENTRY, SO WE CAN STEP THROUGH THE ACCOUNT ; BUFFER. ADD #A.LEN,R0 ; POINT TO NEXT ENTRY SUB #A.LEN,COUNT ; COMPUTE WORDS LEFT IN BUFFER BHI 10$ ; IF STILL MORE TO PROCESS IN THIS BUFFER ; LOOP BACK AND CHECK NEXT ACCOUNT 50$: CMPB #IE.EOF,IOSB ; OTHERWISE CHECK FOR END OF FILE BEQ 60$ ; YES, EOF FOUND AND WE ARE DONE FOR NOW TSTB IOSB ; BE SURE WE DON'T HAVE ANY READ ERRORS BMI 54$ ; A READ ERROR FOUND, SET CARRY BEFORE EXITING MOV TEMP,R4 ; RESTORE R4 ADD #$BFLEN/512.,Q.IOPL+10(R4) ; NO ERRORS, SO POINT TO NEXT VBN ADC Q.IOPL+6(R4) ; BR 5$ ; READ IN A NEW BUFFER 54$: INC REDERR ; LET THE MAINLINE CODE KNOW ITS A READ ERROR 55$: SEC ; SET CARRY AS AN ERROR FLAG BR 65$ ; SKIP 60$: TST USRFLG ; DID WE FIND A MATCH BEQ 65$ ; YES, RETURN MOV #ER5,R0 ; PRINT OUT MESSAGE "INVALID ACCOUNT" CALL WRIT ; ON TERMINAL 65$: RETURN ; 70$: INC WRTERR ; LET THE MAINLINE CODE KNOW ITS A WRITE ERROR BR 55$ ; SET CARRY AND EXIT 100$: MOV TEMP,R4 ; RESTORE R4 (DPB ADDRESS) MOV #IO.WVB,2(R4) ; NOW GET SET TO WRIT OUT THE BLOCK JUST READ IN MOV IOSB+2,Q.IOPL+2(R4) ; SET COUNT OF BYTES TO WRITE BACK OUT CALL QIO ; WRITE OUT THE BLOCK MOV #IO.RVB,2(R4) ; RESTORE DPB MOV #$BFLEN,Q.IOPL+2(R4) ; AND LENGTH TSTB IOSB ; ANY ERRORS? BMI 70$ ; OH SHIT!!, SET CARRY, EXIT AND SALVAGE FILE IF POSSIBLE BR 60$ ; NO ERRORS, SO GO BACK TO MAINLINE CODE ;+ ; MATCH -- COMPARE THE 18 CHARACTERS IN THE PASSWORD-NAME BLOCK OF THE ; ACCOUNT FILE TO THE PASSWORD-NAME INPUT FROM TI: ; IF A MATCH IS FOUND CLEAR USRFLG. ; IF A MATCH IS FOUND RESET THOSE VALUES FLAGED BY FLGFLG,PRVFLG ; OR TSKFLG. ;- MATCH: ADD #A.PSWD,R0 ; POINT TO PASSWORD ENTRY IN ACCOUNT MOV #PSWD,R1 ; LOAD R1 WITH ADDRESS OF PASSWORD-NAME TO CHECK OUT CLR R2 ; RESET COUNTER 10$: CMPB (R0)+,(R1)+ ; DO CHARACTERS MATCH BNE 70$ ; NO, RETURN INC R2 ; YES, INCREMENT R2 CMP #18.,R2 ; 18 CHARACTERS YET? BEQ 20$ ; YES, AND ALL 18 MATCH, ITS A KEEPER BR 10$ ; NO, NO MATCH YET AND STILL SOME CHARACTERS TO CHECK, LOOP 20$: MOV #0,USRFLG ; ZERO USRFLG TST FLGFLG ; RESET ACNT IN USE FLAG? BEQ 25$ ; NO MOV ENTRY,R0 ; YES, RESET ENTRY ADDRESS ADD #A.TERM,R0 ; POINT TO TERMINAL IN USE FLAG MOV #0,(R0)+ ; ZERO FIRST WORD MOV #0,(R0) ; AND THE SECOND MOV ENTRY,R0 ; RESTORE ENTRY ADDRESS ; JGD03 ADD #A.VTRM,R0 ; POINT TO BATCH FLAG WORD ; JGD03 CLR (R0) ; ZERO THE FLAG ; JGD03 25$: TST PRVFLG ; RESET PRIVLEGE MASK WORD? BEQ 30$ ; NO , SKIP MOV ENTRY,R0 ; YES, RESTORE ENTRY ADDRESS ADD #A.PRIV,R0 ; POINT TO PRIVLEGE MASK WORD MOV PRIV,(R0) ; INSERT NEW PRIVLEGE MASK WORD 30$: TST TSKFLG ; RESET TASK NAME BEQ 50$ ; NO, SO EXIT MOV ENTRY,R0 ; RESTORE POINTER ADD #A.TNAM,R0 ; POINT TO TASK NAME ENTRY MOV #6.,R2 ; SET COUNTER TO TRANSFER 6 CHARACTERS MOV #TASK,R1 ; GET ADDRESS OF NEW TASK NAME 35$: MOVB (R1)+,(R0)+ ; MOVE IN A CHARACTER SOB R2,35$ ; LOOP UNTIL ALL SIX CHARACTERS TRANSFERED ;50$: RETURN ; ALL DONE, RETURN 50$: TST BLKFLG ; SET ALLOWED # OF BLOCKS? BEQ 70$ ; NO, SO EXIT MOV ENTRY,R0 ; YES, RESTORE ENTRY ADDRESS ADD #A.ABLK,R0 ; POINT TO ALLOWED NUMBER OF BLOCKS MOV BLK,(R0) ; INSERT NEW ALLOWED BLOCK NUMBER 70$: RETURN ; ALL DONE , RETURN ;+ ; ; ***ZERO -- ZERO THE APPROPRIATE ACCOUNT ENTRIES ; R0 - INITIALLY POINTS TO START OF ACCOUNT ENTRY ; ; ;- ZERO: TST RSTFLG ; SEE IF TERMINAL LOGON FLAG TO BE ZEROED BEQ 10$ ; NO, GO SEE IF LOGONS TO BE ZEROED ADD #A.TERM,R0 ; POINT TO THE TERMINAL IN USE ENTRY FLAG MOV #0,(R0)+ ; ZERO FIRST WORD MOV #0,(R0) ; ZERO SECOND WORD MOV ENTRY,R0 ; RESTORE POINTER ; JGD03 ADD #A.VTRM,R0 ; POINT TO BATCH FLAG ; JGD03 CLR (R0) ; RESET TO ZERO ; JGD03 10$: TST LGNFLG ; SEE IF NUMBER OF LOGONS ARE TO BE ZEROED BEQ 20$ ; NO, SEE IF TERMINAL LOGON TIME TO BE ZEROED MOV ENTRY,R0 ; RESTORE POINTER TO ACCOUNT BLOCK ADD #A.NLOG,R0 ; POINT TO NUMBER OF LOGONS ENTRY MOV #0,(R0) ; ZERO THE ENTRY 20$: TST TIMFLG ; SHOULD WE ZERO THE TIME ENTRY BEQ 30$ ; NO, THEN EXIT MOV ENTRY,R0 ; RESET POINTER TO START OF ACCOUNT BLOCK ADD #A.CTIM,R0 ; POINT TO TOTAL CONNECT TIME MOV #0,(R0) ; ZERO IT OUT MOV ENTRY,R0 ; RESET POINTER TO START OF ACCOUNT BLOCK ; JGD02 ADD #A.CPU,R0 ; POINT TO TOTAL CPU TIME ; JGD02 MOV #0,(R0)+ ; ZERO IT OUT ; JGD02 MOV #0,(R0) ; ZERO OUT HIGH VAL FOR CPU TIME ALSO ; JGD02 30$: RETURN ; ALL DONE FOR NOW ;+ ; ***LOOP -- COMMON LOOP TO FILL IN CHARACTERS ; ; R0 - ADDRESS OF BUFFER CONTAINING CHARACTER ; R1 - ADDRESS OF BUFFER TO FILL ; R3 - NUMBER OF CHARACTERS TO TRANSFER ;- LOOP: MOVB (R0)+,(R1)+ ; MOVE CHARACTER INTO NAME DEC R3 ; DECREMENT COUNT BGT LOOP ; KEEP LOOPING IF MORE CHARACTERS LEFT RETURN ; OTHERWISE , RETURN .END $SETEP