![]() |
Disk ARchive
2.5.2
Full featured and portable backup and archiving tool
|
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 00031 00032 #ifndef FILESYSTEM_HPP 00033 #define FILESYSTEM_HPP 00034 00035 #include "../my_config.h" 00036 00037 extern "C" 00038 { 00039 #if HAVE_UNISTD_H 00040 #include <unistd.h> 00041 #endif 00042 00043 #if HAVE_SYS_STAT_H 00044 #include <sys/stat.h> 00045 #endif 00046 } // end extern "C" 00047 00048 #include <map> 00049 #include <vector> 00050 #include "catalogue.hpp" 00051 #include "infinint.hpp" 00052 #include "etage.hpp" 00053 #include "criterium.hpp" 00054 #include "fsa_family.hpp" 00055 #include "on_pool.hpp" 00056 #include "cat_all_entrees.hpp" 00057 00058 namespace libdar 00059 { 00062 00064 00065 class filesystem_hard_link_read : virtual protected mem_ui, virtual public on_pool 00066 { 00067 // this class is not to be used directly 00068 // it only provides some routine for the inherited classes 00069 00070 public: 00071 filesystem_hard_link_read(const user_interaction & dialog, 00072 bool x_furtive_read_mode, 00073 const fsa_scope & scope) : mem_ui(dialog) { furtive_read_mode = x_furtive_read_mode; sc = scope; }; 00074 00075 // the copy of the current object would make copy of addresses in 00076 // corres_read that could be released twice ... thus, copy constructor and 00077 // assignement are forbidden for this class: 00078 00079 filesystem_hard_link_read(const filesystem_hard_link_read & ref) : mem_ui(ref.get_ui()) { throw SRC_BUG; }; 00080 const filesystem_hard_link_read & operator = (const filesystem_hard_link_read & ref) { throw SRC_BUG; }; 00081 00082 // get the last assigned number for a hard linked inode 00083 const infinint & get_last_etoile_ref() const { return etiquette_counter; }; 00084 00085 virtual ~filesystem_hard_link_read() {}; 00086 00088 const fsa_scope get_fsa_scope() const { return sc; }; 00089 00090 protected: 00091 // reset the whole list of hard linked inodes (hard linked inode stay alive but are no more referenced by the current object) 00092 void corres_reset() { corres_read.clear(); etiquette_counter = 0; }; 00093 00094 // create and return a libdar object corresponding to one pointed to by its path 00095 // during this operation, hard linked inode are recorded in a list to be easily pointed 00096 // to by a new reference to it. 00097 cat_nomme *make_read_entree(path & lieu, //< path of the file to read 00098 const std::string & name, //< name of the file to read 00099 bool see_hard_link, //< whether we want to detect hard_link and eventually return a cat_mirage object (not necessary when diffing an archive with filesystem) 00100 const mask & ea_mask); //< which EA to consider when creating the object 00101 00102 private: 00103 00104 // private datastructure 00105 00106 struct couple 00107 { 00108 nlink_t count; //< counts the number of hard link on that inode that have not yet been found in filesystem, once this count reaches zero, the "couple" structure can be dropped and the "holder" too (no more expected hard links to be found) 00109 cat_etoile *obj; //< the address of the corresponding cat_etoile object for that inode 00110 cat_mirage holder; //< it increments by one the obj internal counters, thus, while this object is alive, the obj will not be destroyed 00111 00112 couple(cat_etoile *ptr, nlink_t ino_count) : holder("FAKE", ptr) { count = ino_count; obj = ptr; }; 00113 }; 00114 00115 struct node 00116 { 00117 node(ino_t num, dev_t dev) { numnode = num; device = dev; }; 00118 00119 // this operator is required to use the type node in a std::map 00120 bool operator < (const node & ref) const { return numnode < ref.numnode || (numnode == ref.numnode && device < ref.device); }; 00121 ino_t numnode; 00122 dev_t device; 00123 }; 00124 00125 // private variable 00126 00127 std::map <node, couple> corres_read; 00128 infinint etiquette_counter; 00129 bool furtive_read_mode; 00130 fsa_scope sc; 00131 00132 }; 00133 00134 00135 00137 00138 class filesystem_backup : public filesystem_hard_link_read 00139 { 00140 public: 00141 filesystem_backup(const user_interaction & dialog, 00142 const path &root, 00143 bool x_info_details, 00144 const mask & x_ea_mask, 00145 bool check_no_dump_flag, 00146 bool alter_atime, 00147 bool furtive_read_mode, 00148 bool x_cache_directory_tagging, 00149 infinint & root_fs_device, 00150 bool x_ignore_unknown, 00151 const fsa_scope & scope); 00152 filesystem_backup(const filesystem_backup & ref) : mem_ui(ref.get_ui()), filesystem_hard_link_read(ref.get_ui(), ref.furtive_read_mode, get_fsa_scope()) { copy_from(ref); }; 00153 const filesystem_backup & operator = (const filesystem_backup & ref) { detruire(); copy_from(ref); return *this; }; 00154 ~filesystem_backup() { detruire(); }; 00155 00156 void reset_read(infinint & root_fs_device); 00157 bool read(cat_entree * & ref, infinint & errors, infinint & skipped_dump); 00158 void skip_read_to_parent_dir(); 00159 // continue reading in parent directory and 00160 // ignore all entry not yet read of current directory 00161 private: 00162 00163 path *fs_root; //< filesystem's root to consider 00164 bool info_details; //< detailed information returned to the user 00165 mask *ea_mask; //< mask defining the EA to consider 00166 bool no_dump_check; //< whether to check against the nodump flag presence 00167 bool alter_atime; //< whether to set back atime or not 00168 bool furtive_read_mode; //< whether to use furtive read mode (if true, alter_atime is ignored) 00169 bool cache_directory_tagging; //< whether to consider cache directory taggin standard 00170 path *current_dir; //< needed to translate from an hard linked inode to an already allocated object 00171 std::vector<etage> pile; //< to store the contents of a directory 00172 bool ignore_unknown; //< whether to ignore unknown inode types 00173 00174 void detruire(); 00175 void copy_from(const filesystem_backup & ref); 00176 }; 00177 00178 00180 00181 class filesystem_diff : public filesystem_hard_link_read 00182 { 00183 public: 00184 filesystem_diff(const user_interaction & dialog, 00185 const path &root, 00186 bool x_info_details, 00187 const mask & x_ea_mask, 00188 bool alter_atime, 00189 bool furtive_read_mode, 00190 const fsa_scope & scope); 00191 filesystem_diff(const filesystem_diff & ref) : mem_ui(ref.get_ui()), filesystem_hard_link_read(ref.get_ui(), ref.furtive_read_mode, get_fsa_scope()) { copy_from(ref); }; 00192 const filesystem_diff & operator = (const filesystem_diff & ref) { detruire(); copy_from(ref); return *this; }; 00193 ~filesystem_diff() { detruire(); }; 00194 00195 void reset_read(); 00196 bool read_filename(const std::string & name, cat_nomme * &ref); 00197 // looks for a file of name given in argument, in current reading directory 00198 // if this is a directory, subsequent read take place in it 00199 00200 void skip_read_filename_in_parent_dir(); 00201 // subsequent calls to read_filename will take place in parent directory. 00202 00203 private: 00204 struct filename_struct 00205 { 00206 datetime last_acc; 00207 datetime last_mod; 00208 }; 00209 00210 path *fs_root; 00211 bool info_details; 00212 mask *ea_mask; 00213 bool alter_atime; 00214 bool furtive_read_mode; 00215 path *current_dir; 00216 std::vector<filename_struct> filename_pile; 00217 00218 void detruire(); 00219 void copy_from(const filesystem_diff & ref); 00220 }; 00221 00223 00224 class filesystem_hard_link_write : virtual protected mem_ui, virtual public on_pool 00225 { 00226 // this class is not to be used directly 00227 // it only provides routines to its inherited classes 00228 00229 public: 00230 filesystem_hard_link_write(const user_interaction & dialog) : mem_ui(dialog) { corres_write.clear(); }; 00231 filesystem_hard_link_write(const filesystem_hard_link_write & ref) : mem_ui(ref) { throw SRC_BUG; }; 00232 const filesystem_hard_link_write & operator = (const filesystem_hard_link_write & ref) { throw SRC_BUG; }; 00233 00234 void write_hard_linked_target_if_not_set(const cat_mirage *ref, const std::string & chemin); 00235 // if a hard linked inode has not been restored (no change, or less recent than the one on filesystem) 00236 // it is necessary to inform filesystem, where to hard link on, any future hard_link 00237 // that could be necessary to restore. 00238 00239 bool known_etiquette(const infinint & eti); 00240 // return true if an inode in filesystem has been seen for that hard linked inode 00241 00245 void clear_corres_if_pointing_to(const infinint & ligne, const std::string & path); 00246 00247 protected: 00248 void corres_reset() { corres_write.clear(); }; 00249 void make_file(const cat_nomme * ref, //< object to restore in filesystem 00250 const path & ou, //< where to restore it 00251 bool dir_perm, //< false for already existing directories, this makes dar set the minimum available permission to be able to restore files in that directory at a later time 00252 cat_inode::comparison_fields what_to_check, //< defines whether to restore permission, ownership, dates, etc. 00253 const fsa_scope & scope); //< fsa scope to use for restoration 00254 // generate inode or make a hard link on an already restored or existing inode. 00255 00256 00258 00266 bool raw_set_ea(const cat_nomme *e, 00267 const ea_attributs & list_ea, 00268 const std::string & spot, 00269 const mask & ea_mask); 00270 // check whether the inode for which to restore EA is not a hard link to 00271 // an already restored inode. if not, it calls the proper ea_filesystem call to restore EA 00272 00274 00278 bool raw_clear_ea_set(const cat_nomme *e, const std::string & path); 00279 00280 00281 private: 00282 struct corres_ino_ea 00283 { 00284 std::string chemin; 00285 bool ea_restored; 00286 }; 00287 00288 std::map <infinint, corres_ino_ea> corres_write; 00289 }; 00290 00291 00293 00294 class filesystem_restore : public filesystem_hard_link_write, public filesystem_hard_link_read 00295 { 00296 public: 00298 filesystem_restore(const user_interaction & dialog, 00299 const path & root, 00300 bool x_warn_overwrite, 00301 bool x_info_details, 00302 const mask & x_ea_mask, 00303 cat_inode::comparison_fields what_to_check, 00304 bool x_warn_remove_no_match, 00305 bool empty, 00306 const crit_action *x_overwrite, 00307 bool x_only_overwrite, 00308 const fsa_scope & scope); 00310 filesystem_restore(const filesystem_restore & ref) : mem_ui(ref), filesystem_hard_link_write(ref), filesystem_hard_link_read(get_ui(), true, get_fsa_scope()) { throw SRC_BUG; }; 00312 const filesystem_restore & operator = (const filesystem_restore & ref) { throw SRC_BUG; }; 00314 ~filesystem_restore() { restore_stack_dir_ownership(); detruire(); }; 00315 00317 void reset_write(); 00318 00319 typedef enum 00320 { 00321 done_data_restored, //< data has been restored to filesystem 00322 done_no_change_no_data, //< no change in filesystem because no data present in archive 00323 done_no_change_policy, //< no change in filesystem because of overwiting policy decision 00324 done_data_removed //< data (= whole inode) removed from filesystem 00325 } action_done_for_data; 00326 00328 00337 void write(const cat_entree *x, 00338 action_done_for_data & data_restored, 00339 bool & ea_restored, 00340 bool & data_created, 00341 bool & hard_link, 00342 bool & fsa_restored); 00343 00344 00349 void ignore_overwrite_restrictions_for_next_write() { ignore_over_restricts = true; }; 00350 00351 00352 private: 00353 class stack_dir_t : public cat_directory 00354 { 00355 public: 00356 stack_dir_t(const cat_directory & ref, bool restore) : cat_directory(ref) { restore_date = restore; }; 00357 00358 bool get_restore_date() const { return restore_date; }; 00359 void set_restore_date(bool val) { restore_date = val; }; 00360 00361 private: 00362 bool restore_date; 00363 }; 00364 00365 path *fs_root; 00366 bool info_details; 00367 mask *ea_mask; 00368 bool warn_overwrite; 00369 cat_inode::comparison_fields what_to_check; 00370 bool warn_remove_no_match; 00371 std::vector<stack_dir_t> stack_dir; 00372 path *current_dir; 00373 bool empty; 00374 bool ignore_over_restricts; 00375 const crit_action *overwrite; 00376 bool only_overwrite; 00377 00378 void detruire(); 00379 void restore_stack_dir_ownership(); 00380 00381 // subroutines of write() 00382 00384 void action_over_remove(const cat_inode *in_place, 00385 const cat_detruit *to_be_added, 00386 const std::string & spot, 00387 over_action_data action); 00389 void action_over_data(const cat_inode *in_place, 00390 const cat_nomme *to_be_added, 00391 const std::string & spot, 00392 over_action_data action, 00393 action_done_for_data & data_done); 00395 bool action_over_ea(const cat_inode *in_place, 00396 const cat_nomme *to_be_added, 00397 const std::string & spot, 00398 over_action_ea action); 00400 bool action_over_fsa(const cat_inode *in_place, 00401 const cat_nomme *to_be_added, 00402 const std::string & spot, 00403 over_action_ea action); 00404 00405 }; 00406 00407 00409 00410 } // end of namespace 00411 00412 #endif