![]() |
Disk ARchive
2.5.2
Full featured and portable backup and archiving tool
|
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 00025 00026 #ifndef CATALOGUE_HPP 00027 #define CATALOGUE_HPP 00028 00029 #include "../my_config.h" 00030 00031 extern "C" 00032 { 00033 #if HAVE_UNISTD_H 00034 #include <unistd.h> 00035 #endif 00036 } // end extern "C" 00037 00038 #include "infinint.hpp" 00039 #include "generic_file.hpp" 00040 #include "path.hpp" 00041 #include "compressor.hpp" 00042 #include "integers.hpp" 00043 #include "mask.hpp" 00044 #include "user_interaction.hpp" 00045 #include "label.hpp" 00046 #include "escape.hpp" 00047 #include "on_pool.hpp" 00048 #include "datetime.hpp" 00049 #include "slice_layout.hpp" 00050 #include "mem_ui.hpp" 00051 #include "cat_entree.hpp" 00052 #include "cat_nomme.hpp" 00053 #include "cat_directory.hpp" 00054 00055 namespace libdar 00056 { 00057 00060 00062 class catalogue : protected mem_ui, public on_pool 00063 { 00064 public : 00065 catalogue(const user_interaction & dialog, 00066 const datetime & root_last_modif, 00067 const label & data_name); 00068 catalogue(const user_interaction & dialog, 00069 const pile_descriptor & pdesc, 00070 const archive_version & reading_ver, 00071 compression default_algo, 00072 bool lax, 00073 const label & lax_layer1_data_name, //< ignored unless in lax mode, in lax mode unless it is a cleared label, forces the catalogue label to be equal to the lax_layer1_data_name for it be considered a plain internal catalogue, even in case of corruption 00074 bool only_detruit = false); //< if set to true, only directories and detruit objects are read from the archive 00075 catalogue(const catalogue & ref) : mem_ui(ref), out_compare(ref.out_compare) { partial_copy_from(ref); }; 00076 const catalogue & operator = (const catalogue &ref); 00077 virtual ~catalogue() { detruire(); }; 00078 00079 00080 // reading methods. The reading is iterative and uses the current_read cat_directory pointer 00081 00082 virtual void reset_read() const; // set the reading cursor to the beginning of the catalogue 00083 virtual void end_read() const; // set the reading cursor to the end of the catalogue 00084 virtual void skip_read_to_parent_dir() const; 00085 // skip all items of the current dir and of any subdir, the next call will return 00086 // next item of the parent dir (no cat_eod to exit from the current dir !) 00087 virtual bool read(const cat_entree * & ref) const; 00088 // sequential read (generates cat_eod) and return false when all files have been read 00089 virtual bool read_if_present(std::string *name, const cat_nomme * & ref) const; 00090 // pseudo-sequential read (reading a directory still 00091 // implies that following read are located in this subdirectory up to the next EOD) but 00092 // it returns false if no entry of this name are present in the current directory 00093 // a call with nullptr as first argument means to set the current dir the parent directory 00094 void remove_read_entry(std::string & name); 00095 // in the currently read directory, removes the entry which name is given in argument 00096 const cat_directory & get_current_reading_dir() const { if(current_read == nullptr) throw SRC_BUG; return *current_read; }; 00097 // remove from the catalogue all the entries that have not yet been read 00098 // by read(). 00099 void tail_catalogue_to_current_read(); 00100 00101 00102 void reset_sub_read(const path &sub); // initialise sub_read to the given directory 00103 bool sub_read(const cat_entree * &ref); // sequential read of the catalogue, ignoring all that 00104 // is not part of the subdirectory specified with reset_sub_read 00105 // the read include the inode leading to the sub_tree as well as the pending cat_eod 00106 00107 // return true if the last read entry has already been read 00108 // and has not to be counted again. This is never the case for catalogue but may occure 00109 // with escape_catalogue (where from the 'virtual'). 00110 // last this method gives a valid result only if the last read() entry is a directory as 00111 // only directory may be read() twice. 00112 virtual bool read_second_time_dir() const { return false; }; 00113 00114 00115 // Additions methods. The addition is also iterative but uses its specific current_add directory pointer 00116 00117 void reset_add(); 00118 00120 // real implementation is only needed in escape_catalogue class, here there nothing to be done 00121 virtual void pre_add(const cat_entree *ref) const {}; 00122 virtual void pre_add_ea(const cat_entree *ref) const {}; 00123 virtual void pre_add_crc(const cat_entree *ref) const {}; 00124 virtual void pre_add_dirty() const {}; 00125 virtual void pre_add_ea_crc(const cat_entree *ref) const {}; 00126 virtual void pre_add_waste_mark() const {}; 00127 virtual void pre_add_failed_mark() const {}; 00128 virtual void pre_add_fsa(const cat_entree *ref) const {}; 00129 virtual void pre_add_fsa_crc(const cat_entree *ref) const {}; 00130 virtual escape *get_escape_layer() const { return nullptr; }; 00131 00132 void add(cat_entree *ref); // add at end of catalogue (sequential point of view) 00133 void re_add_in(const std::string &subdirname); // return into an already existing subdirectory for further addition 00134 void re_add_in_replace(const cat_directory &dir); // same as re_add_in but also set the properties of the existing directory to those of the given argument 00135 void add_in_current_read(cat_nomme *ref); // add in currently read directory 00136 const cat_directory & get_current_add_dir() const { if(current_add == nullptr) throw SRC_BUG; return *current_add; }; 00137 00138 00139 00140 // Comparison methods. The comparision is here also iterative and uses its specific current_compare directory pointer 00141 00142 void reset_compare() const; 00143 bool compare(const cat_entree * name, const cat_entree * & extracted) const; 00144 // returns true if the ref exists, and gives it back in second argument as it is in the current catalogue. 00145 // returns false is no entry of that nature exists in the catalogue (in the current directory) 00146 // if ref is a directory, the operation is normaly relative to the directory itself, but 00147 // such a call implies a chdir to that directory. thus, a call with an EOD is necessary to 00148 // change to the parent directory. 00149 // note : 00150 // if a directory is not present, returns false, but records the inexistant subdirectory 00151 // structure defined by the following calls to this routine, this to be able to know when 00152 // the last available directory is back the current one when changing to parent directory, 00153 // and then proceed with normal comparison of inode. In this laps of time, the call will 00154 // always return false, while it temporary stores the missing directory structure 00155 00156 00157 00158 // non interative methods 00159 00160 00164 infinint update_destroyed_with(const catalogue & ref); 00165 00166 00172 void update_absent_with(const catalogue & ref, infinint aborting_next_etoile); 00173 00174 00176 void drop_all_non_detruits(); 00177 00182 bool is_subset_of(const catalogue & ref) const; 00183 00185 void reset_dump() const; 00186 00188 void dump(const pile_descriptor & pdesc) const; 00189 00190 void listing(bool isolated, 00191 const mask &selection, 00192 const mask & subtree, 00193 bool filter_unsaved, 00194 bool list_ea, 00195 std::string marge) const; 00196 void tar_listing(bool isolated, 00197 const mask & selection, 00198 const mask & subtree, 00199 bool filter_unsaved, 00200 bool list_ea, 00201 std::string beginning) const; 00202 void xml_listing(bool isolated, 00203 const mask & selection, 00204 const mask & subtree, 00205 bool filter_unsaved, 00206 bool list_ea, 00207 std::string beginning) const; 00208 void slice_listing(bool isolated, 00209 const mask & selection, 00210 const mask & subtree, 00211 const slice_layout & slicing) const; 00212 00213 entree_stats get_stats() const { return stats; }; 00214 00216 bool is_empty() const { if(contenu == nullptr) throw SRC_BUG; return contenu->is_empty(); }; 00217 00218 const cat_directory *get_contenu() const { return contenu; }; // used by data_tree 00219 00220 const label & get_data_name() const { return ref_data_name; }; 00221 datetime get_root_dir_last_modif() const { return contenu->get_last_modif(); }; 00222 00224 void launch_recursive_has_changed_update() const { contenu->recursive_has_changed_update(); }; 00225 00226 datetime get_root_mtime() const { return contenu->get_last_modif(); }; 00227 00229 void reset_all(); 00230 00231 void set_to_unsaved_data_and_FSA() { if(contenu == nullptr) throw SRC_BUG; contenu->recursively_set_to_unsaved_data_and_FSA(); }; 00232 00234 void change_location(const pile_descriptor & pdesc) { contenu->change_location(pdesc); }; 00235 00236 protected: 00237 entree_stats & access_stats() { return stats; }; 00238 void set_data_name(const label & val) { ref_data_name = val; }; 00239 void copy_detruits_from(const catalogue & ref); // needed for escape_catalogue implementation only. 00240 00241 const cat_eod * get_r_eod_address() const { return & r_eod; }; // cat_eod are never stored in the catalogue 00242 // however it is sometimes required to return such a reference to a valid object 00243 // owned by the catalogue. 00244 00245 00248 void swap_stuff(catalogue & ref); 00249 00250 private : 00251 cat_directory *contenu; 00252 path out_compare; 00253 cat_directory *current_compare; 00254 cat_directory *current_add; 00255 cat_directory *current_read; 00256 path *sub_tree; 00257 signed int sub_count; 00258 entree_stats stats; 00259 label ref_data_name; 00260 00261 void partial_copy_from(const catalogue &ref); 00262 void detruire(); 00263 00264 static const cat_eod r_eod; // needed to return eod reference, without taking risk of saturating memory 00265 static const U_I CAT_CRC_SIZE; 00266 }; 00267 00268 00269 00271 00272 } // end of namespace 00273 00274 #endif