DataMuseum.dk

Presents historical artifacts from the history of:

Rational R1000/400

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Rational R1000/400

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦62f534cf8⟧ Ada Source

    Length: 33792 (0x8400)
    Types: Ada Source
    Notes: 03_class, FILE, R1k_Segment, e3_tag, package body Tcp, seg_02597d

Derivation

└─⟦8527c1e9b⟧ Bits:30000544 8mm tape, Rational 1000, Arrival backup of disks in PAM's R1000
    └─ ⟦cfc2e13cd⟧ »Space Info Vol 2« 
        └─⟦this⟧ 

E3 Source Code



with System;
with Unchecked_Conversion;
with Mac_Types;
use Mac_Types;
with Memory;
with Osutils;
with Devices;
package body Tcp is


    -- MacTCP return Codes in the range -23000 through -23049

    Inprogress : constant := 1;    -- I/O in progress

    Ipbadlaperr : constant := -23000;   -- bad network configuration
    Ipbadcnfgerr : constant := -23001;   -- bad IP configuration error
    Ipnocnfgerr : constant := -23002;   -- missing IP or LAP configuration error
    Iploaderr : constant := -23003;   -- error in MacTCP load
    Ipbadaddr : constant := -23004;   -- error in getting address
    Connectionclosing : constant := -23005;   -- connection is closing
    Invalidlength : constant := -23006;
    Connectionexists : constant :=
       -23007;   -- request conflicts with existing connection
    Connectiondoesntexist : constant := -23008;  -- connection does not exist
    Insufficientresources : constant :=
       -23009;  -- insufficient resources to perform request
    Invalidstreamptr : constant := -23010;
    Streamalreadyopen : constant := -23011;
    Connectionterminated : constant := -23012;
    Invalidbufptr : constant := -23013;
    Invalidrds : constant := -23014;
    Invalidwds : constant := -23014;
    Openfailed : constant := -23015;
    Commandtimeout : constant := -23016;
    Duplicatesocket : constant := -23017;

-- Error codes from internal IP functions
    Ipdontfragerr : constant :=
       -23032;   -- Packet too large to send w/o fragmenting
    Ipdestdeaderr : constant := -23033;   -- destination not responding
    Ipnofragmemerr : constant := -23036;   -- no memory to send fragmented pkt
    Iprouteerr : constant := -23037;   -- can't route packet off-net

    Namesyntaxerr : constant := -23041;
    Cachefault : constant := -23042;
    Noresultproc : constant := -23043;
    Nonameserver : constant := -23044;
    Authnameerr : constant := -23045;
    Noanserr : constant := -23046;
    Dnrerr : constant := -23047;
    Outofmemory : constant := -23048;

-- Command codes

    Ipctlgetaddr : constant := 15;
    Tcpcreate : constant := 30;
    Tcppassiveopen : constant := 31;
    Tcpactiveopen : constant := 32;
    Tcpsend : constant := 34;
    Tcpnocopyrcv : constant := 35;
    Tcprcvbfrreturn : constant := 36;
    Tcprcv : constant := 37;
    Tcpclose : constant := 38;
    Tcpabort : constant := 39;
    Tcpstatus : constant := 40;
    Tcpextendedstat : constant := 41;
    Tcprelease : constant := 42;
    Tcpglobalinfo : constant := 43;
    Tcpctlmax : constant := 49;

    type Ippb is
        record
            Fill1 : Mac_Types.Longint;
            Fill2 : Mac_Types.Longint;
            Fill3 : Mac_Types.Longint;
            Iocompletion : Mac_Types.Procptr;
            Ioresult : Mac_Types.Integer;
            Ionameptr : Mac_Types.Stringptr;
            Iovrefnum : Mac_Types.Integer;
            Iocrefnum : Mac_Types.Integer;
            Cscode : Mac_Types.Integer;
            Ouraddress : Ip_Addr;
            Ournetmask : Mac_Types.Longint;
        end record;
    type Ippbptr is access Ippb;

    type Tcpcreatepb is
        record
            Fill1 : Mac_Types.Longint;
            Fill2 : Mac_Types.Longint;
            Fill3 : Mac_Types.Longint;
            Iocompletion : Mac_Types.Procptr;  -- TCPIOCompletionProc;
            Ioresult : Mac_Types.Integer;
            Ionameptr : Mac_Types.Stringptr;
            Iovrefnum : Mac_Types.Integer;
            Iocrefnum : Mac_Types.Integer;
            Cscode : Mac_Types.Integer;
            Tcpstream : Stream_Ptr;
            Rcvbuff : Mac_Types.Ptr;
            Rcvbufflen : Mac_Types.Longint;
            Notifyproc : Mac_Types.Procptr;   -- TCPNotifyProc
            Userdataptr : Mac_Types.Ptr;
        end record;
    type Tcpcreatepbptr is access Tcpcreatepb;

    type Tcpclosepb is
        record
            Fill1 : Mac_Types.Longint;
            Fill2 : Mac_Types.Longint;
            Fill3 : Mac_Types.Longint;
            Iocompletion : Mac_Types.Procptr;  -- TCPIOCompletionProc;
            Ioresult : Mac_Types.Integer;
            Ionameptr : Mac_Types.Stringptr;
            Iovrefnum : Mac_Types.Integer;
            Iocrefnum : Mac_Types.Integer;
            Cscode : Mac_Types.Integer;
            Tcpstream : Stream_Ptr;
            Ulptimeoutvalue : Mac_Types.Byte;
            Ulptimeoutaction : Mac_Types.Byte;
            Validityflags : Mac_Types.Byte;
            Userdataptr : Mac_Types.Ptr;
        end record;
    type Tcpclosepbptr is access Tcpclosepb;

    type Tcpabortpb is
        record
            Fill1 : Mac_Types.Longint;
            Fill2 : Mac_Types.Longint;
            Fill3 : Mac_Types.Longint;
            Iocompletion : Mac_Types.Procptr;  -- TCPIOCompletionProc;
            Ioresult : Mac_Types.Integer;
            Ionameptr : Mac_Types.Stringptr;
            Iovrefnum : Mac_Types.Integer;
            Iocrefnum : Mac_Types.Integer;
            Cscode : Mac_Types.Integer;
            Tcpstream : Stream_Ptr;
            Userdataptr : Mac_Types.Ptr;
        end record;
    type Tcpabortpbptr is access Tcpabortpb;

    type Tcpglobalinfopb is
        record
            Fill1 : Mac_Types.Longint;
            Fill2 : Mac_Types.Longint;
            Fill3 : Mac_Types.Longint;
            Iocompletion : Mac_Types.Procptr;  -- TCPIOCompletionProc;
            Ioresult : Mac_Types.Integer;
            Ionameptr : Mac_Types.Stringptr;
            Iovrefnum : Mac_Types.Integer;
            Iocrefnum : Mac_Types.Integer;
            Cscode : Mac_Types.Integer;
            Tcpstream : Stream_Ptr;
            Tcpparamptr : Tcp.Tcpparamptr;
            Tcpstatsptr : Tcp.Tcpstatsptr;
            Tcpcdbtable : Mac_Types.Varlongint;
            Userdataptr : Mac_Types.Ptr;
        end record;
    type Tcpglobalinfopbptr is access Tcpglobalinfopb;


    Csleeptime : constant := 0.3;
    Refnum : Mac_Types.Integer := 0;

-- Conversion
    function As_Varinteger is new Unchecked_Conversion
                                     (Source => System.Address,
                                      Target => Mac_Types.Varinteger);

    function As_Ippbptr is new Unchecked_Conversion
                                  (Source => Ptr, Target => Ippbptr);
    function As_Ptr is new Unchecked_Conversion
                              (Source => Ippbptr, Target => Ptr);
    function As_Parmblkptr is
       new Unchecked_Conversion (Source => Ippbptr,
                                 Target => Osutils.Parmblkptr);


    function As_Tcpcreatepbptr is
       new Unchecked_Conversion (Source => Ptr, Target => Tcpcreatepbptr);
    function As_Ptr is new Unchecked_Conversion
                              (Source => Tcpcreatepbptr, Target => Ptr);
    function As_Parmblktr is new Unchecked_Conversion
                                     (Source => Tcpcreatepbptr,
                                      Target => Osutils.Parmblkptr);

    function As_Tcpopenpbptr is new Unchecked_Conversion
                                       (Source => Ptr, Target => Tcpopenpbptr);
    function As_Ptr is new Unchecked_Conversion
                              (Source => Tcpopenpbptr, Target => Ptr);
    function As_Parmblkptr is
       new Unchecked_Conversion (Source => Tcpopenpbptr,
                                 Target => Osutils.Parmblkptr);

    function As_Tcpsendpbptr is new Unchecked_Conversion
                                       (Source => Ptr, Target => Tcpsendpbptr);
    function As_Ptr is new Unchecked_Conversion
                              (Source => Tcpsendpbptr, Target => Ptr);
    function As_Parmblkptr is
       new Unchecked_Conversion (Source => Tcpsendpbptr,
                                 Target => Osutils.Parmblkptr);

    function As_Tcpreceivepbptr is
       new Unchecked_Conversion (Source => Ptr, Target => Tcpreceivepbptr);
    function As_Ptr is new Unchecked_Conversion
                              (Source => Tcpreceivepbptr, Target => Ptr);
    function As_Parmblkptr is new Unchecked_Conversion
                                     (Source => Tcpreceivepbptr,
                                      Target => Osutils.Parmblkptr);

    function As_Tcpclosepbptr is
       new Unchecked_Conversion (Source => Ptr, Target => Tcpclosepbptr);
    function As_Ptr is new Unchecked_Conversion
                              (Source => Tcpclosepbptr, Target => Ptr);
    function As_Parmblkptr is
       new Unchecked_Conversion (Source => Tcpclosepbptr,
                                 Target => Osutils.Parmblkptr);

    function As_Tcpabortpbptr is
       new Unchecked_Conversion (Source => Ptr, Target => Tcpabortpbptr);
    function As_Ptr is new Unchecked_Conversion
                              (Source => Tcpabortpbptr, Target => Ptr);
    function As_Parmblkptr is
       new Unchecked_Conversion (Source => Tcpabortpbptr,
                                 Target => Osutils.Parmblkptr);

    function As_Tcpstatuspbptr is
       new Unchecked_Conversion (Source => Ptr, Target => Tcpstatuspbptr);
    function As_Ptr is new Unchecked_Conversion
                              (Source => Tcpstatuspbptr, Target => Ptr);
    function As_Parmblkptr is new Unchecked_Conversion
                                     (Source => Tcpstatuspbptr,
                                      Target => Osutils.Parmblkptr);

    function As_Tcpglobalinfopbptr is
       new Unchecked_Conversion (Source => Ptr, Target => Tcpglobalinfopbptr);
    function As_Ptr is new Unchecked_Conversion
                              (Source => Tcpglobalinfopbptr, Target => Ptr);
    function As_Parmblkptr is
       new Unchecked_Conversion (Tcpglobalinfopbptr,
                                 Target => Osutils.Parmblkptr);



-- Raise an exception if an error occured
    procedure Check_Error (Err : Mac_Types.Oserr) is
    begin
        case Err is
            when Mac_Types.Noerr =>
                null;
            when Commandtimeout =>
                raise Timeout_Error;
            when others =>
                raise Device_Error;
        end case;
    end Check_Error;

-- Opens the MacTCP driver.

    use Mac_Types;
    procedure Open_Tcp_Driver is
        Err : Oserr;
        Ipp_Name : Str255;

    begin
        Ipp_Name (0) := Char'Val (4);
        Ipp_Name (1 .. 4) := ".IPP";
        Err := Devices.Opendriver (Ipp_Name, As_Varinteger (Refnum'Address));
        Check_Error (Err);
    end Open_Tcp_Driver;


-- Creates a new TCP stream in preparation for initiating a connection.
--   A buffer must be provided for storing incoming data waiting to be processed

    procedure Low_Tcp_Create_Stream (A_Stream : out Stream_Ptr;
                                     Connectionbuffer : Ptr;
                                     Connbufferlen : Natural;
                                     Notify_Proc : Procptr;
                                     Userdataptr : Ptr) is

        Err : Oserr;
        Pb : Tcpcreatepbptr;

    begin
        Pb := As_Tcpcreatepbptr (Memory.Newptr (Tcpcreatepb'Size / 8));

        Pb.Iocompletion := null;
        Pb.Iocrefnum := Refnum;
        Pb.Cscode := Tcpcreate;
        Pb.Ioresult := 1;
        Pb.Rcvbuff := Connectionbuffer;
        Pb.Rcvbufflen := Connbufferlen;
        Pb.Notifyproc := Notify_Proc;
        Pb.Userdataptr := Userdataptr;
        Err := Devices.Pbcontrol (As_Parmblkptr (Pb), True);
        while Pb.Ioresult = 1 loop
            delay Csleeptime;
        end loop;

        A_Stream := Pb.Tcpstream;
        Err := Pb.Ioresult;
        Memory.Disposptr (As_Ptr (Pb));
        Check_Error (Err);
    end Low_Tcp_Create_Stream;


-- If TCPWaitForConnection is called asynchronously, this command retrieves the
--   result of the call.  It should be called when the above command completes.

    procedure Low_Finish_Tcp_Wait_For_Connection (Pb : in out Tcpopenpbptr;
                                                  Remotehost : out Ip_Addr;
                                                  Remoteport : out Tcp_Port;
                                                  Localhost : out Ip_Addr;
                                                  Localport : out Tcp_Port) is

        Err : Oserr;
    begin
        Remotehost := Pb.Remotehost;
        Remoteport := Pb.Remoteport;
        Localhost := Pb.Localhost;
        Localport := Pb.Localport;
        Err := Pb.Ioresult;
        Memory.Disposptr (As_Ptr (Pb));
        Pb := null;
        Check_Error (Err);
    end Low_Finish_Tcp_Wait_For_Connection;


-- Waits for a connection to be opened on a specified port from a specified address.
-- It completes when a connection is made, or a timeout value is reached.  This call
-- may be made asynchronously.

    procedure Low_Tcp_Wait_For_Connection (A_Stream : Stream_Ptr;
                                           Timeout : Byte;
                                           Remotehost : in out Ip_Addr;
                                           Remoteport : in out Tcp_Port;
                                           Localhost : out Ip_Addr;
                                           Localport : in out Tcp_Port;
                                           Async : Boolean;
                                           Userdataptr : Ptr;
                                           Returnblock : out Tcpopenpbptr) is

        Err : Oserr;
        Pb : Tcpopenpbptr;

    begin
        Pb := As_Tcpopenpbptr (Memory.Newptr (Tcpopenpb'Size / 8));

        Pb.Iocompletion := null;
        Pb.Iocrefnum := Refnum;
        Pb.Cscode := Tcppassiveopen;
        Pb.Ioresult := 1;
        Pb.Tcpstream := A_Stream;
        Pb.Ulptimeoutvalue := Timeout;
        Pb.Ulptimeoutaction := 1;
        Pb.Validityflags := 16#C0#;
        Pb.Commandtimeoutvalue := Timeout;
        Pb.Remotehost := Remotehost;
        Pb.Remoteport := Remoteport;
        Pb.Localport := Localport;
        Pb.Tosflags := 0;
        Pb.Precedence := 0;
        Pb.Dontfrag := False;
        Pb.Timetolive := 0;
        Pb.Security := 0;
        Pb.Optioncnt := 0;
        Pb.Userdataptr := Userdataptr;
        Err := Devices.Pbcontrol (As_Parmblkptr (Pb), True);
        if not Async then
            while Pb.Ioresult = 1 loop
                delay Csleeptime;
            end loop;
            Low_Finish_Tcp_Wait_For_Connection
               (Pb, Remotehost, Remoteport, Localhost, Localport);
        end if;
        Returnblock := Pb;
    end Low_Tcp_Wait_For_Connection;


-- Attempts to initiate a connection with a host specified by host and port.

    procedure Low_Tcp_Open_Connection (A_Stream : Stream_Ptr;
                                       Timeout : Byte;
                                       Remotehost : Ip_Addr;
                                       Remoteport : Tcp_Port;
                                       Localhost : out Ip_Addr;
                                       Localport : in out Tcp_Port;
                                       Userdataptr : Ptr) is

        Err : Oserr;
        Pb : Tcpopenpbptr;

    begin
        Pb := As_Tcpopenpbptr (Memory.Newptr (Tcpopenpb'Size / 8));

        Pb.Iocompletion := null;
        Pb.Iocrefnum := Refnum;
        Pb.Cscode := Tcpactiveopen;
        Pb.Ioresult := 1;
        Pb.Tcpstream := A_Stream;
        Pb.Ulptimeoutvalue := Timeout;
        Pb.Ulptimeoutaction := 1;
        Pb.Validityflags := 16#C0#;
        Pb.Commandtimeoutvalue := Timeout;
        Pb.Remotehost := Remotehost;
        Pb.Remoteport := Remoteport;
        Pb.Localport := Localport;
        Pb.Tosflags := 0;
        Pb.Precedence := 0;
        Pb.Dontfrag := False;
        Pb.Timetolive := 0;
        Pb.Security := 0;
        Pb.Optioncnt := 0;
        Pb.Userdataptr := Userdataptr;
        Err := Devices.Pbcontrol (As_Parmblkptr (Pb), True);
        while Pb.Ioresult = 1 loop
            delay Csleeptime;
        end loop;
        Localhost := Pb.Localhost;
        Localport := Pb.Localport;
        Err := Pb.Ioresult;
        Memory.Disposptr (As_Ptr (Pb));
        Check_Error (Err);
    end Low_Tcp_Open_Connection;


-- This routine should be called when a TCPSendData call completes.  It returns the
-- error code generated upon completion of the CallTCPSend.

    procedure Low_Finish_Tcp_Send (Pb : in out Tcpsendpbptr) is
        Err : Oserr;
    begin
        Err := Pb.Ioresult;
        Memory.Disposptr (As_Ptr (Pb));
        Pb := null;
        Check_Error (Err);
    end Low_Finish_Tcp_Send;


-- Sends data through an open connection stream.  Note that the connection must be
-- open before any data is sent. This call may be made asynchronously.

    procedure Low_Tcp_Send_Data (A_Stream : Stream_Ptr;
                                 Timeout : Byte;
                                 Push : Boolean;
                                 Urgent : Boolean;
                                 Wdsptr : Ptr;
                                 Async : Boolean;
                                 Userdataptr : Ptr;
                                 Returnblock : out Tcpsendpbptr) is

        Err : Oserr;
        Pb : Tcpsendpbptr;

    begin
        Pb := As_Tcpsendpbptr (Memory.Newptr (Tcpsendpb'Size / 8));

        Pb.Iocompletion := null;
        Pb.Iocrefnum := Refnum;
        Pb.Cscode := Tcpsend;
        Pb.Ioresult := 1;
        Pb.Tcpstream := A_Stream;
        Pb.Ulptimeoutvalue := Timeout;
        Pb.Ulptimeoutaction := 1;
        Pb.Validityflags := 16#C0#;
        Pb.Pushflag := Push;
        Pb.Urgentflag := Urgent;
        Pb.Wdsptr := Wdsptr;
        Pb.Userdataptr := Userdataptr;
        Err := Devices.Pbcontrol (As_Parmblkptr (Pb), True);
        if not Async then
            while Pb.Ioresult = 1 loop
                delay Csleeptime;
            end loop;
            Low_Finish_Tcp_Send (Pb);
        end if;

        Returnblock := Pb;
    end Low_Tcp_Send_Data;

--

    procedure Low_Finish_Tcp_No_Copy_Rcv (Pb : in out Tcpreceivepbptr;
                                          Urgent : out Boolean;
                                          Mark : out Boolean) is

        Err : Oserr;
    begin
        Urgent := Pb.Urgentflag;
        Mark := Pb.Markflag;

        Err := Pb.Ioresult;
        Memory.Disposptr (As_Ptr (Pb));
        Pb := null;
        Check_Error (Err);
    end Low_Finish_Tcp_No_Copy_Rcv;

--

    procedure Low_Tcp_No_Copy_Rcv (A_Stream : Stream_Ptr;
                                   Timeout : Byte;
                                   Urgent : out Boolean;
                                   Mark : out Boolean;
                                   Rdsptr : Ptr;
                                   Numentry : B_16;
                                   Async : Boolean;
                                   Userdataptr : Ptr;
                                   Returnblock : out Tcpreceivepbptr) is

        Err : Oserr;
        Pb : Tcpreceivepbptr;

    begin
        Pb := As_Tcpreceivepbptr (Memory.Newptr (Tcpreceivepb'Size / 8));

        Pb.Iocompletion := null;
        Pb.Iocrefnum := Refnum;
        Pb.Cscode := Tcpnocopyrcv;
        Pb.Ioresult := 1;
        Pb.Tcpstream := A_Stream;
        Pb.Commandtimeoutvalue := Timeout;
        Pb.Rdsptr := Rdsptr;
        Pb.Rdslength := Numentry;
        Pb.Userdataptr := Userdataptr;
        Err := Devices.Pbcontrol (As_Parmblkptr (Pb), True);
        if not Async then
            while Pb.Ioresult = 1 loop
                delay Csleeptime;
            end loop;
            Low_Finish_Tcp_No_Copy_Rcv (Pb, Urgent, Mark);
        end if;

        Returnblock := Pb;
    end Low_Tcp_No_Copy_Rcv;

--
    procedure Low_Tcp_Bfr_Return (A_Stream : Stream_Ptr; Rdsptr : Ptr) is

        Err : Oserr;
        Pb : Tcpreceivepbptr;

    begin
        Pb := As_Tcpreceivepbptr (Memory.Newptr (Tcpreceivepb'Size / 8));

        Pb.Iocompletion := null;
        Pb.Iocrefnum := Refnum;
        Pb.Cscode := Tcprcvbfrreturn;
        Pb.Ioresult := 1;
        Pb.Tcpstream := A_Stream;
        Pb.Rdsptr := Rdsptr;
        Err := Devices.Pbcontrol (As_Parmblkptr (Pb), True);
        while Pb.Ioresult = 1 loop
            delay Csleeptime;
        end loop;
        Err := Pb.Ioresult;
        Memory.Disposptr (As_Ptr (Pb));
        Pb := null;
        Check_Error (Err);
    end Low_Tcp_Bfr_Return;


-- If the below is called asynchronously, this routine returns the data that was
-- received from the remote host.

    procedure Low_Finish_Tcp_Recv (Pb : in out Tcpreceivepbptr;
                                   Urgent : out Boolean;
                                   Mark : out Boolean;
                                   Rcvlen : out B_16) is

        Err : Oserr;
    begin
        Rcvlen := Pb.Rcvbufflen;
        Urgent := Pb.Urgentflag;
        Mark := Pb.Markflag;
        Err := Pb.Ioresult;
        Memory.Disposptr (As_Ptr (Pb));
        Check_Error (Err);
    end Low_Finish_Tcp_Recv;


-- Attempts to pull data out of the incoming stream for a connection. If data is
-- not present, the routine waits a specified amout of time before returning with
-- a timeout error.  This call may be made asynchronously.

    procedure Low_Tcp_Recv_Data (A_Stream : Stream_Ptr;
                                 Timeout : Byte;
                                 Urgent : out Boolean;
                                 Mark : out Boolean;
                                 Rcvbuff : Ptr;
                                 Rcvlen : in out B_16;
                                 Async : Boolean;
                                 Userdataptr : Ptr;
                                 Returnblock : out Tcpreceivepbptr) is

        Err : Oserr;
        Pb : Tcpreceivepbptr;

    begin
        Pb := As_Tcpreceivepbptr (Memory.Newptr (Tcpreceivepb'Size / 8));

        Pb.Iocompletion := null;
        Pb.Iocrefnum := Refnum;
        Pb.Cscode := Tcprcv;
        Pb.Ioresult := 1;
        Pb.Tcpstream := A_Stream;
        Pb.Commandtimeoutvalue := Timeout;
        Pb.Rcvbuff := Rcvbuff;
        Pb.Rcvbufflen := Rcvlen;
        Pb.Userdataptr := Userdataptr;
        Err := Devices.Pbcontrol (As_Parmblkptr (Pb), True);
        if not Async then
            while Pb.Ioresult = 1 loop
                delay Csleeptime;
            end loop;
            Low_Finish_Tcp_Recv (Pb, Urgent, Mark, Rcvlen);
        end if;

        Returnblock := Pb;
    end Low_Tcp_Recv_Data;


-- Gracefully closes a connection with a remote host.  This is not always possible,
-- and the programmer might have to resort to CallTCPAbort, described next.

    procedure Low_Tcp_Close (A_Stream : Stream_Ptr; Timeout : Byte) is

        Err : Oserr;
        Pb : Tcpclosepbptr;

    begin
        Pb := As_Tcpclosepbptr (Memory.Newptr (Tcpclosepb'Size / 8));

        Pb.Iocompletion := null;
        Pb.Iocrefnum := Refnum;
        Pb.Cscode := Tcpclose;
        Pb.Ioresult := 1;
        Pb.Tcpstream := A_Stream;
        Pb.Ulptimeoutvalue := Timeout;
        Pb.Validityflags := 16#C0#;
        Pb.Ulptimeoutaction := 1;
        Pb.Userdataptr := null;
        Err := Devices.Pbcontrol (As_Parmblkptr (Pb), True);
        while Pb.Ioresult = 1 loop
            delay Csleeptime;
        end loop;
        Err := Pb.Ioresult;
        Memory.Disposptr (As_Ptr (Pb));
        Check_Error (Err);
    end Low_Tcp_Close;


-- Should be called if a CallTCPClose fails to close a connection properly.
-- This call should not normally be used to terminate connections.

    procedure Low_Tcp_Abort (A_Stream : Stream_Ptr) is

        Err : Oserr;
        Pb : Tcpabortpbptr;

    begin
        Pb := As_Tcpabortpbptr (Memory.Newptr (Tcpabortpb'Size / 8));

        Pb.Iocompletion := null;
        Pb.Iocrefnum := Refnum;
        Pb.Cscode := Tcpabort;
        Pb.Ioresult := 1;
        Pb.Tcpstream := A_Stream;
        Pb.Userdataptr := null;
        Err := Devices.Pbcontrol (As_Parmblkptr (Pb), True);
        while Pb.Ioresult = 1 loop
            delay Csleeptime;
        end loop;
        Err := Pb.Ioresult;
        Memory.Disposptr (As_Ptr (Pb));
        Check_Error (Err);
    end Low_Tcp_Abort;


--
    procedure Low_Tcp_Status (A_Stream : Stream_Ptr;
                              Thestatus : out Tcpstatuspb) is

        Err : Oserr;
        Pb : Tcpstatuspbptr;

    begin
        Pb := As_Tcpstatuspbptr (Memory.Newptr (Tcpstatuspb'Size / 8));

        Pb.Iocompletion := null;
        Pb.Iocrefnum := Refnum;
        Pb.Cscode := Tcpstatus;
        Pb.Ioresult := 1;
        Pb.Tcpstream := A_Stream;
        Pb.Userdataptr := null;
        Err := Devices.Pbcontrol (As_Parmblkptr (Pb), True);
        while Pb.Ioresult = 1 loop
            delay Csleeptime;
        end loop;
        Thestatus := Pb.all;
        Err := Pb.Ioresult;
        Memory.Disposptr (As_Ptr (Pb));
        Check_Error (Err);
    end Low_Tcp_Status;


-- Deallocates internal buffers used to hold connection data. This should be
-- called after a connection has been closed.

    procedure Low_Tcp_Release (A_Stream : Stream_Ptr;
                               Recvptr : out Ptr;
                               Recvlen : out Longint) is

        Err : Oserr;
        Pb : Tcpcreatepbptr;

    begin
        Pb := As_Tcpcreatepbptr (Memory.Newptr (Tcpcreatepb'Size / 8));

        Pb.Iocompletion := null;
        Pb.Iocrefnum := Refnum;
        Pb.Cscode := Tcprelease;
        Pb.Ioresult := 1;
        Pb.Tcpstream := A_Stream;
        Pb.Userdataptr := null;
        Err := Devices.Pbcontrol (As_Parmblkptr (Pb), True);
        while Pb.Ioresult = 1 loop
            delay Csleeptime;
        end loop;
        Recvptr := Pb.Rcvbuff;
        Recvlen := Pb.Rcvbufflen;
        Err := Pb.Ioresult;
        Memory.Disposptr (As_Ptr (Pb));
        Check_Error (Err);
    end Low_Tcp_Release;

--
    procedure Low_Tcp_Global_Info
                 (Tcpparam : out Tcpparamptr; Tcpstat : out Tcpstatsptr) is

        Err : Oserr;
        Pb : Tcpglobalinfopbptr;

    begin
        Pb := As_Tcpglobalinfopbptr (Memory.Newptr (Tcpglobalinfopb'Size / 8));

        Pb.Iocompletion := null;
        Pb.Iocrefnum := Refnum;
        Pb.Cscode := Tcpglobalinfo;
        Pb.Ioresult := 1;
        Pb.Userdataptr := null;
        Err := Devices.Pbcontrol (As_Parmblkptr (Pb), True);
        while Pb.Ioresult = 1 loop
            delay Csleeptime;
        end loop;
        Tcpparam := Pb.Tcpparamptr;
        Tcpstat := Pb.Tcpstatsptr;
        Err := Pb.Ioresult;
        Memory.Disposptr (As_Ptr (Pb));
        Check_Error (Err);
    end Low_Tcp_Global_Info;


-- Returns the IP address of the local computer.

    procedure Get_My_Ip (Ipnum : out Ip_Addr) is

        Err : Oserr;
        Pb : Ippbptr;

    begin
        Pb := As_Ippbptr (Memory.Newptr (Ippb'Size / 8));

        Pb.Iocompletion := null;
        Pb.Iocrefnum := Refnum;
        Pb.Ioresult := 1;
        Pb.Cscode := Ipctlgetaddr;
        Err := Devices.Pbcontrol (As_Parmblkptr (Pb), True);
        while Pb.Ioresult = 1 loop
            delay Csleeptime;
        end loop;
        Ipnum := Pb.Ouraddress;
        Err := Pb.Ioresult;
        Memory.Disposptr (As_Ptr (Pb));
        Check_Error (Err);
    end Get_My_Ip;

-- Kills any pending calls to the TCP driver

    procedure Low_Kill_Tcp (Pb : Tcpopenpbptr) is
    begin
        Check_Error (Devices.Pbkillio (As_Parmblkptr (Pb), False));
    end Low_Kill_Tcp;

    procedure Low_Kill_Tcp (Pb : Tcpsendpbptr) is
    begin
        Check_Error (Devices.Pbkillio (As_Parmblkptr (Pb), False));
    end Low_Kill_Tcp;

    procedure Low_Kill_Tcp (Pb : Tcpreceivepbptr) is
    begin
        Check_Error (Devices.Pbkillio (As_Parmblkptr (Pb), False));
    end Low_Kill_Tcp;


end Tcp;

E3 Meta Data

    nblk1=20
    nid=1d
    hdr6=3c
        [0x00] rec0=1b rec1=00 rec2=01 rec3=048
        [0x01] rec0=17 rec1=00 rec2=02 rec3=038
        [0x02] rec0=1f rec1=00 rec2=03 rec3=036
        [0x03] rec0=1c rec1=00 rec2=04 rec3=00c
        [0x04] rec0=18 rec1=00 rec2=05 rec3=034
        [0x05] rec0=1a rec1=00 rec2=06 rec3=004
        [0x06] rec0=18 rec1=00 rec2=20 rec3=02e
        [0x07] rec0=00 rec1=00 rec2=07 rec3=002
        [0x08] rec0=12 rec1=00 rec2=08 rec3=07e
        [0x09] rec0=15 rec1=00 rec2=09 rec3=024
        [0x0a] rec0=13 rec1=00 rec2=0a rec3=038
        [0x0b] rec0=23 rec1=00 rec2=0b rec3=062
        [0x0c] rec0=1d rec1=00 rec2=0c rec3=01a
        [0x0d] rec0=19 rec1=00 rec2=1f rec3=084
        [0x0e] rec0=16 rec1=00 rec2=0d rec3=042
        [0x0f] rec0=1d rec1=00 rec2=0e rec3=068
        [0x10] rec0=1a rec1=00 rec2=11 rec3=036
        [0x11] rec0=1f rec1=00 rec2=10 rec3=00e
        [0x12] rec0=1c rec1=00 rec2=12 rec3=006
        [0x13] rec0=23 rec1=00 rec2=13 rec3=04a
        [0x14] rec0=19 rec1=00 rec2=14 rec3=078
        [0x15] rec0=1f rec1=00 rec2=15 rec3=02e
        [0x16] rec0=1d rec1=00 rec2=16 rec3=050
        [0x17] rec0=1a rec1=00 rec2=18 rec3=022
        [0x18] rec0=1f rec1=00 rec2=19 rec3=072
        [0x19] rec0=21 rec1=00 rec2=17 rec3=016
        [0x1a] rec0=22 rec1=00 rec2=1a rec3=060
        [0x1b] rec0=22 rec1=00 rec2=1b rec3=012
        [0x1c] rec0=22 rec1=00 rec2=0f rec3=03e
        [0x1d] rec0=1d rec1=00 rec2=1c rec3=000
        [0x1e] rec0=00 rec1=10 rec2=00 rec3=000
        [0x1f] rec0=00 rec1=00 rec2=00 rec3=000
    tail 0x21720790483a35dd9b58a 0x42a00088462060003
Free Block Chain:
  0x1d: 0000  00 1e 00 1b 80 04 54 63 70 3b 04 00 00 00 00 00  ┆      Tcp;      ┆
  0x1e: 0000  00 00 00 6b 80 08 65 72 72 20 74 68 65 6e 08 00  ┆   k  err then  ┆