# 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 : 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