Disk ARchive  2.4.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
sar.hpp
Go to the documentation of this file.
1 /*********************************************************************/
2 // dar - disk archive - a backup/restoration program
3 // Copyright (C) 2002-2052 Denis Corbin
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 //
19 // to contact the author : http://dar.linux.free.fr/email.html
20 /*********************************************************************/
21 // $Id: sar.hpp,v 1.51.2.1 2011/07/23 16:36:31 edrusb Rel $
22 //
23 /*********************************************************************/
24 
25 
29 
30 #ifndef SAR_HPP
31 #define SAR_HPP
32 
33 #include "../my_config.h"
34 
35 #include <string>
36 #include "infinint.hpp"
37 #include "generic_file.hpp"
38 #include "header.hpp"
39 #include "path.hpp"
40 #include "integers.hpp"
41 #include "hash_fichier.hpp"
42 
43 namespace libdar
44 {
45  // contextual is defined in generic_file module
46 
49 
51 
56  class sar : public generic_file, public contextual, protected mem_ui
57  {
58  public:
59 
61 
74  sar(user_interaction & dialog,
75  const std::string & base_name,
76  const std::string & extension,
77  const path & dir,
78  bool by_the_end,
79  const infinint & x_min_digits,
80  bool lax = false,
81  const std::string & execute = "");
82 
83 
85 
106  sar(user_interaction & dialog,
107  const std::string & base_name,
108  const std::string & extension,
109  const infinint & file_size,
110  const infinint & first_file_size,
111  bool x_warn_overwrite,
112  bool x_allow_overwrite,
113  const infinint & pause,
114  const path & dir,
115  const label & data_name,
116  const std::string & slice_permission,
117  const std::string & slice_user_ownership,
118  const std::string & slice_group_ownership,
119  hash_algo x_hash,
120  const infinint & x_min_digits,
121  const std::string & execute = "");
122 
124 
125  sar(const sar & ref) : generic_file(ref), mem_ui(ref), archive_dir(ref.archive_dir) { throw Efeature("class sar's copy constructor is not implemented"); };
126 
128  ~sar();
129 
130  // inherited from generic_file
131  bool skip(const infinint &pos);
132  bool skip_to_eof();
133  bool skip_relative(S_I x);
135 
136  // informational routines
137  infinint get_sub_file_size() const { return size; };
138  infinint get_first_sub_file_size() const { return first_size; };
139  bool get_total_file_number(infinint &num) const { num = of_last_file_num; return of_last_file_known; };
140  bool get_last_file_size(infinint &num) const { num = of_last_file_size; return of_last_file_known; };
141 
142  // disable execution of user command when destroying the current object
143  void disable_natural_destruction() { natural_destruction = false; };
144 
145  // enable back execution of user command when destroying the current object
146  void enable_natural_destruction() { natural_destruction = true; };
147 
148  // true if sar's header is from an old archive format (<= "07")
149  bool is_an_old_start_end_archive() const { return old_sar; };
150 
151  // return the internal_name used to link slices toghether
152  const label & get_internal_name_used() const { return of_internal_name; };
153 
154  // return the data_name used to link slices toghether
155  const label & get_data_name() const { return of_data_name; };
156 
157  protected :
158  U_I inherited_read(char *a, U_I size);
159  void inherited_write(const char *a, U_I size);
160  void inherited_sync_write() {}; // nothing to do
161  void inherited_terminate();
162 
163  private :
164  path archive_dir; //< path where to look for slices
165  std::string base; //< archive base name
166  std::string ext; //< archive extension
167  std::string hook; //< command line to execute between slices
168  infinint size; //< size of slices
169  infinint first_size; //< size of first slice
170  infinint first_file_offset; //< where data start in the first slice
171  infinint other_file_offset; //< where data start in the slices other than the first
172  infinint file_offset; //< current reading/writing position in the current slice (relative to the whole slice file, including headers)
173  U_I perm; //< permission to set when creating slices
174  std::string slice_user; //< user for new slices
175  std::string slice_group; //< group for new slice
176  hash_algo hash; //< whether to build a hashing when creating slices, and if so, which algorithm to use
177  infinint min_digits; //< minimum number of digits the slices number is stored with in the filename
178  bool natural_destruction; //< whether to execute commands between slices on object destruction
179 
180  // these following variables are modified by open_file / open_file_init
181  // else the are used only for reading
182  infinint of_current; //< number of the open slice
183  infinint size_of_current; //< size of the current slice (used in reading mode only)
184  infinint of_max_seen; //< highest slice number seen so far
185  bool of_last_file_known; //< whether the T terminal slice has been met
186  infinint of_last_file_num; //< number of the last slice (if met)
187  infinint of_last_file_size; //< size of the last slice (if met)
188  label of_internal_name; //< internal name shared in all slice header
189  label of_data_name; //< internal name linked to data (transparent to dar_xform and used by isolated catalogue as reference)
190  fichier *of_fd; //< file object currently openned
191  char of_flag; //< flags of the open file
192  bool initial; //< do not launch hook command-line during sar initialization
193  bool lax; //< whether to try to go further reading problems
194 
195  // these are the option flags
196  bool opt_warn_overwrite; //< a warning must be issued before overwriting a slice
197  bool opt_allow_overwrite; //< is slice overwriting allowed
198 
199  //
200  infinint pause; //< do we pause between slices
201  bool old_sar; //< true if the read sar has an old header (format <= "07")
202 
203  bool skip_forward(U_I x); //< skip forward in sar global contents
204  bool skip_backward(U_I x); //< skip backward in sar global contents
205  void close_file(bool terminal); //< close current openned file, adding (in write mode only) a terminal mark (last slice) or not
206  void open_readonly(const char *fic, const infinint &num); //< open file of name "filename" for read only "num" is the slice number
207  void open_writeonly(const char *fic, const infinint &num); //< open file of name "filename" for write only "num" is the slice number
208  void open_file_init(); //< initialize some of_* fields
209  void open_file(infinint num); //< close current slice and open the slice 'num'
210  void set_offset(infinint offset); //< skip to current slice relative offset
211  void open_last_file(); //< open the last slice, ask the user, test, until last slice available
212  bool is_current_eof_a_normal_end_of_slice() const; //< return true if current reading position is at end of slice
213  infinint bytes_still_to_read_in_slice() const; //< returns the number of bytes expected before the end of slice
214  header make_write_header(const infinint &num, char flag);
215 
216  // function to lauch the eventually existing command to execute after/before each slice
217  void hook_execute(const infinint &num);
218  };
219 
220 
222 
223  class trivial_sar : public generic_file , public contextual, protected mem_ui
224  {
225  public:
227  trivial_sar(user_interaction & dialog, //< how to interact with the user
228  const std::string & base_name, //< archive basename to create
229  const std::string & extension, //< archive extension
230  const path & dir, //< where to store the archive
231  const label & data_name, //< tag that follows the data when archive is dar_xform'ed
232  const std::string & execute, //< command line to execute at end of slice creation
233  bool allow_over, //< whether to allow overwriting
234  bool warn_over, //< whether to warn before overwriting
235  const std::string & slice_permission, //< slice permission
236  const std::string & slice_user_ownership, //< slice user
237  const std::string & slice_group_ownership, //< slice group
238  hash_algo x_hash, //< whether to build a hash of the slice, and which algo to use for that
239  const infinint & min_digits); //< is the minimum number of digits the slices number is stored with in the filename
240 
242  trivial_sar(user_interaction & dialog, //< how to interact with the user
243  const std::string & pipename, //< if set to '-' the data are read from standard input, else the given file is expected to be named pipe to read data from
244  bool lax); //< whether to be laxist or follow the normal and strict controlled procedure
245 
246 
248  trivial_sar(user_interaction & dialog,
249  generic_file * f, //< in case of exception the generic_file "f" is not released, this is the duty of the caller to do so, else (success), the object becomes owned by the trivial_sar and must not be released by the caller.
250  const label & data_name,
251  const std::string & execute);
252 
254  trivial_sar(const trivial_sar & ref) : generic_file(ref), mem_ui(ref), archive_dir("/") { throw SRC_BUG; };
255 
257  ~trivial_sar();
258 
259  const trivial_sar & operator = (const trivial_sar & ref) { throw SRC_BUG; };
260 
261  bool skip(const infinint & pos) { if(is_terminated()) throw SRC_BUG; return reference->skip(pos + offset); };
262  bool skip_to_eof() { if(is_terminated()) throw SRC_BUG; return reference->skip_to_eof(); };
263  bool skip_relative(S_I x);
265 
266  // contextual inherited method
267  bool is_an_old_start_end_archive() const { return old_sar; };
268  const label & get_data_name() const { return of_data_name; };
269 
270  protected:
271  U_I inherited_read(char *a, U_I size);
272  void inherited_write(const char *a, U_I size) { reference->write(a, size); };
274  void inherited_terminate();
275 
276  private:
277  generic_file *reference; //< points to the underlying data, not owned by "this"
278  infinint offset; //< offset to apply to get the first byte of data out of SAR headers
279  infinint end_of_slice; //< when end of slice/archive is met, there is an offset by 1 compared to the offset of reference. end_of_slice is set to 1 in that situation, else it is always equal to zero
280  std::string hook; //< command to execute after slice writing (not used in read-only mode)
281  std::string base; //< basename of the archive (used for string susbstitution in hook)
282  std::string ext; //< extension of the archive (used for string substitution in hook)
283  path archive_dir; //< path of the archiv (used for string substitution in hook)
284  label of_data_name; //< archive's data name
285  bool old_sar; //< true if the read sar has an old header (format <= "07")
286  infinint x_min_digits; //< minimum number of digits in slice name
287 
288  void init(); //< write the slice header and set the offset field (write mode), or (read-mode), reads the slice header an set offset field
289  void build(user_interaction & dialog,
290  generic_file *f,
291  const label & data_name,
292  const std::string & execute);
293  };
294 
295 
297 
298  extern std::string sar_make_filename(const std::string & base_name, const infinint & num, const infinint & min_digits, const std::string & ext);
299 
301 
302 } // end of namespace
303 
304 #endif