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 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
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,
00203 const inode &other,
00204 const mask & ea_mask,
00205 comparison_fields what_to_check,
00206 const infinint & hourshift) const;
00207
00208
00209
00210
00211
00212
00213
00214
00216
00217
00218
00219 enum ea_status { ea_none, ea_partial, ea_fake, ea_full };
00220
00221
00222
00223
00224
00225
00226 void ea_set_saved_status(ea_status status);
00227 ea_status ea_get_saved_status() const { return ea_saved; };
00228
00229
00230 void ea_attach(ea_attributs *ref);
00231 const ea_attributs *get_ea(user_interaction & dialog) const;
00232 void ea_detach() const;
00233
00234
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
00240 infinint get_last_change() const;
00241 void set_last_change(const infinint & x_time);
00242
00243
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
00263 infinint *ea_offset;
00264 ea_attributs *ea;
00265
00266 infinint *last_cha;
00267 crc ea_crc;
00268 infinint *fs_dev;
00269 generic_file *storage;
00270 dar_version edit;
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;
00300 void clean_data();
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
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
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);
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
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
00434
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);
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();
00468
00469 void dump(user_interaction & dialog, generic_file & f) const;
00470 void add_children(nomme *r);
00471 bool has_children() const { return fils.size() != 0; };
00472 void reset_read_children() const;
00473 bool read_children(const nomme * &r) const;
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
00485
00486 unsigned char signature() const { return mk_signature('d', get_saved_status()); };
00487
00488
00489 bool get_recursive_has_changed() const { return recursive_has_changed; };
00490
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
00531
00532
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
00565
00566
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
00595
00596
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
00621
00622
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
00647
00648
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;
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
00728
00729 bool read(const entree * & ref);
00730
00731 bool read_if_present(std::string *name, const nomme * & ref);
00732
00733
00734
00735
00736
00737 void reset_sub_read(const path &sub);
00738 bool sub_read(const entree * &ref);
00739
00740
00741
00742 void reset_add();
00743 void add(entree *ref);
00744 void add_in_current_read(nomme *ref);
00745
00746 void reset_compare();
00747 bool compare(const entree * name, const entree * & extracted);
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760 bool direct_read(const path & ref, const nomme * &ret);
00761
00762 infinint update_destroyed_with(catalogue & ref);
00763
00764
00765 void update_absent_with(catalogue & ref);
00766
00767
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; };
00776
00777 #ifdef LIBDAR_SPECIAL_ALLOC
00778 USE_SPECIAL_ALLOC(catalogue);
00779 #endif
00780
00781 private :
00782 directory *contenu;
00783 path out_compare;
00784 directory *current_compare;
00785 directory *current_add;
00786 directory *current_read;
00787 path *sub_tree;
00788 signed int sub_count;
00789 entree_stats stats;
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;
00797 };
00798
00800
00801 }
00802
00803 #endif