agpl_1.0.0_b5da3320/src/agpl-os_utils.adb

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
with Agpl.Interfaces.C.Types;
with Agpl.Strings;
with Agpl.Strings.Fields;
--  with Agpl.Trace; use Agpl.Trace;
with Interfaces.C;
with Interfaces.C.Strings;

package body Agpl.Os_Utils is

   package Ic renames Standard.Interfaces.C;
   package Agpl_C renames Agpl.Interfaces.C.Types;

   function Get_Free_Disk_Space (Path : String := ".") return Float
   is
      C_Path : constant Agpl_C.Cstring := Agpl_C.New_Cstring (Path);

      function Internal (Path : Ic.Strings.Chars_Ptr) return Ic.double;
      pragma Import (C, Internal, "agpl__os_utils__get_free_disk_space_c");
   begin
      return Float (Internal (C_Path.Ptr));
   end Get_Free_Disk_Space;

   -----------
   -- Spawn --
   -----------

   function Spawn (Command : String) return Integer is
      Cc : constant Agpl_C.Cstring := Agpl_C.New_Cstring (Command);

      function Spawn_C (Command : Ic.Strings.Chars_Ptr) return Ic.Int;
      pragma Import (C, Spawn_C, "agpl__os_utils__spawn_c");
   begin
      return Integer (Spawn_C (Cc.Ptr));
   end Spawn;

   -------------------------------
   -- Network_Interfaces_Length --
   -------------------------------

   function Network_Interfaces_Length return Natural is
      function C_Internal return Agpl_C.Int;
      pragma Import (C, C_Internal, "agpl__os_utils__num_ifaces");
   begin
      return Natural (C_Internal);
   end Network_Interfaces_Length;

   ------------------
   -- Ip_Addresses --
   ------------------

   function Ip_Addresses return Address_Vector is
      Addresses : Address_Vector;

      function C_Internal (Index : Agpl_C.Int;
                           Addr  : Ic.Strings.Chars_Ptr) return Agpl_C.Return_Code;
      pragma Import (C, C_Internal, "agpl__os_utils__iface_addr");
   begin
      for I in 1 .. Network_Interfaces_Length loop
         declare
            use Agpl_C;
            Addr : constant Agpl_C.Cstring :=
              Agpl_C.New_Cstring ("255.255.255.255");
         begin
            if C_Internal (Agpl_C.Int (I), Addr.Ptr) = Return_Ok then
               Addresses.Append (Addr.Value);
            else
               raise Program_Error with "IP_Addresses internal call failed";
            end if;
         end;
      end loop;

      return Addresses;
   end Ip_Addresses;

   ------------------
   -- Address_Kind --
   ------------------

   function Address_Kind (Address : String) return Address_Kinds is
      use Agpl.Strings;
      use Agpl.Strings.Fields;

      function Is_Valid return Boolean is
      begin
         if Num_Tokens (Address, '.') /= 4 then
            return False;
         end if;

         for I in 1 .. 4 loop
            declare
               Val : constant Integer :=
                 Integer'Value (Select_Field (Address, I, '.'));
            begin
               if Val < 0 or else Val > 255 or else
                 Trim (Val'Img) /= Select_Field (Address, I, '.')
               then
                  return False;
               end if;
            end;
         end loop;

         return True;
      exception
         when others =>
            return False;
      end Is_Valid;

   begin
      if not Is_Valid then
         return Malformed;
      end if;

      if Head (Address, '.') = "0" then
         return Malformed;
      elsif Head (Address, '.') = "127" then
         return Local;
      elsif Head (Address, '.') = "10" then
         return Internal;
      elsif Head (Address, '.') = "192" and then
        Select_Field (Address, 2, '.') = "168"
      then
         return Internal;
      elsif Head (Address, '.') = "172" and then
        Natural'Value (Select_Field (Address, 2, '.')) in 16 .. 31
      then
         return Internal;
      else
         return Public;
      end if;
   end Address_Kind;

end Agpl.Os_Utils;