1
------------------------------------------------------------------------------
5
-- S Y S T E M . G A R L I C . N A M I N G --
11
-- Copyright (C) 1996,1997 Free Software Foundation, Inc. --
13
-- GARLIC is free software; you can redistribute it and/or modify it under --
14
-- terms of the GNU General Public License as published by the Free Soft- --
15
-- ware Foundation; either version 2, or (at your option) any later ver- --
16
-- sion. GARLIC is distributed in the hope that it will be useful, but --
17
-- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABI- --
18
-- LITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --
19
-- License for more details. You should have received a copy of the GNU --
20
-- General Public License distributed with GARLIC; see file COPYING. If --
21
-- not, write to the Free Software Foundation, 59 Temple Place - Suite 330, --
22
-- Boston, MA 02111-1307, USA. --
24
-- As a special exception, if other files instantiate generics from this --
25
-- unit, or you link this unit with other files to produce an executable, --
26
-- this unit does not by itself cause the resulting executable to be --
27
-- covered by the GNU General Public License. This exception does not --
28
-- however invalidate any other reasons why the executable file might be --
29
-- covered by the GNU Public License. --
31
-- GLADE is maintained by ACT Europe. --
32
-- (email: glade-report@act-europe.fr) --
34
------------------------------------------------------------------------------
37
with Interfaces.C; use Interfaces.C;
38
with Interfaces.C.Strings; use Interfaces.C.Strings;
39
with System.Garlic.Constants; use System.Garlic.Constants;
40
with System.Garlic.OS_Lib; use System.Garlic.OS_Lib;
41
with Unchecked_Conversion;
42
with Unchecked_Deallocation;
44
package body System.Garlic.Naming is
48
Default_Buffer_Size : constant := 16384;
51
new Unchecked_Deallocation (char_array, char_array_access);
53
function Allocate (Size : Positive := Default_Buffer_Size)
54
return char_array_access;
57
function Parse_Entry (Host : Hostent)
61
procedure Raise_Naming_Error
64
-- Raise the exception Naming_Error with an appropriate error message.
66
protected Gethost_In_Progress is
70
Locked : Boolean := False;
71
end Gethost_In_Progress;
72
-- We have to protect this.
78
function Address_Of (Something : String)
82
if Is_IP_Address (Something) then
83
return Value (Something);
85
return Info_Of (Something) .Addresses (1);
93
procedure Adjust (Object : in out Host_Entry)
95
Aliases : String_Array renames Object.Aliases;
97
Object.Name := new String'(Object.Name.all);
98
for I in Aliases'Range loop
99
Aliases (I) := new String'(Aliases (I) .all);
108
(Size : Positive := Default_Buffer_Size)
109
return char_array_access
112
return new char_array (1 .. size_t (Size));
119
function Any_Address return Address
122
return To_Address (Inaddr_Any);
129
procedure Finalize (Object : in out Host_Entry)
131
Aliases : String_Array renames Object.Aliases;
133
new Unchecked_Deallocation (String, String_Access);
136
for I in Aliases'Range loop
141
-------------------------
142
-- Gethost_In_Progress --
143
-------------------------
145
protected body Gethost_In_Progress is
151
entry Lock when not Locked is
165
end Gethost_In_Progress;
171
function Host_Name return String
173
Buff : char_array_access := Allocate;
174
Buffer : constant chars_ptr := To_Chars_Ptr (Buff);
175
Res : constant int := C_Gethostname (Buffer, Buff'Length);
177
if Res = Failure then
179
Raise_Naming_Error (C_Errno, "");
182
Result : constant String := Value (Buffer);
193
function Image (Add : Address) return String
196
function Image (A : Address_Component) return String;
197
-- Return the string corresponding to its argument without
198
-- the leading space.
204
function Image (A : Address_Component)
207
Im : constant String := Address_Component'Image (A);
209
return Im (2 .. Im'Last);
213
return Image (Add.H1) & "." & Image (Add.H2) & "." &
214
Image (Add.H3) & "." & Image (Add.H4);
221
function Info_Of (Name : String)
224
Res : Hostent_Access;
225
C_Name : chars_ptr := New_String (Name);
227
Gethost_In_Progress.Lock;
228
Res := C_Gethostbyname (C_Name);
231
Gethost_In_Progress.Unlock;
232
Raise_Naming_Error (C_Errno, Name);
235
Result : constant Host_Entry := Parse_Entry (Res.all);
237
Gethost_In_Progress.Unlock;
246
function Info_Of (Addr : Address)
250
new Unchecked_Conversion (Source => In_Addr_Access,
251
Target => chars_ptr);
252
Temp : aliased In_Addr := To_In_Addr (Addr);
253
C_Addr : constant chars_ptr := Convert (Temp'Unchecked_Access);
254
Res : Hostent_Access;
256
Gethost_In_Progress.Lock;
257
Res := C_Gethostbyaddr (C_Addr,
258
C.Int (Temp'Size / CHAR_BIT),
261
Gethost_In_Progress.Unlock;
262
Raise_Naming_Error (C_Errno, Image (Addr));
265
Result : constant Host_Entry := Parse_Entry (Res.all);
267
Gethost_In_Progress.Unlock;
272
------------------------
273
-- Info_Of_Name_Or_IP --
274
------------------------
276
function Info_Of_Name_Or_IP (Something : String)
280
if Is_IP_Address (Something) then
281
return Info_Of (Value (Something));
283
return Info_Of (Something);
285
end Info_Of_Name_Or_IP;
291
function Is_IP_Address (Something : String)
294
First : constant Natural := Character'Pos (Something (Something'First));
296
return First >= Character'Pos ('0') and then
297
First <= Character'Pos ('9');
304
function Name_Of (Something : String)
307
Hostent : constant Host_Entry := Info_Of_Name_Or_IP (Something);
309
if Hostent.Name = null then
310
Ada.Exceptions.Raise_Exception (Naming_Error'Identity,
311
"No name for " & Something);
313
return Hostent.Name.all;
320
function Parse_Entry (Host : Hostent)
323
C_Aliases : constant Thin.Chars_Ptr_Array :=
324
Chars_Ptr_Pointers.Value (Host.H_Aliases);
325
C_Addr : constant In_Addr_Access_Array :=
326
In_Addr_Access_Pointers.Value
328
Result : Host_Entry (N_Aliases => C_Aliases'Length - 1,
329
N_Addresses => C_Addr'Length - 1);
331
Result.Name := new String'(Value (Host.H_Name));
332
for I in 1 .. Result.Aliases'Last loop
334
Index : Natural := I - 1 + Natural (C_Aliases'First);
335
Current : chars_ptr renames C_Aliases (size_t (Index));
337
Result.Aliases (I) := new String'(Value (Current));
340
for I in Result.Addresses'Range loop
342
Index : Natural := I - 1 + Natural (C_Addr'First);
343
Current : In_Addr_Access renames C_Addr (Index);
345
Result.Addresses (I) := To_Address (Current.all);
351
------------------------
352
-- Raise_Naming_Error --
353
------------------------
355
procedure Raise_Naming_Error
360
function Error_Message return String;
361
-- Return the message according to Errno.
367
function Error_Message return String is
370
when Host_Not_Found => return "Host not found";
371
when Try_Again => return "Try again";
372
when No_Recovery => return "No recovery";
373
when No_Address => return "No address";
374
when others => return "Unknown error" &
380
Ada.Exceptions.Raise_Exception (Naming_Error'Identity,
381
Error_Message & ": " & Message);
382
end Raise_Naming_Error;
388
function To_Address (Addr : In_Addr) return Address
391
return (H1 => Address_Component (Addr.S_B1),
392
H2 => Address_Component (Addr.S_B2),
393
H3 => Address_Component (Addr.S_B3),
394
H4 => Address_Component (Addr.S_B4));
401
function To_In_Addr (Addr : Address) return In_Addr
404
return (S_B1 => unsigned_char (Addr.H1),
405
S_B2 => unsigned_char (Addr.H2),
406
S_B3 => unsigned_char (Addr.H3),
407
S_B4 => unsigned_char (Addr.H4));
414
function Value (Add : String) return Address
417
new Unchecked_Conversion (Source => unsigned_long,
419
C_Add : chars_ptr := New_String (Add);
420
Converted : constant In_Addr := Convert (C_Inet_Addr (C_Add));
423
return (H1 => Address_Component (Converted.S_B1),
424
H2 => Address_Component (Converted.S_B2),
425
H3 => Address_Component (Converted.S_B3),
426
H4 => Address_Component (Converted.S_B4));
429
end System.Garlic.Naming;