Source file : ada_directories_extensions.adb
-- (c) Martin M. Dowie, 2003-2004
pragma License (Modified_GPL);
with Ada.Exceptions; use Ada.Exceptions;
with Ada.Unchecked_Conversion;
with GNAT.Calendar;
with Interfaces.C.Strings; use Interfaces.C.Strings;
with Win32.crt.Stat;
with Win32.crt.Time;
with Win32.crt.Utime;
package body Ada_Directories_Extensions is
type utimbuf_ptr is access all Win32.crt.Utime.utimbuf;
pragma Convention (C, utimbuf_ptr);
Null_utimbuf_ptr : constant utimbuf_ptr := null;
--------------
-- To_PCSTR --
--------------
function To_PCSTR is
new Ada.Unchecked_Conversion (Interfaces.C.Strings.chars_ptr,
Win32.PCSTR);
-----------
-- To_tm --
-----------
function To_tm (From : Ada.Calendar.Time)
return Win32.crt.Time.tm;
-----------
-- utime --
-----------
-- Can't use Win32.crt.Utime binding as it is wrong. It uses
-- an access parameter which means we can't pass 'NULL' which
-- is actually a valid value to pass and the one required to
-- provide this 'touch' facility.
--
function utime (filename : Interfaces.C.Strings.chars_ptr;
utimbuf : utimbuf_ptr)
return Interfaces.C.int;
pragma Import (C, utime, "_utime");
-----------------------
-- Set_Access_Time --
-----------------------
procedure Set_Access_Time (Directory_Entry : in Directory_Entry_Type;
To : in Ada.Calendar.Time) is
begin
Set_Access_Time (Full_Name (Directory_Entry), To);
end Set_Access_Time;
-----------------------
-- Set_Access_Time --
-----------------------
procedure Set_Access_Time (Name : in String;
To : in Ada.Calendar.Time) is
use type Interfaces.C.int;
File_Stat : aliased Win32.crt.Stat.struct_stat;
C_Name : constant Win32.PCSTR :=
To_PCSTR (New_String (Full_Name (Name)));
Ok : constant Interfaces.C.int :=
Win32.crt.Stat.stat (C_Name, File_Stat'Access);
begin
if Ok /= 0 then
-- Validate (Name);
Raise_Exception (Use_Error'Identity,
"Unknown fault in setting access time");
end if;
declare
Tm : aliased Win32.crt.Time.tm := To_tm (To);
Buffer : aliased Win32.crt.Utime.utimbuf :=
(actime => Win32.crt.Time.mktime (Tm'Access),
modtime => File_Stat.st_mtime);
Ok : constant Interfaces.C.int :=
utime (New_String (Full_Name (Name)),
Buffer'Unchecked_Access);
begin
if Ok /= 0 then
Raise_Exception (Program_Error'Identity,
"Could not change time - check access rights [" &
Simple_Name (Name) & "]");
end if;
end;
end Set_Access_Time;
---------------------------
-- Set_Modification_Time --
---------------------------
procedure Set_Modification_Time (Directory_Entry : in Directory_Entry_Type;
To : in Ada.Calendar.Time) is
begin
Set_Modification_Time (Full_Name (Directory_Entry), To);
end Set_Modification_Time;
---------------------------
-- Set_Modification_Time --
---------------------------
procedure Set_Modification_Time (Name : in String;
To : in Ada.Calendar.Time) is
use type Interfaces.C.int;
File_Stat : aliased Win32.crt.Stat.struct_stat;
C_Name : constant Win32.PCSTR :=
To_PCSTR (New_String (Full_Name (Name)));
Ok : constant Interfaces.C.int :=
Win32.crt.Stat.stat (C_Name, File_Stat'Access);
begin
if Ok /= 0 then
-- Validate (Name);
Raise_Exception (Use_Error'Identity,
"Unknown fault in setting modification time");
end if;
declare
Tm : aliased Win32.crt.Time.tm := To_tm (To);
Buffer : aliased Win32.crt.Utime.utimbuf :=
(actime => File_Stat.st_atime,
modtime => Win32.crt.Time.mktime (Tm'Access));
Ok : constant Interfaces.C.int :=
utime (New_String (Full_Name (Name)),
Buffer'Unchecked_Access);
begin
if Ok /= 0 then
Raise_Exception (Program_Error'Identity,
"Could not change modification time - check " &
"access rights [" & Simple_Name (Name) & "]");
end if;
end;
end Set_Modification_Time;
---------------
-- Set_Times --
---------------
procedure Set_Times (Directory_Entry : in Directory_Entry_Type;
Access_Time : in Ada.Calendar.Time;
Modification_Time : in Ada.Calendar.Time) is
begin
Set_Times (Full_Name (Directory_Entry), Access_Time, Modification_Time);
end Set_Times;
---------------
-- Set_Times --
---------------
procedure Set_Times (Name : in String;
Access_Time : in Ada.Calendar.Time;
Modification_Time : in Ada.Calendar.Time) is
use type Interfaces.C.int;
File_Stat : aliased Win32.crt.Stat.struct_stat;
C_Name : constant Win32.PCSTR :=
To_PCSTR (New_String (Full_Name (Name)));
Ok : constant Interfaces.C.int :=
Win32.crt.Stat.stat (C_Name, File_Stat'Access);
begin
if Ok /= 0 then
-- Validate (Name);
Raise_Exception (Use_Error'Identity,
"Unknown fault in setting times");
end if;
declare
Atm : aliased Win32.crt.Time.tm := To_tm (Access_Time);
Mtm : aliased Win32.crt.Time.tm := To_tm (Modification_Time);
Buffer : aliased Win32.crt.Utime.utimbuf :=
(actime => Win32.crt.Time.mktime (Atm'Access),
modtime => Win32.crt.Time.mktime (Mtm'Access));
Ok : constant Interfaces.C.int :=
utime (New_String (Full_Name (Name)),
Buffer'Unchecked_Access);
begin
if Ok /= 0 then
Raise_Exception (Program_Error'Identity,
"Could not change times - check " &
"access rights [" & Simple_Name (Name) & "]");
end if;
end;
end Set_Times;
-----------------------------
-- Touch_Modification_Time --
-----------------------------
procedure Touch_Modification_Time
(Directory_Entry : in Directory_Entry_Type) is
begin
Touch_Modification_Time (Full_Name (Directory_Entry));
end Touch_Modification_Time;
-----------------------------
-- Touch_Modification_Time --
-----------------------------
procedure Touch_Modification_Time (Name : in String) is
use type Interfaces.C.int;
Ok : constant Interfaces.C.int := utime (New_String (Full_Name (Name)),
Null_utimbuf_ptr);
begin
if Ok /= 0 then
-- Validate (Name);
Raise_Exception (Program_Error'Identity,
"Could not change time - check access rights [" &
Simple_Name (Name) & "]");
end if;
end Touch_Modification_Time;
-----------
-- To_tm --
-----------
function To_tm (From : Ada.Calendar.Time)
return Win32.crt.Time.tm is
use type Win32.INT;
Year : Ada.Calendar.Year_Number;
Month : Ada.Calendar.Month_Number;
Day : Ada.Calendar.Day_Number;
Hour : GNAT.Calendar.Hour_Number;
Minute : GNAT.Calendar.Minute_Number;
Second : GNAT.Calendar.Second_Number;
Sub_Second : GNAT.Calendar.Second_Duration;
begin
GNAT.Calendar.Split
(From, Year, Month, Day, Hour, Minute, Second, Sub_Second);
return (tm_sec => Win32.INT (Second),
tm_min => Win32.INT (Minute),
tm_hour => Win32.INT (Hour),
tm_mday => Win32.INT (Day),
tm_mon => Win32.INT (Month) - 1,
tm_year => Win32.INT (Year) - 1900,
tm_wday => Win32.INT (GNAT.Calendar.Day_Name'Pos
(GNAT.Calendar.Day_Of_Week (From))),
tm_yday => Win32.INT (GNAT.Calendar.Day_In_Year (From)),
tm_isdst => -1);
end To_tm;
--------------
-- Validate --
--------------
procedure Validate (Name : in Directory_Entry_Type) is
begin
Validate (Full_Name (Name));
end Validate;
--------------
-- Validate --
--------------
procedure Validate (Name : in String) is
begin
-- if not Port.Is_Valid_Filename (Name) then
-- Raise_Exception (Name_Error'Identity,
-- "Invalid name [" & Name & "]");
-- end if;
if not Exists (Name) then
Raise_Exception (Use_Error'Identity,
"Does not exist [" & Name & "]");
end if;
end Validate;
end Ada_Directories_Extensions;
Zip-Ada: Ada library for zip archive files (.zip).
Ada programming.
Some news about Zip-Ada and other related Ada projects
on Gautier's blog.