Disk ARchive 2.4.2
filesystem.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines