.TITLE GETLOG - GET LOGGED ON USERS .IDENT /1.0/ .ENABL LC ;+ ; ; Free software BY ; Project Software & Development, Inc. ; ; This software is furnished for free and may be used and copied as ; desired. This software or any other copies thereof may be provided or ; otherwise made available to any other person. No title to and ; ownership of the software is hereby transferred or allowed. ; ; The information in this software is subject to change without notice ; and should not be construed as a commitment by PROJECT SOFTWARE ; AND DEVELOPMENT, INC. ; ; PROJECT SOFTWARE assumes no responsibility for the use or reliability ; of this software on any equipment whatsoever. ; ; Project Software & Development, Inc. ; 14 Story St. ; Cambridge, Ma. 02138 ; 617-661-1444 ; ; ; Title: GETLOG ; Author: Robin Miller ; Date: July 27, 1982 ; ; Description: ; ; This module searches through the system tables to generate a list ; of all the logged on terminals. It also calls a routine to ensure we ; are running on the correct Executive by checking the bit mask ($BTMSK) ; in system common. ; ; Modification History: ; ;- .ENABL AMA .NLIST BEX .MCALL DCBDF$, HDRDF$, SCBDF$, UCBDF$ DCBDF$ ; DEFINE DCB OFFSETS HDRDF$ ; DEFINE TASK HEADER OFFSETS SCBDF$ ; DEFINE SCB OFFSETS UCBDF$ ; DEFINE UCB OFFSETS ; Macro to generate error messages. .MACRO ERRMSG LABEL,MSG .NCHR $$$, .PSECT $ERMSG,RO,D,REL,CON LABEL: .ASCII "MSG" .EVEN .PSECT MOV #LABEL,R1 MOV #$$$,R2 CALL OUTMSG .ENDM ; Local equates: BELL = 7 ; ASCII FOR BELL ; Local storage: TTNAME: .ASCII /TT/ ; NAME OF UCB TO FIND .WORD 0 ; UNIT NUMBER TO FIND .SBTTL GETLOG - GET A LIST OF LOGGED ON TERMINALS ;+ ; ; GETLOG - Get a list of all logged on terminals. ; ; Inputs: ; R5 = address of storage buffer. ; ; Outputs: ; R0 = the number of terminals logged on. ; R5 filled with entrys of the form: ; .WORD logon_uic ; .WORD terminal_number ; . ; . ; .WORD -1 ; END OF TABLE ; ; Registers R1 - R5 are preserved. ; ;- GETLOG::CALL $SAVAL ; SAVE ALL REGISTERS CALL CKEXEC ; CHECK THE EXECUTIVE CLR R0 ; INITIALIZE LOGGED ON COUNT CLR R2 ; SHOW WE DON'T HAVE A DCB YET MOV #TTNAME,R3 ; TERMINAL DESCRIPTION BLOCK CLR 2(R3) ; START WITH TT0: ; Get the terminal UCB address and check logged on status. 20$: CALL GETUCB ; GET THE TERMINAL'S UCB BCS 100$ ; IF CS, END OF TERMINAL UCB'S BIT #U2.LOG,U.CW2(R1) ; IS THIS TERMINAL LOGGED IN ? BNE 30$ ; IF NE, NO (TRY NEXT) ; Make an entry in the user buffer for this terminal. INC R0 ; COUNT THIS TERMINAL MOV 2(R3),(R5)+ ; COPY THE TERMINAL NUMBER MOV U.LUIC(R1),(R5)+ ; COPY THE LOGIN UIC 30$: INC 2(R3) ; POINT TO NEXT TERMINAL # BR 20$ ; AND TRY TO GET NEXT UCB 100$: MOV #-1,(R5) ; SHOW END OF TABLE MOV R0,2(SP) ; PASS BACK NEW R0 RETURN .SBTTL GETUCB - GET A UNIT CONTROL BLOCK (UCB) ADDRESS ;+ ; ; GETUCB -- Get a Unit Control Block (UCB) address. ; ; Inputs: ; R2 = the DCB address. ; R3 = Address of 2-word descriptor with format: ; (R3) = ASCII mneumonic. ; 2(R3) = unit number. ; ; Outputs: ; R1 = Address of the UCB. ; R2 = Address of the DCB. ; ; Registers R3 - R5 are preserved. ; ;- GETUCB: JSR R5,$SAVRG ; SAVE REGISTERS R3 - R5 CMP 2(R3),#256. ; IS UNIT # IN RANGE ? BLO 10$ ; IF LO, YES (PROCEED) SEC ; NO, SHOW IT AIN'T BR 100$ ; AND RETURN ... ;+ ; ; While in system state, the system stack contains: ; ; 20(SP) = PS pushed by EMT trap. ; 16(SP) = PC pushed by EMT trap. ; 14(SP) = Saved R5. (Users registers). ; 12(SP) = Saved R4. " " ; 10(SP) = Saved R3. " " ; 06(SP) = Saved R2. " " ; 04(SP) = Saved R1. " " ; 02(SP) = Saved R0. " " ; 00(SP) = Return address for system exit. ; ;- 10$: CALL $SWSTK,100$ ; SWITCH TO SYSTEM STATE MOV 6(SP),R2 ;; GET THE USER'S R2 BNE 12$ ;; IF NE, ALREADY GOT A DCB MOV $DEVHD,R2 ;; GET ADDRESS OF DEVICE TABLE ; Find the specified DCB. 12$: CMP (R3),D.NAM(R2) ;; IS THIS THE DESIRED DCB ? BEQ 20$ ;; IF EQ, YES (CHECK UNIT) 15$: MOV D.LNK(R2),R2 ;; NO, POINT TO NEXT DCB BNE 12$ ;; IF NE, GOT ONE BEQ 50$ ;; END OF DEVICES, ERROR ; Found the desired DCB. 20$: MOV 2(R3),R5 ;; GET THE UNIT NUMBER CMPB R5,D.UNIT(R2) ;; IS UNIT ON THIS DCB ? BLO 15$ ;; IF LO, NO (NEXT DCB) CMPB R5,D.UNIT+1(R2) ;; MAYBE, IS IT REALLY ? BHI 15$ ;; IF HI, NO (NEXT DCB) MOVB D.UNIT(R2),R4 ;; GET FIRST UNIT NUMBER MOV D.UCB(R2),R1 ;; GET FIRST UCB ADDRESS SUB R4,R5 ;; COMPUTE RELATIVE UNIT NUMBER BEQ 45$ ;; IF EQ, THIS IS THE ONE 30$: ADD D.UCBL(R2),R1 ;; ELSE, POINT TO NEXT UCB DEC R5 ;; FOUND IT YET ? BNE 30$ ;; IF NE, NO (LOOP) ; Found a UCB with the specified unit number. 45$: MOV R1,4(SP) ;; SET USER R1 MOV R2,6(SP) ;; SET USER R2 RETURN ;; RETURN TO USER STATE ; End of DCB's, set carry bit in users PSW to show error. 50$: MOV @$HEADR,R3 ;; GET USER SP INCB 6(R3) ;; SET CARRY IN USER PS RETURN ;; RETURN TO USER STATE 100$: RETURN .SBTTL CKEXEC -- CHECK FOR CORRECT EXECUTIVE ;+ ; ; CKEXEC - Check for correct Executive. ; ; This routine checks a series of locations in the Executive starting ; at label $BTMSK. There are 16 words which will be checked. Each ; word corresponds to a bit position. For example, word 0 = 1, ; word 1 = 2, word 2 = 4, word 3 = 10, etc. ; ; Inputs: ; None ; ; Outputs: ; Returns if correct Executive, else report error and exit. ; ; All registers are preserved. ; ;- CKEXEC: JSR R2,$SAVVR ; SAVE R0 - R2 MOV #1,R0 ; START AT BIT 0 MOV #$BTMSK,R1 ; ADDRESS OF BIT MAP MOV #16.,R2 ; ITERATION COUNT 10$: CMP R0,(R1)+ ; DO WE HAVE A MATCH ? BNE 20$ ; IF NE, NO ASL R0 ; NEXT BIT THEN SOB R2,10$ ; LOOP TILL DONE RETURN ; MADE IT ; Write the message and exit. 20$: ERRMSG WRONG,<%USERS-FATAL, built with wrong Executive symbol table.> JMP EXIT ; USE COMMON EXIT .END