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