Disk ARchive 2.3.10
|
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.5 2008/05/16 11:00:17 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, const inode &other, const mask & ea_mask, comparison_fields what_to_check) const; 00203 // throw Erange exception if a difference has been detected 00204 // this is not a symetrical comparison, but all what is present 00205 // in the current object is compared against the argument 00206 // which may contain supplementary informations 00207 // used for DIFFERENCE 00208 00209 00210 00212 // EXTENDED ATTRIBUTS Methods 00213 // 00214 00215 enum ea_status { ea_none, ea_partial, ea_fake, ea_full }; 00216 // ea_none : no EA present for this inode in filesystem 00217 // ea_partial : EA present in filesystem but not stored (ctime used to check changes) 00218 // ea_fake : EA present in filesystem but not attached to this inode (isolation context) 00219 // ea_full : EA present in filesystem and attached to this inode 00220 00221 // I : to know whether EA data is present or not for this object 00222 void ea_set_saved_status(ea_status status); 00223 ea_status ea_get_saved_status() const { return ea_saved; }; 00224 00225 // II : to associate EA list to an inode object (mainly for backup operation) #EA_FULL only# 00226 void ea_attach(ea_attributs *ref); 00227 const ea_attributs *get_ea(user_interaction & dialog) const; 00228 void ea_detach() const; //discards any future call to get_ea() ! 00229 00230 // III : to record where is dump the EA in the archive #EA_FULL only# 00231 void ea_set_offset(const infinint & pos) { *ea_offset = pos; }; 00232 void ea_set_crc(const crc & val) { copy_crc(ea_crc, val); }; 00233 void ea_get_crc(crc & val) const { copy_crc(val, ea_crc); }; 00234 00235 // IV : to know/record if EA have been modified #EA_FULL, EA_PARTIAL or EA_FAKE# 00236 infinint get_last_change() const; 00237 void set_last_change(const infinint & x_time); 00238 00239 // V : for archive migration (merging) 00240 void change_ea_location(generic_file *loc) { storage = loc; }; 00241 00243 00244 #ifdef LIBDAR_SPECIAL_ALLOC 00245 USE_SPECIAL_ALLOC(inode); 00246 #endif 00247 00248 protected: 00249 virtual void sub_compare(user_interaction & dialog, const inode & other) const {}; 00250 00251 private : 00252 U_16 uid; 00253 U_16 gid; 00254 U_16 perm; 00255 infinint *last_acc, *last_mod; 00256 saved_status xsaved; 00257 ea_status ea_saved; 00258 // the following is used only if ea_saved == full 00259 infinint *ea_offset; 00260 ea_attributs *ea; 00261 // the following is used if ea_saved == full or ea_saved == partial 00262 infinint *last_cha; 00263 crc ea_crc; 00264 infinint *fs_dev; 00265 generic_file *storage; // where are stored EA 00266 dar_version edit; // need to know EA format used in archive file 00267 }; 00268 00270 class file : public inode 00271 { 00272 public : 00273 file(U_16 xuid, U_16 xgid, U_16 xperm, 00274 const infinint & last_access, 00275 const infinint & last_modif, 00276 const std::string & src, 00277 const path & che, 00278 const infinint & taille, 00279 const infinint & fs_device); 00280 file(const file & ref); 00281 file(user_interaction & dialog, 00282 generic_file & f, 00283 const dar_version & reading_ver, 00284 saved_status saved, 00285 compression default_algo, 00286 generic_file *data_loc, 00287 generic_file *ea_loc); 00288 ~file() { detruit(); }; 00289 00290 void dump(user_interaction & dialog, generic_file & f) const; 00291 bool has_changed_since(const inode & ref, const infinint & hourshift, inode::comparison_fields what_to_check) const; 00292 infinint get_size() const { return *size; }; 00293 infinint get_storage_size() const { return *storage_size; }; 00294 void set_storage_size(const infinint & s) { *storage_size = s; }; 00295 generic_file *get_data(user_interaction & dialog, bool keep_compressed = false) const; // return a newly alocated object in read_only mode 00296 void clean_data(); // partially free memory (but get_data() becomes disabled) 00297 void set_offset(const infinint & r); 00298 unsigned char signature() const { return mk_signature('f', get_saved_status()); }; 00299 00300 void set_crc(const crc &c) { copy_crc(check, c); }; 00301 bool get_crc(crc & c) const; 00302 entree *clone() const { return new file(*this); }; 00303 00304 compression get_compression_algo_used() const { return algo; }; 00305 00306 // object migration methods (merging) 00307 void change_compression_algo_used(compression x) { algo = x; }; 00308 void change_location(generic_file *x) { loc = x; }; 00309 00310 00311 #ifdef LIBDAR_SPECIAL_ALLOC 00312 USE_SPECIAL_ALLOC(file); 00313 #endif 00314 00315 protected : 00316 void sub_compare(user_interaction & dialog, const inode & other) const; 00317 00318 private : 00319 enum { empty, from_path, from_cat } status; 00320 path chemin; 00321 infinint *offset; 00322 infinint *size; 00323 infinint *storage_size; 00324 00325 bool available_crc; 00326 crc check; 00327 00328 generic_file *loc; 00329 compression algo; 00330 00331 void detruit(); 00332 }; 00333 00335 class etiquette 00336 { 00337 public: 00338 virtual infinint get_etiquette() const = 0; 00339 virtual const file_etiquette *get_inode() const = 0; 00340 virtual ~etiquette() {}; 00341 00342 #ifdef LIBDAR_SPECIAL_ALLOC 00343 USE_SPECIAL_ALLOC(etiquette); 00344 #endif 00345 }; 00346 00348 class file_etiquette : public file, public etiquette 00349 { 00350 public : 00351 file_etiquette(U_16 xuid, U_16 xgid, U_16 xperm, 00352 const infinint & last_access, 00353 const infinint & last_modif, 00354 const std::string & src, 00355 const path & che, 00356 const infinint & taille, 00357 const infinint & fs_device, 00358 const infinint & etiquette_number); 00359 file_etiquette(const file_etiquette & ref); 00360 file_etiquette(user_interaction & dialog, 00361 generic_file & f, 00362 const dar_version & reading_ver, 00363 saved_status saved, 00364 compression default_algo, 00365 generic_file *data_loc, 00366 generic_file *ea_loc); 00367 00368 void dump(user_interaction & dialog, generic_file &f) const; 00369 unsigned char signature() const { return mk_signature('e', get_saved_status()); }; 00370 entree *clone() const { return new file_etiquette(*this); }; 00371 00372 void change_etiquette(const infinint & new_val) { etiquette = new_val; }; 00373 00374 // inherited from etiquette 00375 infinint get_etiquette() const { return etiquette; }; 00376 const file_etiquette *get_inode() const { return this; }; 00377 00378 #ifdef LIBDAR_SPECIAL_ALLOC 00379 USE_SPECIAL_ALLOC(file_etiquette); 00380 #endif 00381 00382 private : 00383 infinint etiquette; 00384 }; 00385 00387 class hard_link : public nomme, public etiquette 00388 { 00389 public : 00390 hard_link(const std::string & name, file_etiquette *ref); 00391 hard_link(generic_file & f, infinint & etiquette); // with etiquette, a call to set_reference() follows 00392 00393 void dump(user_interaction & dialog, generic_file &f) const; 00394 unsigned char signature() const { return 'h'; }; 00395 entree *clone() const { return new hard_link(*this); }; 00396 void set_reference(file_etiquette *ref); 00397 00398 // inherited from etiquette 00399 infinint get_etiquette() const; 00400 const file_etiquette *get_inode() const { return x_ref; }; 00401 00402 #ifdef LIBDAR_SPECIAL_ALLOC 00403 USE_SPECIAL_ALLOC(hard_link); 00404 #endif 00405 private : 00406 file_etiquette *x_ref; 00407 }; 00408 00410 class lien : public inode 00411 { 00412 public : 00413 lien(U_16 uid, U_16 gid, U_16 perm, 00414 const infinint & last_access, 00415 const infinint & last_modif, 00416 const std::string & name, 00417 const std::string & target, 00418 const infinint & fs_device); 00419 lien(user_interaction & dialog, 00420 generic_file & f, 00421 const dar_version & reading_ver, 00422 saved_status saved, 00423 generic_file *ea_loc); 00424 00425 void dump(user_interaction & dialog, generic_file & f) const; 00426 const std::string & get_target() const; 00427 void set_target(std::string x); 00428 00429 // using the method is_more_recent_than() from inode 00430 // using method has_changed_since() from inode class 00431 unsigned char signature() const { return mk_signature('l', get_saved_status()); }; 00432 entree *clone() const { return new lien(*this); }; 00433 00434 #ifdef LIBDAR_SPECIAL_ALLOC 00435 USE_SPECIAL_ALLOC(lien); 00436 #endif 00437 protected : 00438 void sub_compare(user_interaction & dialog, const inode & other) const; 00439 00440 private : 00441 std::string points_to; 00442 }; 00443 00445 class directory : public inode 00446 { 00447 public : 00448 directory(U_16 xuid, U_16 xgid, U_16 xperm, 00449 const infinint & last_access, 00450 const infinint & last_modif, 00451 const std::string & xname, 00452 const infinint & device); 00453 directory(const directory &ref); // only the inode part is build, no children is duplicated (empty dir) 00454 directory(user_interaction & dialog, 00455 generic_file & f, 00456 const dar_version & reading_ver, 00457 saved_status saved, 00458 entree_stats & stats, 00459 std::map <infinint, file_etiquette *> & corres, 00460 compression default_algo, 00461 generic_file *data_loc, 00462 generic_file *ea_loc); 00463 ~directory(); // detruit aussi tous les fils et se supprime de son 'parent' 00464 00465 void dump(user_interaction & dialog, generic_file & f) const; 00466 void add_children(nomme *r); // when r is a directory, 'parent' is set to 'this' 00467 bool has_children() const { return fils.size() != 0; }; 00468 void reset_read_children() const; 00469 bool read_children(const nomme * &r) const; // read the direct children of the directory, returns false if no more is available 00470 void listing(user_interaction & dialog, 00471 const mask &m = bool_mask(true), bool filter_unsaved = false, const std::string & marge = "") const; 00472 void tar_listing(user_interaction & dialog, 00473 const mask &m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const; 00474 void xml_listing(user_interaction & dialog, 00475 const mask &m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const; 00476 directory * get_parent() const { return parent; }; 00477 bool search_children(const std::string &name, nomme *&ref); 00478 bool callback_for_children_of(user_interaction & dialog, const std::string & sdir) const; 00479 00480 // using is_more_recent_than() from inode class 00481 // using method has_changed_since() from inode class 00482 unsigned char signature() const { return mk_signature('d', get_saved_status()); }; 00483 00484 // some data has changed since archive of reference in this directory or subdirectories 00485 bool get_recursive_has_changed() const { return recursive_has_changed; }; 00486 // update the recursive_has_changed field 00487 void recursive_has_changed_update() const; 00488 00489 entree *clone() const { return new directory(*this); }; 00490 00491 #ifdef LIBDAR_SPECIAL_ALLOC 00492 USE_SPECIAL_ALLOC(directory); 00493 #endif 00494 private : 00495 directory *parent; 00496 std::vector<nomme *> fils; 00497 std::vector<nomme *>::iterator it; 00498 bool recursive_has_changed; 00499 00500 void clear(); 00501 }; 00502 00504 class device : public inode 00505 { 00506 public : 00507 device(U_16 uid, U_16 gid, U_16 perm, 00508 const infinint & last_access, 00509 const infinint & last_modif, 00510 const std::string & name, 00511 U_16 major, 00512 U_16 minor, 00513 const infinint & fs_device); 00514 device(user_interaction & dialog, 00515 generic_file & f, 00516 const dar_version & reading_ver, 00517 saved_status saved, 00518 generic_file *ea_loc); 00519 00520 void dump(user_interaction & dialog, generic_file & f) const; 00521 int get_major() const { if(get_saved_status() != s_saved) throw SRC_BUG; else return xmajor; }; 00522 int get_minor() const { if(get_saved_status() != s_saved) throw SRC_BUG; else return xminor; }; 00523 void set_major(int x) { xmajor = x; }; 00524 void set_minor(int x) { xminor = x; }; 00525 00526 // using method is_more_recent_than() from inode class 00527 // using method has_changed_since() from inode class 00528 // signature is left pure abstract 00529 00530 #ifdef LIBDAR_SPECIAL_ALLOC 00531 USE_SPECIAL_ALLOC(device); 00532 #endif 00533 00534 protected : 00535 void sub_compare(user_interaction & dialog, const inode & other) const; 00536 00537 private : 00538 U_16 xmajor, xminor; 00539 }; 00540 00542 class chardev : public device 00543 { 00544 public: 00545 chardev(U_16 uid, U_16 gid, U_16 perm, 00546 const infinint & last_access, 00547 const infinint & last_modif, 00548 const std::string & name, 00549 U_16 major, 00550 U_16 minor, 00551 const infinint & fs_device) : device(uid, gid, perm, last_access, 00552 last_modif, name, 00553 major, minor, fs_device) {}; 00554 chardev(user_interaction & dialog, 00555 generic_file & f, 00556 const dar_version & reading_ver, 00557 saved_status saved, 00558 generic_file *ea_loc) : device(dialog, f, reading_ver, saved, ea_loc) {}; 00559 00560 // using dump from device class 00561 // using method is_more_recent_than() from device class 00562 // using method has_changed_since() from device class 00563 unsigned char signature() const { return mk_signature('c', get_saved_status()); }; 00564 entree *clone() const { return new chardev(*this); }; 00565 00566 #ifdef LIBDAR_SPECIAL_ALLOC 00567 USE_SPECIAL_ALLOC(chardev); 00568 #endif 00569 }; 00570 00572 class blockdev : public device 00573 { 00574 public: 00575 blockdev(U_16 uid, U_16 gid, U_16 perm, 00576 const infinint & last_access, 00577 const infinint & last_modif, 00578 const std::string & name, 00579 U_16 major, 00580 U_16 minor, 00581 const infinint & fs_device) : device(uid, gid, perm, last_access, 00582 last_modif, name, 00583 major, minor, fs_device) {}; 00584 blockdev(user_interaction & dialog, 00585 generic_file & f, 00586 const dar_version & reading_ver, 00587 saved_status saved, 00588 generic_file *ea_loc) : device(dialog, f, reading_ver, saved, ea_loc) {}; 00589 00590 // using dump from device class 00591 // using method is_more_recent_than() from device class 00592 // using method has_changed_since() from device class 00593 unsigned char signature() const { return mk_signature('b', get_saved_status()); }; 00594 entree *clone() const { return new blockdev(*this); }; 00595 00596 #ifdef LIBDAR_SPECIAL_ALLOC 00597 USE_SPECIAL_ALLOC(blockdev); 00598 #endif 00599 }; 00600 00602 class tube : public inode 00603 { 00604 public : 00605 tube(U_16 xuid, U_16 xgid, U_16 xperm, 00606 const infinint & last_access, 00607 const infinint & last_modif, 00608 const std::string & xname, 00609 const infinint & fs_device) : inode(xuid, xgid, xperm, last_access, last_modif, xname, fs_device) { set_saved_status(s_saved); }; 00610 tube(user_interaction & dialog, 00611 generic_file & f, 00612 const dar_version & reading_ver, 00613 saved_status saved, 00614 generic_file *ea_loc) : inode(dialog, f, reading_ver, saved, ea_loc) {}; 00615 00616 // using dump from inode class 00617 // using method is_more_recent_than() from inode class 00618 // using method has_changed_since() from inode class 00619 unsigned char signature() const { return mk_signature('p', get_saved_status()); }; 00620 entree *clone() const { return new tube(*this); }; 00621 00622 #ifdef LIBDAR_SPECIAL_ALLOC 00623 USE_SPECIAL_ALLOC(tube); 00624 #endif 00625 }; 00626 00628 class prise : public inode 00629 { 00630 public : 00631 prise(U_16 xuid, U_16 xgid, U_16 xperm, 00632 const infinint & last_access, 00633 const infinint & last_modif, 00634 const std::string & xname, 00635 const infinint & fs_device) : inode(xuid, xgid, xperm, last_access, last_modif, xname, fs_device) { set_saved_status(s_saved); }; 00636 prise(user_interaction & dialog, 00637 generic_file & f, 00638 const dar_version & reading_ver, 00639 saved_status saved, 00640 generic_file *ea_loc) : inode(dialog, f, reading_ver, saved, ea_loc) {}; 00641 00642 // using dump from inode class 00643 // using method is_more_recent_than() from inode class 00644 // using method has_changed_since() from inode class 00645 unsigned char signature() const { return mk_signature('s', get_saved_status()); }; 00646 entree *clone() const { return new prise(*this); }; 00647 00648 #ifdef LIBDAR_SPECIAL_ALLOC 00649 USE_SPECIAL_ALLOC(prise); 00650 #endif 00651 }; 00652 00654 class detruit : public nomme 00655 { 00656 public : 00657 detruit(const std::string & name, unsigned char firm) : nomme(name) { signe = firm; }; 00658 detruit(generic_file & f) : nomme(f) { if(f.read((char *)&signe, 1) != 1) throw Erange("detruit::detruit", gettext("missing data to build")); }; 00659 00660 void dump(user_interaction & dialog, generic_file & f) const { nomme::dump(dialog, f); f.write((char *)&signe, 1); }; 00661 unsigned char get_signature() const { return signe; }; 00662 void set_signature(unsigned char x) { signe = x; }; 00663 unsigned char signature() const { return 'x'; }; 00664 entree *clone() const { return new detruit(*this); }; 00665 00666 #ifdef LIBDAR_SPECIAL_ALLOC 00667 USE_SPECIAL_ALLOC(detruit); 00668 #endif 00669 private : 00670 unsigned char signe; 00671 }; 00672 00674 class ignored : public nomme 00675 { 00676 public : 00677 ignored(const std::string & name) : nomme(name) {}; 00678 ignored(generic_file & f) : nomme(f) { throw SRC_BUG; }; 00679 00680 void dump(user_interaction & dialog, generic_file & f) const { throw SRC_BUG; }; 00681 unsigned char signature() const { return 'i'; }; 00682 entree *clone() const { return new ignored(*this); }; 00683 #ifdef LIBDAR_SPECIAL_ALLOC 00684 USE_SPECIAL_ALLOC(ignored); 00685 #endif 00686 }; 00687 00689 class ignored_dir : public inode 00690 { 00691 public: 00692 ignored_dir(const directory &target) : inode(target) {}; 00693 ignored_dir(user_interaction & dialog, 00694 generic_file & f, 00695 const dar_version & reading_ver, 00696 generic_file *ea_loc) : inode(dialog, f, reading_ver, s_not_saved, ea_loc) { throw SRC_BUG; }; 00697 00698 void dump(user_interaction & dialog, generic_file & f) const; // behaves like an empty directory 00699 unsigned char signature() const { return 'j'; }; 00700 entree *clone() const { return new ignored_dir(*this); }; 00701 #ifdef LIBDAR_SPECIAL_ALLOC 00702 USE_SPECIAL_ALLOC(ignored_dir); 00703 #endif 00704 }; 00705 00707 class catalogue 00708 { 00709 public : 00710 catalogue(user_interaction & dialog); 00711 catalogue(user_interaction & dialog, 00712 generic_file & f, 00713 const dar_version & reading_ver, 00714 compression default_algo, 00715 generic_file *data_loc, 00716 generic_file *ea_loc); 00717 catalogue(const catalogue & ref) : out_compare(ref.out_compare) { partial_copy_from(ref); }; 00718 catalogue & operator = (const catalogue &ref); 00719 ~catalogue() { detruire(); }; 00720 00721 void reset_read(); 00722 void skip_read_to_parent_dir(); 00723 // skip all items of the current dir and of any subdir, the next call will return 00724 // next item of the parent dir (no eod to exit from the current dir !) 00725 bool read(const entree * & ref); 00726 // sequential read (generates eod) and return false when all files have been read 00727 bool read_if_present(std::string *name, const nomme * & ref); 00728 // pseudo-sequential read (reading a directory still 00729 // implies that following read are located in this subdirectory up to the next EOD) but 00730 // it returns false if no entry of this name are present in the current directory 00731 // a call with NULL as first argument means to set the current dir the parent directory 00732 00733 void reset_sub_read(const path &sub); // return false if the path do not exists in catalogue 00734 bool sub_read(const entree * &ref); // sequential read of the catalogue, ignoring all that 00735 // is not part of the subdirectory specified with reset_sub_read 00736 // the read include the inode leading to the sub_tree as well as the pending eod 00737 00738 void reset_add(); 00739 void add(entree *ref); // add at end of catalogue (sequential point of view) 00740 void add_in_current_read(nomme *ref); // add in currently read directory 00741 00742 void reset_compare(); 00743 bool compare(const entree * name, const entree * & extracted); 00744 // returns true if the ref exists, and gives it back in second argument as it is in the current catalogue. 00745 // returns false is no entry of that nature exists in the catalogue (in the current directory) 00746 // if ref is a directory, the operation is normaly relative to the directory itself, but 00747 // such a call implies a chdir to that directory. thus, a call with an EOD is necessary to 00748 // change to the parent directory. 00749 // note : 00750 // if a directory is not present, returns false, but records the inexistant subdirectory 00751 // structure defined by the following calls to this routine, this to be able to know when 00752 // the last available directory is back the current one when changing to parent directory, 00753 // and then proceed with normal comparison of inode. In this laps of time, the call will 00754 // always return false, while it temporary stores the missing directory structure 00755 00756 bool direct_read(const path & ref, const nomme * &ret); 00757 00758 infinint update_destroyed_with(catalogue & ref); 00759 // ref must have the same root, else the operation generates an exception 00760 00761 void update_absent_with(catalogue & ref); 00762 // in case of abortion, complete missing files as if what could not be 00763 // inspected had not changed since the reference was done 00764 00765 void dump(generic_file & ref) const; 00766 void listing(const mask &m = bool_mask(true), bool filter_unsaved = false, const std::string & marge = "") const; 00767 void tar_listing(const mask & m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const; 00768 void xml_listing(const mask & m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const; 00769 entree_stats get_stats() const { return stats; }; 00770 00771 const directory *get_contenu() const { return contenu; }; // used by data_tree 00772 00773 #ifdef LIBDAR_SPECIAL_ALLOC 00774 USE_SPECIAL_ALLOC(catalogue); 00775 #endif 00776 00777 private : 00778 directory *contenu; 00779 path out_compare; // stores the missing directory structure, when extracting 00780 directory *current_compare; // points to the current directory when extracting 00781 directory *current_add; // points to the directory where to add the next file with add_file; 00782 directory *current_read; // points to the directory where the next item will be read 00783 path *sub_tree; // path to sub_tree 00784 signed int sub_count; // count the depth in of read routine in the sub_tree 00785 entree_stats stats; // statistics catalogue contents 00786 00787 user_interaction *cat_ui; 00788 00789 void partial_copy_from(const catalogue &ref); 00790 void detruire(); 00791 00792 static const eod r_eod; // needed to return eod reference, without taking risk of saturating memory 00793 }; 00794 00796 00797 } // end of namespace 00798 00799 #endif