|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 23552 (0x5c00) Types: Ada Source Notes: 03_class, FILE, R1k_Segment, e3_tag, package body Transport, seg_052ab5
└─⟦8527c1e9b⟧ Bits:30000544 8mm tape, Rational 1000, Arrival backup of disks in PAM's R1000 └─⟦cfc2e13cd⟧ »Space Info Vol 2« └─⟦this⟧
with Byte_Defs; with Socket_System_Interface; with System; with System_Interface; with Transport_Defs; with Unchecked_Conversion; with Unix_Base_Types; with Text_Io; use Text_Io; package body Transport is Prototype_Error : exception; Unix_Error : constant Unix_Base_Types.Int := -1; type Process_Kind is (Nul, Server, Client); type Socket_Status_Kind is (Open, Connected, Not_Connected, Closed); -- For Servers: -- Open implies that the passive socket is Open, Bound and Listening. -- Connected means that the _accept call has completed and a -- connection with a remote (active) socket has been established. -- For Clients: -- Open implies that the local _socket call has completed successfully. -- Connected implies that the _connect call has completed successfully -- and that an active connection to the specified remote socket -- has been established. -- For both Servers and Clients: -- Not_Connected implies that the Connection is still open after a -- transmit or receive failure. The socket should be Closed and then -- reopened. You CANNOT simply reconnect a socket that is -- Not_Connected. -- -- Private type completion type Connection_Info is record Kind : Process_Kind := Nul; Socket_Status : Socket_Status_Kind := Closed; Local_Socket_Descriptor : Unix_Base_Types.Int := Unix_Error; Tcp_Socket_Descriptor : Unix_Base_Types.Int := Unix_Error; Local_Sockaddr_In : Socket_System_Interface.Sockaddr_In; Remote_Sockaddr_In : Socket_System_Interface.Sockaddr_In; Next : Connection_Id := null; end record; Free_List : Connection_Id := null; function ">" (L, R : Byte_Defs.Byte) return Boolean renames Byte_Defs.">"; function "-" (L, R : Byte_Defs.Byte) return Byte_Defs.Byte renames Byte_Defs."-"; function "=" (Left : Transport_Defs.Status_Code; Right : Transport_Defs.Status_Code) return Boolean renames Transport_Defs."="; function "=" (Left : Transport_Defs.Socket_Id; Right : Transport_Defs.Socket_Id) return Boolean renames Transport_Defs."="; function To_Sockaddr_In is new Unchecked_Conversion (Source => Socket_System_Interface.Sockaddr, Target => Socket_System_Interface.Sockaddr_In); function To_Sockaddr is new Unchecked_Conversion (Source => Socket_System_Interface.Sockaddr_In, Target => Socket_System_Interface.Sockaddr); function To_Sockaddr_In_Ptr is new Unchecked_Conversion (Source => System.Address, Target => Socket_System_Interface.Sockaddr_In_Ptr); function To_Sockaddr_Ptr is new Unchecked_Conversion (Source => System.Address, Target => Socket_System_Interface.Sockaddr_Ptr); function To_Int_Ptr is new Unchecked_Conversion (Source => System.Address, Target => Socket_System_Interface.Int_Ptr); function Get return Connection_Id is separate; procedure Free (Connection : Connection_Id) is separate; procedure Start_System_Call is separate; function Finish_System_Call return Unix_Base_Types.Int is separate; function Convert_Errno (Errno : Unix_Base_Types.Int) return Transport_Defs.Status_Code is separate; function Byte_String_To_Integer (Bs : Byte_Defs.Byte_String) return Unix_Base_Types.Int is separate; procedure Open_Server (Connection : out Transport.Connection_Id; Status : out Transport_Defs.Status_Code; Network : in Transport_Defs.Network_Name; Local_Socket : in Transport_Defs. Socket_Id) is separate; procedure Open_Client (Connection : out Transport.Connection_Id; Status : out Transport_Defs.Status_Code; Network : in Transport_Defs. Network_Name) is separate; -- -- Spec level routines -- procedure Open (Connection : out Transport.Connection_Id; Status : out Transport_Defs.Status_Code; Network : Transport_Defs.Network_Name; Local_Socket : Transport_Defs.Socket_Id := Transport_Defs.Null_Socket_Id) is -- IT IS ASSUMED THAT Server TASK WILL BE STARTED ON A KNOWN LOCAL -- SOCKET. Client TASKS WON'T CARE WHAT LOCAL_SOCKET THEY START ON -- AND WILL CALL OPEN WITH Local_Socket = -- Transport_Defs.Null_Socket_Id. -- Is_Server : constant Boolean := Local_Socket /= Transport_Defs.Null_Socket_Id; begin if Is_Server then Open_Server (Connection => Connection, Status => Status, Network => Network, Local_Socket => Local_Socket); else Open_Client (Connection => Connection, Status => Status, Network => Network); end if; end Open; procedure Close (Connection : Transport.Connection_Id) is separate; procedure Connect (Connection : Transport.Connection_Id; Status : out Transport_Defs.Status_Code; Remote_Host : Transport_Defs.Host_Id; Remote_Socket : Transport_Defs.Socket_Id; Max_Wait : Duration := Duration'Last) is -- Laddr_In : Socket_System_Interface.Sockaddr_In := (Sin_Family => Socket_System_Interface.Af_Inet, Sin_Port => Unix_Base_Types.Ushort (Byte_String_To_Integer (Byte_Defs.Byte_String (Transport_Defs.Normalize (Remote_Socket)))), Sin_Addr => Unix_Base_Types.U_Long (Byte_String_To_Integer (Byte_Defs.Byte_String (Transport_Defs.Normalize (Remote_Host)))), Sin_Zero => (others => Ascii.Nul)); Laddrlen : Unix_Base_Types.Int := Laddr_In'Size / System.Storage_Unit; Laddr_In_Ptr : Socket_System_Interface.Sockaddr_In_Ptr := To_Sockaddr_In_Ptr (Laddr_In'Address); Temp_Connection : Connection_Id := Connection; System_Call_Result : Unix_Base_Types.Int; Errno : Unix_Base_Types.Int; begin if Temp_Connection = Null_Connection_Id or else Temp_Connection.Socket_Status /= Open then Status := Transport_Defs.Not_Open; return; elsif Temp_Connection.Socket_Status = Not_Connected then Status := Transport_Defs.Not_Connected; return; end if; Status := Transport_Defs.Ok; Start_System_Call; System_Call_Result := Socket_System_Interface.Connect (S => Temp_Connection.Local_Socket_Descriptor, Addr => Laddr_In_Ptr, Addrlen => Laddrlen); Errno := Finish_System_Call; if (System_Call_Result < 0) then Status := Convert_Errno (Errno => Errno); return; end if; Temp_Connection.Socket_Status := Connected; Temp_Connection.Local_Sockaddr_In := Laddr_In; end Connect; -- -- Form a passive connection. This connection must be formed by a -- Server. It waits for a remote connection from an active Client. -- procedure Connect (Connection : Transport.Connection_Id; Status : out Transport_Defs.Status_Code; Max_Wait : Duration := Duration'Last) is Temp_Connection : Connection_Id := Connection; Laddr : Socket_System_Interface.Sockaddr; Laddr_Ptr : Socket_System_Interface.Sockaddr_Ptr := To_Sockaddr_Ptr (Laddr'Address); Laddrlen : Unix_Base_Types.Int := Temp_Connection.Local_Sockaddr_In'Size / System.Storage_Unit; Laddrlen_Ptr : Socket_System_Interface.Int_Ptr := To_Int_Ptr (Laddrlen'Address); Tcp_Connection : Unix_Base_Types.Int; Errno : Unix_Base_Types.Int; begin if Temp_Connection = Null_Connection_Id or else Temp_Connection.Socket_Status = Closed then Status := Transport_Defs.Not_Open; return; elsif Temp_Connection.Socket_Status = Not_Connected then Status := Transport_Defs.Not_Connected; return; end if; Accept_Loop: loop Status := Transport_Defs.Ok; Start_System_Call; Tcp_Connection := Socket_System_Interface.Saccept (S => Temp_Connection.Local_Socket_Descriptor, Addr => Laddr_Ptr, Addrlen => Laddrlen_Ptr); Errno := Finish_System_Call; if (Tcp_Connection < 0) then Status := Convert_Errno (Errno => Errno); if Errno /= System_Interface.Error.Eintr then return; end if; else exit Accept_Loop; end if; end loop Accept_Loop; Temp_Connection.Socket_Status := Connected; Temp_Connection.Tcp_Socket_Descriptor := Tcp_Connection; Temp_Connection.Remote_Sockaddr_In := To_Sockaddr_In (Laddr_Ptr.all); end Connect; procedure Disconnect (Connection : Transport.Connection_Id) is Temp_Connect : Transport.Connection_Id := Connection; System_Call_Result : Unix_Base_Types.Int; File_Descriptor : Unix_Base_Types.Int; begin if Temp_Connect = Null_Connection_Id or else Temp_Connect.Socket_Status /= Connected then return; end if; if Temp_Connect.Kind = Server then File_Descriptor := Temp_Connect.Tcp_Socket_Descriptor; else File_Descriptor := Temp_Connect.Local_Socket_Descriptor; end if; if Temp_Connect.Kind = Client then System_Call_Result := Socket_System_Interface.Shutdown (S => File_Descriptor, How => 2); end if; System_Call_Result := System_Interface.File_Io.Close (Fildes => File_Descriptor); if System_Call_Result < 0 then raise Program_Error; else if Temp_Connect.Kind = Server then Temp_Connect.Tcp_Socket_Descriptor := Unix_Error; Temp_Connect.Socket_Status := Open; else Temp_Connect.Local_Socket_Descriptor := Unix_Error; Temp_Connect.Socket_Status := Closed; end if; end if; end Disconnect; function Is_Open (Connection : Transport.Connection_Id) return Boolean is begin if Connection = Null_Connection_Id then return False; end if; case Connection.Kind is when Server | Client => return (Connection.Socket_Status = Open) or (Connection.Socket_Status = Not_Connected); when others => return False; end case; end Is_Open; function Is_Connected (Connection : Transport.Connection_Id) return Boolean is begin if Connection = Null_Connection_Id then return False; end if; case Connection.Kind is when Server | Client => return Connection.Socket_Status = Connected; when others => return False; end case; end Is_Connected; procedure Transmit (Connection : Transport.Connection_Id; Status : out Transport_Defs.Status_Code; Data : Byte_Defs.Byte_String; Count : out Natural; Max_Wait : Duration := Duration'Last; More : Boolean := False) is File_Descriptor : Unix_Base_Types.Int; System_Call_Result : Unix_Base_Types.Int; Errno : Unix_Base_Types.Int; Temp_Connect : Transport.Connection_Id := Connection; Amount_Remaining : Natural := Data'Length; Index : Natural := Data'First; Lcount : Natural := 0; begin Count := 0; if Temp_Connect = Null_Connection_Id then Status := Transport_Defs.Not_Open; return; end if; if Temp_Connect.Socket_Status /= Connected then Status := Transport_Defs.Not_Connected; return; end if; Status := Transport_Defs.Ok; if Temp_Connect.Kind = Server then File_Descriptor := Temp_Connect.Tcp_Socket_Descriptor; else File_Descriptor := Temp_Connect.Local_Socket_Descriptor; end if; Transmit_Loop: while Amount_Remaining > 0 loop Start_System_Call; System_Call_Result := System_Interface.File_Io.Write (Fildes => File_Descriptor, Buf => Unix_Base_Types.To_Char_Ptr (Data (Index)'Address), Nbyte => Amount_Remaining); Errno := Finish_System_Call; if (System_Call_Result < 0) then Status := Convert_Errno (Errno => Errno); if Temp_Connect.Kind = Client then System_Call_Result := Socket_System_Interface.Shutdown (S => File_Descriptor, How => 2); end if; System_Call_Result := System_Interface.File_Io.Close (Fildes => File_Descriptor); if System_Call_Result < 0 then raise Program_Error; else if Temp_Connect.Kind = Server then Temp_Connect.Tcp_Socket_Descriptor := Unix_Error; Temp_Connect.Socket_Status := Not_Connected; else Temp_Connect.Local_Socket_Descriptor := Unix_Error; Temp_Connect.Socket_Status := Closed; end if; end if; return; end if; Lcount := Lcount + System_Call_Result; Amount_Remaining := Amount_Remaining - System_Call_Result; Index := Index + System_Call_Result; Count := Lcount; end loop Transmit_Loop; end Transmit; procedure Receive (Connection : Transport.Connection_Id; Status : out Transport_Defs.Status_Code; Data : out Byte_Defs.Byte_String; Count : out Natural; Max_Wait : Duration := Duration'Last) is File_Descriptor : Unix_Base_Types.Int; Length : Unix_Base_Types.Int; System_Call_Result : Unix_Base_Types.Int; Errno : Unix_Base_Types.Int := System_Interface.Error.Eintr; Temp_Connect : Transport.Connection_Id := Connection; begin Count := 0; if Temp_Connect = Null_Connection_Id then Status := Transport_Defs.Not_Open; return; end if; if Temp_Connect.Socket_Status /= Connected then Status := Transport_Defs.Not_Connected; return; end if; if Temp_Connect.Kind = Server then File_Descriptor := Temp_Connect.Tcp_Socket_Descriptor; else File_Descriptor := Temp_Connect.Local_Socket_Descriptor; end if; Status := Transport_Defs.Ok; Start_System_Call; Length := System_Interface.File_Io.Read (Fildes => File_Descriptor, Buf => Unix_Base_Types.To_Char_Ptr (Data'Address), Nbyte => Data'Length); Errno := Finish_System_Call; if (Length > 0) then Count := Length; else if (Length < 0) then Status := Convert_Errno (Errno => Errno); elsif (Length = 0) then Status := Transport_Defs.Not_Connected; end if; if Temp_Connect.Kind = Client then System_Call_Result := Socket_System_Interface.Shutdown (S => File_Descriptor, How => 2); end if; System_Call_Result := System_Interface.File_Io.Close (Fildes => File_Descriptor); if System_Call_Result < 0 then raise Program_Error; else if Temp_Connect.Kind = Server then Temp_Connect.Tcp_Socket_Descriptor := Unix_Error; Temp_Connect.Socket_Status := Not_Connected; else Temp_Connect.Local_Socket_Descriptor := Unix_Error; Temp_Connect.Socket_Status := Closed; end if; end if; end if; end Receive; function Network (Connection : Transport.Connection_Id) return Transport_Defs.Network_Name is begin return "TCP/IP"; --[prototype] end Network; function Local_Host (Connection : Transport.Connection_Id) return Transport_Defs.Host_Id is begin raise Prototype_Error; --[prototype] return Transport_Defs.Null_Host_Id; end Local_Host; function Local_Socket (Connection : Transport.Connection_Id) return Transport_Defs.Socket_Id is Sid : constant Transport_Defs.Socket_Id := Transport_Defs.Socket_Id' (Byte_Defs.Byte (Integer (Connection.Local_Sockaddr_In.Sin_Port) / 256), Byte_Defs.Byte (Integer (Connection.Local_Sockaddr_In.Sin_Port) mod 256)); begin return Sid; end Local_Socket; function Remote_Host (Connection : Transport.Connection_Id) return Transport_Defs.Host_Id is begin raise Prototype_Error; --[prototype] return Transport_Defs.Null_Host_Id; end Remote_Host; function Remote_Socket (Connection : Transport.Connection_Id) return Transport_Defs.Socket_Id is begin return Transport_Defs.Socket_Id' (Byte_Defs.Byte (Integer (Connection.Remote_Sockaddr_In.Sin_Port) / 256), Byte_Defs.Byte (Integer (Connection.Remote_Sockaddr_In.Sin_Port) mod 256)); end Remote_Socket; end Transport;
nblk1=16 nid=b hdr6=2a [0x00] rec0=21 rec1=00 rec2=01 rec3=018 [0x01] rec0=1a rec1=00 rec2=02 rec3=058 [0x02] rec0=1e rec1=00 rec2=03 rec3=00a [0x03] rec0=1c rec1=00 rec2=04 rec3=060 [0x04] rec0=16 rec1=00 rec2=05 rec3=082 [0x05] rec0=1a rec1=00 rec2=06 rec3=01a [0x06] rec0=15 rec1=00 rec2=07 rec3=034 [0x07] rec0=1f rec1=00 rec2=08 rec3=010 [0x08] rec0=20 rec1=00 rec2=09 rec3=01c [0x09] rec0=1b rec1=00 rec2=0a rec3=030 [0x0a] rec0=20 rec1=00 rec2=16 rec3=024 [0x0b] rec0=21 rec1=00 rec2=0c rec3=00c [0x0c] rec0=1f rec1=00 rec2=0d rec3=05a [0x0d] rec0=21 rec1=00 rec2=0e rec3=006 [0x0e] rec0=1a rec1=00 rec2=0f rec3=058 [0x0f] rec0=1e rec1=00 rec2=10 rec3=058 [0x10] rec0=1d rec1=00 rec2=11 rec3=012 [0x11] rec0=26 rec1=00 rec2=12 rec3=012 [0x12] rec0=1e rec1=00 rec2=13 rec3=00a [0x13] rec0=20 rec1=00 rec2=14 rec3=010 [0x14] rec0=07 rec1=00 rec2=15 rec3=000 [0x15] rec0=00 rec1=04 rec2=80 rec3=016 tail 0x21759fe9487a14f34e032 0x42a00088462060003 Free Block Chain: 0xb: 0000 00 00 03 fc 80 05 69 66 3b 20 20 05 00 14 20 20 ┆ if; ┆