.TITLE BYE - MCR BYE COMMAND .IDENT /01.8X/ ; ; COPYRIGHT (C) 1976, 1977 ; DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE FOR USE ONLY ON A ; SINGLE COMPUTER SYSTEM AND MAY BE COPIED ONLY 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 EXCEPT FOR USE ON SUCH ; SYSTEM AND TO ONE WHO AGREES TO THESE LICENSE TERMS. TITLE ; TO AND OWNERSHIP OF THE SOFTWARE SHALL AT ALL TIMES REMAIN ; IN DEC. ; ; THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO CHANGE WITHOUT ; NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL ; EQUIPMENT CORPORATION. ; ; DEC ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ; ITS SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DEC. ; ; ; VERSION: 01.8X ; BY: H. LEV ; DATE: 7/15/75 ; ; MODIFIED: ; ; EB038 11-APR-77 CLEAN UP A BIT ; ; JGD01 INSERT TOTAL LOGONTIME INTO ACCOUNT FILE ; PREVENT PRIVLEDGED USER FROM LOGGING OFF ; IF LOGONS DISSABLED. DON'T LOG OFF USER ; IF ACCOUNT FILE BUSY. ; ; JGD04 PASS A REQUEST TO MCR TO UPDATE THE ACCOUNT ; FILE WITH THE NUMBER OF FILES AND DISK BLOCKS ; USED BY THE USER. THECOMMAND IS PASSED TO ...UPD ; WHICH MUST BE INSTALLED. DOCUMENTATION ON ; ...UPD IS CONTAINED IN THE FILE ACCBLK.MAC ; ; JGD05 IF BIT 4 IN U.PRV1 IS SET, TO NOT ABORT NON ; PRIVLEGED TASKS. ; ; JGD06 CHANGE ALL REFERENCES TO U.CW3 TO U.PRV1=U.LUIC-2 ; ; JGD07 MODIFICATIONS TO ALLOW ...SUB, BAT...(PSEUDO BATCH ; USING A VIRTUAL TERMINAL) TO WORK. ; 1) IF CAN'T FIND LOGIN FLAG OR ACCOUNT FILE ERROR ; DON'T PASS MESSAGE TO UPDATE DISK BLOCK USAGE ; SO THAT THE ACCOUNTING PACKAGE MAY BE USED ON ; SYSTEMS WITH MULTIPLEXERS. ; ; EB044 3-MAY-77 IMPROVE ABORT SUBROUTINE ; BLS012 12-JUN-77 IF NOT LOGGING OFF OF CO: OUTPUT ; MESSAGE WITH UIC AND TIME TO CO: ; ; BLS018 21-JUN-77 FIX BUG IF NOT MULTI-USER SYSTEM ; ; PL015 10-NOV-77 ADD SUPPORT FOR 3 DIGIT UNIT NUMBERS ; .MCALL MRKT$S,DIR$,EXIT$S,WTSE$S,QIO$,GMCR$,ABRT$ .MCALL CMKT$S,WTLO$S,GTIM$S,MTADF$,UCBDF$ ; JGD01 .MCALL GLUN$S,OPEN$U,CLOSE$,MRKT$ ; JGD01 MTADF$ ; DEFINE ANSI MAGTAPE DATA STRUCTURES UCBDF$ ; DEFINE TERMINAL UCB OFFSETS ; JGD06 .IFNDF D$$H11&D$$J11&D$$M11&D$$ZMD&D$$Z11 ; JGD06 U.PRV1=U.CW3 ; FOR SYSTEMS WITH ONLY DL11'S ; JGD06 .IFF ; JGD06 U.PRV1=U.LUIC-2 ; FOR SYSTEMS WITH MULTIPLEXERS ; JGD06 .ENDC ; JGD06 ; ;CONSTANTS ; LUN1=1 ; TI: LUN ; JGD01 LUN2=2 ; ACNT FILE LUN ; JGD01 EFN1=1 ; EVENT FLAG FOR ALL I/O ; JGD01 GLNBUF: .BLKW 6. ; GET LUN BUFFER ; JGD01 ENTRY: .WORD 0 ; ADDRESS OF ACCOUNT ENTRY ; JGD01 PRVFLG: .WORD 0 ; FLAG TO INDICATE TERMINAL SHOULD BE RESET PRIVLEGED ; JGD01 OPNERR: .WORD 0 ; ACCOUNT FILE OPEN ERROR FLAG ; JGD01 SKPFLG: .WORD 0 ; =0 ->UPDATE DISK BLOCK USAGE, =1->SKIP UPDATE ; JGD07 ; LOCAL DATA ; ATERS=24 ; DEFINE UCB OFFSET TO ADDITIONAL ; EB038 ; TERMINAL STATUS WORD ; EB038 ; ; ERROR MESSAGES ; .NLIST BEX ERR1: .ASCII <15>/BYE -- DEVICE / ERR1DV: .ASCIZ /XXNN: BEING DISMOUNTED/ MSG1: .ASCII <12>/XX-XXX-XX XX:XX / MSG1A: .ASCIZ /DDNN: LOGGED OFF/<15><12>/>/ MSG1B: .ASCIZ <15><12>/>/ ; TO SIGNAL BATCH ALL IS DONE ; JGD07 MSG2: .ASCIZ <15>/HAVE A GOOD MORNING/ MSG3: .ASCIZ <15>/HAVE A GOOD AFTERNOON/ MSG4: .ASCIZ <15>/HAVE A GOOD EVENING/ MSG5: .ASCIZ <15>/GO TO BED, YOU DESERVE A REST/ MSG6: .ASCIZ <15><12>/BYE -- STILL LOGGED ONTO FIRST TERMINAL?/<15><12><7>/>/ MSG7: .ASCIZ <15><12>/BYE -- ACCOUNT FILE BUSY -- TRY AGAIN/<15><12><7>/>/ ; JGD01 MSG8: .ASCIZ <15><12>/BYE -- PRIVILEGED LOGOFFS DISABLED/<15><12><7> ; JGD01 MSG9: .ASCIZ <15><12>/BYE -- ACCOUNT READ ERROR -- GET HELP!/<15><12><7>/>/ ; JGD01 MSG10: .ASCIZ <15><12>/BYE -- ACCOUNT FILE LOCKED -- TRY AGAIN!/<15><12><7>/>/; JGD01 LGOMSG: .ASCIZ /LOGOUT USER / ;BLS012 MONTH: .ASCII /JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC/ .LIST BEX ; ; INTERNAL MCR COMMANDS ; UPDAT: .ASCIZ %UPD XXXX:[GGG,MMM]PASWRD/UP%<15> ; JGD01 .EVEN DEASSN: .ASCIZ %ASN =/LOGIN%<15> ; DE-ASSIGN ALL LOGIN LOGICAL UNITS DMO: .ASCIZ /DMO XXNN:XXXXXX/<33> ; DISMOUNT ALL UNMOUNTED DEVICES NOHOLD: .BYTE 33,134,0 ; EXIT HOLD SCREEN MODE ESCAPE SEQUENCE .EVEN UCB: .WORD 0 ; UCB ADDRESS OF TI FDPB: QIO$ IO.RVB,LUN2,EFN1,,IOSB,,<$ACTBF,$BFLEN,,,1> ; JGD01 IOSB: .BLKW 2 ; IOSTATUS BLOCK ERRDPB: QIO$ IO.WVB,1,1,,IOSTAT,,<0,0,40> ; EB038 IOSTAT: .BLKW 2 ; I/O STATUS BLOCK ;**-1 MKT: MRKT$ 1,1,2 ; WAIT 1 SECOND ; JGD01 GMCR: GMCR$ ABRT: ABRT$ X TNAM = ABRT+2 ; TASK NAME TIMBUF: .BLKW 8. ; TIME BUFFER $BYEEP: DIR$ #GMCR ; GET MCR COMMAND LINE BIT #FE.MUP,$FMASK ; MULTI-USER PROTECTION SUPPORTED? BNE 2$ ; YES JMP BYEXIT ; NO, JUST EXIT ;BLS018 2$: MOV $TKTCB,R0 ; GET OUR TCB ADDRESS ;**-1 MOV T.UCB(R0),R0 ; GET TI UCB ADDRESS BIT #FE.NLG,$FMASK ; ARE LOGONS DISABLED ; JGD01 BEQ 201$ ; NO, SO CONTINUE ON WITH LOGOFF ; JGD01 BIT #U2.PRV,U.CW2(R0) ; IS TERMINAL PRIVLEGED ; JGD01 BEQ 201$ ; NO , SO CONTINUE WITH LOGOF ; JGD01 MOV #MSG8,R0 ; PRIVLEDGED, SO PRINT WARNING AND EXIT ; JGD01 CALL BYEERR ; WITHOUT LOGING OFF TERMINAL ; JGD01 EXIT$S ; EXIT ; JGD01 201$: MOV U.RED(R0),R0 ; FOLLOW REDIRECT POINTER CMP R0,U.RED(R0) ; END OF LIST? BNE 201$ ; NO, LOOP MOV R0,UCB ; YES, STORE TI UCB ADDRESS BIT #U2.PRV,U.CW2(R0) ; IS TERMINAL PRIVLEDGED ; JGD01 BEQ 210$ ; IF NOT PRIVLEDGED SKIP OVER ; JGD01 INC PRVFLG ; SET PRIVLEGE FLAG FOR LATER ; JGD01 210$: BIS #U2.SLV,U.CW2(R0) ; TEMPORARILY SLAVE TI ; EB038 BIT #U2.HLD,U.CW2(R0) ; IS TERMINAL IN HOLD SCREEN MODE? BEQ 3$ ; NO BIC #U2.HLD,U.CW2(R0) ; YES, CLEAR FLAG MOV #NOHOLD,R0 ; GET ESCAPE SEQUENCE TO CLEAR IT CLR ERRDPB+Q.IOPL+4 ; SET NO CARRIAGE CONTROL CALL BYEERR ; SEND IT OUT MOV #40,ERRDPB+Q.IOPL+4 ; RESET CARRIAGE CONTROL 3$: BIT #20,U.PRV1(R0) ; SHOULD WE SKIP ABOFTING TASKS ; JGD05 BNE 301$ ; IF NE, YES, SKIP TO END ; JGD05 CALL ABORT ; ABORT ALL ACTIVE TASKS FROM TI: ; JGD05 301$: MOV UCB,R0 ; GET TI UCB ADDRESS ; JGD05 BIS #U2.PRV,U.CW2(R0) ; SET PRIVILEGED IF NOT ALREADY 4$: MOV #DEASSN,R5 ; GET DEASSIGN COMMAND CALL GIVMCR ; GIVE IT TO MCR BCC 5$ ; OKAY CALL WAIT1 ; WAIT 1 SECOND BR 4$ ; TRY IT AGAIN 5$: CALL WAIT1 ; WAIT ONE SECOND MOV UCB,R0 ; GET TI UCB ADDRESS BIT #U2.AT.,U.CW2(R0) ; IS MCR DONE? BNE 5$ ; NO, WAIT SOME MORE BIC #U2.PRV,U.CW2(R0) ; SET TERMINAL NOT PRIVILEGED MOV $DEVHD,R5 ; GET FIRST DCB ADDRESS 10$: CLR R4 ; CLEAR FOR BISB ; PL015 CLR R3 ; ; PL015 BISB D.UNIT+1(R5),R4 ; GET HIGH UNIT ; PL015 BISB D.UNIT(R5),R3 ; GET LOW UNIT ; PL015 SUB R3,R4 ; COMPUTE NUMBER OF UNITS ON DCB ;**-2 MOV D.UCB(R5),R3 ; GET FIRST UCB ADDRESS 20$: CMP U.OWN(R3),UCB ; ALLOCATED TO OUR UCB? BNE 30$ ; NO BIT #DV.MNT,U.CW1(R3) ; MOUNTABLE DEVICE? BEQ 27$ ; NO BITB #US.MNT,U.STS(R3) ; YES, IS IT MOUNTED? BNE 27$ ; NO MOV #ERR1DV,R0 ; GET DEVICE TEXT ADDRESS MOVB #40,4(R0) ; PUT BLANK IN LAST POSITION MOV R3,-(SP) ; SAVE UCB ADDRESS CALL $FMTDV ; FORMAT DEVICE NAME MOV (SP)+,R3 ; RESTORE UCB ADDRESS MOV #ERR1,R0 ; GET ERROR MESSAGE ADDRESS CALL BYEERR ; PRINT IT MOV #DMO+4,R0 ; POINT TO DEVICE AREA MOV R3,-(SP) ; SAVE DEVICE UCB ADDRESS CALL $FMTDV ; FORMAT DEVICE NAME MOV (SP)+,R3 ; RESTORE UCB ADDRESS BITB #US.LAB,U.STS(R3) ; IS THIS ANSI MAGTAPE? BEQ 24$ ; NO MOV U.VCB(R3),R1 ; YES, GET VSCB ADDRESS MOV V.MVL(R1),R1 ; GET MOUNTED VOLUME LIST BEQ 24$ ; ZERO, NO MOUNTED VOLUMES 21$: CMP R3,M.UCB(R1) ; IS THIS THE UNIT WE WANT? BEQ 22$ ; YES MOV M.NXT(R1),R1 ; NO, GET NEXT MVL NODE BNE 21$ ; LOOP BR 24$ ; COULDN'T FIND IT 22$: MOV M.VIDP(R1),R1 ; GET ADDRESS OF VOLUME LABEL MOV #6.,R2 ; SET SIZE OF LABEL 23$: MOVB (R1)+,(R0)+ ; GET NEXT CHARACTER OF LABEL DEC R2 ; DONE? BGT 23$ ; NO, LOOP 24$: MOVB #33,(R0)+ ; SET TO NOT PROMPT CLRB (R0) ; SET END OF MESSAGE MOV R5,-(SP) ; SAVE R5 MOV #DMO,R5 ; GET ADDRESS OF COMMAND CALL GIVMCR ; GIVE IT TO MCR MOV (SP)+,R5 ; RESTORE R5 25$: CALL WAIT1 ; WAIT ONE SECOND BITB #US.MNT,U.STS(R3) ; IS IT STILL MOUNTED? BEQ 25$ ; YES, WAIT UNTIL ITS DISMOUNTED 27$: CLR U.OWN(R3) ; DEAALOCATE DEVICE BICB #US.PUB,U.ST2(R3) ; AND SET IT PRIVATE 30$: DEC R4 ; ALL UCBS CHECKED? BMI 40$ ; YES ADD D.UCBL(R5),R3 ; NO, POINT TO NEXT UCB BR 20$ ; LOOP 40$: MOV D.LNK(R5),R5 ; GET NEXT DCB BNE 10$ ; AND LOOP UNTIL END OF LIST GTIM$S #TIMBUF ; GET TIME AND FILL TIME BUFFER ; JGD01 CALL LOGOFF ; FIND ACCOUNT FOR TERMINAL AND UPDATE ; JGD01 ; THE TOTAL LOGON TIME IN MINUTES ; JGD01 TST OPNERR ; IF THE ACCOUNT FILE IS BUSY DON'T LOG OFF ; JGD01 ; USER. LET HIM TRY AGAIN ; JGD01 BEQ BYE1 ; ENTRY MADE INTO ACCOUNT FILE, SO PROCEED ; JGD01 ; TO LOG OFF TERMINAL ; JGD01 MOV UCB,R0 ; ACCOUNT FILE WAS LOCKED, SO SET TERMINAL ; JGD01 BIC #U2.SLV,U.CW2(R0) ; SO CAN TRY AGAIN, IE NON SLAVE ; JGD01 BIS #U2.PRV,U.CW2(R0) ; TEMPORARILY MAKE PRIVLEGE ; JGD01 TST PRVFLG ; SHOULD TERMINAL BE PRIVLEDGED ; JGD01 BGT 50$ ; YES, LEAVE PRIVLEGED AND EXIT ; JGD01 BIC #U2.PRV,U.CW2(R0) ; OTHERWISE SET NON PRIVLEDGED ; JGD01 50$: EXIT$S ; LET USER TRY AGAIN TO LOG OFF ; JGD01 BYE1: ;CALL LGOLOG ; LOG LOGOUT ON CO: ;BLS012 ; ROL -(SP) ; SAVE C-BIT FOR WAIT-CHECK ;BLS012 ; GTIM$S #TIMBUF ; GET TIME ;BLS012 TST SKPFLG ; IF>0, TI: IS VT:,MUST SKIP PRINTING EXIT MESSAGES ; JGD07 ; BGT 12$ ; IF GT, SKIP PRINTING ; JGD07 BEQ 8$ ; IF EQ, PRINT EXIT MESSAGES ; JGD07 MOV #MSG1B,R0 ; IS VT, SO PRINT '>' ON EXIT ; JGD07 BR 11$ ; CALL BYEERR TO PRINT MESSAGE ; JGD07 8$: MOV TIMBUF+6,R1 ; GET HOUR ;**-1 MOV #MSG5,R0 ; DEFAULT TO 0-6AM CMP R1,#6. ; IS IT 0-6AM? BLT 10$ ; YES MOV #MSG2,R0 ; NO, DEFAULT TO 6-12AM CMP R1,#12. ; IS IT 6-12AM? BLT 10$ ; YES MOV #MSG3,R0 ; NO, DEFAULT TO 0-6PM CMP R1,#18. ; IS IT 0-6PM? BLT 10$ ; YES MOV #MSG4,R0 ; NO, IT MUST BE 6-12PM 10$: CALL BYEERR ; PRINT MESSAGE MOV #MSG1+1,R0 ; GET BUFFER FOR TIME CALL DATTIM ; CONVERT TIME TO ASCII MOV UCB,R3 ; GET TI UCB ADDRESS MOV #MSG1A,R0 ; GET ADDRESS FOR DEVICE NAME MOV R0,R1 ; COPY IT ADD #3,R1 ; POINT TO AREA FOR LAST DIGIT OF UNIT NUMBER MOVB #40,(R1) ; AND BLANK MOVB (R1)+,(R1) ; IT OUT CALL $FMTDV ; FORMAT DEVICE NAME MOV #MSG1,R0 ; GET MESSAGE ADDRESS CLR ERRDPB+Q.IOPL+4 ; SET NO CARRIAGE CONTROL 11$: CALL BYEERR ; ISSUE IT 12$: MOV UCB,R0 ; GET TI UCB ADDRESS ; JGD07 CLR U.LUIC(R0) ; ZERO LOGIN PROTECTION UIC ; JGD04 BIT #100,U.PRV1(R0) ; IS BIT 6 OF THE PRIVLEGE MASK WORD SET ; JGD04 BEQ 25$ ; NO, SO DON'T UPDATE DISK BLOCK USAGE ; JGD04 TST SKPFLG ; SHOULD WE SKIP DISK BLOCK USAGE UPDATE ANYWAY ; JGD07 BNE 15$ ; IF NE, YES , DON'T SEND A MESSAGE TO ...UPD ; JGD07 MOV #UPDAT,R5 ; MOVE IN COMMAND TO UPDATE THE USERS ACCOUNT FILE ; JGD04 CALL GIVMCR ; GIVE IT TO MCR ; JGD04 15$: MOV UCB,R0 ; GET TI UCB ADDRESS ; JGD07 BIS #U2.LOG,U.CW2(R0) ; LOG TERMINAL OFF BIC #U2.SLV,U.CW2(R0) ; RESET TERMINAL STATUS ; EB038 CLR U.UIC(R0) ; ZERO DEFAULT UIC ;**-1 CLR U.LUIC(R0) ; ZERO LOGIN PROTECTION UIC ; ROR (SP)+ ; NEED TO WAIT ON CO:? ;BLS012 ; BCS 20$ ; IF CS NO ;BLS012 ; CALL $COWAT ; YES--WAIT FOR IT ;BLS012 20$: ;BLS012 MOV UCB,R0 ; GET TI: UCB ADDRESS ; JGD04 25$: BIS #U2.LOG,U.CW2(R0) ; LOG TERMINAL OFF ; JGD04 BIC #U2.SLV,U.CW2(R0) ; RESET TERMINAL STATUS ; JGD04 MOV $TKTCB,R1 ; GET OUR TCB ADDRESS ; JGD04 BIC #T3.MCR,T.ST3(R1) ; INHIBIT PROMPT FROM MCR BYEXIT: ; REF LABEL BLS018 30$: EXIT$S ; EXIT ;+ ; *** - ABORT - ABORT ALL NON-PRIVILEGED TASKS RUNNING FROM TI: ; ;- ABORT: CALL $SWSTK,40$ ; SWITCH TO SYSTEM STATE CLR TNAM ; SET NO TASK FOUND MOV $TSKHD,R5 ; GET START OF TASK LIST 20$: TST T.TCBL(R5) ; NULL TASK TCB? BEQ 30$ ; YES, DONE BIT #TS.EXE!TS.MSG,T.STAT(R5) ; TASK NOT ACTIVE OR BEING ABORTED? ; EB044 BNE 25$ ; YES, DO NOT ABORT IT ; EB044 CMP UCB,T.UCB(R5) ; RUNNING FROM TI:? BNE 25$ ; NO BIT #T2.HLT,T.ST2(R5) ; YES, IS IT BEING ABORTED? ; EB044 BNE 25$ ; YES ;**-1 BIT #T3.PRV!T3.SLV,T.ST3(R5) ; NO, PRIVILEGED OR SLAVED TASK? ; EB044 BNE 25$ ; YES, DON'T ABORT IT ;**-5 MOV T.NAM(R5),TNAM ; NO, GET TASK NAME MOV T.NAM+2(R5),TNAM+2 ; BR 30$ ; 25$: MOV T.TCBL(R5),R5 ; GET NEXT TCB BR 20$ ; TRY IT 30$: RETURN ; RETURN TO USER STATE 40$: TST TNAM ; ANY TASK FOUND TO ABORT? BEQ 50$ ; NO DIR$ #ABRT ; YES, ABORT IT BR ABORT ; AND TRY AGAIN 50$: RETURN ; ;BLS012 ;+ ;BLS012 ; *** LGOLOG - LOG LOGOUT ON CO: ;BLS012 ; ;BLS012 ; INPUTS: ;BLS012 ; ;BLS012 ; OUTPUTS: ;BLS012 ; CC MSG WAS OUTPUT--BE SURE TO CALL $COWAT BEFORE EXIT ;BLS012 ; CS MSG WAS NOT OUTPUT--DO NOT CALL $COWAT ;BLS012 ; ;BLS012 ;- ;BLS012 ;BLS012 LGOLOG: MOV $HEADR,R0 ; GET MY HEADER ADDRESS ;BLS012 MOV H.LUN+<*4>(R0),R0 ; GET LUN 3 (CO:) UCB ;BLS012 MOV UCB,R3 ; GET MY UCB ADDRESS ALSO ;BLS012 CMP U.RED(R0),R3 ; IS CO: REDIRECTED TO MY TI:? ;BLS012 BNE 20$ ; IF NE NO ;BLS012 SEC ; FLAG TO NOT WAIT FOR CO: ;BLS012 RETURN ; BACK TO CALLER WITH C SET ;BLS012 20$: MOV #$COBUF,R0 ; ADDRESS OF BUFFER ;BLS012 MOV #LGOMSG,R1 ; MSG TO STORE ;BLS012 30$: MOVB (R1)+,(R0)+ ; COPY MSG ;BLS012 BNE 30$ ; WATCH FOR NULL ;BLS012 DEC R0 ; OVERWRITE IT THO ;BLS012 MOVB #'[,(R0)+ ; START UIC ;BLS012 CLR R1 ; SET TO GET GRP ;BLS012 BISB U.LUIC+1(R3),R1 ; GET IT ;BLS012 CLR R2 ; SUPPRESS LDNG ZEROS ;BLS012 CALL $CBOMG ; CONVERT AND OUTPUT ;BLS012 MOVB #',,(R0)+ ; OUTPUT A COMMA ;BLS012 CLR R1 ; PREPARE TO GET MEM ;BLS012 BISB U.LUIC(R3),R1 ; GET IT ;BLS012 CLR R2 ; SUPPRESS LEADING ZEROES ;BLS012 CALL $CBOMG ; CONVERT AND OUTPUT ;BLS012 MOVB #'],(R0)+ ; TERMINATE UIC ;BLS012 MOVB #40,(R0)+ ; SET A SPACE ;BLS012 CALL $FMTDV ; SEND DEVICE NAME ;BLS012 CALLR $COLOG ; BEGIN OUTPUT TO CO: AND RETURN ;BLS012 GIVMCR: CALL $SWSTK,15$ ; SWITCH TO SYSTEM STATE MOV #84.,R1 ; SET LENGTH OF MCR BUFFER CALL $ALOCB ; TRY TO GET IT BCC 5$ ; GOT IT MOV @$HEADR,R0 ; GET OUR USER STACK POINTER INC 6(R0) ; SET USER MODE CS BR 15$ ; 5$: MOV R0,R1 ; COPY ADDRESS CLR (R0)+ ; ZERO LINK WORD MOV UCB,(R0)+ ; SET IT IN BUFFER 10$: MOVB (R5)+,(R0)+ ; MOVE IN COMMAND BNE 10$ ; LOOP TILL END MOV UCB,R4 ; GET TI UCB ADDRESS BIS #U2.AT.,U.CW2(R4) ; SET BIT TO SYNCHRONIZE WITH MCR CALL $QMCRL ; QUE COMMAND TO MCR 15$: RETURN ; RETURN TO USER STATE ;+ ; *** - BYEERR - ERROR MESSAGE PROCESSOR ; ; INPUT: ; R0 - MESSAGE ADDRESS ; ;- BYEERR: MOV R0,ERRDPB+Q.IOPL ; SET BUFFER ADDRESS MOV R0,R1 ; COPY BUFFER ADDRESS 10$: TSTB (R1)+ ; END OF MESSAGE? BNE 10$ ; NO, LOOP TIL END SUB R0,R1 ; COMPUTE MESSAGE LENGTH DEC R1 ; COMPENSATE MOV R1,ERRDPB+Q.IOPL+2 ; SET MESSAGE LENGTH MOV UCB,R1 ; GET TI: UCB ADDRESS ; EB038 BIC #201,U.CNT+2+ATERS(R1) ; FAKE A CONTROL/Q ; EB038 DIR$ #ERRDPB ; ISSUE MESSAGE BCS 20$ ; ERROR MRKT$S #2,#5,#2 ; SET TIMER FOR 5 SECONDS WTLO$S 0,#3 ; WAIT FOR I/O OR TIMER CMKT$S ; CANCEL TIMER CMPB #IS.SUC,IOSTAT ; I/O COMPLETE? BEQ 20$ ; YES MOV #IO.KIL,ERRDPB+2 ; NO, KILL IT DIR$ #ERRDPB ; WTSE$S #1 ; WAIT TILL DONE MOV #IO.WVB,ERRDPB+2 ; RESET FUNCTION CODE ; EB038 CALLR WAIT1 ; WAIT FOR KILLED I/O TO COMPLETE ; EB038 20$: RETURN ; ;**-1 ;+ ; *** - WAIT1 - WAIT ONE SECOND ;- WAIT1: MRKT$S #2,#1,#2 ; MARK TIME FOR ONE SECOND WTSE$S #2 ; WAIT FOR RING RETURN ; WAKE UP AND TELL CALLER ;+ ; *** - DATTIM - CONVERT DATE AND TIME TO ASCII ; ; INPUT: ; R0 - BUFFER ADDRESS ; TIMBUF - DATA RETURNED BY GTIM$ ; OUTPUT: ; R0 - UPDATED (16. CHARACTERS) ; R1, R2, R3 - USED ;- DATTIM: MOVB TIMBUF+4,R1 ; GET DAY CALL TWODEC ; CONVERT TO TWO DECIMAL DIGITS MOVB #'-,(R0)+ ; MOVB TIMBUF+2,R1 ; GET MONTH CALL GETMON ; CONVERT TO ASCII MOVB #'-,(R0)+ ; MOVB TIMBUF,R1 ; GET YEAR CALL TWODEC ; CONVERT TO TWO DECIMAL DIGITS MOVB #40,(R0)+ ; MOVB TIMBUF+6,R1 ; GET HOUR CALL TWODEC ; CONVERT TO TWO DECIMAL DIGITS MOVB #':,(R0)+ ; MOVB TIMBUF+10,R1 ; GET MINUTE CALL TWODEC ; CONVERT TO TWO DECIMAL DIGITS MOVB #40,(R0)+ ; RETURN ; ;+ ; *** - TWODEC - CONVERT BINARY NUMBER TO TWO DECIMAL DIGITS ; ; INPUT: ; R0 - BUFFER ADDRESS ; R1 - BINARY NUMBER TO BE CONVERTED ; OUTPUT: ; R0 - UPDATED ; R1, R2, AND R3 USED ;- TWODEC: CMP R1,#10. ; >= 10.? BGE 10$ ; YES MOVB #'0,(R0)+ ; NO, PUT IN LEADING ZERO 10$: CLR R2 ; SET TO SUPPRESS LEADING ZEROES CALL $CBDMG ; CONVERT TO DECIMAL RETURN ; ;+ ; *** - GETMON - CONVERT MONTH TO ASCII ; ; INPUT: ; R0 - BUFFER ADDRESS ; R1 - MONTH (1-12) ; OUTPUT: ; R0 - UPDATED ; R1, R2 USED ;- GETMON: DEC R1 ; CONVERT TO INDEX MOV R1,R2 ; COPY IT ADD R2,R1 ; MULTIPLY BY ADD R2,R1 ; THREE ADD #MONTH,R1 ; GET ADDRESS OF MONTH IN ASCII MOVB (R1)+,(R0)+ ; MOVE MONTH MOVB (R1)+,(R0)+ ; INTO BUFFER MOVB (R1),(R0)+ ; RETURN ; ;+ ; JGD01 ; *** -LOGOFF - OPEN ACCOUNT FILE, COMPUTE LOGON TIME FOR THIS TERMINAL ; JGD01 ; SESSION(MINUTES), AND ADD TO ACCOUNT FILE VALUE ; JGD01 ;- ; JGD01 LOGOFF: CLR ENTRY ; ZERO ACCOUNT FILE ENTRY POINT ; JGD01 CLR OPNERR ; SET OPEN ERROR FLAG INITIALLY TO "NO ERROR" ; JGD01 GLUN$S #LUN1,#GLNBUF ; GET TERMINAL NUMBER ; JGD01 CMP #"VT,GLNBUF ; ARE WE TRYING TO LOG OFF OF VIRTUAL TERMINAL? ; JGD07 BNE 50$ ; NO, PROCEED AS ALWAYS ; JGD07 INC SKPFLG ; YES, SET FLAG SO AS NOT TO UPDATE ACCOUNT ; JGD07 BR 100$ ; AND RETURN, POSTHASTE ; JGD07 50$: CALL OPEN ; OPEN [0,0]RSX11.SYS--THE ACCOUNT FILE ; JGD07 BCS 100$ ; SKIP ALL THE REST IF THE FILE WON'T OPEN ; JGD01 CALL SEARCH ; SEARCH ACCOUNT FILE FOR CURRENT ACCOUNT ; JGD01 ; LOGGED ONTO THIS TERMINAL ; JGD01 BCS 100$ ; DIDN'T FIND TI# IN ACNT ; JGD01 CALL UPDATE ; COMPUTE LOGON TIME FOR THIS TERMINAL ; JGD01 ; AND ADD IT TO TOTAL IN ACCOUNT FILE ; JGD01 BCS 100$ ; DON'T CLOSE HERE IF FILE LOCKED ; JGD01 CALL CLOSE ; CLOSE THE FILE ; JGD01 100$: RETURN ; RETURN AND FINISH LOGGING OFF ; JGD01 ;+ ; JGD01 ; *** - OPEN - OPEN [0,0]RSX11.SYS FOR UPDATE ; JGD01 ;- ; JGD01 OPEN: OPEN$U #$ACTFL,,,#FD.RWM ;OPEN [0,0]RSX11.SYS FOR UPDATE ; JGD01 BCC 50$ ; CARRY CLEAR IMPLIES FILE OPEN ; JGD01 ; IF SET-->FILE LOCKED, BUSY,OR FCS ERROR ; JGD01 CMP OPNERR,#5 ; FIVE FAILURES? ; JGD01 BLT 25$ ; NO, LETS TRY OPENING IT AGAIN ; JGD01 20$: MOV #MSG7,R0 ; YES, LOOKS LIKE ACCOUNT FILE BUSY ; JGD01 CALL BYEERR ; PRINT MESSAGE TO TRY LOGGING OFF AGAIN ; JGD01 ; UNLESS LOGGING OFF SUCESSFUL, A NONPRIVLEDGED ; JGD01 ; USER CAN'T LOG ON AGAIN(VIA HELLO) ; JGD01 SEC ; SET "CARRY" TO DECLARE FAILURE ; JGD01 RETURN ; TRYING TO UPDATE THE ACCOUNT FILE ; JGD01 25$: DIR$ #MKT ; MAYBE FILE IS BUSY, WAIT ONE SECOND ; JGD01 BCS 20$ ; ERROR?, TRY LOGGING OFF LATER, MARK TIMES ; JGD01 ; SHOULD WORK! ; JGD01 WTSE$S #1 ; WAIT FOR MARK TIME TO COMPLETE AND SET EFN 1 ; JGD01 INC OPNERR ; INCREMENT # OF TIMES TRIED ; JGD01 BR OPEN ; LETS TRY AGAIN ; JGD01 50$: CLR OPNERR ; RESET ERROR FLAG TO NO ERROR ; JGD01 RETURN ; ALL DONE GO BACK ; JGD01 ;+ ; JGD01 ; *** - QIO - ISSUE QIO ; JGD01 ; ; JGD01 ; INPUT: ; JGD01 ; R4 - DPB ADDRESS ; JGD01 ; ; JGD01 ;- ; JGD01 QIO: DIR$ R4 ; ISSUE QIO ; JGD01 BCS 10$ ; ERROR ; JGD01 MOVB Q.IOEF(R4),R5 ; GET EVENT FLAG TO WAIT ON ; JGD01 WTSE$S R5 ; WAIT FOR I/O COMPLETION ; JGD01 10$: RETURN ; ; JGD01 ;+ ; JGD01 ; ** - CLOSE - CLOSE THE ACCOUNT FILE ; JGD01 ;- ; JGD01 CLOSE: CLOSE$ #$ACTFL ; CLOSE ACCOUNT FILE ; JGD01 RETURN ; ; JGD01 ;+ ; JGD01 ; *** - SEARCH - SEARCH FILE FOR LOGED ON TERMINAL ; JGD01 ; ; JGD01 ; OUTPUT: ; JGD01 ; R0 - ADDRESS OF ACCOUNT ENTRY ; JGD01 ; ENTRY - ADDRESS OF START OF ACCOUNT BLOCK IN BUFFER ; JGD01 ; CARRY CLEAR - ACCOUNT FOUND ; JGD01 ; CARRY SET - ACCOUNT NOT FOUND ; JGD01 ;- ; JGD01 SEARCH: MOV #FDPB,R4 ; GET FILE DPB ADDRESS ; JGD01 MOV #1,Q.IOPL+10(R4) ; SET TO START AT VBN 1 ; JGD01 CLR Q.IOPL+6(R4) ; ; JGD01 5$: CALL QIO ; READ NEXT BLOCK ; JGD01 MOV IOSB+2,R2 ; GET COUNT OF WORDS READ ; JGD01 BEQ 25$ ; ZERO, NO WORDS READ ; JGD01 MOV #$ACTBF,R0 ; GET BUFFER ADDRESS ; JGD01 10$: MOV R0,ENTRY ; YES, SAVE ENTRY ADDRESS ; JGD01 ADD #A.TERM,R0 ; POINT ADDRESS AT TT ENTRY ; JGD01 INC R0 ; POINT ADDRESS AT TERMINAL # ; JGD01 INC R0 ; ; JGD01 CMP GLNBUF+2,(R0) ; IS ACNT ENTRY THE SAME AS TI'S #? ; JGD01 BNE 20$ ; NO, KEEP GOING ; JGD01 MOV ENTRY,R0 ; YES, THEN RESTORE ENTRY ADDRESS ; JGD01 JMP 40$ ; FOUND TERMINAL NUMBER ; JGD01 20$: MOV ENTRY,R0 ; RESTORE ENTRY POINTER ; JGD01 ADD #A.LEN,R0 ; POINT TO NEXT ENTRY ; JGD01 SUB #A.LEN,R2 ; COMPUTE WORDS LEFT IN BUFFER ; JGD01 BHI 10$ ; LOOP, MORE LEFT ; JGD01 25$: CMPB #IE.EOF,IOSB ; END OF FILE? ; JGD01 BEQ 50$ ; YES(MUST HAVE LOGGED OFF BEFORE) ; JGD01 ; BUT PRIVLEDGED USERS MAY DO THIS ; JGD01 TSTB IOSB ; ANY ERRORS? ; JGD01 BMI 60$ ; YES(A READ ERROR?) ; JGD01 ADD #$BFLEN/512.,Q.IOPL+10(R4) ; NO, POINT TO NEXT VBN ; JGD01 ADC Q.IOPL+6(R4) ; ; JGD01 JMP 5$ ; READ IN NEXT BUFFER ; JGD01 40$: RETURN ; ; JGD01 50$: CALL CLOSE ; CLOSE THE ACCOUNT FILE ; JGD01 MOV #MSG6,R0 ; USER COULD BE LOGGED ONTO OTHER TERMINAL ALSO ; JGD01 ; OR ACCOUNT FILE GOT SCRAMBLED ; JGD01 55$: CALL BYEERR ; WARN USER ; JGD01 INC SKPFLG ; IF ANY ERROR, OR ACCOUNT NOT FOUND DO NOT ; JGD07 ; TRY AND UPDATE DISK BLOCK USAGE ; JGD07 SEC ; BE SURE TO SKIP UPDATE PART("TTN" NOT ZEROED) ; JGD01 ; IF A READ ERROR FOUND OR IF THE "TTN" ENTRY ; JGD01 ; INTO THE ACCOUNT FILE IS NOT FOUND, LOG OFF ; JGD01 ; THE USER. A PRIVLEDGED USER CAN GET BACK ON ; JGD01 ; AND UNLOCK A NONPRIVLEDGED ACCOUNT ; JGD01 RETURN ; RETURN ; JGD01 60$: CALL CLOSE ; ACCOUNT FILE READ FAILURE, LOG OFF AND ; JGD01 ; GET HELP ; JGD01 MOV #MSG9,R0 ; PRINT -- FILE READ FAILURE ; JGD01 BR 55$ ; PRINT ERROR MESSAGE AND EXIT ; JGD01 ;+ ; JGD01 ; *** - UPDATE -- ADD CURRENT TERMINAL LOGON TIME TO TOTAL TIME ; JGD01 ; IN DATA FILE ; JGD01 ;- ; JGD01 UPDATE: MOV #FDPB,R4 ; GET THE FILE DPB ADDRESS ; JGD01 MOV #IO.WVB,2(R4) ; SET QIO FOR WRITE TO FILE ; JGD01 MOV IOSB+2,Q.IOPL+2(R4) ; SET COUNT OF BYTES TO WRITE ; JGD01 MOV ENTRY,R0 ; POINT TO START OF ACCOUNT FILE ; JGD04 ADD #A.SYDV,R0 ; POINT TO DEVICE NAME ; JGD04 MOVB (R0)+,UPDAT+4 ; MOVE IN THE DEVICE NAME ; JGD04 MOVB (R0)+,UPDAT+5 ; ; JGD04 MOVB (R0)+,UPDAT+6 ; ; JGD04 MOVB (R0)+,UPDAT+7 ; ALL 4 CHARACTERS ; JGD04 MOV ENTRY,R0 ; RESTORE POINTER ; JGD04 ADD #A.GRP,R0 ; POINT TO GROUP ENTRY ; JGD04 MOVB (R0)+,UPDAT+10. ; MOVE IN THE GROUP CODE ; JGD04 MOVB (R0)+,UPDAT+11. ; ; JGD04 MOVB (R0)+,UPDAT+12. ; ; JGD04 MOVB (R0)+,UPDAT+14. ; MOVE IN THE MEMBER CODE ; JGD04 MOVB (R0)+,UPDAT+15. ; ; JGD04 MOVB (R0)+,UPDAT+16. ; ALL DONE ; JGD04 MOV ENTRY,R0 ; RESET POINTER TO START OF ACCOUNT BLOCK ; JGD04 ADD #A.PSWD,R0 ; POINT TO PASSWORD ENTRY ; JGD04 MOVB (R0)+,UPDAT+18. ; MOVE IN THE 6 LETTER PASSWORD ; JGD04 MOVB (R0)+,UPDAT+19. ; ; JGD04 MOVB (R0)+,UPDAT+20. ; ; JGD04 MOVB (R0)+,UPDAT+21. ; ; JGD04 MOVB (R0)+,UPDAT+22. ; ; JGD04 MOVB (R0)+,UPDAT+23. ; ALL DONE ; JGD04 MOV ENTRY,R0 ; GET ADDRESS OF ACCOUNT ENTRY ; JGD01 ADD #A.TERM,R0 ; POINT TO TERMINAL NUMBER ENTRY ; JGD01 CLR (R0)+ ; REMOVE "TT" ENTRY FROM FILE ; JGD01 CLR (R0) ; REMOVE TERMINAL NUMBER FROM FILE ; JGD01 MOVB TIMBUF+4,R1 ; GET DAY, TO BE SURE LOGOFF IS ON SAME DAY ; JGD01 MOV ENTRY,R0 ; AS LOGON. GET ADDRESS OF ACCOUNT ENTRY ; JGD01 ADD #A.LDAT,R0 ; POINT TO DATE ENTRY ; JGD01 CMPB (R0),R1 ; IF DATES NOT EQUAL, DON'T ADD TIME TO ACNT ; JGD01 BNE 10$ ; NOT EQUAL SO ONLY ZERO TERMINAL NUMBER ; JGD01 ; AND LOG OFF ; JGD01 MOVB TIMBUF+6,R1 ; GET HOUR AT WHICH TERMINAL LOGGED OFF ; JGD01 MUL #74,R1 ; MULTIPLY BY 60 TO PUT IN MINUITS ; JGD01 MOVB TIMBUF+10,R0 ; GET MINUITES AT LOGOFF ; JGD01 ADD R0,R1 ; ADD TO GET THE TOTAL CLOCK MINUITS ; JGD01 MOV ENTRY,R0 ; GET ADDRESS OF ACCOUNT FILE ENTRY ; JGD01 ADD #A.LDAT+2,R0 ; POINT TO THE HOUR/YEAR WORD ; JGD01 INC R0 ; POINT TO HOUR-THE HIGH BYTE ; JGD01 MOVB (R0)+,R3 ; SAVE THE HOUR ; JGD01 MUL #74,R3 ; CONVERT TO MINUITS ; JGD01 MOVB (R0),R2 ; GET MINUITS AT LOGON TIME ; JGD01 ADD R2,R3 ; COMPUTE TOTAL CLOCK MINUITS AT LOGON ; JGD01 SUB R3,R1 ; GET TOTAL TIME LOGGED AT TERMINAL THIS TIME ; JGD01 MOV ENTRY,R0 ; RESTORE FILE ADDRESS ; JGD01 ADD #A.CTIM,R0 ; POINT TO TOTAL CONNECT TIME ENTRY ; JGD01 ADD (R0),R1 ; ADD LOGON TIME TO TOTAL CONNECT TIME ; JGD01 BVS 10$ ; IF ACCOUNT WOULD OVERFLOW DON'T ADD MORE IN ; JGD01 MOV R1,(R0) ; OTHERWISE, INSERT INTO THE ACCOUNT FILE ; JGD01 10$: CALL QIO ; WRITE OUT THE UPDATED ACCOUNT BLOCK ; JGD01 TSTB IOSB ; CHECK TO SEE IF ERROR ON WRITE TO ACNT ; JGD01 ; THIS GUARDS AGAINST DK0: BEING WRITE LOCKED ; JGD01 BGT 20$ ; NO ERROR IF >0, SO SKIP OVER THE NEXT LINES ; JGD01 INC OPNERR ; SET OPNERR AS FLAG SO WON'T LOG OFF TERMINAL ; JGD01 CALL CLOSE ; CLOSE THE FILE FAST, THE DISK IS WRITE LOCKED ; JGD01 MOV #MSG10,R0 ; WARN THE USER THAT ACCOUNT IS WRITE LOCKED ; JGD01 CALL BYEERR ; PRINT OUT THE MESSAGE ; JGD01 SEC ; SET CARRY TO FLAG ERROR ; JGD01 20$: MOV #IO.RVB,2(R4) ; RESTORE THE DPB ; JGD01 MOV #$BFLEN,Q.IOPL+2(R4) ; AND THE BUFFER LENGTH ; JGD01 RETURN ; ; JGD01 .END $BYEEP ;