|
Disk ARchive
2.4.12
|
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 00055 namespace libdar 00056 { 00059 00061 00062 class filesystem_hard_link_read : virtual protected mem_ui 00063 { 00064 // this class is not to be used directly 00065 // it only provides some routine for the inherited classes 00066 00067 public: 00068 filesystem_hard_link_read(user_interaction & dialog, 00069 bool x_furtive_read_mode) : mem_ui(dialog) { furtive_read_mode = x_furtive_read_mode; }; 00070 00071 // the copy of the current object would make copy of addresses in 00072 // corres_read that could be released twice ... thus, copy constructor and 00073 // assignement are forbidden for this class: 00074 00075 filesystem_hard_link_read(const filesystem_hard_link_read & ref) : mem_ui(ref.get_ui()) { throw SRC_BUG; }; 00076 const filesystem_hard_link_read & operator = (const filesystem_hard_link_read & ref) { throw SRC_BUG; }; 00077 00078 // get the last assigned number for a hard linked inode 00079 const infinint & get_last_etoile_ref() const { return etiquette_counter; }; 00080 00081 virtual ~filesystem_hard_link_read() {}; 00082 00083 protected: 00084 // reset the whole list of hard linked inodes (hard linked inode stay alive but are no more referenced by the current object) 00085 void corres_reset() { corres_read.clear(); etiquette_counter = 0; }; 00086 00087 // create and return a libdar object corresponding to one pointed to by its path 00088 // during this operation, hard linked inode are recorded in a list to be easily pointed 00089 // to by a new reference to it. 00090 nomme *make_read_entree(path & lieu, //< path of the file to read 00091 const std::string & name, //< name of the file to read 00092 bool see_hard_link, //< whether we want to detect hard_link and eventually return a mirage object (not necessary when diffing an archive with filesystem) 00093 const mask & ea_mask); //< which EA to consider when creating the object 00094 00095 private: 00096 00097 // private datastructure 00098 00099 struct couple 00100 { 00101 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) 00102 etoile *obj; //< the address of the corresponding etoile object for that inode 00103 mirage holder; //< it increments by one the obj internal counters, thus, while this object is alive, the obj will not be destroyed 00104 00105 couple(etoile *ptr, nlink_t ino_count) : holder("FAKE", ptr) { count = ino_count; obj = ptr; }; 00106 }; 00107 00108 struct node 00109 { 00110 node(ino_t num, dev_t dev) { numnode = num; device = dev; }; 00111 00112 // this operator is required to use the type node in a std::map 00113 bool operator < (const node & ref) const { return numnode < ref.numnode || (numnode == ref.numnode && device < ref.device); }; 00114 ino_t numnode; 00115 dev_t device; 00116 }; 00117 00118 // private variable 00119 00120 std::map <node, couple> corres_read; 00121 infinint etiquette_counter; 00122 bool furtive_read_mode; 00123 00124 }; 00125 00126 00127 00129 00130 class filesystem_backup : public filesystem_hard_link_read 00131 { 00132 public: 00133 filesystem_backup(user_interaction & dialog, 00134 const path &root, 00135 bool x_info_details, 00136 const mask & x_ea_mask, 00137 bool check_no_dump_flag, 00138 bool alter_atime, 00139 bool furtive_read_mode, 00140 bool x_cache_directory_tagging, 00141 infinint & root_fs_device, 00142 bool x_ignore_unknown); 00143 filesystem_backup(const filesystem_backup & ref) : mem_ui(ref.get_ui()), filesystem_hard_link_read(ref.get_ui(), ref.furtive_read_mode) { copy_from(ref); }; 00144 const filesystem_backup & operator = (const filesystem_backup & ref) { detruire(); copy_from(ref); return *this; }; 00145 ~filesystem_backup() { detruire(); }; 00146 00147 void reset_read(infinint & root_fs_device); 00148 bool read(entree * & ref, infinint & errors, infinint & skipped_dump); 00149 void skip_read_to_parent_dir(); 00150 // continue reading in parent directory and 00151 // ignore all entry not yet read of current directory 00152 private: 00153 00154 path *fs_root; //< filesystem's root to consider 00155 bool info_details; //< detailed information returned to the user 00156 mask *ea_mask; //< mask defining the EA to consider 00157 bool no_dump_check; //< whether to check against the nodump flag presence 00158 bool alter_atime; //< whether to set back atime or not 00159 bool furtive_read_mode; //< whether to use furtive read mode (if true, alter_atime is ignored) 00160 bool cache_directory_tagging; //< whether to consider cache directory taggin standard 00161 path *current_dir; //< needed to translate from an hard linked inode to an already allocated object 00162 std::vector<etage> pile; //< to store the contents of a directory 00163 bool ignore_unknown; //< whether to ignore unknown inode types 00164 00165 void detruire(); 00166 void copy_from(const filesystem_backup & ref); 00167 }; 00168 00169 00171 00172 class filesystem_diff : public filesystem_hard_link_read 00173 { 00174 public: 00175 filesystem_diff(user_interaction & dialog, 00176 const path &root, 00177 bool x_info_details, 00178 const mask & x_ea_mask, 00179 bool alter_atime, 00180 bool furtive_read_mode); 00181 filesystem_diff(const filesystem_diff & ref) : mem_ui(ref.get_ui()), filesystem_hard_link_read(ref.get_ui(), ref.furtive_read_mode) { copy_from(ref); }; 00182 const filesystem_diff & operator = (const filesystem_diff & ref) { detruire(); copy_from(ref); return *this; }; 00183 ~filesystem_diff() { detruire(); }; 00184 00185 void reset_read(); 00186 bool read_filename(const std::string & name, nomme * &ref); 00187 // looks for a file of name given in argument, in current reading directory 00188 // if this is a directory, subsequent read take place in it 00189 00190 void skip_read_filename_in_parent_dir(); 00191 // subsequent calls to read_filename will take place in parent directory. 00192 00193 private: 00194 struct filename_struct 00195 { 00196 infinint last_acc; 00197 infinint last_mod; 00198 }; 00199 00200 path *fs_root; 00201 bool info_details; 00202 mask *ea_mask; 00203 bool alter_atime; 00204 bool furtive_read_mode; 00205 path *current_dir; 00206 std::vector<filename_struct> filename_pile; 00207 00208 void detruire(); 00209 void copy_from(const filesystem_diff & ref); 00210 }; 00211 00213 00214 class filesystem_hard_link_write : virtual protected mem_ui 00215 { 00216 // this class is not to be used directly 00217 // it only provides routines to its inherited classes 00218 00219 public: 00220 filesystem_hard_link_write(user_interaction & dialog) : mem_ui(dialog) { corres_write.clear(); }; 00221 filesystem_hard_link_write(const filesystem_hard_link_write & ref) : mem_ui(ref) { throw SRC_BUG; }; 00222 const filesystem_hard_link_write & operator = (const filesystem_hard_link_write & ref) { throw SRC_BUG; }; 00223 00224 void write_hard_linked_target_if_not_set(const mirage *ref, const std::string & chemin); 00225 // if a hard linked inode has not been restored (no change, or less recent than the one on filesystem) 00226 // it is necessary to inform filesystem, where to hard link on, any future hard_link 00227 // that could be necessary to restore. 00228 00229 bool known_etiquette(const infinint & eti); 00230 // return true if an inode in filesystem has been seen for that hard linked inode 00231 00235 void clear_corres_if_pointing_to(const infinint & ligne, const std::string & path); 00236 00237 protected: 00238 void corres_reset() { corres_write.clear(); }; 00239 void make_file(const nomme * ref, //< object to restore in filesystem 00240 const path & ou, //< where to restore it 00241 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 00242 inode::comparison_fields what_to_check); //< defines whether to restore permission, ownership, dates, etc. 00243 // generate inode or make a hard link on an already restored or existing inode. 00244 00245 00247 00253 bool raw_set_ea(const nomme *e, 00254 const ea_attributs & list_ea, 00255 const std::string & spot, 00256 const mask & ea_mask); 00257 // check whether the inode for which to restore EA is not a hard link to 00258 // an already restored inode. if not, it calls the proper ea_filesystem call to restore EA 00259 00261 00265 bool raw_clear_ea_set(const nomme *e, const std::string & path); 00266 00267 00268 private: 00269 struct corres_ino_ea 00270 { 00271 std::string chemin; 00272 bool ea_restored; 00273 }; 00274 00275 std::map <infinint, corres_ino_ea> corres_write; 00276 }; 00277 00278 00280 00281 class filesystem_restore : public filesystem_hard_link_write, public filesystem_hard_link_read 00282 { 00283 public: 00285 filesystem_restore(user_interaction & dialog, 00286 const path & root, 00287 bool x_warn_overwrite, 00288 bool x_info_details, 00289 const mask & x_ea_mask, 00290 inode::comparison_fields what_to_check, 00291 bool x_warn_remove_no_match, 00292 bool empty, 00293 const crit_action *x_overwrite, 00294 bool x_only_overwrite); 00296 filesystem_restore(const filesystem_restore & ref) : mem_ui(ref), filesystem_hard_link_write(ref), filesystem_hard_link_read(get_ui(), true) { throw SRC_BUG; }; 00298 const filesystem_restore & operator = (const filesystem_restore & ref) { throw SRC_BUG; }; 00300 ~filesystem_restore() { restore_stack_dir_ownership(); detruire(); }; 00301 00303 void reset_write(); 00304 00305 typedef enum 00306 { 00307 done_data_restored, //< data has been restored to filesystem 00308 done_no_change_no_data, //< no change in filesystem because no data present in archive 00309 done_no_change_policy, //< no change in filesystem because of overwiting policy decision 00310 done_data_removed //< data (= whole inode) removed from filesystem 00311 } action_done_for_data; 00312 00314 00322 void write(const entree *x, action_done_for_data & data_restored, bool & ea_restored, bool & data_created, bool & hard_link); 00323 00324 00329 void ignore_overwrite_restrictions_for_next_write() { ignore_over_restricts = true; }; 00330 00331 00332 private: 00333 class stack_dir_t : public directory 00334 { 00335 public: 00336 stack_dir_t(const directory & ref, bool restore) : directory(ref) { restore_date = restore; }; 00337 00338 bool get_restore_date() const { return restore_date; }; 00339 void set_restore_date(bool val) { restore_date = val; }; 00340 00341 private: 00342 bool restore_date; 00343 }; 00344 00345 path *fs_root; 00346 bool info_details; 00347 mask *ea_mask; 00348 bool warn_overwrite; 00349 inode::comparison_fields what_to_check; 00350 bool warn_remove_no_match; 00351 std::vector<stack_dir_t> stack_dir; 00352 path *current_dir; 00353 bool empty; 00354 bool ignore_over_restricts; 00355 const crit_action *overwrite; 00356 bool only_overwrite; 00357 00358 void detruire(); 00359 void restore_stack_dir_ownership(); 00360 00361 // subroutines of write() 00362 void action_over_remove(const inode *in_place, const detruit *to_be_added, const std::string & spot, over_action_data action); 00363 void action_over_data(const inode *in_place, 00364 const nomme *to_be_added, 00365 const std::string & spot, 00366 over_action_data action, 00367 action_done_for_data & data_done); 00368 bool action_over_ea(const inode *in_place, const nomme *to_be_added, const std::string & spot, over_action_ea action); 00369 }; 00370 00372 00373 } // end of namespace 00374 00375 #endif
1.7.6.1