00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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 }
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,
00065 s_fake,
00066 s_not_saved
00067 };
00068
00069 struct entree_stats
00070 {
00071 infinint num_x;
00072 infinint num_d;
00073 infinint num_f;
00074 infinint num_c;
00075 infinint num_b;
00076 infinint num_p;
00077 infinint num_s;
00078 infinint num_l;
00079 infinint num_hard_linked_inodes;
00080 infinint num_hard_link_entries;
00081
00082 infinint saved;
00083 infinint total;
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
00112
00113
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
00125 unsigned char signature() const { return 'z'; };
00126 entree *clone() const { return new eod(); };
00127
00128
00129
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 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
00144
00145
00146
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,
00166 cf_ignore_owner,
00167 cf_mtime,
00168 cf_inode_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
00198 virtual bool has_changed_since(const inode & ref, const infinint & hourshift, comparison_fields what_to_check) const;
00199
00200
00201
00202 void compare(user_interaction & dialog, const inode &other, const mask & ea_mask, comparison_fields what_to_check) const;
00203
00204
00205
00206
00207
00208
00209
00210
00212
00213
00214
00215 enum ea_status { ea_none, ea_partial, ea_fake, ea_full };
00216
00217
00218
00219
00220
00221
00222 void ea_set_saved_status(ea_status status);
00223 ea_status ea_get_saved_status() const { return ea_saved; };
00224
00225
00226 void ea_attach(ea_attributs *ref);
00227 const ea_attributs *get_ea(user_interaction & dialog) const;
00228 void ea_detach() const;
00229
00230
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
00236 infinint get_last_change() const;
00237 void set_last_change(const infinint & x_time);
00238
00239
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
00259 infinint *ea_offset;
00260 ea_attributs *ea;
00261
00262 infinint *last_cha;
00263 crc ea_crc;
00264 infinint *fs_dev;
00265 generic_file *storage;
00266 dar_version edit;
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;
00296 void clean_data();
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
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
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);
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
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 std::string get_target() const;
00427 void set_target(std::string x);
00428
00429
00430
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);
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();
00464
00465 void dump(user_interaction & dialog, generic_file & f) const;
00466 void add_children(nomme *r);
00467 bool has_children() const { return fils.size() != 0; };
00468 void reset_read_children() const;
00469 bool read_children(const nomme * &r) const;
00470 void listing(user_interaction & dialog,
00471 const mask &m = bool_mask(true), bool filter_unsaved = false, 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
00481
00482 unsigned char signature() const { return mk_signature('d', get_saved_status()); };
00483
00484
00485 bool get_recursive_has_changed() const { return recursive_has_changed; };
00486
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
00527
00528
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
00561
00562
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
00591
00592
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
00617
00618
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
00643
00644
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;
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
00724
00725 bool read(const entree * & ref);
00726
00727 bool read_if_present(std::string *name, const nomme * & ref);
00728
00729
00730
00731
00732
00733 void reset_sub_read(const path &sub);
00734 bool sub_read(const entree * &ref);
00735
00736
00737
00738 void reset_add();
00739 void add(entree *ref);
00740 void add_in_current_read(nomme *ref);
00741
00742 void reset_compare();
00743 bool compare(const entree * name, const entree * & extracted);
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756 bool direct_read(const path & ref, const nomme * &ret);
00757
00758 infinint update_destroyed_with(catalogue & ref);
00759
00760
00761 void update_absent_with(catalogue & ref);
00762
00763
00764
00765 void dump(generic_file & ref) const;
00766 void listing(const mask &m = bool_mask(true), bool filter_unsaved = false, 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; };
00772
00773 #ifdef LIBDAR_SPECIAL_ALLOC
00774 USE_SPECIAL_ALLOC(catalogue);
00775 #endif
00776
00777 private :
00778 directory *contenu;
00779 path out_compare;
00780 directory *current_compare;
00781 directory *current_add;
00782 directory *current_read;
00783 path *sub_tree;
00784 signed int sub_count;
00785 entree_stats stats;
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;
00793 };
00794
00796
00797 }
00798
00799 #endif