bmw6957@TAMCHEM.BITNET (Brad Wilson) (07/15/87)
> Does anyone have a program to return the remote node and id of a process > that has logged in via SET HOST ? > > I can get this information about the CURRENT process via the logical names > SYS$REM_NODE and SYS$REM_ID in the job logical name table, but how can I > access the job table of another process ? It appears that job tables have > names of the form LNM$JOB_<jib> where <jib> is the value of PCB$L_JIB in the > process's Process Control Block, but I don't have enough "internals" experienc > to get at other process's PCBs. If someone has a piece of code to get this > far, then I can take it from there. Ok, Dave, here is the code to get the job logical name table. I'm posting to the net in case anyone else is interested. I originally wrote this code for the purpose of obtaining the remote node and id, but never finished the project beyond this point (It's not difficult, I just ran out of time). Extract the following into a command procedure file and invoke it as @file. It will create three files: GETJIB.MAR, JOBTABLE.FOR and TEST.FOR. If the checksums are ok it will go ahead and compile and link the test routine. Good luck. Brad Wilson -------------------- (cut here) ------------------- $ copy:=copy $ create:=create $ write:=write $ create getjib.mar $deck/dollars="$END-OF-FILE$" .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 $END-OF-FILE$ $ create jobtable.for $deck/dollars="$END-OF-FILE$" Subroutine JobTable (Epid, Name) * * Author: Brad Wilson * Department of Chemistry * Texas A&M University * College Station, TX 77843 * BMW6957@TAMCHEM.BITNET * * VMS version 4.x * Additional routines necessary: GETJIB * * Arguments: EPID Longword, passed by reference. This * is the external PID of the process for * which the routine returns the JOB logical * name table. The Epid is available via * the $GETJPI system service. * * NAME 16 byte character string, passed by * descriptor. The routine returns the * logical name table's name here. * * Constructs the name of the job logical name table for the process * specified by 'Epid'. The constructed name is returned in 'Name' * which must be at least 16 characters long. The job logical name * table has a name of the form: * * LNM$JOB_xxxxxxxx * * where xxxxxxxx is the hexadecimal address of the process's JIB * (Job Information Block). This routine calls GETJIB to retrieve * the JIB address for the given process. If GETJIB fails, a blank * name is returned. * * Implicit Integer*4 (A-Z) Character*(*) Name * JIB=GETJIB(Epid) If(JIB.ge.0) Then Name=' ' Else Write(Name,Fmt='(''LNM$JOB_'',Z8.8)') JIB End If * End $END-OF-FILE$ $ create test.for $deck/dollars="$END-OF-FILE$" Program Test_jobtable Implicit Integer*4 (A-Z) Include '($JPIDEF)' Character*16 Table_Name * * Get the Epid for our process * Iret = Lib$Getjpi(JPI$_PID,,,Epid) If ( .not. Iret ) Call Exit ( Iret ) * * Find the name of the Job table * Call JobTable( Epid, Table_Name ) Write(Unit=6,Fmt='('' The Job table for the current'// 1 ' process is: '',A16)') Table_Name End $END-OF-FILE$ $ all_OK = "TRUE" $ checksum getjib.mar $ if checksum$checksum.eqs."503979704" Then goto OK1 $ Write sys$output "GETJIB.MAR may be corrupt -- checksum failed" $ all_OK = "FALSE" $OK1: $ checksum jobtable.for $ if checksum$checksum.eqs."604439292" Then goto OK2 $ Write sys$output "JOBTABLE.FOR may be corrupt -- checksum failed" $ all_OK = "FALSE" $OK2: $ checksum test.for $ if checksum$checksum.eqs."558121729" Then goto OK3 $ Write sys$output "TEST.FOR may be corrupt -- checksum failed" $ all_OK = "FALSE" $OK3: $ if all_OK then goto linkit $ Copy sys$input sys$output Due to errors encountered, the test program will not be built. Please check the files listed above and correct the problem. $ exit $linkit: $ macro:=macro $ fortram:=fortran $ link:=link $ macro getjib $ fortran/nocheck jobtable $ fortran/nocheck test $ link test,jobtable,getjib $ Copy sys$input sys$output The test program TEST.EXE has been built. You will need CMKRNL privilege to run it. It should tell you the name of the current process's logical name table. $ exit