Disk ARchive
2.4.2
|
00001 /*********************************************************************/ 00002 // dar - disk archive - a backup/restoration program 00003 // Copyright (C) 2002-2052 Denis Corbin 00004 // 00005 // This program is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU General Public License 00007 // as published by the Free Software Foundation; either version 2 00008 // of the License, or (at your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with this program; if not, write to the Free Software 00017 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00018 // 00019 // to contact the author : http://dar.linux.free.fr/email.html 00020 /*********************************************************************/ 00021 // $Id: sar.hpp,v 1.51.2.1 2011/07/23 16:36:31 edrusb Rel $ 00022 // 00023 /*********************************************************************/ 00024 00025 00029 00030 #ifndef SAR_HPP 00031 #define SAR_HPP 00032 00033 #include "../my_config.h" 00034 00035 #include <string> 00036 #include "infinint.hpp" 00037 #include "generic_file.hpp" 00038 #include "header.hpp" 00039 #include "path.hpp" 00040 #include "integers.hpp" 00041 #include "hash_fichier.hpp" 00042 00043 namespace libdar 00044 { 00045 // contextual is defined in generic_file module 00046 00049 00051 00056 class sar : public generic_file, public contextual, protected mem_ui 00057 { 00058 public: 00059 00061 00074 sar(user_interaction & dialog, 00075 const std::string & base_name, 00076 const std::string & extension, 00077 const path & dir, 00078 bool by_the_end, 00079 const infinint & x_min_digits, 00080 bool lax = false, 00081 const std::string & execute = ""); 00082 00083 00085 00106 sar(user_interaction & dialog, 00107 const std::string & base_name, 00108 const std::string & extension, 00109 const infinint & file_size, 00110 const infinint & first_file_size, 00111 bool x_warn_overwrite, 00112 bool x_allow_overwrite, 00113 const infinint & pause, 00114 const path & dir, 00115 const label & data_name, 00116 const std::string & slice_permission, 00117 const std::string & slice_user_ownership, 00118 const std::string & slice_group_ownership, 00119 hash_algo x_hash, 00120 const infinint & x_min_digits, 00121 const std::string & execute = ""); 00122 00124 00125 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"); }; 00126 00128 ~sar(); 00129 00130 // inherited from generic_file 00131 bool skip(const infinint &pos); 00132 bool skip_to_eof(); 00133 bool skip_relative(S_I x); 00134 infinint get_position(); 00135 00136 // informational routines 00137 infinint get_sub_file_size() const { return size; }; 00138 infinint get_first_sub_file_size() const { return first_size; }; 00139 bool get_total_file_number(infinint &num) const { num = of_last_file_num; return of_last_file_known; }; 00140 bool get_last_file_size(infinint &num) const { num = of_last_file_size; return of_last_file_known; }; 00141 00142 // disable execution of user command when destroying the current object 00143 void disable_natural_destruction() { natural_destruction = false; }; 00144 00145 // enable back execution of user command when destroying the current object 00146 void enable_natural_destruction() { natural_destruction = true; }; 00147 00148 // true if sar's header is from an old archive format (<= "07") 00149 bool is_an_old_start_end_archive() const { return old_sar; }; 00150 00151 // return the internal_name used to link slices toghether 00152 const label & get_internal_name_used() const { return of_internal_name; }; 00153 00154 // return the data_name used to link slices toghether 00155 const label & get_data_name() const { return of_data_name; }; 00156 00157 protected : 00158 U_I inherited_read(char *a, U_I size); 00159 void inherited_write(const char *a, U_I size); 00160 void inherited_sync_write() {}; // nothing to do 00161 void inherited_terminate(); 00162 00163 private : 00164 path archive_dir; //< path where to look for slices 00165 std::string base; //< archive base name 00166 std::string ext; //< archive extension 00167 std::string hook; //< command line to execute between slices 00168 infinint size; //< size of slices 00169 infinint first_size; //< size of first slice 00170 infinint first_file_offset; //< where data start in the first slice 00171 infinint other_file_offset; //< where data start in the slices other than the first 00172 infinint file_offset; //< current reading/writing position in the current slice (relative to the whole slice file, including headers) 00173 U_I perm; //< permission to set when creating slices 00174 std::string slice_user; //< user for new slices 00175 std::string slice_group; //< group for new slice 00176 hash_algo hash; //< whether to build a hashing when creating slices, and if so, which algorithm to use 00177 infinint min_digits; //< minimum number of digits the slices number is stored with in the filename 00178 bool natural_destruction; //< whether to execute commands between slices on object destruction 00179 00180 // these following variables are modified by open_file / open_file_init 00181 // else the are used only for reading 00182 infinint of_current; //< number of the open slice 00183 infinint size_of_current; //< size of the current slice (used in reading mode only) 00184 infinint of_max_seen; //< highest slice number seen so far 00185 bool of_last_file_known; //< whether the T terminal slice has been met 00186 infinint of_last_file_num; //< number of the last slice (if met) 00187 infinint of_last_file_size; //< size of the last slice (if met) 00188 label of_internal_name; //< internal name shared in all slice header 00189 label of_data_name; //< internal name linked to data (transparent to dar_xform and used by isolated catalogue as reference) 00190 fichier *of_fd; //< file object currently openned 00191 char of_flag; //< flags of the open file 00192 bool initial; //< do not launch hook command-line during sar initialization 00193 bool lax; //< whether to try to go further reading problems 00194 00195 // these are the option flags 00196 bool opt_warn_overwrite; //< a warning must be issued before overwriting a slice 00197 bool opt_allow_overwrite; //< is slice overwriting allowed 00198 00199 // 00200 infinint pause; //< do we pause between slices 00201 bool old_sar; //< true if the read sar has an old header (format <= "07") 00202 00203 bool skip_forward(U_I x); //< skip forward in sar global contents 00204 bool skip_backward(U_I x); //< skip backward in sar global contents 00205 void close_file(bool terminal); //< close current openned file, adding (in write mode only) a terminal mark (last slice) or not 00206 void open_readonly(const char *fic, const infinint &num); //< open file of name "filename" for read only "num" is the slice number 00207 void open_writeonly(const char *fic, const infinint &num); //< open file of name "filename" for write only "num" is the slice number 00208 void open_file_init(); //< initialize some of_* fields 00209 void open_file(infinint num); //< close current slice and open the slice 'num' 00210 void set_offset(infinint offset); //< skip to current slice relative offset 00211 void open_last_file(); //< open the last slice, ask the user, test, until last slice available 00212 bool is_current_eof_a_normal_end_of_slice() const; //< return true if current reading position is at end of slice 00213 infinint bytes_still_to_read_in_slice() const; //< returns the number of bytes expected before the end of slice 00214 header make_write_header(const infinint &num, char flag); 00215 00216 // function to lauch the eventually existing command to execute after/before each slice 00217 void hook_execute(const infinint &num); 00218 }; 00219 00220 00222 00223 class trivial_sar : public generic_file , public contextual, protected mem_ui 00224 { 00225 public: 00227 trivial_sar(user_interaction & dialog, //< how to interact with the user 00228 const std::string & base_name, //< archive basename to create 00229 const std::string & extension, //< archive extension 00230 const path & dir, //< where to store the archive 00231 const label & data_name, //< tag that follows the data when archive is dar_xform'ed 00232 const std::string & execute, //< command line to execute at end of slice creation 00233 bool allow_over, //< whether to allow overwriting 00234 bool warn_over, //< whether to warn before overwriting 00235 const std::string & slice_permission, //< slice permission 00236 const std::string & slice_user_ownership, //< slice user 00237 const std::string & slice_group_ownership, //< slice group 00238 hash_algo x_hash, //< whether to build a hash of the slice, and which algo to use for that 00239 const infinint & min_digits); //< is the minimum number of digits the slices number is stored with in the filename 00240 00242 trivial_sar(user_interaction & dialog, //< how to interact with the user 00243 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 00244 bool lax); //< whether to be laxist or follow the normal and strict controlled procedure 00245 00246 00248 trivial_sar(user_interaction & dialog, 00249 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. 00250 const label & data_name, 00251 const std::string & execute); 00252 00254 trivial_sar(const trivial_sar & ref) : generic_file(ref), mem_ui(ref), archive_dir("/") { throw SRC_BUG; }; 00255 00257 ~trivial_sar(); 00258 00259 const trivial_sar & operator = (const trivial_sar & ref) { throw SRC_BUG; }; 00260 00261 bool skip(const infinint & pos) { if(is_terminated()) throw SRC_BUG; return reference->skip(pos + offset); }; 00262 bool skip_to_eof() { if(is_terminated()) throw SRC_BUG; return reference->skip_to_eof(); }; 00263 bool skip_relative(S_I x); 00264 infinint get_position(); 00265 00266 // contextual inherited method 00267 bool is_an_old_start_end_archive() const { return old_sar; }; 00268 const label & get_data_name() const { return of_data_name; }; 00269 00270 protected: 00271 U_I inherited_read(char *a, U_I size); 00272 void inherited_write(const char *a, U_I size) { reference->write(a, size); }; 00273 void inherited_sync_write() {}; 00274 void inherited_terminate(); 00275 00276 private: 00277 generic_file *reference; //< points to the underlying data, not owned by "this" 00278 infinint offset; //< offset to apply to get the first byte of data out of SAR headers 00279 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 00280 std::string hook; //< command to execute after slice writing (not used in read-only mode) 00281 std::string base; //< basename of the archive (used for string susbstitution in hook) 00282 std::string ext; //< extension of the archive (used for string substitution in hook) 00283 path archive_dir; //< path of the archiv (used for string substitution in hook) 00284 label of_data_name; //< archive's data name 00285 bool old_sar; //< true if the read sar has an old header (format <= "07") 00286 infinint x_min_digits; //< minimum number of digits in slice name 00287 00288 void init(); //< write the slice header and set the offset field (write mode), or (read-mode), reads the slice header an set offset field 00289 void build(user_interaction & dialog, 00290 generic_file *f, 00291 const label & data_name, 00292 const std::string & execute); 00293 }; 00294 00295 00297 00298 extern std::string sar_make_filename(const std::string & base_name, const infinint & num, const infinint & min_digits, const std::string & ext); 00299 00301 00302 } // end of namespace 00303 00304 #endif