DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ B T ┃
Length: 16054 (0x3eb6) Types: TextFile Names: »B«
└─⟦bad92a95e⟧ Bits:30000535 8mm tape, Rational 1000, RPC 1_0_2 └─ ⟦bb34fe6e2⟧ »DATA« └─⟦15d8b76c6⟧ └─⟦this⟧
with Byte_Defs; with Socket_System_Interface; with System_Interface; with Unix_Base_Types; package body Transport is function ">" (L, R : Byte_Defs.Byte) return Boolean renames Byte_Defs.">"; function "-" (L, R : Byte_Defs.Byte) return Byte_Defs.Byte renames Byte_Defs."-"; type Connection_Info is record Connection_Establishment_Socket : Unix_Base_Types.Int := -1; Transmission_Socket : Unix_Base_Types.Int := -1; Next : Connection_Id := null; end record; Free_List : Connection_Id := null; function "=" (L, R : Byte_Defs.Byte_String) return Boolean renames Byte_Defs."="; function Get return Connection_Id is The_Connection : Connection_Id; begin if Free_List = null then The_Connection := new Connection_Info; else The_Connection := Free_List; Free_List := Free_List.Next; end if; return The_Connection; end Get; procedure Free (Connection : Connection_Id) is begin Connection.Next := Free_List; Free_List := Connection; end Free; procedure Start_System_Call is begin null; end Start_System_Call; function Finish_System_Call return Unix_Base_Types.Int is Errno : Integer := System_Interface.Error.Errno; begin return Errno; end Finish_System_Call; function Convert_Errno (Errno : Unix_Base_Types.Int) return Transport_Defs.Status_Code is begin case Errno is when System_Interface.Error.Econnreset | System_Interface.Error.Eremoterelease => return Transport_Defs.Connection_Broken; when System_Interface.Error.Enomem => return Transport_Defs.No_Free_Memory; when System_Interface.Error.Eacces => return Transport_Defs.Access_Denied; when System_Interface.Error.Eprotonosupport => return Transport_Defs.Protocol_Not_Supported; when System_Interface.Error.Eaddrinuse => return Transport_Defs.Socket_In_Use; when System_Interface.Error.Enetunreach => return Transport_Defs.Network_Unreachable; when System_Interface.Error.Enotconn => return Transport_Defs.Not_Connected; when System_Interface.Error.Eshutdown => return Transport_Defs.Not_Open; when System_Interface.Error.Etimedout => return Transport_Defs.Timed_Out; when System_Interface.Error.Econnrefused => return Transport_Defs.Connection_Refused; when System_Interface.Error.Ehostunreach => return Transport_Defs.Host_Unreachable; when others => return Transport_Defs.Status_Code (Errno + Unix_Base_Types.Int (100)); end case; end Convert_Errno; function Byte_String_To_Integer (Bs : Byte_Defs.Byte_String) return Unix_Base_Types.Int is Result : Unix_Base_Types.Int := 0; Int_Length : constant := 4; Normalized_Bs : Byte_Defs.Byte_String (0 .. Int_Length - 1) := (others => 0); Negative : Boolean := False; Shifter : Integer := 0; begin if Bs'Length < Int_Length then Normalized_Bs ((Normalized_Bs'Last - Bs'Length) + 1 .. Normalized_Bs'Last) := Bs; else Normalized_Bs := Bs ((Bs'Last - Int_Length) + 1 .. Bs'Last); end if; if Normalized_Bs (0) > Byte_Defs.Byte (2 ** 7 - 1) then Negative := True; end if; for I in reverse Normalized_Bs'Range loop if Negative then Normalized_Bs (I) := Byte_Defs.Byte'Last - Normalized_Bs (I); end if; Result := Result + Integer (Normalized_Bs (I)) * (2 ** Shifter); Shifter := Shifter + 8; end loop; if Negative then return -Result - 1; else return Result; end if; end Byte_String_To_Integer; 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 System_Call_Result : Integer; Lconnection : Connection_Id := Null_Connection_Id; Addr : 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 (Local_Socket)))), Sin_Addr => Socket_System_Interface.Inaddr_Any, Sin_Zero => (others => Ascii.Nul)); Errno : Integer; begin Connection := Null_Connection_Id; Status := Transport_Defs.Ok; Start_System_Call; System_Call_Result := Socket_System_Interface.Socket (Af => Unix_Base_Types.Int (Socket_System_Interface.Af_Inet), Socket_Type => Socket_System_Interface.Sock_Stream, Protocol => 0); Errno := Finish_System_Call; if System_Call_Result = -1 then Status := Convert_Errno (Errno); return; end if; Lconnection := Get; Lconnection.Connection_Establishment_Socket := System_Call_Result; if Byte_Defs.Byte_String (Local_Socket) /= Byte_Defs.Byte_String (Transport_Defs.Null_Socket_Id) then Start_System_Call; System_Call_Result := Socket_System_Interface.Bind (S => Unix_Base_Types.Int (Lconnection.Connection_Establishment_Socket), Addr => Addr, Addrlen => 16); Errno := Finish_System_Call; if System_Call_Result = -1 then Status := Convert_Errno (Errno); System_Call_Result := System_Interface.File_Io.Close (Fildes => Lconnection.Connection_Establishment_Socket); Free (Lconnection); return; end if; end if; Connection := Lconnection; end Open; procedure Close (Connection : Transport.Connection_Id) is Error : Unix_Base_Types.Int; Lconnection : Connection_Id := Connection; begin if Connection /= Null_Connection_Id then Error := Socket_System_Interface.Shutdown (S => Connection.Transmission_Socket, How => 2); Error := System_Interface.File_Io.Close (Connection.Transmission_Socket); Error := Socket_System_Interface.Shutdown (S => Connection.Connection_Establishment_Socket, How => 2); Error := System_Interface.File_Io.Close (Connection.Connection_Establishment_Socket); Lconnection.Connection_Establishment_Socket := -1; Lconnection.Transmission_Socket := -1; Free (Lconnection); end if; end Close; 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 System_Call_Result : Integer; Errno : Integer := System_Interface.Error.Etimedout; Addr : 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)); begin if not Is_Open (Connection) then Status := Transport_Defs.Not_Open; return; end if; Status := Transport_Defs.Ok; while Errno = System_Interface.Error.Etimedout loop Start_System_Call; System_Call_Result := Socket_System_Interface.Connect (S => Connection.Connection_Establishment_Socket, Addr => Addr, Addrlen => 16); Errno := Finish_System_Call; end loop; if System_Call_Result = -1 then Status := Convert_Errno (Errno); else Connection.Transmission_Socket := Connection.Connection_Establishment_Socket; end if; end Connect; procedure Connect (Connection : Transport.Connection_Id; Status : out Transport_Defs.Status_Code; Max_Wait : Duration := Duration'Last) is System_Call_Result : Integer; Errno : Integer := 0; Addr : Socket_System_Interface.Sockaddr; begin if not Is_Open (Connection) then Status := Transport_Defs.Not_Open; return; end if; Status := Transport_Defs.Ok; Start_System_Call; System_Call_Result := Socket_System_Interface.Listen (S => Connection.Connection_Establishment_Socket, Backlog => 5); Errno := Finish_System_Call; if System_Call_Result = -1 then Status := Convert_Errno (Errno); else loop Start_System_Call; System_Call_Result := Socket_System_Interface.Saccept (S => Connection.Connection_Establishment_Socket, Addr => Addr, Addrlen => 16); Errno := Finish_System_Call; exit when Errno /= System_Interface.Error.Eintr; end loop; if System_Call_Result = -1 then Status := Convert_Errno (Errno); else Connection.Transmission_Socket := System_Call_Result; end if; end if; end Connect; procedure Disconnect (Connection : Transport.Connection_Id) is Error : Integer; begin if Connection /= Null_Connection_Id and then Connection.Transmission_Socket /= -1 then Error := Socket_System_Interface.Shutdown (S => Connection.Transmission_Socket, How => 2); Connection.Transmission_Socket := -1; end if; end Disconnect; function Is_Open (Connection : Transport.Connection_Id) return Boolean is begin return Connection /= Null_Connection_Id and then Connection.Connection_Establishment_Socket /= -1; end Is_Open; function Is_Connected (Connection : Transport.Connection_Id) return Boolean is begin return Connection /= Null_Connection_Id and then Connection.Transmission_Socket /= -1; --should be getpeername; 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 System_Call_Result : Integer := 1; Errno : Integer := 0; Bytes_Sent : Integer := 0; function Disconnected return Boolean is begin return System_Call_Result = 0; end Disconnected; function More_Data return Boolean is begin return Bytes_Sent < Data'Length; end More_Data; function No_Error return Boolean is begin return Errno = 0 or Errno = System_Interface.Error.Eintr; end No_Error; begin Count := 0; Status := Transport_Defs.Ok; if not Is_Open (Connection) then Status := Transport_Defs.Not_Open; return; end if; if not Is_Connected (Connection) then Status := Transport_Defs.Not_Connected; return; end if; while No_Error and More_Data and not Disconnected loop declare Buffer : constant Byte_Defs.Byte_String := Data (Data'First + Bytes_Sent .. Data'Last); begin Start_System_Call; System_Call_Result := System_Interface.File_Io.Write (Fildes => Connection.Transmission_Socket, Buf => Unix_Base_Types.To_Char_Ptr (Buffer'Address), Nbyte => Buffer'Length); Errno := Finish_System_Call; end; if System_Call_Result /= -1 then Bytes_Sent := Bytes_Sent + System_Call_Result; end if; end loop; Count := Bytes_Sent; if System_Call_Result = -1 then Status := Convert_Errno (Errno); return; end if; if Disconnected then Status := Transport_Defs.Connection_Broken; System_Call_Result := Socket_System_Interface.Shutdown (Connection.Transmission_Socket, 2); System_Call_Result := System_Interface.File_Io.Close (Connection.Transmission_Socket); Connection.Transmission_Socket := -1; end if; 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 System_Call_Result : Integer; Errno : Integer; begin Count := 0; Status := Transport_Defs.Ok; if not Is_Open (Connection) then Status := Transport_Defs.Not_Open; end if; if not Is_Connected (Connection) then Status := Transport_Defs.Not_Connected; end if; loop Start_System_Call; System_Call_Result := System_Interface.File_Io.Read (Fildes => Connection.Transmission_Socket, Buf => Unix_Base_Types.To_Char_Ptr (Data (Data'First)'Address), Nbyte => Data'Length); Errno := Finish_System_Call; exit when Errno /= System_Interface.Error.Eintr; end loop; if System_Call_Result = -1 then Status := Convert_Errno (Errno); return; end if; if System_Call_Result = 0 then Status := Transport_Defs.Connection_Broken; System_Call_Result := Socket_System_Interface.Shutdown (Connection.Transmission_Socket, 2); System_Call_Result := System_Interface.File_Io.Close (Connection.Transmission_Socket); Connection.Transmission_Socket := -1; else Count := System_Call_Result; end if; end Receive; end Transport;