Disk ARchive  2.4.12
 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 
25 
26 #ifndef SAR_HPP
27 #define SAR_HPP
28 
29 #include "../my_config.h"
30 
31 #include <string>
32 #include "infinint.hpp"
33 #include "generic_file.hpp"
34 #include "header.hpp"
35 #include "path.hpp"
36 #include "integers.hpp"
37 #include "hash_fichier.hpp"
38 
39 namespace libdar
40 {
41  // contextual is defined in generic_file module
42 
45 
47 
52  class sar : public generic_file, public contextual, protected mem_ui
53  {
54  public:
55 
57 
70  sar(user_interaction & dialog,
71  const std::string & base_name,
72  const std::string & extension,
73  const path & dir,
74  bool by_the_end,
75  const infinint & x_min_digits,
76  bool lax = false,
77  const std::string & execute = "");
78 
79 
81 
103  sar(user_interaction & dialog,
104  const std::string & base_name,
105  const std::string & extension,
106  const infinint & file_size,
107  const infinint & first_file_size,
108  bool x_warn_overwrite,
109  bool x_allow_overwrite,
110  const infinint & pause,
111  const path & dir,
112  const label & data_name,
113  const std::string & slice_permission,
114  const std::string & slice_user_ownership,
115  const std::string & slice_group_ownership,
116  hash_algo x_hash,
117  const infinint & x_min_digits,
118  bool format_07_compatible,
119  const std::string & execute = "");
120 
122 
123  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"); };
124 
126  ~sar();
127 
128  // inherited from generic_file
129  bool skip(const infinint &pos);
130  bool skip_to_eof();
131  bool skip_relative(S_I x);
133 
134  // informational routines
135  infinint get_sub_file_size() const { return size; };
136  infinint get_first_sub_file_size() const { return first_size; };
137  bool get_total_file_number(infinint &num) const { num = of_last_file_num; return of_last_file_known; };
138  bool get_last_file_size(infinint &num) const { num = of_last_file_size; return of_last_file_known; };
139 
140  // disable execution of user command when destroying the current object
141  void disable_natural_destruction() { natural_destruction = false; };
142 
143  // enable back execution of user command when destroying the current object
144  void enable_natural_destruction() { natural_destruction = true; };
145 
146  // true if sar's header is from an old archive format (<= "07")
147  bool is_an_old_start_end_archive() const { return old_sar; };
148 
149  // return the internal_name used to link slices toghether
150  const label & get_internal_name_used() const { return of_internal_name; };
151 
152  // return the data_name used to link slices toghether
153  const label & get_data_name() const { return of_data_name; };
154 
155  protected :
156  U_I inherited_read(char *a, U_I size);
157  void inherited_write(const char *a, U_I size);
158  void inherited_sync_write() {}; // nothing to do
159  void inherited_terminate();
160 
161  private :
162  path archive_dir; //< path where to look for slices
163  std::string base; //< archive base name
164  std::string ext; //< archive extension
165  std::string hook; //< command line to execute between slices
166  infinint size; //< size of slices
167  infinint first_size; //< size of first slice
168  infinint first_file_offset; //< where data start in the first slice
169  infinint other_file_offset; //< where data start in the slices other than the first
170  infinint file_offset; //< current reading/writing position in the current slice (relative to the whole slice file, including headers)
171  bool force_perm; //< enforce slice permission with perm field value below
172  U_I perm; //< permission to set when creating slices
173  std::string slice_user; //< user for new slices
174  std::string slice_group; //< group for new slice
175  hash_algo hash; //< whether to build a hashing when creating slices, and if so, which algorithm to use
176  infinint min_digits; //< minimum number of digits the slices number is stored with in the filename
177  bool natural_destruction; //< whether to execute commands between slices on object destruction
178 
179  // these following variables are modified by open_file / open_file_init
180  // else the are used only for reading
181  infinint of_current; //< number of the open slice
182  infinint size_of_current; //< size of the current slice (used in reading mode only)
183  infinint of_max_seen; //< highest slice number seen so far
184  bool of_last_file_known; //< whether the T terminal slice has been met
185  infinint of_last_file_num; //< number of the last slice (if met)
186  infinint of_last_file_size; //< size of the last slice (if met)
187  label of_internal_name; //< internal name shared in all slice header
188  label of_data_name; //< internal name linked to data (transparent to dar_xform and used by isolated catalogue as reference)
189  fichier *of_fd; //< file object currently openned
190  char of_flag; //< flags of the open file
191  bool initial; //< do not launch hook command-line during sar initialization
192  bool lax; //< whether to try to go further reading problems
193 
194  // these are the option flags
195  bool opt_warn_overwrite; //< a warning must be issued before overwriting a slice
196  bool opt_allow_overwrite; //< is slice overwriting allowed
197 
198  //
199  infinint pause; //< do we pause between slices
200  bool old_sar; //< in read-mode, is true if the read sar has an old header (format <= "07"), in write mode, is true if it is requested to build old slice headers
201 
202  bool skip_forward(U_I x); //< skip forward in sar global contents
203  bool skip_backward(U_I x); //< skip backward in sar global contents
204  void close_file(bool terminal); //< close current openned file, adding (in write mode only) a terminal mark (last slice) or not
205  void open_readonly(const char *fic, const infinint &num); //< open file of name "filename" for read only "num" is the slice number
206  void open_writeonly(const char *fic, const infinint &num); //< open file of name "filename" for write only "num" is the slice number
207  void open_file_init(); //< initialize some of_* fields
208  void open_file(infinint num); //< close current slice and open the slice 'num'
209  void set_offset(infinint offset); //< skip to current slice relative offset
210  void open_last_file(); //< open the last slice, ask the user, test, until last slice available
211  bool is_current_eof_a_normal_end_of_slice() const; //< return true if current reading position is at end of slice
212  infinint bytes_still_to_read_in_slice() const; //< returns the number of bytes expected before the end of slice
213  header make_write_header(const infinint &num, char flag);
214 
215  // function to lauch the eventually existing command to execute after/before each slice
216  void hook_execute(const infinint &num);
217  };
218 
219 
221 
222  class trivial_sar : public generic_file , public contextual, protected mem_ui
223  {
224  public:
226  trivial_sar(user_interaction & dialog, //< how to interact with the user
227  const std::string & base_name, //< archive basename to create
228  const std::string & extension, //< archive extension
229  const path & dir, //< where to store the archive
230  const label & data_name, //< tag that follows the data when archive is dar_xform'ed
231  const std::string & execute, //< command line to execute at end of slice creation
232  bool allow_over, //< whether to allow overwriting
233  bool warn_over, //< whether to warn before overwriting
234  const std::string & slice_permission, //< slice permission
235  const std::string & slice_user_ownership, //< slice user
236  const std::string & slice_group_ownership, //< slice group
237  hash_algo x_hash, //< whether to build a hash of the slice, and which algo to use for that
238  const infinint & min_digits, //< is the minimum number of digits the slices number is stored with in the filename
239  bool format_07_compatible); //< build a slice header backward compatible with 2.3.x
240 
241 
243  trivial_sar(user_interaction & dialog, //< how to interact with the user
244  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
245  bool lax); //< whether to be laxist or follow the normal and strict controlled procedure
246 
247 
249  trivial_sar(user_interaction & dialog,
250  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.
251  const label & data_name,
252  bool format_07_compatible,
253  const std::string & execute);
254 
256  trivial_sar(const trivial_sar & ref) : generic_file(ref), mem_ui(ref), archive_dir("/") { throw SRC_BUG; };
257 
259  ~trivial_sar();
260 
261  const trivial_sar & operator = (const trivial_sar & ref) { throw SRC_BUG; };
262 
263  bool skip(const infinint & pos) { if(is_terminated()) throw SRC_BUG; return reference->skip(pos + offset); };
264  bool skip_to_eof() { if(is_terminated()) throw SRC_BUG; return reference->skip_to_eof(); };
265  bool skip_relative(S_I x);
267 
268  // contextual inherited method
269  bool is_an_old_start_end_archive() const { return old_sar; };
270  const label & get_data_name() const { return of_data_name; };
271 
272  protected:
273  U_I inherited_read(char *a, U_I size);
274  void inherited_write(const char *a, U_I size) { reference->write(a, size); };
276  void inherited_terminate();
277 
278  private:
279  generic_file *reference; //< points to the underlying data, not owned by "this"
280  infinint offset; //< offset to apply to get the first byte of data out of SAR headers
281  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
282  std::string hook; //< command to execute after slice writing (not used in read-only mode)
283  std::string base; //< basename of the archive (used for string susbstitution in hook)
284  std::string ext; //< extension of the archive (used for string substitution in hook)
285  path archive_dir; //< path of the archiv (used for string substitution in hook)
286  label of_data_name; //< archive's data name
287  bool old_sar; //< true if the read sar has an old header (format <= "07") or the to be written is must keep a version 07 format.
288  infinint x_min_digits; //< minimum number of digits in slice name
289 
290  void init(); //< write the slice header and set the offset field (write mode), or (read-mode) reads the slice header an set offset field
291  void build(user_interaction & dialog,
292  generic_file *f,
293  const label & data_name,
294  const std::string & execute);
295  };
296 
297 
299 
300  extern std::string sar_make_filename(const std::string & base_name, const infinint & num, const infinint & min_digits, const std::string & ext);
301 
303 
304 } // end of namespace
305 
306 #endif