GKN@SDSC.ARPA.UUCP (12/20/86)
Todd, Denis, Arno and Info-VAX readers in general: There have been several questions regarding LAT on the list lately, so here is a subroutine and an example program which will retrieve the name of the server, the port name and session number of a given LAT terminal connection. Please note that this routine will work ONLY with LAT Plus V01.012 and with VMS V4.2 or higher. It requires CMKRNL. The routine itself is as paranoid about argument checking as I know how to make it, so the chances of it crashing your system are pretty low. However, as pointed out in the recent past, one should never test privileged code on a system where there are real live users who might get angry if the system ceases to work... It works fine on my V4.5 cluster, and the code was derived from a program I've been running since V4.2. Please check the version of your LTDRIVER.EXE with ANALYZE/IMAGE and ensure that it says "LATPLUS V01.012" before running a program which calls this routine. Digital considers the LAT protocol proprietary, and therefore does not publish anything about it, and has removed the listings of LTDRIVER and LATCP from the uFiche as of VMS V4.4. I figured out enough about the format of a LT UCB using SDA one afternoon to be able to retrieve this information. However, since LAT is subject to change, this routine may cease to work in the future. I know it will NOT work with older versions of LAT. To build the example program, do: $ Macro LAT_INFO $ Fortran LAT $ Link LAT+LAT_INFO Hope this helps. gkn -------------------------------------- Arpa: GKN@SDSC.ARPA Bitnet: GKN@SDSC Span: SDSC::GKN (5.600) USPS: Gerard K. Newman San Diego Supercomputer Center P.O. Box 85608 San Diego, CA 92138 AT&T: 619.534.5076 -------------------------------------LAT.FOR------------------------------------ Program LAT Include '($JPIDEF)' Character Server*24, Port*16, Terminal*16 Integer Session, Status, LIB$GETJPI, LAT_INFO, SYS$EXIT External LIB$GETJPI, LAT_INFO, SYS$EXIT Call LIB$GETJPI (JPI$_TERMINAL,,,,Terminal,) Status = LAT_INFO (Terminal, Session, Server, Port) If (.not. Status) Call SYS$EXIT(%Val(Status)) Write (6,100) Terminal, Server, Port, Session Call SYS$EXIT(%Val(1)) 100 Format (1X,'Terminal: ',A,' Server: ',A,' Port: ',A, 1 ' Session: ',I2) End ---------------------------------LAT_INFO.MAR----------------------------------- .Title LAT_Info - Get information about a LAT terminal .Ident /V01.000/ .Enable SUP .Default Displacement,Word .Subtitle Introduction ;+ ; ; ----- LAT_Info: Get information about a LAT terminal ; ; ; Facility: ; ; VAX/VMS system programming ; ; Abstract: ; ; This module provides a routine which can be called from any ; VAX native language to obtain information about a specific ; LAT terminal. ; ; Environment: ; ; VAX/VMS native mode, VMS V4.2 or later, LATPlus V01.012, CMKRNL ; privilege. ; ; ; ; Version: V01.000 ; Date: 19-Dec-1986 ; ; Gerard K. Newman ; San Diego Supercomputer Center ; GA Technologies ; P.O. Box 85608 ; San Diego, CA 92138 ; 619.534.5076 ; ; GKN@SDSC.ARPA, GKN@SDSC.BITNET ; ; Modifications: ; ; ;- .Page .Subtitle Local definitions .Library "SYS$LIBRARY:LIB" ;Get special macros from here .Link "SYS$SYSTEM:SYS.STB"/Selective_Search ;Ease the link process a bit .NoCross ;Save a tree $DCDEF ;Device class & type definitions $DDBDEF ;Device data block offsets $SSDEF ;System service codes $TTYUCBDEF ;Terminal UCB offsets $UCBDEF ;UCB offsets .Cross ;Turn CREF back on ; Local definitions ; Constants that are likely to change in a future release of VMS that are not ; defined in SYS.STB or in a macro anywhere. These values come from looking ; at the running system with SDA. ; Offset in an LT UCB to the length of the port name, which is a counted ; string. Immediately following the port name is another counted string ; which is the LAT node name. UCB$B_LT_PORT = ^X134 ;Offset to the port name length UCB$B_LT_SESS = ^X195 ;Offset to the session number .Page .Subtitle LAT_INFO - Get information about a LAT terminal ;+ ; ; ----- LAT_INFO: Get information about a LAT terminal ; ; ; This routine can be called by any VAX native language to obtain the server ; name, port name and session number of a LAT connection given a LT device ; name. The calling program must have CMKRNL privilege and must be linked ; with SYS.STB. ; ; Caveats: ; ; Will only work with fixed (non-dynamic) string descriptors. ; ; Call sequence: ; ; status.wlv = LAT_INFO (terminal.rt.dx, session.wlr, server.wt.dx, port.wt.dx) ; ; Inputs: ; ; 4(AP) - Address of a descriptor of the LT device name. ; 8(AP) - Address of a longword to return the session number in. ; 12(AP) - Address of a descriptor to return the server name. ; 16(AP) - Address of a descriptor to return the server port name. ; ; Outputs: ; ; R0 - SS$_NOPRIV: No CMKRNL privilege. ; - SS$_ACCVIO: One of the arguments is not accessible. ; - SS$_NOSUCHDEV: The specified LT device can't be found. ; - SS$_IVDEVNAM: The specified device isn't a LAT terminal. ; - SS$_NORMAL: Success. ; ;- .Psect LAT_INFO EXE,RD,NOWRT,PIC,SHR,PAGE .Entry LAT_INFO,^M<> ;Entry here $CMKRNL_S ROUTIN=B^20$,- ;Do this ARGLST=(AP) ; in kernel mode 10$: RET ;Done, status in R0 ; Here in kernel mode to do all of the actual work. 20$: .Word ^M<R2,R3,R4,R5,R6,R7,R8,R9,R10,R11> ;Here in kernel mode to get some info ; First, check to see if we can read the argument list. MOVL #SS$_ACCVIO,R0 ;Presume we can't IFNORD #<5*4>,(AP),10$ ;Probe the argument list ; Check the number of arguments MOVL #SS$_INSFARG,R0 ;Presume we have too few arguments CMPB #4,(AP) ;Do we have enough arguments? BNEQ 10$ ;If NEQ no, it's wrong somehow ; Check to see if we can write the session number. MOVL #SS$_ACCVIO,R0 ;Presume we can't IFNOWRT #4,@8(AP),10$ ;Probe the output session number ; See if we can read the device name descriptor. MOVL 4(AP),R1 ;Address the LT device name descriptor JSB G^EXE$PROBER_DSC ;Probe the descriptor BLBC R0,10$ ;Sigh. MOVQ R1,-(SP) ;Save a safe copy of the probed descriptor MOVL SP,R11 ;Remember where it is CLRW 2(R11) ;Never mind the type and class info ; See if we have write access to the two output descriptors. MOVL 12(AP),R1 ;Address the server name output descriptor JSB G^EXE$PROBEW_DSC ;Probe the descriptor BLBC R0,10$ ;Sigh. MOVQ R1,-(SP) ;Stash a safe copy of the descriptor MOVL SP,R10 ;Remember where I put it CLRW 2(R10) ;Never mind the type and class info MOVL 16(AP),R1 ;Address the port name output descriptor JSB G^EXE$PROBEW_DSC ;Probe the descriptor BLBC R0,10$ ;Sigh. MOVQ R1,-(SP) ;Stash a safe copy of said descriptor MOVL SP,R9 ;Remember where it is CLRW 2(R9) ;Never mind the type and class info ; Ok. Now go hunt down the device the user told us was a LAT terminal ; and see if it really is. MOVL G^SCH$GL_CURPCB,R4 ;Get my PCB address JSB G^SCH$IOLOCKR ;Lock the I/O database mutex MOVL R11,R1 ;Address the device name descriptor JSB G^IOC$SEARCHDEV ;Go search for the device. BLBC R0,30$ ;We lose. ; Now check to see if it's even a terminal, and if it is see if it's a LAT ; terminal. Remember to chain to the physical UCB first in case this is ; a disconnectable terminal. MOVL #SS$_IVDEVNAM,R0 ;Presume it isn't a terminal MOVL UCB$L_TL_PHYUCB(R1),R1 ;Get to the "real" UCB CMPB #DC$_TERM,UCB$B_DEVCLASS(R1) ;Is it a terminal? BNEQ 30$ ;If NEQ no. MOVL UCB$L_DDB(R1),R2 ;Find the DDB CMPW #^A/LT/,DDB$T_NAME+1(R2) ;Is this a LAT terminal? BNEQ 30$ ;If NEQ no ; It's a LAT terminal all right. Obtain the server name, port name and ; session number. MOVZBL UCB$B_LT_SESS(R1),@8(AP) ;Stash the session number MOVAB UCB$B_LT_PORT(R1),R1 ;Address the port name MOVL R9,R6 ;Here's the output descriptor address BSBB MOVE_ASCIC ;Move the port name MOVW (R6),@16(AP) ;Replace the length MOVL R10,R6 ;R1 now points at the server name BSBB MOVE_ASCIC ;So go move it, too MOVW (R6),@12(AP) ;Replace the length MOVL #SS$_NORMAL,R0 ;Success! 30$: PUSHL R0 ;Save the return status MOVL G^SCH$GL_CURPCB,R4 ;Get my PCB address again JSB G^SCH$IOUNLOCK ;Unlock the I/O database mutex SETIPL #0 ;Drop back down from IPL$_ASTDEL POPL R0 ;Restore the return status RET ;Back to user mode ; Short subroutine to move a .Ascic string to a place described by a ; descriptor. Forms a proper descriptor of the result, and handles ; short buffers, etc. ; ; Inputs: ; ; R1 - Address of the .Ascic string ; R6 - Address of the output descriptor ; ; Outputs: ; ; R1 - Address of one byte past the end of the .Ascic string ; R0-R5 - Smashed MOVE_ASCIC: ;Here to move a .Ascic string MOVZBL (R1)+,R0 ;Grab the string length CMPW (R6),R0 ;Check the string length BGEQU 10$ ;If GEQU then we can use it MOVZWL (R6),R0 ;Else only copy what will fit 10$: MOVW R0,(R6) ;Stash the length MOVC3 R0,(R1),@4(R6) ;Copy the string RSB ;Done .End -------------------------------------------------------------------------------- [end of message] -------