keystoreada_1.1.0_d28d822c/tools/akt-commands-extract.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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
-----------------------------------------------------------------------
--  akt-commands-extract -- Get content from keystore
--  Copyright (C) 2019 Stephane Carrez
--  Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
--  Licensed under the Apache License, Version 2.0 (the "License");
--  you may not use this file except in compliance with the License.
--  You may obtain a copy of the License at
--
--      http://www.apache.org/licenses/LICENSE-2.0
--
--  Unless required by applicable law or agreed to in writing, software
--  distributed under the License is distributed on an "AS IS" BASIS,
--  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--  See the License for the specific language governing permissions and
--  limitations under the License.
-----------------------------------------------------------------------
with Ada.Text_IO;
with Ada.Command_Line;
with Ada.Directories;
with Ada.Streams.Stream_IO;
with GNAT.Regpat;
with Util.Streams.Raw;
with Util.Systems.Os;
with Util.Files;
with Util.Streams.Files;
package body AKT.Commands.Extract is

   use GNAT.Strings;

   --  ------------------------------
   --  Get a value from the keystore.
   --  ------------------------------
   overriding
   procedure Execute (Command   : in out Command_Type;
                      Name      : in String;
                      Args      : in Argument_List'Class;
                      Context   : in out Context_Type) is
      pragma Unreferenced (Name);

      Output : Util.Streams.Raw.Raw_Stream;

      procedure Extract_Directory (Path   : in String;
                                   Output : in String);
      procedure Extract_Standard_Output (Name : in String);
      procedure Extract_File (Name   : in String;
                              Output : in String);

      procedure Extract_File (Name   : in String;
                              Output : in String) is
         Target : constant String
           := Util.Files.Compose ((if Output = "" then "." else Output), Name);
         Dir    : constant String
           := Ada.Directories.Containing_Directory (Target);
         File   : Util.Streams.Files.File_Stream;
      begin
         Ada.Directories.Create_Path (Dir);
         File.Create (Mode => Ada.Streams.Stream_IO.Out_File,
                      Name => Target);
         Context.Wallet.Get (Name   => Name,
                             Output => File);

      exception
         when Keystore.Not_Found =>
            AKT.Commands.Log.Error (-("Value '{0}' not found"), Name);
            Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);

      end Extract_File;

      procedure Extract_Directory (Path   : in String;
                                   Output : in String) is
         Pattern : constant GNAT.Regpat.Pattern_Matcher := GNAT.Regpat.Compile (Path & "/.*");
         List    : Keystore.Entry_Map;
         Iter    : Keystore.Entry_Cursor;
      begin
         Context.Wallet.List (Pattern => Pattern,
                              Filter  => (Keystore.T_FILE => True, others => False),
                              Content => List);
         if List.Is_Empty then
            AKT.Commands.Log.Error (-("Value '{0}' not found"), Path);
            Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);
            return;
         end if;

         Iter := List.First;
         while Keystore.Entry_Maps.Has_Element (Iter) loop
            declare
               Name   : constant String := Keystore.Entry_Maps.Key (Iter);
            begin
               Ada.Text_IO.Put_Line (-("Extract ") & Name);
               Extract_File (Name, Output);

            end;
            Keystore.Entry_Maps.Next (Iter);
         end loop;
      end Extract_Directory;

      procedure Extract_Standard_Output (Name : in String) is
      begin
         Context.Wallet.Get (Name, Output);

      exception
         when Keystore.Not_Found =>
            AKT.Commands.Log.Error (-("Value '{0}' not found"), Name);
            Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure);

      end Extract_Standard_Output;

   begin
      Context.Open_Keystore (Args, Use_Worker => True);

      if Context.First_Arg > Args.Get_Count then
         AKT.Commands.Log.Error (-("Missing file or directory to extract"));
         raise Error;
      end if;

      if Command.Use_Stdout then
         Output.Initialize (File => Util.Systems.Os.STDOUT_FILENO);

         for I in Context.First_Arg .. Args.Get_Count loop
            Extract_Standard_Output (Args.Get_Argument (I));
         end loop;
      else
         for I in Context.First_Arg .. Args.Get_Count loop
            declare
               Name : constant String := Args.Get_Argument (I);
            begin
               if Context.Wallet.Contains (Name) then
                  Extract_File (Name, Command.Output.all);

               else
                  Extract_Directory (Name, Command.Output.all);
               end if;
            end;
         end loop;
      end if;
   end Execute;

   --  ------------------------------
   --  Setup the command before parsing the arguments and executing it.
   --  ------------------------------
   procedure Setup (Command : in out Command_Type;
                    Config  : in out GNAT.Command_Line.Command_Line_Configuration;
                    Context : in out Context_Type) is
      package GC renames GNAT.Command_Line;
   begin
      Drivers.Command_Type (Command).Setup (Config, Context);
      GC.Define_Switch (Config, Command.Output'Access,
                        "-o:", "--output=",
                        -("Store the result in the output file or directory"));
      GC.Define_Switch (Config => Config,
                        Output => Command.Use_Stdout'Access,
                        Switch => "--",
                        Help => -("Use the standard input to read the content"));
   end Setup;

end AKT.Commands.Extract;