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: catalogue.hpp,v 1.48.2.6 2010/09/12 16:32:51 edrusb Rel $ 00022 // 00023 /*********************************************************************/ 00024 00028 00029 #ifndef CATALOGUE_HPP 00030 #define CATALOGUE_HPP 00031 00032 #include "../my_config.h" 00033 00034 extern "C" 00035 { 00036 #if HAVE_UNISTD_H 00037 #include <unistd.h> 00038 #endif 00039 } // end extern "C" 00040 00041 #include <vector> 00042 #include <map> 00043 #include "infinint.hpp" 00044 #include "generic_file.hpp" 00045 #include "path.hpp" 00046 #include "header_version.hpp" 00047 #include "ea.hpp" 00048 #include "compressor.hpp" 00049 #include "integers.hpp" 00050 #include "mask.hpp" 00051 #include "special_alloc.hpp" 00052 #include "user_interaction.hpp" 00053 00054 namespace libdar 00055 { 00056 class file_etiquette; 00057 class entree; 00058 00061 00062 enum saved_status 00063 { 00064 s_saved, //< inode is saved in the archive 00065 s_fake, //< inode is not saved in the archive but is in the archive of reference (isolation context) 00066 s_not_saved //< inode is not saved in the archive 00067 }; 00068 00069 struct entree_stats 00070 { 00071 infinint num_x; // number of file referenced as destroyed since last backup 00072 infinint num_d; // number of directories 00073 infinint num_f; // number of plain files (hard link or not, thus file directory entries) 00074 infinint num_c; // number of char devices 00075 infinint num_b; // number of block devices 00076 infinint num_p; // number of named pipes 00077 infinint num_s; // number of unix sockets 00078 infinint num_l; // number of symbolic links 00079 infinint num_hard_linked_inodes; // number of inode that have more than one link (inode with "hard links") 00080 infinint num_hard_link_entries; // total number of hard links (file directory entry pointing to an 00081 // inode already linked in the same or another directory (i.e. hard linked)) 00082 infinint saved; // total number of saved inode (unix inode, not inode class) hard links do not count here 00083 infinint total; // total number of inode in archive (unix inode, not inode class) hard links do not count here 00084 void clear() { num_x = num_d = num_f = num_c = num_b = num_p 00085 = num_s = num_l = num_hard_linked_inodes 00086 = num_hard_link_entries = saved = total = 0; }; 00087 void add(const entree *ref); 00088 void listing(user_interaction & dialog) const; 00089 }; 00090 00091 extern unsigned char mk_signature(unsigned char base, saved_status state); 00092 extern void unmk_signature(unsigned char sig, unsigned char & base, saved_status & state); 00093 00095 class entree 00096 { 00097 public : 00098 static entree *read(user_interaction & dialog, 00099 generic_file & f, const dar_version & reading_ver, 00100 entree_stats & stats, 00101 std::map <infinint, file_etiquette *> & corres, 00102 compression default_algo, 00103 generic_file *data_loc, 00104 generic_file *ea_loc); 00105 00106 virtual ~entree() {}; 00107 virtual void dump(user_interaction & dialog, generic_file & f) const; 00108 virtual unsigned char signature() const = 0; 00109 virtual entree *clone() const = 0; 00110 00111 // SPECIAL ALLOC not adapted here 00112 // because some inherited class object (eod) are 00113 // temporary 00114 }; 00115 00116 extern bool compatible_signature(unsigned char a, unsigned char b); 00117 00119 class eod : public entree 00120 { 00121 public : 00122 eod() {}; 00123 eod(generic_file & f) {}; 00124 // dump defined by entree 00125 unsigned char signature() const { return 'z'; }; 00126 entree *clone() const { return new eod(); }; 00127 00128 // eod are generally temporary object they are NOT 00129 // well adapted to "SPECIAL ALLOC" 00130 }; 00131 00133 class nomme : public entree 00134 { 00135 public : 00136 nomme(const std::string & name) { xname = name; }; 00137 nomme(generic_file & f); 00138 void dump(user_interaction & dialog, generic_file & f) const; 00139 00140 const std::string & get_name() const { return xname; }; 00141 void change_name(const std::string & x) { xname = x; }; 00142 bool same_as(const nomme & ref) const { return xname == ref.xname; }; 00143 // no need to have a virtual method, as signature will differ in inherited classes (argument type changes) 00144 00145 // signature() is kept as an abstract method 00146 // clone() is abstract 00147 00148 #ifdef LIBDAR_SPECIAL_ALLOC 00149 USE_SPECIAL_ALLOC(nomme); 00150 #endif 00151 00152 private : 00153 std::string xname; 00154 }; 00155 00157 class inode : public nomme 00158 { 00159 public: 00160 00162 00163 enum comparison_fields 00164 { 00165 cf_all, //< consider any available field for comparing inodes 00166 cf_ignore_owner, //< consider any available field except ownership fields 00167 cf_mtime, //< consider any available field except ownership and permission fields 00168 cf_inode_type //< only consider the file type 00169 }; 00170 00171 inode(U_16 xuid, U_16 xgid, U_16 xperm, 00172 const infinint & last_access, 00173 const infinint & last_modif, 00174 const std::string & xname, const infinint & device); 00175 inode(user_interaction & dialog, 00176 generic_file & f, 00177 const dar_version & reading_ver, 00178 saved_status saved, 00179 generic_file *ea_loc); 00180 inode(const inode & ref); 00181 ~inode(); 00182 00183 void dump(user_interaction & dialog, generic_file & f) const; 00184 U_16 get_uid() const { return uid; }; 00185 U_16 get_gid() const { return gid; }; 00186 U_16 get_perm() const { return perm; }; 00187 infinint get_last_access() const { return *last_acc; }; 00188 infinint get_last_modif() const { return *last_mod; }; 00189 void set_last_access(const infinint & x_time) { *last_acc = x_time; }; 00190 void set_last_modif(const infinint & x_time) { *last_mod = x_time; }; 00191 saved_status get_saved_status() const { return xsaved; }; 00192 void set_saved_status(saved_status x) { xsaved = x; }; 00193 infinint get_device() const { return *fs_dev; }; 00194 00195 bool same_as(const inode & ref) const; 00196 bool is_more_recent_than(const inode & ref, const infinint & hourshift) const; 00197 // used for RESTORATION 00198 virtual bool has_changed_since(const inode & ref, const infinint & hourshift, comparison_fields what_to_check) const; 00199 // signature() left as an abstract method 00200 // clone is abstract too 00201 // used for INCREMENTAL BACKUP 00202 void compare(user_interaction & dialog, 00203 const inode &other, 00204 const mask & ea_mask, 00205 comparison_fields what_to_check, 00206 const infinint & hourshift) const; 00207 // throw Erange exception if a difference has been detected 00208 // this is not a symetrical comparison, but all what is present 00209 // in the current object is compared against the argument 00210 // which may contain supplementary informations 00211 // used for DIFFERENCE 00212 00213 00214 00216 // EXTENDED ATTRIBUTS Methods 00217 // 00218 00219 enum ea_status { ea_none, ea_partial, ea_fake, ea_full }; 00220 // ea_none : no EA present for this inode in filesystem 00221 // ea_partial : EA present in filesystem but not stored (ctime used to check changes) 00222 // ea_fake : EA present in filesystem but not attached to this inode (isolation context) 00223 // ea_full : EA present in filesystem and attached to this inode 00224 00225 // I : to know whether EA data is present or not for this object 00226 void ea_set_saved_status(ea_status status); 00227 ea_status ea_get_saved_status() const { return ea_saved; }; 00228 00229 // II : to associate EA list to an inode object (mainly for backup operation) #EA_FULL only# 00230 void ea_attach(ea_attributs *ref); 00231 const ea_attributs *get_ea(user_interaction & dialog) const; 00232 void ea_detach() const; //discards any future call to get_ea() ! 00233 00234 // III : to record where is dump the EA in the archive #EA_FULL only# 00235 void ea_set_offset(const infinint & pos) { *ea_offset = pos; }; 00236 void ea_set_crc(const crc & val) { copy_crc(ea_crc, val); }; 00237 void ea_get_crc(crc & val) const { copy_crc(val, ea_crc); }; 00238 00239 // IV : to know/record if EA have been modified #EA_FULL, EA_PARTIAL or EA_FAKE# 00240 infinint get_last_change() const; 00241 void set_last_change(const infinint & x_time); 00242 00243 // V : for archive migration (merging) 00244 void change_ea_location(generic_file *loc) { storage = loc; }; 00245 00247 00248 #ifdef LIBDAR_SPECIAL_ALLOC 00249 USE_SPECIAL_ALLOC(inode); 00250 #endif 00251 00252 protected: 00253 virtual void sub_compare(user_interaction & dialog, const inode & other) const {}; 00254 00255 private : 00256 U_16 uid; 00257 U_16 gid; 00258 U_16 perm; 00259 infinint *last_acc, *last_mod; 00260 saved_status xsaved; 00261 ea_status ea_saved; 00262 // the following is used only if ea_saved == full 00263 infinint *ea_offset; 00264 ea_attributs *ea; 00265 // the following is used if ea_saved == full or ea_saved == partial 00266 infinint *last_cha; 00267 crc ea_crc; 00268 infinint *fs_dev; 00269 generic_file *storage; // where are stored EA 00270 dar_version edit; // need to know EA format used in archive file 00271 }; 00272 00274 class file : public inode 00275 { 00276 public : 00277 file(U_16 xuid, U_16 xgid, U_16 xperm, 00278 const infinint & last_access, 00279 const infinint & last_modif, 00280 const std::string & src, 00281 const path & che, 00282 const infinint & taille, 00283 const infinint & fs_device); 00284 file(const file & ref); 00285 file(user_interaction & dialog, 00286 generic_file & f, 00287 const dar_version & reading_ver, 00288 saved_status saved, 00289 compression default_algo, 00290 generic_file *data_loc, 00291 generic_file *ea_loc); 00292 ~file() { detruit(); }; 00293 00294 void dump(user_interaction & dialog, generic_file & f) const; 00295 bool has_changed_since(const inode & ref, const infinint & hourshift, inode::comparison_fields what_to_check) const; 00296 infinint get_size() const { return *size; }; 00297 infinint get_storage_size() const { return *storage_size; }; 00298 void set_storage_size(const infinint & s) { *storage_size = s; }; 00299 generic_file *get_data(user_interaction & dialog, bool keep_compressed = false) const; // return a newly alocated object in read_only mode 00300 void clean_data(); // partially free memory (but get_data() becomes disabled) 00301 void set_offset(const infinint & r); 00302 unsigned char signature() const { return mk_signature('f', get_saved_status()); }; 00303 00304 void set_crc(const crc &c) { copy_crc(check, c); }; 00305 bool get_crc(crc & c) const; 00306 entree *clone() const { return new file(*this); }; 00307 00308 compression get_compression_algo_used() const { return algo; }; 00309 00310 // object migration methods (merging) 00311 void change_compression_algo_used(compression x) { algo = x; }; 00312 void change_location(generic_file *x) { loc = x; }; 00313 00314 00315 #ifdef LIBDAR_SPECIAL_ALLOC 00316 USE_SPECIAL_ALLOC(file); 00317 #endif 00318 00319 protected : 00320 void sub_compare(user_interaction & dialog, const inode & other) const; 00321 00322 private : 00323 enum { empty, from_path, from_cat } status; 00324 path chemin; 00325 infinint *offset; 00326 infinint *size; 00327 infinint *storage_size; 00328 00329 bool available_crc; 00330 crc check; 00331 00332 generic_file *loc; 00333 compression algo; 00334 00335 void detruit(); 00336 }; 00337 00339 class etiquette 00340 { 00341 public: 00342 virtual infinint get_etiquette() const = 0; 00343 virtual const file_etiquette *get_inode() const = 0; 00344 virtual ~etiquette() {}; 00345 00346 #ifdef LIBDAR_SPECIAL_ALLOC 00347 USE_SPECIAL_ALLOC(etiquette); 00348 #endif 00349 }; 00350 00352 class file_etiquette : public file, public etiquette 00353 { 00354 public : 00355 file_etiquette(U_16 xuid, U_16 xgid, U_16 xperm, 00356 const infinint & last_access, 00357 const infinint & last_modif, 00358 const std::string & src, 00359 const path & che, 00360 const infinint & taille, 00361 const infinint & fs_device, 00362 const infinint & etiquette_number); 00363 file_etiquette(const file_etiquette & ref); 00364 file_etiquette(user_interaction & dialog, 00365 generic_file & f, 00366 const dar_version & reading_ver, 00367 saved_status saved, 00368 compression default_algo, 00369 generic_file *data_loc, 00370 generic_file *ea_loc); 00371 00372 void dump(user_interaction & dialog, generic_file &f) const; 00373 unsigned char signature() const { return mk_signature('e', get_saved_status()); }; 00374 entree *clone() const { return new file_etiquette(*this); }; 00375 00376 void change_etiquette(const infinint & new_val) { etiquette = new_val; }; 00377 00378 // inherited from etiquette 00379 infinint get_etiquette() const { return etiquette; }; 00380 const file_etiquette *get_inode() const { return this; }; 00381 00382 #ifdef LIBDAR_SPECIAL_ALLOC 00383 USE_SPECIAL_ALLOC(file_etiquette); 00384 #endif 00385 00386 private : 00387 infinint etiquette; 00388 }; 00389 00391 class hard_link : public nomme, public etiquette 00392 { 00393 public : 00394 hard_link(const std::string & name, file_etiquette *ref); 00395 hard_link(generic_file & f, infinint & etiquette); // with etiquette, a call to set_reference() follows 00396 00397 void dump(user_interaction & dialog, generic_file &f) const; 00398 unsigned char signature() const { return 'h'; }; 00399 entree *clone() const { return new hard_link(*this); }; 00400 void set_reference(file_etiquette *ref); 00401 00402 // inherited from etiquette 00403 infinint get_etiquette() const; 00404 const file_etiquette *get_inode() const { return x_ref; }; 00405 00406 #ifdef LIBDAR_SPECIAL_ALLOC 00407 USE_SPECIAL_ALLOC(hard_link); 00408 #endif 00409 private : 00410 file_etiquette *x_ref; 00411 }; 00412 00414 class lien : public inode 00415 { 00416 public : 00417 lien(U_16 uid, U_16 gid, U_16 perm, 00418 const infinint & last_access, 00419 const infinint & last_modif, 00420 const std::string & name, 00421 const std::string & target, 00422 const infinint & fs_device); 00423 lien(user_interaction & dialog, 00424 generic_file & f, 00425 const dar_version & reading_ver, 00426 saved_status saved, 00427 generic_file *ea_loc); 00428 00429 void dump(user_interaction & dialog, generic_file & f) const; 00430 const std::string & get_target() const; 00431 void set_target(std::string x); 00432 00433 // using the method is_more_recent_than() from inode 00434 // using method has_changed_since() from inode class 00435 unsigned char signature() const { return mk_signature('l', get_saved_status()); }; 00436 entree *clone() const { return new lien(*this); }; 00437 00438 #ifdef LIBDAR_SPECIAL_ALLOC 00439 USE_SPECIAL_ALLOC(lien); 00440 #endif 00441 protected : 00442 void sub_compare(user_interaction & dialog, const inode & other) const; 00443 00444 private : 00445 std::string points_to; 00446 }; 00447 00449 class directory : public inode 00450 { 00451 public : 00452 directory(U_16 xuid, U_16 xgid, U_16 xperm, 00453 const infinint & last_access, 00454 const infinint & last_modif, 00455 const std::string & xname, 00456 const infinint & device); 00457 directory(const directory &ref); // only the inode part is build, no children is duplicated (empty dir) 00458 directory(user_interaction & dialog, 00459 generic_file & f, 00460 const dar_version & reading_ver, 00461 saved_status saved, 00462 entree_stats & stats, 00463 std::map <infinint, file_etiquette *> & corres, 00464 compression default_algo, 00465 generic_file *data_loc, 00466 generic_file *ea_loc); 00467 ~directory(); // detruit aussi tous les fils et se supprime de son 'parent' 00468 00469 void dump(user_interaction & dialog, generic_file & f) const; 00470 void add_children(nomme *r); // when r is a directory, 'parent' is set to 'this' 00471 bool has_children() const { return fils.size() != 0; }; 00472 void reset_read_children() const; 00473 bool read_children(const nomme * &r) const; // read the direct children of the directory, returns false if no more is available 00474 void listing(user_interaction & dialog, 00475 const mask &m = bool_mask(true), bool filter_unsaved = false, const std::string & marge = "") const; 00476 void tar_listing(user_interaction & dialog, 00477 const mask &m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const; 00478 void xml_listing(user_interaction & dialog, 00479 const mask &m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const; 00480 directory * get_parent() const { return parent; }; 00481 bool search_children(const std::string &name, nomme *&ref); 00482 bool callback_for_children_of(user_interaction & dialog, const std::string & sdir) const; 00483 00484 // using is_more_recent_than() from inode class 00485 // using method has_changed_since() from inode class 00486 unsigned char signature() const { return mk_signature('d', get_saved_status()); }; 00487 00488 // some data has changed since archive of reference in this directory or subdirectories 00489 bool get_recursive_has_changed() const { return recursive_has_changed; }; 00490 // update the recursive_has_changed field 00491 void recursive_has_changed_update() const; 00492 00493 entree *clone() const { return new directory(*this); }; 00494 00495 #ifdef LIBDAR_SPECIAL_ALLOC 00496 USE_SPECIAL_ALLOC(directory); 00497 #endif 00498 private : 00499 directory *parent; 00500 std::vector<nomme *> fils; 00501 std::vector<nomme *>::iterator it; 00502 bool recursive_has_changed; 00503 00504 void clear(); 00505 }; 00506 00508 class device : public inode 00509 { 00510 public : 00511 device(U_16 uid, U_16 gid, U_16 perm, 00512 const infinint & last_access, 00513 const infinint & last_modif, 00514 const std::string & name, 00515 U_16 major, 00516 U_16 minor, 00517 const infinint & fs_device); 00518 device(user_interaction & dialog, 00519 generic_file & f, 00520 const dar_version & reading_ver, 00521 saved_status saved, 00522 generic_file *ea_loc); 00523 00524 void dump(user_interaction & dialog, generic_file & f) const; 00525 int get_major() const { if(get_saved_status() != s_saved) throw SRC_BUG; else return xmajor; }; 00526 int get_minor() const { if(get_saved_status() != s_saved) throw SRC_BUG; else return xminor; }; 00527 void set_major(int x) { xmajor = x; }; 00528 void set_minor(int x) { xminor = x; }; 00529 00530 // using method is_more_recent_than() from inode class 00531 // using method has_changed_since() from inode class 00532 // signature is left pure abstract 00533 00534 #ifdef LIBDAR_SPECIAL_ALLOC 00535 USE_SPECIAL_ALLOC(device); 00536 #endif 00537 00538 protected : 00539 void sub_compare(user_interaction & dialog, const inode & other) const; 00540 00541 private : 00542 U_16 xmajor, xminor; 00543 }; 00544 00546 class chardev : public device 00547 { 00548 public: 00549 chardev(U_16 uid, U_16 gid, U_16 perm, 00550 const infinint & last_access, 00551 const infinint & last_modif, 00552 const std::string & name, 00553 U_16 major, 00554 U_16 minor, 00555 const infinint & fs_device) : device(uid, gid, perm, last_access, 00556 last_modif, name, 00557 major, minor, fs_device) {}; 00558 chardev(user_interaction & dialog, 00559 generic_file & f, 00560 const dar_version & reading_ver, 00561 saved_status saved, 00562 generic_file *ea_loc) : device(dialog, f, reading_ver, saved, ea_loc) {}; 00563 00564 // using dump from device class 00565 // using method is_more_recent_than() from device class 00566 // using method has_changed_since() from device class 00567 unsigned char signature() const { return mk_signature('c', get_saved_status()); }; 00568 entree *clone() const { return new chardev(*this); }; 00569 00570 #ifdef LIBDAR_SPECIAL_ALLOC 00571 USE_SPECIAL_ALLOC(chardev); 00572 #endif 00573 }; 00574 00576 class blockdev : public device 00577 { 00578 public: 00579 blockdev(U_16 uid, U_16 gid, U_16 perm, 00580 const infinint & last_access, 00581 const infinint & last_modif, 00582 const std::string & name, 00583 U_16 major, 00584 U_16 minor, 00585 const infinint & fs_device) : device(uid, gid, perm, last_access, 00586 last_modif, name, 00587 major, minor, fs_device) {}; 00588 blockdev(user_interaction & dialog, 00589 generic_file & f, 00590 const dar_version & reading_ver, 00591 saved_status saved, 00592 generic_file *ea_loc) : device(dialog, f, reading_ver, saved, ea_loc) {}; 00593 00594 // using dump from device class 00595 // using method is_more_recent_than() from device class 00596 // using method has_changed_since() from device class 00597 unsigned char signature() const { return mk_signature('b', get_saved_status()); }; 00598 entree *clone() const { return new blockdev(*this); }; 00599 00600 #ifdef LIBDAR_SPECIAL_ALLOC 00601 USE_SPECIAL_ALLOC(blockdev); 00602 #endif 00603 }; 00604 00606 class tube : public inode 00607 { 00608 public : 00609 tube(U_16 xuid, U_16 xgid, U_16 xperm, 00610 const infinint & last_access, 00611 const infinint & last_modif, 00612 const std::string & xname, 00613 const infinint & fs_device) : inode(xuid, xgid, xperm, last_access, last_modif, xname, fs_device) { set_saved_status(s_saved); }; 00614 tube(user_interaction & dialog, 00615 generic_file & f, 00616 const dar_version & reading_ver, 00617 saved_status saved, 00618 generic_file *ea_loc) : inode(dialog, f, reading_ver, saved, ea_loc) {}; 00619 00620 // using dump from inode class 00621 // using method is_more_recent_than() from inode class 00622 // using method has_changed_since() from inode class 00623 unsigned char signature() const { return mk_signature('p', get_saved_status()); }; 00624 entree *clone() const { return new tube(*this); }; 00625 00626 #ifdef LIBDAR_SPECIAL_ALLOC 00627 USE_SPECIAL_ALLOC(tube); 00628 #endif 00629 }; 00630 00632 class prise : public inode 00633 { 00634 public : 00635 prise(U_16 xuid, U_16 xgid, U_16 xperm, 00636 const infinint & last_access, 00637 const infinint & last_modif, 00638 const std::string & xname, 00639 const infinint & fs_device) : inode(xuid, xgid, xperm, last_access, last_modif, xname, fs_device) { set_saved_status(s_saved); }; 00640 prise(user_interaction & dialog, 00641 generic_file & f, 00642 const dar_version & reading_ver, 00643 saved_status saved, 00644 generic_file *ea_loc) : inode(dialog, f, reading_ver, saved, ea_loc) {}; 00645 00646 // using dump from inode class 00647 // using method is_more_recent_than() from inode class 00648 // using method has_changed_since() from inode class 00649 unsigned char signature() const { return mk_signature('s', get_saved_status()); }; 00650 entree *clone() const { return new prise(*this); }; 00651 00652 #ifdef LIBDAR_SPECIAL_ALLOC 00653 USE_SPECIAL_ALLOC(prise); 00654 #endif 00655 }; 00656 00658 class detruit : public nomme 00659 { 00660 public : 00661 detruit(const std::string & name, unsigned char firm) : nomme(name) { signe = firm; }; 00662 detruit(generic_file & f) : nomme(f) { if(f.read((char *)&signe, 1) != 1) throw Erange("detruit::detruit", gettext("missing data to build")); }; 00663 00664 void dump(user_interaction & dialog, generic_file & f) const { nomme::dump(dialog, f); f.write((char *)&signe, 1); }; 00665 unsigned char get_signature() const { return signe; }; 00666 void set_signature(unsigned char x) { signe = x; }; 00667 unsigned char signature() const { return 'x'; }; 00668 entree *clone() const { return new detruit(*this); }; 00669 00670 #ifdef LIBDAR_SPECIAL_ALLOC 00671 USE_SPECIAL_ALLOC(detruit); 00672 #endif 00673 private : 00674 unsigned char signe; 00675 }; 00676 00678 class ignored : public nomme 00679 { 00680 public : 00681 ignored(const std::string & name) : nomme(name) {}; 00682 ignored(generic_file & f) : nomme(f) { throw SRC_BUG; }; 00683 00684 void dump(user_interaction & dialog, generic_file & f) const { throw SRC_BUG; }; 00685 unsigned char signature() const { return 'i'; }; 00686 entree *clone() const { return new ignored(*this); }; 00687 #ifdef LIBDAR_SPECIAL_ALLOC 00688 USE_SPECIAL_ALLOC(ignored); 00689 #endif 00690 }; 00691 00693 class ignored_dir : public inode 00694 { 00695 public: 00696 ignored_dir(const directory &target) : inode(target) {}; 00697 ignored_dir(user_interaction & dialog, 00698 generic_file & f, 00699 const dar_version & reading_ver, 00700 generic_file *ea_loc) : inode(dialog, f, reading_ver, s_not_saved, ea_loc) { throw SRC_BUG; }; 00701 00702 void dump(user_interaction & dialog, generic_file & f) const; // behaves like an empty directory 00703 unsigned char signature() const { return 'j'; }; 00704 entree *clone() const { return new ignored_dir(*this); }; 00705 #ifdef LIBDAR_SPECIAL_ALLOC 00706 USE_SPECIAL_ALLOC(ignored_dir); 00707 #endif 00708 }; 00709 00711 class catalogue 00712 { 00713 public : 00714 catalogue(user_interaction & dialog); 00715 catalogue(user_interaction & dialog, 00716 generic_file & f, 00717 const dar_version & reading_ver, 00718 compression default_algo, 00719 generic_file *data_loc, 00720 generic_file *ea_loc); 00721 catalogue(const catalogue & ref) : out_compare(ref.out_compare) { partial_copy_from(ref); }; 00722 catalogue & operator = (const catalogue &ref); 00723 ~catalogue() { detruire(); }; 00724 00725 void reset_read(); 00726 void skip_read_to_parent_dir(); 00727 // skip all items of the current dir and of any subdir, the next call will return 00728 // next item of the parent dir (no eod to exit from the current dir !) 00729 bool read(const entree * & ref); 00730 // sequential read (generates eod) and return false when all files have been read 00731 bool read_if_present(std::string *name, const nomme * & ref); 00732 // pseudo-sequential read (reading a directory still 00733 // implies that following read are located in this subdirectory up to the next EOD) but 00734 // it returns false if no entry of this name are present in the current directory 00735 // a call with NULL as first argument means to set the current dir the parent directory 00736 00737 void reset_sub_read(const path &sub); // return false if the path do not exists in catalogue 00738 bool sub_read(const entree * &ref); // sequential read of the catalogue, ignoring all that 00739 // is not part of the subdirectory specified with reset_sub_read 00740 // the read include the inode leading to the sub_tree as well as the pending eod 00741 00742 void reset_add(); 00743 void add(entree *ref); // add at end of catalogue (sequential point of view) 00744 void add_in_current_read(nomme *ref); // add in currently read directory 00745 00746 void reset_compare(); 00747 bool compare(const entree * name, const entree * & extracted); 00748 // returns true if the ref exists, and gives it back in second argument as it is in the current catalogue. 00749 // returns false is no entry of that nature exists in the catalogue (in the current directory) 00750 // if ref is a directory, the operation is normaly relative to the directory itself, but 00751 // such a call implies a chdir to that directory. thus, a call with an EOD is necessary to 00752 // change to the parent directory. 00753 // note : 00754 // if a directory is not present, returns false, but records the inexistant subdirectory 00755 // structure defined by the following calls to this routine, this to be able to know when 00756 // the last available directory is back the current one when changing to parent directory, 00757 // and then proceed with normal comparison of inode. In this laps of time, the call will 00758 // always return false, while it temporary stores the missing directory structure 00759 00760 bool direct_read(const path & ref, const nomme * &ret); 00761 00762 infinint update_destroyed_with(catalogue & ref); 00763 // ref must have the same root, else the operation generates an exception 00764 00765 void update_absent_with(catalogue & ref); 00766 // in case of abortion, complete missing files as if what could not be 00767 // inspected had not changed since the reference was done 00768 00769 void dump(generic_file & ref) const; 00770 void listing(const mask &m = bool_mask(true), bool filter_unsaved = false, const std::string & marge = "") const; 00771 void tar_listing(const mask & m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const; 00772 void xml_listing(const mask & m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const; 00773 entree_stats get_stats() const { return stats; }; 00774 00775 const directory *get_contenu() const { return contenu; }; // used by data_tree 00776 00777 #ifdef LIBDAR_SPECIAL_ALLOC 00778 USE_SPECIAL_ALLOC(catalogue); 00779 #endif 00780 00781 private : 00782 directory *contenu; 00783 path out_compare; // stores the missing directory structure, when extracting 00784 directory *current_compare; // points to the current directory when extracting 00785 directory *current_add; // points to the directory where to add the next file with add_file; 00786 directory *current_read; // points to the directory where the next item will be read 00787 path *sub_tree; // path to sub_tree 00788 signed int sub_count; // count the depth in of read routine in the sub_tree 00789 entree_stats stats; // statistics catalogue contents 00790 00791 user_interaction *cat_ui; 00792 00793 void partial_copy_from(const catalogue &ref); 00794 void detruire(); 00795 00796 static const eod r_eod; // needed to return eod reference, without taking risk of saturating memory 00797 }; 00798 00800 00801 } // end of namespace 00802 00803 #endif