From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 30-OCT-1989 13:34
To:	MRGATE::"ARISIA::EVERHART"
Subj:	How to determine if a terminal is a LAT terminal without looking at the terminal name (was: Connecting to a LAT or terminal port)

Message-Id:  <8910301341.AA26643@crdgw1.ge.com>
Received: From AQUA.BACS.INDIANA.EDU by CRVAX.SRI.COM with TCP; Mon, 30 OCT 89 05:17:28 PDT
Date: 26 Oct 89 16:37:00 EST
From: "IVAX::IJAH400" <ijah400%ivax.decnet@aqua.bacs.indiana.edu>
Subject: How to determine if a terminal is a LAT terminal without looking at the terminal name (was: Connecting to a LAT or terminal port)
To: "info-vax" <info-vax@sri.com>

In a recent INFO-VAX article, scoughlan@ucsd.edu (Sean Coughlan) writes:
>In article <8910250416.AA22530@ucbvax.Berkeley.EDU> JOE@FHCRCVAX.BITNET (Joe
> Meadows) writes:
>>>In article <9011@max.u.washington.edu>,
>>>foam@max.u.washington.edu (Mark Jungck) writes:
>>>> How do I tell whether I'm using a LAT line or
>>>> not?
>
>Try the following (from DCL):
>	$ a=f$getdvi("TT:","DEVDEPEND2")
>	$ b=(a.and.4)
>		if b is not equal to 0 then you are on a remote
>		device (Such as a LAT)
>
>	The 4 is from $DEVDEF library module (DEV$M_RTT Terminal has
>	remote terminal UCB extension.).
>	See IO Users :part 1 page 8-20.
>
>	Sean Coughlan
>	scoughlan@ucsd.edu

No, Sean.  You've got DEVDEPEND and DEVCHAR mixed up.  DEV$M_RTT is one
of the device-INDEPENDENT characteristics, which are in DEVCHAR and DEVCHAR2
(see table 8-4 in I/O Users part 1 page 8-20).  DEV$M_RTT is in DEVCHAR2
and is set for RT terminals.  It isn't set for LAT terminals.  The code
shown above is looking at the device-DEPENDENT characteristics, and happens
to be looking at the bit TT2$M_HANGUP (which also happens to be 4, see table
8-6, pp 8-22 - 8-26).  LAT terminals usually have this bit set, but don't
have to.  Lots of other types of terminals may have it set too (usually any
dial-in modem port).

To find out if a given terminal is a LAT terminal, if you're writing in
in MACRO or a HLL and want to be picky (looking at the first two letters
of the terminal name isn't good enough for you) you can assign a channel
to the terminal, do a sense mode or sense characteristics $QIO with the
read modem function modifier (IO$M_RD_MODEM), and look at the controller
type code you get back and see if it is equal to DT$_LAT.  The terminal
device read modem function modifier is described in section 8.4.5.2 on
pp 8-55/56 of the I/O User's ref. Part 1.  The manual claims it's not
supported for LAT devices (right under a table of controller type codes
that has an entry for the LAT server!) but executing the function for a LAT
terminal returns the controller type code DC$_LAT as expected.  This was
under VMS version 5.1-1.  The blurb about "unsupported for LAT" may just
mean that the "receive modem" signal field is unsupported for LAT.

Appended below is a C program in VMS_SHARE format that prints out the
controller type and receive modem signals, given a device name.  It requires
SHARE privilege to look at devices that are allocated to other users.
Also is a session log of a sample run.

In summary, there's no way to do this from DCL, and given all the trouble
it takes it's probably easier to just look at the first two letters of the
terminal name.

- Jim Harvey, Senior Analyst/Programmer, IUPUI Computing Svcs. (DEC Systems)
Internet: ijah400@indyvax.iupui.edu   UUCP: ...{uunet, ?}!iuvax!ivax!ijah400
BITNET: ijah400@indyvax   AT&T: (317) 274-0747                   Disclaimer:
Opinions expressed here are my own and not necessarily those of my employer.

-------------->8 *** READMODEM.1_OF_1 *** Clip and Save *** 8<-----------------
$! ................... Cut between dotted lines and save. ...................
$!...........................................................................
$! VAX/VMS archive file created by VMS_SHARE V06.10 7-FEB-1989.
$!
$! VMS_SHARE was written by James Gray (Gray:OSBUSouth@Xerox.COM) from
$! VMS_SHAR by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au).
$!
$! To unpack, simply save, concatinate all parts into one file and
$! execute (@) that file.
$!
$! This archive was created by user IJAH400
$! on 26-OCT-1989 15:47:31.42.
$!
$! It contains the following 1 file:
$!        READMODEM.C
$!
$!============================================================================
$ SET SYMBOL/SCOPE=( NOLOCAL, NOGLOBAL )
$ VERSION = F$GETSYI( "VERSION" )
$ IF VERSION .GES "V4.4" THEN GOTO VERSION_OK
$ WRITE SYS$OUTPUT "You are running VMS ''VERSION'; ", -
    "VMS_SHARE V06.10 7-FEB-1989 requires VMS V4.4 or higher."
$ EXIT 44 ! SS$_ABORT
$VERSION_OK:
$ GOTO START
$!
$UNPACK_FILE:
$ WRITE SYS$OUTPUT "Creating ''FILE_IS'"
$ DEFINE/USER_MODE SYS$OUTPUT NL:
$ EDIT/TPU/COMMAND=SYS$INPUT/NODISPLAY/OUTPUT='FILE_IS'/NOSECTION -
    VMS_SHARE_DUMMY.DUMMY
b_part := CREATE_BUFFER( "{Part}", GET_INFO( COMMAND_LINE, "file_name" ) )
; s_file_spec := GET_INFO( COMMAND_LINE, "output_file" ); SET( OUTPUT_FILE
, b_part, s_file_spec ); b_errors := CREATE_BUFFER( "{Errors}" ); i_errors
:= 0; pat_beg_1 := ANCHOR & "-+-+-+ Beginning"; pat_beg_2 := LINE_BEGIN
& "+-+-+-+ Beginning"; pat_end := ANCHOR & "+-+-+-+-+ End"; POSITION
( BEGINNING_OF( b_part ) ); LOOP EXITIF SEARCH( SPAN( ' ' )@r_trail
& LINE_END, FORWARD) = 0; POSITION( r_trail ); ERASE( r_trail ); ENDLOOP
; POSITION( BEGINNING_OF( b_part ) ); i_append_line := 0; LOOP EXITIF MARK
( NONE ) = END_OF( b_part ); s_x := ERASE_CHARACTER( 1 )
; IF s_x = '+' THEN r_skip := SEARCH( pat_beg_1, FORWARD, EXACT ); IF r_skip
<> 0 THEN s_x := ''; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ERASE_LINE; ENDIF
; ENDIF; IF s_x = '-' THEN r_skip := SEARCH( pat_end, FORWARD, EXACT )
; IF r_skip <> 0 THEN s_x := ''; MOVE_HORIZONTAL( -CURRENT_OFFSET ); m_skip
:= MARK( NONE ); r_skip := SEARCH( pat_beg_2, FORWARD, EXACT ); IF r_skip
<> 0 THEN POSITION( END_OF( r_skip ) ); MOVE_HORIZONTAL( -CURRENT_OFFSET )
; MOVE_VERTICAL( 1 ); MOVE_HORIZONTAL( -1 ); ELSE POSITION( END_OF( b_part )
); ENDIF; ERASE( CREATE_RANGE( m_skip, MARK( NONE ), NONE ) ); ENDIF; ENDIF
; IF s_x = 'V' THEN s_x := ''; IF i_append_line <> 0 THEN APPEND_LINE
; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF; i_append_line := 1
; MOVE_VERTICAL( 1 ); ENDIF; IF s_x = 'X' THEN s_x := ''; IF i_append_line
<> 0 THEN APPEND_LINE; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ENDIF
; i_append_line := 0; MOVE_VERTICAL( 1 ); ENDIF; IF s_x <> '' THEN i_errors
:= i_errors + 1; s_text := CURRENT_LINE; POSITION( b_errors ); COPY_TEXT
( "The following line could not be unpacked properly:" ); SPLIT_LINE
; COPY_TEXT( s_x ); COPY_TEXT( s_text ); POSITION( b_part ); MOVE_VERTICAL
( 1 ); ENDIF; ENDLOOP; POSITION( BEGINNING_OF( b_part ) ); LOOP r_x := SEARCH
( "`", FORWARD, EXACT ); EXITIF r_x = 0; POSITION( r_x ); ERASE_CHARACTER( 1
); COPY_TEXT( ASCII( INT( ERASE_CHARACTER( 3 ) ) ) ); ENDLOOP
; IF i_errors = 0 THEN SET( NO_WRITE, b_errors, ON ); ELSE POSITION
( BEGINNING_OF( b_errors ) ); COPY_TEXT( FAO
( "The following !UL errors were detected while unpacking !AS", i_errors
, s_file_spec ) ); SPLIT_LINE; SET( OUTPUT_FILE, b_errors, "SYS$COMMAND" )
; ENDIF; EXIT;
$ DELETE VMS_SHARE_DUMMY.DUMMY;*
$ CHECKSUM 'FILE_IS
$ WRITE SYS$OUTPUT " CHECKSUM ", -
  F$ELEMENT( CHECKSUM_IS .EQ. CHECKSUM$CHECKSUM, ",", "failed!!,passed." )
$ RETURN
$!
$START:
$ FILE_IS = "READMODEM.C"
$ CHECKSUM_IS = 1797749870
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X#module readmodem
X
X/*
X**`009This program prompts for a terminal's device name (if not given on
X**`009the command line) and prints out the controller class and modem
X**`009control bits for the terminal in hex.
X*/
X
X#include dcdef
X#include descrip
X#include dvidef
X#include iodef
X#include ssdef
X#include stdio
X#include ttdef
X
X#define success(arg) ((arg) & 1)
X#define failure(arg) (`126(arg) & 1)
X#define check(arg) (failure(arg) ? LIB$STOP(arg) : 1)
X
Xstruct item_list_3 `123
X    unsigned short buffer_length, item_code;
X    unsigned long buffer_address;
X    unsigned long return_length_address;
X`125;
X
Xstruct iosb_block `123
X    unsigned short iostat;
X    unsigned short transfer_count;
X    unsigned long devdepend_info;
X`125;
X
Xstruct sense_modem_block `123
X    unsigned char controller_type;
X    char unused_1;
X    unsigned char receive_modem;
X    char unused_2[5];
X`125;
X
Xstruct thing_to_name `123
X    long int thing;
X    char *name;
X`125;
X
Xstatic const struct thing_to_name controller_names[] = `123
X    `123 DT$_DZ11, "DZ11 or DZV11" `125,
X    `123 DT$_DZ32, "DZ32" `125,
X    `123 DT$_DMF32, "DMF32" `125,
X    `123 DT$_DMB32, "DMB32" `125,
X    `123 DT$_DMZ32, "DMZ32" `125,
X    `123 DT$_DHV, "DHV11" `125,
X    `123 DT$_DHU, "DHU11" `125,
X    `123 DT$_LAT, "LAT server" `125,
X    `123 -1, "unknown" `125
X`125;
X
Xstatic const struct thing_to_name signal_names[] = `123
X    `123 TT$M_DS_DSR, "DSR" `125,
X    `123 TT$M_DS_RING, "RING" `125,
X    `123 TT$M_DS_CARRIER, "CARRIER" `125,
X    `123 TT$M_DS_CTS, "CTS" `125,
X    `123 TT$M_DS_SECREC, "Sec RxD" `125,
X    `123 0, 0 `125
X`125;
X
X
Xmain ()
X`123
X    unsigned long status;
X    int i;
X    unsigned short channel;
X    static struct sense_modem_block sense_modem;
X    static struct iosb_block iosb;
X    static const $DESCRIPTOR(prompt,"Device: ");
X    static char devnam_s[16];
X    static struct dsc$descriptor_s devnam =
X`009`123 sizeof(devnam_s), DSC$K_DTYPE_T, DSC$K_CLASS_S, devnam_s `125;
X    static long int devclass, junk;
X    static const struct item_list_3 dvilist[] = `123
X`009`123 sizeof(devclass), DVI$_DEVCLASS, &devclass, &junk `125,
X`009`123 0, 0, 0, 0 `125,
X    `125;
X
X    /* Get the device name */
X    status = LIB$GET_FOREIGN(&devnam,&prompt,&devnam.dsc$w_length,0);
X    check(status);
X
X    /* Assign a channel to the device */
X    status = SYS$ASSIGN(&devnam,&channel,0,0);
X    check(status);
X
X    /* Read device class, return IVDEVNAM for non-terminals */
X    status = SYS$GETDVIW(0,channel,0,&dvilist,&iosb,0,0,0);
X    check(status);  check(iosb.iostat);
X    if (devclass != DC$_TERM)
X`009LIB$STOP(SS$_IVDEVNAM);
X
X    /* Read the modem information */
X    status = SYS$QIOW(0,channel,IO$_SENSEMODE`124IO$M_RD_MODEM,&iosb,0,0,
X`009`009`009&sense_modem,0,0,0,0,0);
X    check(status);  check(iosb.iostat);
X
X    /* Lookup controller type and print it on the terminal */
X    for (i = 0;  controller_names[i].thing > 0;  i++)
X`009if (sense_modem.controller_type == controller_names[i].thing)
X`009    break;
X    printf("Controller class: %d - %s\n",sense_modem.controller_type,
X`009`009controller_names[i].name);
X
X    /* Print out state of modem signals too */
X    printf("Modem signals:   ");
X    for (i = 0;  signal_names[i].thing != 0;  i++)
X`009if (signal_names[i].thing & sense_modem.receive_modem)
X`009    printf(" %s",signal_names[i].name);
X    if (sense_modem.receive_modem == 0)
X`009printf(" none");
X    printf("\n");
X
X    /* Deassign channel and exit */
X    status = SYS$DASSGN(channel);  check(status);
X`125
$ GOSUB UNPACK_FILE
$ EXIT
-------------->8 *** READMODEM.1_OF_1 *** Clip and Save *** 8<-----------------

Sample run:

[PHOTO: Recording initiated 26-OCT-1989 15:26]
SYSTEM> cc readmodem
SYSTEM> link readmodem,sys$input/option
sys$share:vaxcrtl.exe/share
*EXIT*
SYSTEM> run readmodem
Device: lta6076
Controller class: 74 - LAT server
Modem signals:    none
SYSTEM> run readmodem
Device: txa0
Controller class: 27 - DMB32
Modem signals:    CTS
SYSTEM> run readmodem
Device: nty4
Controller class: 255 - unknown
Modem signals:    DSR CARRIER CTS
SYSTEM> run readmodem
Device: opa0
Controller class: 0 - unknown
Modem signals:    DSR RING CARRIER CTS
SYSTEM> run readmodem
Device: rta1
%SYSTEM-F-DEVREQERR, device request error
SYSTEM> lo
  Process PHOTO_665F logged out at 26-OCT-1989 15:27:55.98
[PHOTO: Recording terminated 26-OCT-1989 15:27 READMODEM.LOG;1]

Two oddities are the operator console on our 8800 (OPA0) and a WIN/TCP Telnet
terminal device (NTY4).  Anyone know what the significance of type codes
0 and 255 might be?

- Jim Harvey, Senior Analyst/Programmer, IUPUI Computing Svcs. (DEC Systems)
Internet: ijah400@indyvax.iupui.edu   UUCP: ...{uunet, ?}!iuvax!ivax!ijah400
BITNET: ijah400@indyvax   AT&T: (317) 274-0747                   Disclaimer:
Opinions expressed here are my own and not necessarily those of my employer.


