Disk ARchive 2.3.11
|
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 : dar.linux@free.fr 00020 /*********************************************************************/ 00021 // $Id: filesystem.hpp,v 1.22.2.3 2009/04/07 08:45:29 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 00057 namespace libdar 00058 { 00061 00063 class filesystem_hard_link_read 00064 { 00065 // this class is not to be used directly 00066 // it only provides some routine for the inherited classes 00067 00068 public: 00069 filesystem_hard_link_read(user_interaction & dialog) { fs_ui = dialog.clone(); }; 00070 filesystem_hard_link_read(const filesystem_hard_link_read & ref) { copy_from(ref); }; 00071 filesystem_hard_link_read & operator = (const filesystem_hard_link_read & ref) { detruire(); copy_from(ref); return *this; }; 00072 ~filesystem_hard_link_read() { detruire(); }; 00073 00074 00075 void forget_etiquette(file_etiquette *obj); 00076 // tell the filesystem module that the reference of that etiquette does not 00077 // exist anymore (not covered by filter for example) 00078 00079 protected: 00080 void corres_reset() { corres_read.clear(); etiquette_counter = 0; }; 00081 00082 nomme *make_read_entree(path & lieu, const std::string & name, bool see_hard_link, const mask & ea_mask); 00083 00084 user_interaction & get_fs_ui() const { return *fs_ui; }; 00085 00086 private: 00087 struct couple 00088 { 00089 nlink_t count; 00090 file_etiquette *obj; 00091 }; 00092 00093 struct node 00094 { 00095 node(ino_t num, dev_t dev) { numnode = num; device = dev; }; 00096 00097 // this operator is required to use the type node in a std::map 00098 bool operator < (const node & ref) const { return numnode < ref.numnode || (numnode == ref.numnode && device < ref.device); }; 00099 ino_t numnode; 00100 dev_t device; 00101 }; 00102 00103 std::map <node, couple> corres_read; 00104 infinint etiquette_counter; 00105 00106 user_interaction *fs_ui; 00107 00108 void copy_from(const filesystem_hard_link_read & ref); 00109 void detruire(); 00110 }; 00111 00112 00114 class filesystem_backup : public filesystem_hard_link_read 00115 { 00116 public: 00117 filesystem_backup(user_interaction & dialog, 00118 const path &root, 00119 bool x_info_details, 00120 const mask & x_ea_mask, 00121 bool check_no_dump_flag, 00122 bool alter_atime, 00123 bool x_cache_directory_tagging, 00124 infinint & root_fs_device); 00125 filesystem_backup(const filesystem_backup & ref) : filesystem_hard_link_read(ref.get_fs_ui()) { copy_from(ref); }; 00126 filesystem_backup & operator = (const filesystem_backup & ref) { detruire(); copy_from(ref); return *this; }; 00127 ~filesystem_backup() { detruire(); }; 00128 00129 void reset_read(infinint & root_fs_device); 00130 bool read(entree * & ref, infinint & errors, infinint & skipped_dump); 00131 void skip_read_to_parent_dir(); 00132 // continue reading in parent directory and 00133 // ignore all entry not yet read of current directory 00134 private: 00135 00136 path *fs_root; 00137 bool info_details; 00138 mask *ea_mask; 00139 bool no_dump_check; 00140 bool alter_atime; 00141 bool cache_directory_tagging; 00142 path *current_dir; // to translate from an hard linked inode to an already allocated object 00143 std::vector<etage> pile; // to store the contents of a directory 00144 00145 void detruire(); 00146 void copy_from(const filesystem_backup & ref); 00147 }; 00148 00150 class filesystem_diff : public filesystem_hard_link_read 00151 { 00152 public: 00153 filesystem_diff(user_interaction & dialog, 00154 const path &root, bool x_info_details, 00155 const mask & x_ea_mask, bool alter_atime); 00156 filesystem_diff(const filesystem_diff & ref) : filesystem_hard_link_read(ref.get_fs_ui()) { copy_from(ref); }; 00157 filesystem_diff & operator = (const filesystem_diff & ref) { detruire(); copy_from(ref); return *this; }; 00158 ~filesystem_diff() { detruire(); }; 00159 00160 void reset_read(); 00161 bool read_filename(const std::string & name, nomme * &ref); 00162 // looks for a file of name given in argument, in current reading directory 00163 // if this is a directory subsequent read are done in it 00164 void skip_read_filename_in_parent_dir(); 00165 // subsequent calls to read_filename will take place in parent directory. 00166 00167 private: 00168 struct filename_struct 00169 { 00170 infinint last_acc; 00171 infinint last_mod; 00172 }; 00173 00174 path *fs_root; 00175 bool info_details; 00176 mask *ea_mask; 00177 bool alter_atime; 00178 path *current_dir; 00179 std::vector<filename_struct> filename_pile; 00180 00181 void detruire(); 00182 void copy_from(const filesystem_diff & ref); 00183 }; 00184 00186 class filesystem_hard_link_write 00187 { 00188 // this class is not to be used directly 00189 // it only provides routines to its inherited classes 00190 00191 public: 00192 filesystem_hard_link_write(user_interaction & dialog, bool x_ea_erase) { fs_ui = dialog.clone(); ea_erase = x_ea_erase; }; 00193 filesystem_hard_link_write(const filesystem_hard_link_write & ref) { copy_from(ref); }; 00194 filesystem_hard_link_write & operator = (const filesystem_hard_link_write & ref) { detruire(); copy_from(ref); return *this; }; 00195 ~filesystem_hard_link_write() { detruire(); }; 00196 00197 bool ea_has_been_restored(const hard_link *h); 00198 // true if the inode pointed to by the arg has already got its EA restored 00199 bool set_ea(const nomme *e, const ea_attributs & list_ea, path spot, 00200 bool allow_overwrite, bool warn_overwrite, const mask & ea_mask, bool info_details); 00201 // check whether the inode for which to restore EA is not a hard link to 00202 // an already restored inode. if not, it calls the proper ea_filesystem call to restore EA 00203 void write_hard_linked_target_if_not_set(const etiquette *ref, const std::string & chemin); 00204 // if a hard linked inode has not been restored (no change, or less recent than the one on filesystem) 00205 // it is necessary to inform filesystem, where to hard link on, any future hard_link 00206 // that could be necessary to restore. 00207 bool known_etiquette(const infinint & eti); 00208 // return true if an inode in filesystem has been seen for that hard linked inode 00209 00210 // return the ea_ease status (whether EA are first erased before being restored, else they are overwritten) 00211 bool get_ea_erase() const { return ea_erase; }; 00212 // set the ea_erase status 00213 void set_ea_erase(bool status) { ea_erase = status; }; 00214 00215 protected: 00216 void corres_reset() { corres_write.clear(); }; 00217 void make_file(const nomme * ref, const path & ou, bool dir_perm, inode::comparison_fields what_to_check); 00218 // generate inode or make a hard link on an already restored inode. 00219 void clear_corres(const infinint & ligne); 00220 00221 user_interaction & get_fs_ui() const { return *fs_ui; }; 00222 00223 private: 00224 struct corres_ino_ea 00225 { 00226 std::string chemin; 00227 bool ea_restored; 00228 }; 00229 00230 std::map <infinint, corres_ino_ea> corres_write; 00231 user_interaction *fs_ui; 00232 bool ea_erase; 00233 00234 void copy_from(const filesystem_hard_link_write & ref); 00235 void detruire(); 00236 }; 00237 00239 class filesystem_restore : public filesystem_hard_link_write, public filesystem_hard_link_read 00240 { 00241 public: 00242 filesystem_restore(user_interaction & dialog, 00243 const path &root, bool x_allow_overwrite, bool x_warn_overwrite, bool x_info_details, 00244 const mask & x_ea_mask, inode::comparison_fields what_to_check, bool x_warn_remove_no_match, bool empty, bool ea_erase); 00245 filesystem_restore(const filesystem_restore & ref) : filesystem_hard_link_write(ref.filesystem_hard_link_write::get_fs_ui(), ref.get_ea_erase()), filesystem_hard_link_read(ref.filesystem_hard_link_read::get_fs_ui()) { copy_from(ref); }; 00246 filesystem_restore & operator = (const filesystem_restore & ref) { detruire(); copy_from(ref); return *this; }; 00247 ~filesystem_restore() { restore_stack_dir_ownership(); detruire(); }; 00248 00249 void reset_write(); 00250 bool write(const entree *x, bool & created); 00251 // the 'x' argument may be an object from class destroy 00252 // the 'created' argument is set back to true if no overwriting was necessary to restore the file 00253 // return true upon success, 00254 // false if overwriting not allowed or refused 00255 // throw exception on other errors 00256 nomme *get_before_write(const nomme *x); 00257 // in this case the target has to be removed from the filesystem 00258 void pseudo_write(const directory *dir); 00259 // do not restore the directory, just stores that we are now 00260 // inspecting its contents 00261 bool set_ea(const nomme *e, const ea_attributs & l, 00262 bool allow_overwrite, 00263 bool warn_overwrite, 00264 bool info_details) 00265 { return empty ? true : filesystem_hard_link_write::set_ea(e, l, *current_dir, 00266 allow_overwrite, 00267 warn_overwrite, 00268 *ea_mask, 00269 info_details); 00270 }; 00271 00272 protected: 00273 user_interaction & get_fs_ui() const { return filesystem_hard_link_read::get_fs_ui(); }; 00274 00275 private: 00276 path *fs_root; 00277 bool info_details; 00278 mask *ea_mask; 00279 bool allow_overwrite; 00280 bool warn_overwrite; 00281 inode::comparison_fields what_to_check; 00282 bool warn_remove_no_match; 00283 std::vector<directory> stack_dir; 00284 path *current_dir; 00285 bool empty; 00286 00287 void detruire(); 00288 void copy_from(const filesystem_restore & ref); 00289 void restore_stack_dir_ownership(); 00290 }; 00291 00293 00294 } // end of namespace 00295 00296 #endif