MCKEEVER@UMKCVAX2.BITNET (07/27/87)
I was trying to pretty it up before I sent it out, but there are so many
requests on how to get the remote username and node name on the network that
I decided to send it out, and let hackers, techies, or whatever, taylor it
to their needs. Basically, the program scans the system, getting the PIDs
of each user on the system with a $GETJPI call. If the user is on an "RT"
terminal, the program uses Brad Wilson's kernel mode routine to get the JIB
number and the name of the users job logical name table. It then translates
the users SYS$REM_ID and SYS$REM_NODE logical names to get the remote
username and node name, respectively. I realize that the code is not the
most elegant in the world, I just hacked a program I wrote several months
ago when I was first learning MACRO just to see if it would work. Please
excuse any superfluous code. I intend to incorporate this program's
functionality into my OPMON (Operations Monitor) program so that operators
can know where people are coming from. Any comments from the wizzards on
the network on how to improve this program, or progress reports on how other
people are using the program are welcomed. I'm always willing to learn new
tricks.
BTW: My OPMON program is written in MACRO and uses SMG routine's to manage
menus and windows (I like to use SMuGgies). When I get it to the
stage that I wouldn't be ashamed of it of the messy, uncommented
code, I'll put a message out on the net and send it to interested
parties. It shows all interactive users, batch jobs, subprocesses,
detached jobs, and system processes, by catagory, at the same time.
And allows the operator to stop processes, suspend/resume processes,
watch a single process in detail...and a lot more. We find it quite
useful.
+-------------------CUT HERE--------------------------------------------+
$ Write Sys$Output " - Creating JIB.MAR"
$ Create JIB.MAR
$ Deck
.TITLE JP
;
.LIBRARY "SYS$LIBRARY:LIB"
.LINK "SYS$SYSTEM:SYS.STB"/SELECTIVE_SEARCH
;
$JPIDEF
$IODEF
$PCBDEF
$PRDEF
$IPLDEF
$lnmdef
;
.PSECT NONSHARED_DATA PIC, NOEXE, LONG, NOSHR
;
HEXPID: .BLKL 1
GRP: .LONG 0 ; Group UIC
MEM: .LONG 0 ; Member UIC
WILD_CARD: .LONG -1 ; Wildcard PID
HEXPID_RET: .WORD 4
GRP_RET: .WORD 4
MEM_RET: .WORD 4
CR = 13 ; Carriage return
LF = 10 ; Line feed
SYNCH: .LONG IPL$_SYNCH ; IPL level to sync access
;
USERNAME_LEN = 12
USERNAME_OUT = USERNAME_LEN + 1
USERNAME: .BLKB USERNAME_LEN
USERNAME_DSC: .LONG USERNAME_LEN
.ADDRESS USERNAME
;
IMAGE_LEN = 39
IMAGE_OUT = IMAGE_LEN + 1
IMAGE_FILE: .BLKB IMAGE_LEN
IMAGE: .LONG IMAGE_LEN
.ADDRESS IMAGE_FILE
;
UIC_LEN = 9
UIC_OUT = UIC_LEN + 2
UIC: .BLKB UIC_LEN
UIC_DSC: .LONG UIC_LEN
.ADDRESS UIC
;
CTRSTR_PID: .ASCID /!8XL/
CTRSTR_UIC: .ASCID /[!3OL,!3OL]/
JIB_CTRSTR: .ASCID "LNM$JOB_!8XL"
;
JIB_LEN = 16
JIB_OUT = JIB_LEN + 2
JIB: .BLKB JIB_LEN
JIB_DSC: .LONG JIB_LEN
.ADDRESS JIB
;
PID_LEN = 8
PID_OUT = PID_LEN + 2
PID: .BLKB PID_LEN
PID_DSC: .LONG PID_LEN
.ADDRESS PID
;
TERM_LEN = 7
TERM_OUT = TERM_LEN + 1
TERM_LOC: .BLKB TERM_LEN
TERM: .LONG TERM_LEN
.ADDRESS TERM_LOC
;
ARGLST:
.LONG 1
.ADDRESS HEXPID
HEXJIB: .LONG 0
EPID: .LONG 0
;
DETAIL_LEN = 81
DETAIL_END = DETAIL_LEN - 1
DETAIL_LINE: .BLKB DETAIL_LEN
DETAIL_DSC: .LONG DETAIL_LEN
.ADDRESS DETAIL_LINE
rt: .ascii "RT"
;
terminal_dsc: .ascid "TT:"
FILL_CHAR: .ASCII / /
;
trnlnm_list: .word 255, lnm$_string
.address actual_buf, actual_dsc
.long 0
;
index: .word 0
index_ret: .word 0
actual_dsc: .long 255
.address actual_buf
actual_buf: .blkb 255
;
rem_id: .ascid "SYS$REM_ID"
rem_node: .ascid "SYS$REM_NODE"
;
JPI_LIST: .WORD IMAGE_LEN, JPI$_IMAGNAME
.ADDRESS IMAGE_FILE, IMAGE
.WORD TERM_LEN, JPI$_TERMINAL
.ADDRESS TERM_LOC, TERM
.WORD 4, JPI$_GRP
.ADDRESS GRP, GRP_RET
.WORD USERNAME_LEN, JPI$_USERNAME
.ADDRESS USERNAME, USERNAME_DSC
.WORD 4, JPI$_PID
.ADDRESS HEXPID, HEXPID_RET
.WORD 4, JPI$_MEM
.ADDRESS MEM, MEM_RET
.LONG 0
;
.PSECT CODE PIC, SHR, NOWRT, LONG, EXE
.ENTRY BEGIN ^M<R2,R3,R4,R5,R6,R7,R8,R9,R10,R11>
;
; Start GETJPI loop.
;
LOOP: $GETJPI_S EFN=#1, PIDADR=Wild_Card, ITMLST=Jpi_List
BLBS R0, WAIT
CMPW R0, #SS$_NOPRIV
BEQL LOOP
CMPW R0, #SS$_SUSPENDED
BEQL LOOP
CMPW R0, #SS$_NOMOREPROC
BNEQ NO_JUMP
JMP DONE
NO_JUMP:
BRW ERROR_EXIT
;
WAIT:
$WAITFR_S EFN=#1
BLBS R0, 10$
BRW ERROR_EXIT
;
10$: CMPL GRP, #1
BGTR PRINT ; Not a system group number.
BRW LOOP ; Is a system group number.
PRINT:
;
; Format and Print current Terminal, Username, and Image.
;
; Let's try to call the KERNAL mode routine.
;
CALLG ARGLST, G^GETJIB
MOVL R0, HEXJIB
;
40$:
MOVAL DETAIL_LINE, R8
MOVC5 TERM, TERM_LOC, FILL_CHAR, #TERM_OUT, (R8)
ADDL2 #TERM_OUT, R8
MOVC5 USERNAME_DSC, USERNAME, FILL_CHAR, #USERNAME_OUT, (R8)
ADDL2 #USERNAME_OUT, R8
$FAO_S CTRSTR=CTRSTR_PID, OUTBUF=PID_DSC, P1=HEXPID
MOVC5 PID_DSC, PID, FILL_CHAR, #PID_OUT, (R8)
ADDL2 #PID_OUT, R8
$FAO_S CTRSTR=CTRSTR_UIC, OUTBUF=UIC_DSC, P1=GRP, P2=MEM
MOVC5 UIC_DSC, UIC, FILL_CHAR, #UIC_OUT, (R8)
ADDL2 #UIC_OUT, R8
$FAO_S CTRSTR=JIB_CTRSTR, OUTBUF=JIB_DSC, P1=HEXJIB
MOVC5 JIB_DSC, JIB, FILL_CHAR, #JIB_OUT, (R8)
ADDL2 #JIB_OUT, R8
MOVAL IMAGE_FILE, R6
;
LOCC #^A/]/, IMAGE, (R6) ; Locate the first right bracket.
BEQL 31$ ; Was it found.
ADDL3 #1, R1, R6 ; Save Location of good char.
SUBL3 #1, R0, R7
MOVL R0, R10
;
LOCC #^A/]/, R10, (R6) ; Locate the second right bracket.
BEQL 29$
ADDL3 #1, R1, R6 ; Save Location of good char.
SUBL3 #1, R0, R7
MOVL R0, R10
;
29$: MOVL R6, R11 ; Save last useable character.
LOCC #^A/./, R10, (R6) ; Locate the second right bracket.
BEQL 31$
MOVL R1, R6 ; Save Location of good char.
;
SUBL3 R11, R6, R7
MOVC3 R7, (R11), (R8)
ADDL2 R7, R8
31$:
SUBL3 #DETAIL_LINE, R8, DETAIL_DSC
PUSHAL DETAIL_DSC
CALLS #1, G^LIB$PUT_OUTPUT
BLBS R0, 20$
BRW ERROR_EXIT
20$:
OOPS:
cmpc3 #2, term_loc, rt
beql 99$
brw loop
99$:
$trnlnm_s tabnam=jib_dsc, lognam=rem_id, -
itmlst=trnlnm_list
blbs r0, 121$
brw error_exit
121$:
PUSHAL actual_dsc
CALLS #1, G^LIB$PUT_OUTPUT
BLBS R0, 122$
BRW ERROR_EXIT
122$:
$trnlnm_s tabnam=jib_dsc, lognam=rem_node, -
itmlst=trnlnm_list
blbs r0, 123$
brw error_exit
123$:
PUSHAL actual_dsc
calls #1, g^lib$put_output
blbs r0, 124$
brw error_exit
124$:
BRW LOOP ; Do it again.
;
DONE:
MOVL #1, R0
RET
;
ERROR_EXIT:
PUSHL R0
CALLS #1, G^LIB$STOP
RET
;
.END BEGIN
$ EOD
$ Write Sys$Output " - Creating GETJIB.MAR"
$ Create GetJib.Mar
$ Deck
.title GETJIB - get JIB address from EPID
;+
; Author: Brad Wilson
; Department of Chemistry
; Texas A&M University
; College Station, TX 77843
; BMW6957@TAMCHEM.BITNET
;
; VMS Version 4.x
;
; This routine will return the Job Information Block address for a process
; with a given External Process IDentification (EPID). The routine
; operates in kernel mode and requires CMKRNL privilege to execute.
; The calling sequence is:
;
; jib.wlv = getjib(epid.rlr)
;
; jib -- The longword JIB address or zero if an error occurred
; If the process does not have CMKRNL privilege, then
; the value SS$_NOPRIV will be returned here. Note
; that all valid JIB addresses are negative when
; interpreted as a signed value (JIB's reside in
; system P0 space) and this can be used to determine
; if the routine has returned a JIB or a status.
; epid -- The longword EPID of the process for which info is to
; be returned, passed by reference.
;
; NOTES:
;
; Portions of the following code execute at elevated IPL (IPL$_SYNCH).
; Since IPL is raised above IPL$_ASTDEL, page faults MUST NOT OCCUR!
; Anyone modifying the code below should understand the complete
; ramifications of this before proceeding. Important points to note
; are:
; 1) EXE$EPID_TO_PCB is located in non-paged memory, so
; references to it are safe.
; 2) The routine EXE$EPID_TO_PCB will not cause page
; faults (or so the microfiche claim) and is safe to
; call at elevated IPL.
; 3) The PCB structure is in non-paged pool and references
; to it will not cause page faults.
; 4) The DSBINT macro below uses a trick to ensure that
; the code here is all locked into the working set.
; In particular, since the macro references the
; longward "SYNCH", the instruction cannot execute
; until both the instruction AND the value at "SYNCH"
; are in the working set. As long as "SYNCH" and the
; DSBINT macro are less than one page apart, we are
; then guaranteed that all code lying between them
; is in the working set when the DSBINT macro raises
; IPL. Once the IPL has been raised, page faults
; cannot occur, so the code will remain in the
; working set until IPL is lowered by the ENBINT
; macro.
;-
;
.Library "SYS$LIBRARY:LIB" ;Get special macros from here
.Link "SYS$SYSTEM:SYS.STB"/Selective_Search ;Ease the link
; ;process a bit
;
$PCBDEF ; define PCB offsets
$PRDEF ; define privileged registers
$IPLDEF ; define IPL values
;
.Psect CODE,EXE,RD,NOWRT,PIC,SHR,PAGE
;
.entry getjib,^M<>
$cmkrnl_s routin=b^20$,arglst=(ap) ; change to kernel mode
ret ; return whatever k-mode does
;
20$: .WORD ^M<R2,R3,R4,R5> ; EXE$EPID_TO_PCB uses up to R5
CLRL R0 ; Assume an error
IFNORD #<2*4>,(AP),EXIT ; Probe the arglist for read
CMPB #1,(AP) ; Check for one argument
BNEQ EXIT ; Wrong number of arguments
IFNORD #4,@4(AP),EXIT ; Probe EPID for read
MOVL @4(AP),R0 ; Move EPID into R0
BEQL EXIT ; EPID was omitted, return
BEGIN_LOCK:
DSBINT SYNCH ; Raise IPL, lock pages
JSB @#EXE$EPID_TO_PCB ; convert EPID to PCB
BEQL 10$ ; oops, bad news
MOVL PCB$L_JIB(R0),R0 ; read JIB field of PCB
10$: ENBINT ; Lower IPL
EXIT: RET ; Return from kernel mode
SYNCH: .LONG IPL$_SYNCH ; IPL level to sync access
END_LOCK:
ASSUME <END_LOCK-BEGIN_LOCK> LE 512 ; ensure < 1 page locked
.end
$ EOD
$ Write Sys$Output " - MACROing JIB and GETJIB"
$ Macro JIB,GetJib
$ Write Sys$Output " - LINKing JIB and GETJIB"
$ Link/NoTrace JIB,GetJib
$ Type Sys$Input
Ok. JIB.EXE has been created. It's not elegant but it works.
With a little effort you should be able to pretty it up, or
include it in your own programs. Remember, you will need CMKRNL,
and SYSPRV before this thing works correctly. If you see a
job table name of LNM$JOB_00000024, you didn't have the privs you
needed to run the program. CMKRNL gives you the JIB and SYSPRV
allows you to look at someone elses job table. My thanks to
Brad Wilson for writing the kernel mode psect for me.
-------------------------------------------------------------------------
UMU UMUMUMUMUM Brian McKeever
UMU UMUMUMUMUM
UMU UMUMUMUMUM University of Missouri Kansas City
U UM U Computer Science
U UM UM UM 4747 Building Rm. 219
UMUMUMUM UMUM UMUM 5100 RockHill Rd.
UMUMUMUM UMUM UMUM Kansas City, MO 64110
UMUMUMUM UMUM UMUM BITNET: MCKEEVER@UMKCVAX1
-------------------------------------------------------------------------