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:
    Copying the source files from the distribution medium. 
    Compiling the device driver. 
    Loading the device driver. 
    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.
    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:.
    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