Greetings! This page contains a description of and links to my device driver for Alpha/VMS that
allows you to monitor a terminal. The device driver inserts itself between the port and class driver
of a terminal line and logs all characters sent to the terminal line into an internal buffer. A program
with CMKRNL can read the buffer.

The device driver does have a number of limitations. Among them are:

   Only one device may be monitored at any given time. 
   DECnet RT devices may not be monitored. These devices do not use the normal port/class
   driver arrangement, so this device driver cannot insert itself into those lines. 
   You can only watch. You cannot cannot interact with the line you are monitoring. 

Although I am working on some of these limitations, I cannot at the moment predict when an
updated version of the driver will be available.

Installation of the device driver consists of these steps:

 1. Copying the source files from the distribution medium. 
 2. Compiling the device driver. 
 3. Loading the device driver. 

 1. Copying the Device Driver 

   The device driver installation package contains five files:

      LPDRIVER.MAR is the source code for the device driver. 
      LPDRIVER.OPT is a LINK options file for the device driver. 
      LPBUILD.COM is a DCL command file that compiles and links the device driver. 
      LPLOAD.COM is a DCL command file that loads the device driver. 
      BIGBOOGER.FOR is a sample application using the device driver. 

   Copy the files into a suitable working directory.

 2. Compiling the Device Driver

   You must compile and link the device driver before it can be installed into the operating
   system. Do this by executing the LPBUILD command procedure. The compiler will
   generate many informational messages that should be ignored. The build procedure looks
   something like this:


           $ set proc/priv=all
           $ @lpbuild
           1040$:   MOVQ @Ucb$L_SvaPte(R5),@Ucb$L_WindowSvaPte(R5)
           ^
           %AMAC-I-QUADMEMREF, quadword memory references...
           at line number 438 in file USERS:[IVIE.USU20....

            BRB 1010$
           ^
           %AMAC-I-BRANCHBET, branch between routines from...
           at line number 433 in file USERS:[IVIE.USU20....

            BNEQ 1040$
           ^
           %AMAC-I-BRANCHBET, branch between routines...
           at line number 415 in file USERS:[IVIE.USU20....

            BRB 1100$
           ^
           %AMAC-I-BRANCHBET, branch between routines from...
           at line number 416 in file USERS:[IVIE.USU20...
           $

   The build procedure copies the device driver into SYS$LOADABLE_IMAGES:. After
   building the device driver, you should see a file named SYS$LPDRIVER.EXE in
   SYS$LOADABLE_IMAGES:.

 3. Loading the Device Driver

   After the device driver has been assembled and linked, it must be installed into the operating
   system using SYSMAN. This is done by the LPLOAD command procedure. LPLOAD
   loads the device driver and assigns it the name LPA0:. After loading the device driver, you
   should see a device named LPA0: that is online, like this:


           $ @LPLOAD
           $ SHOW DEVICE LP
           Device                  Device           Error
            Name                   Status           Count
           LPA0:                   Online               0
           $

   To the casual observer, LPA0: looks like a line printer:


           $ SHOW DEVICE/FULL LPA0:
           Printer LPA0:, device type LA11, is online, record-oriented  
               device, carriage control.

               Error count                    0    Operations completed...
               Owner process                 ""    Owner UIC...
               Owner process ID        00000000    Dev Prot    S:RWLP,...
               Reference count                0    Default buffer size...
               Page width                    80    Page Length...
               No Carriage_return  Formfeed        Uppercase
               No Passall          No Wrap         No Printall
               No Fallback         No Tab          No Truncate
           $

   Note that a normal user can see the owner UIC and process name of a process connected
   to LPA0:. If you wish to hide your snooping from normal users, you may want to change
   your process name to something innocuous (for example, SYMB0003) when you use the
   device driver.

Using the Device Driver

The device driver is used by a front-end program. It understands only the $QIO commands
necessary to do its job: IO$SenseMode, IO$SenseChar, IO$ConIntRead, IO$ConIntWrite,
IO$ReadVBlk, IO$ReadLBlk, and IO$ReadPBlk.

   IO$SenseMode and IO$SenseChar

   These functions are supported to allow the device driver to put up the facade of being a line
   printer. They work in the manner described by the I/O Users Guide for the line printer
   driver.

   IO$ConIntRead

   This function is used to attach the device driver to a terminal line that is to be monitored. It
   takes the following parameters:

      P1: The name of the controller to which the driver is to be attached. This is passed by
      value and contains a .ASCIC specification of the three-character controller name.
      For example, to attach to a line named TCA1:, P1 would be passed (in FORTRAN)
      as %val( '41435403'X ). 
      P2: The unit number of the line to which the driver is to be attached. This is passed by
      value. For example, to attach to a line named TCA1:, P2 would be passed (in
      FORTRAN) as %val( 1 ). 

   The remaining QIO parameters are not used.

   This QIO may return the following error codes:

      SS$IllIoFunc: The process issuing the $QIO does not have the CMKRNL privilege. 
      SS$BadParam: P1 does not appear to be a .ASCIC specification of a three-letter
      controller name. 
      SS$TermNetDev: The specified terminal line appears to be a DECnet remote
      terminal. Only local terminals, TCP/IP pseudoterminals, and DECwindows
      pseudoterminals may be monitored. 
      SS$DevOffLine: The specified terminal line is marked offline. It is probably a
      template device used to create pseudoterminals as TCP/IP or DECwindows
      terminals are needed. 
      SS$IvDevNam: The specified device is not a terminal. 
      SS$NoSuchDev: There is no device in the system with the specified name. 

   Once connected to the terminal line, all data sent to the terminal is copied into a local buffer.
   The Read $QIOs may be used to extract this data.

   When the buffer fills up, data is not copied until some of the data in the buffer is read.
   However, data flowing to the terminal is not stopped; the data sent while the buffer is full is
   lost.

   IO$ConIntWrite

   This function causes the driver to disconnect itself from any terminal line to which it may be
   connected. No parameters are required (the driver knows to which line it is connected). The
   following error codes may be generated:

      SS$IllIoFunc: The process issuing the $QIO does not have the CMKRNL privilege. 
      SS$Normal: Either the device driver has disconnected itself or it was not connected
      to a terminal. 

   IO$ReadVBlk, IO$ReadLBlk, and IO$ReadPBlk

   Once the device driver has been connected to a terminal line, all data sent to the terminal
   line is copied into a buffer in the device driver. These functions read data from that buffer.

   If there is data in the buffer, the $QIO reads the data that is available and then terminates. If
   there is no data in the buffer, the $QIO will wait for data to arrive in the buffer before reading
   that data and terminating.

   When the buffer becomes full, the device driver stops logging data in the buffer until some of
   the data has been read, making room for new data. While the buffer is full, data can still flow
   to the terminal, it is just not logged; that data is lost.

   The Read $QIOs take the following parameters:

      P1: The address of the buffer that will receive the data. 
      P2: The maximum number of bytes that may be read by this $QIO. The $QIO
      terminates when either the buffer has become empty or this many bytes have been
      read. 

   The Read $QIOs may return the following status:

      SS$IllIoFunc: The process issuing the $QIO does not have the CMKRNL privilege. 
      SS$Normal: The $QIO has been completed. 

   On completion, the high-order word of the first longword of the I/O Status Block indicates
   the number of bytes that were read. This limits transfers to 64KBytes.

The Example Application

BIGBOOGER is an example front end for the device driver. It allows the user to connect to any
terminal line and display the data sent to that terminal line. To compile BIGBOOGER, you need the
FORTRAN compiler. Do this:


        $ FORTRAN BIGBOOGER
        $ LINK BIGBOOGER
        $

When run, BIGBOOGER prompts for the controller name and unit number of the device that you
want to monitor. It then connects to that device and continuously displays what is in the device
driver's buffer. You exit BIGBOOGER by typing Y.

To monitor the terminal TCA1, do this:


                  $ RUN BIGBOOGER
                  Controller (e.g. TXA)? TCA
                  Unit? 1

