.TITLE WHO - Who, What, & Where .IDENT /1.08/ .ENABL LC .NLIST BEX ; Description: WHO provides a display of logged-in terminals along with the ; default UIC and active tasks, if any, for each. An underscore ; (_) preceeding the UIC indicates a privileged user, preceeding ; the taskname indicates a privileged task. ; ; Invocation: WHO [device][/switch] ; device - display only device "dd[n]:" ; switch - /PR to display run priority for each task ; ; Written by: Steve Jobes, Mayo Clinic ; July, 1983 ; ; Modified from other versions of WHO on RSX SIG tapes. ; ; Maintenance: 26-APR-84 SLJ V1.07 a. Add support to request specific ; terminal and task priority ; b. Make sensative to buffer width ; 18-JUL-84 SLJ V1.08 Clean up code a little ; .MCALL ALUN$S,DIR$,EXIT$S,GMCR$,QIOW$ .MCALL DCBDF$,TCBDF$,UCBDF$ DCBDF$ TCBDF$ UCBDF$ GMCR: GMCR$ ; GMCR DPB QDPB: QIOW$ IO.WVB,1,1,,,,<,,40> ; QIO DPB B.PR = 1 ; Display priorities B.DV = 2 ; Specified device .PAGE START: ALUN$S #1,"TI,#0 ; Assign LUN MOV $TKTCB,R1 ; This TCB MOV T.UCB(R1),R1 ; This TCB's UCB MOV U.CW4(R1),R1 ; Buffer length SUB #15.,R1 ; Space for device & UIC ASR R1 ; Divide by eight ASR R1 ; to get maximum tasks ASR R1 ; per line MOV R1,MX ; Keep it here CLRB STAT ; Init status byte DIR$ GMCR ; Get MCR command line BCS READY ; None to get MOV #GMCR,R0 ; Addr of cmd line 10$: MOVB (R0)+,R2 ; Find first blank CMPB #15,R2 ; Carraige return ? BEQ READY ; Yes, EOL CMPB #33,R2 ; Escape ? BEQ READY ; Yes, EOL CMPB #40,R2 ; Space ? BNE 10$ ; No, keep looking 20$: MOVB (R0)+,R2 ; Find next non-blank CMPB #15,R2 ; Carraige return ? BEQ READY ; Yes, EOL CMPB #33,R2 ; Escape ? BEQ READY ; Yes, EOL CMPB #40,R2 ; Space ? BEQ 20$ ; Yes, keep looking CMPB #57,R2 ; Slash ? BEQ 40$ ; Yes, validate MOVB R2,REQDEV ; Assume device name requested MOVB (R0)+,REQDEV+1 ; 2nd character CALL $COTB ; Make unit binary MOV R1,REQUNI ; Unit number requested CMPB #72,R2 ; Find colon ? BNE 30$ ; No, error BIS #B.DV,STAT ; Yes, set flag BR 20$ ; Maybe a switch too 30$: MOV #QDPB,R4 ; QIO DPB MOV #ERM1,Q.IOPL(R4) ; Addr of error message MOV #ERM1L,Q.IOPL+2(R4) ; Length DIR$ R4 ; Display message EXIT$S 40$: CMPB #120,(R0)+ ; Is it "P" ? BNE 30$ ; No CMPB #122,(R0)+ ; Is it "PR" ? BNE 30$ ; No, error BIS #B.PR,STAT ; Yes, set flag ASR MX ; Half number tasks per line .PAGE READY: MOV $DEVHD,R5 ; 1st DCB 10$: MOVB D.UNIT+1(R5),R1 ; Calc number MOVB D.UNIT(R5),R2 ; of units SUB R2,R1 ; for INC R1 ; this DCB BEQ 20$ ; What ? MOV R1,UCBS ; Save number UCBs MOV R2,UCBUNI ; UCB unit number MOV D.UCB(R5),R3 ; 1st UCB CMP D.NAM(R5),#"TT ; Is it a terminal ? BEQ 40$ ; Yes .if df R$$MPL CMP D.NAM(R5),#"VT ; Is it a virtual terminal ? BEQ 40$ ; Yes .endc CMP D.NAM(R5),#"CO ; Is it CO: device ? BEQ 50$ ; Yes, won't be logged in 20$: MOV D.LNK(R5),R5 ; Point to next DCB BNE 10$ ; Another EXIT$S ; All done 30$: ADD D.UCBL(R5),R3 ; Offset to next UCB INC UCBUNI ; Inc UCB unit number DEC UCBS ; Another ? BEQ 20$ ; No more 40$: BIT #U2.LOG,U.CW2(R3) ; Is it logged in ? BNE 30$ ; No, not interested 50$: MOV UCBUNI,R1 ; This unit number BIT #B.DV,STAT ; Device specified ? BEQ 60$ ; No, proceed CMP D.NAM(R5),REQDEV ; Yes, does name match ? BNE 30$ ; No, not interested CMP R1,REQUNI ; Yes, unit match ? BNE 30$ ; No, not interested 60$: MOV #OB,R0 ; Addr output bufr MOV D.NAM(R5),(R0)+ ; Device name CLR R2 ; Zero suppression CALL $CBOMG ; Make unit ASCII MOVB #':,(R0)+ ; Colon CMP UCBUNI,#100 ; Three digit unit ? BLT 70$ ; No DEC R0 ; Yes, back up over colon 70$: MOVB #40,(R0)+ ; Space CMP UCBUNI,#7 ; One digit unit ? BGT 80$ ; No, proceed MOVB #40,(R0)+ ; Yes, another space 80$: BIT #U2.PRV,U.CW2(R3) ; Privileged user ? BEQ 90$ ; No MOVB #'_,-1(R0) ; Yes, flag it 90$: MOVB #'[,(R0)+ ; Left bracket MOVB U.UIC+1(R3),R1 ; Binary group CLR R2 ; Zero suppression CALL $CBTMG ; Make it ASCII MOVB #54,(R0)+ ; Comma MOVB U.UIC(R3),R1 ; Binary member CLR R2 ; Zero suppression CALL $CBTMG ; Make it ASCII MOVB #'],(R0)+ ; Right bracket CALL $SWSTK,140$ ; Switch to System state CLR TC ;; Init task counter MOV $TSKHD,R4 ;; 1st task name 100$: CMP T.UCB(R4),R3 ;; Belong to this UCB ? BNE 130$ ;; No, next task BIT #TS.EXE,T.STAT(R4) ;; Is it active ? BNE 130$ ;; No, next task CMP TC,MX ;; Yes, how many so far ? BLT 110$ ;; Fewer than maximum CLR TC ;; Full line, re-init counter MOVB #15,(R0)+ ;; Carriage return MOVB #12,(R0)+ ;; Line feed MOVB #11,(R0)+ ;; Tab 110$: INC TC ;; Increment counter MOVB #11,(R0)+ ;; Tab MOVB #40,(R0)+ ;; Space BIT #T3.PRV,T.ST3(R4) ;; Privileged task ? BEQ 120$ ;; No MOVB #'_,-1(R0) ;; Yes, flag it 120$: MOV T.NAM(R4),R1 ;; RAD50 task name (1st word) CALL $C5TA ;; Make it ASCII MOV T.NAM+2(R4),R1 ;; 2nd word CALL $C5TA ;; Make it ASCII BIT #B.PR,STAT ;; Request priorities ? BEQ 130$ ;; No, skip it MOVB #40,(R0)+ ;; Space CLR R1 ;; MOVB T.PRI(R4),R1 BISB T.PRI(R4),R1 ;; Priority BIC #177400,R1 CLR R2 ;; Zero suppression CALL $CBDMG ;; Make it ASCII MOVB #56,(R0)+ ;; Decimal 130$: MOV T.TCBL(R4),R4 ;; Next task TST T.TCBL(R4) ;; Done ? BNE 100$ ;; No, check it MOV R0,OBP ;; Output bufr pointer RETURN ;; Return to User state 140$: MOV #QDPB,R4 ; QIO DPB MOV #OB,Q.IOPL(R4) ; Addr of output bufr MOV OBP,R0 ; Output bufr pointer SUB #OB,R0 ; Calc length MOV R0,Q.IOPL+2(R4) ; Put it here DIR$ R4 ; Display message JMP 30$ ; Next .PAGE ; The size of the output buffer can be modified below according to the maximum ; number of tasks expected to be displayed per terminal. A buffer of 256 bytes ; will display about 17 tasks per terminal with priorities on an 80 column ; screen. OB: .BLKB 256. ; Output buffer OBP: .WORD 0 ; Output bufr pointer TC: .WORD 0 ; Task counter MX: .WORD 0 ; Maximum tasks per line UCBS: .WORD 0 ; Number of UCBs in current DCB UCBUNI: .WORD 0 ; UCB unit number REQDEV: .BLKB 2 ; Device name requested REQUNI: .WORD 0 ; Unit number requested STAT: .BYTE 0 ; Status ERM1: .ASCII /WHO -- Syntax error/ ERM1L =.-ERM1 .END START