Disk ARchive  2.5.2
Full featured and portable backup and archiving tool
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 
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines