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
00341 #ifdef LIBDAR_SPECIAL_ALLOC
00342 USE_SPECIAL_ALLOC(etiquette);
00343 #endif
00344 };
00345
00347 class file_etiquette : public file, public etiquette
00348 {
00349 public :
00350 file_etiquette(U_16 xuid, U_16 xgid, U_16 xperm,
00351 const infinint & last_access,
00352 const infinint & last_modif,
00353 const std::string & src,
00354 const path & che,
00355 const infinint & taille,
00356 const infinint & fs_device,
00357 const infinint & etiquette_number);
00358 file_etiquette(const file_etiquette & ref);
00359 file_etiquette(user_interaction & dialog,
00360 generic_file & f,
00361 const dar_version & reading_ver,
00362 saved_status saved,
00363 compression default_algo,
00364 generic_file *data_loc,
00365 generic_file *ea_loc);
00366
00367 void dump(user_interaction & dialog, generic_file &f) const;
00368 unsigned char signature() const { return mk_signature('e', get_saved_status()); };
00369 entree *clone() const { return new file_etiquette(*this); };
00370
00371 void change_etiquette(const infinint & new_val) { etiquette = new_val; };
00372
00373
00374 infinint get_etiquette() const { return etiquette; };
00375 const file_etiquette *get_inode() const { return this; };
00376
00377 #ifdef LIBDAR_SPECIAL_ALLOC
00378 USE_SPECIAL_ALLOC(file_etiquette);
00379 #endif
00380
00381 private :
00382 infinint etiquette;
00383 };
00384
00386 class hard_link : public nomme, public etiquette
00387 {
00388 public :
00389 hard_link(const std::string & name, file_etiquette *ref);
00390 hard_link(generic_file & f, infinint & etiquette);
00391
00392 void dump(user_interaction & dialog, generic_file &f) const;
00393 unsigned char signature() const { return 'h'; };
00394 entree *clone() const { return new hard_link(*this); };
00395 void set_reference(file_etiquette *ref);
00396
00397
00398 infinint get_etiquette() const;
00399 const file_etiquette *get_inode() const { return x_ref; };
00400
00401 #ifdef LIBDAR_SPECIAL_ALLOC
00402 USE_SPECIAL_ALLOC(hard_link);
00403 #endif
00404 private :
00405 file_etiquette *x_ref;
00406 };
00407
00409 class lien : public inode
00410 {
00411 public :
00412 lien(U_16 uid, U_16 gid, U_16 perm,
00413 const infinint & last_access,
00414 const infinint & last_modif,
00415 const std::string & name,
00416 const std::string & target,
00417 const infinint & fs_device);
00418 lien(user_interaction & dialog,
00419 generic_file & f,
00420 const dar_version & reading_ver,
00421 saved_status saved,
00422 generic_file *ea_loc);
00423
00424 void dump(user_interaction & dialog, generic_file & f) const;
00425 std::string get_target() const;
00426 void set_target(std::string x);
00427
00428
00429
00430 unsigned char signature() const { return mk_signature('l', get_saved_status()); };
00431 entree *clone() const { return new lien(*this); };
00432
00433 #ifdef LIBDAR_SPECIAL_ALLOC
00434 USE_SPECIAL_ALLOC(lien);
00435 #endif
00436 protected :
00437 void sub_compare(user_interaction & dialog, const inode & other) const;
00438
00439 private :
00440 std::string points_to;
00441 };
00442
00444 class directory : public inode
00445 {
00446 public :
00447 directory(U_16 xuid, U_16 xgid, U_16 xperm,
00448 const infinint & last_access,
00449 const infinint & last_modif,
00450 const std::string & xname,
00451 const infinint & device);
00452 directory(const directory &ref);
00453 directory(user_interaction & dialog,
00454 generic_file & f,
00455 const dar_version & reading_ver,
00456 saved_status saved,
00457 entree_stats & stats,
00458 std::map <infinint, file_etiquette *> & corres,
00459 compression default_algo,
00460 generic_file *data_loc,
00461 generic_file *ea_loc);
00462 ~directory();
00463
00464 void dump(user_interaction & dialog, generic_file & f) const;
00465 void add_children(nomme *r);
00466 bool has_children() const { return fils.size() != 0; };
00467 void reset_read_children() const;
00468 bool read_children(const nomme * &r) const;
00469 void listing(user_interaction & dialog,
00470 const mask &m = bool_mask(true), bool filter_unsaved = false, std::string marge = "") const;
00471 void tar_listing(user_interaction & dialog,
00472 const mask &m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const;
00473 void xml_listing(user_interaction & dialog,
00474 const mask &m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const;
00475 directory * get_parent() const { return parent; };
00476 bool search_children(const std::string &name, nomme *&ref);
00477 bool callback_for_children_of(user_interaction & dialog, const std::string & sdir) const;
00478
00479
00480
00481 unsigned char signature() const { return mk_signature('d', get_saved_status()); };
00482
00483
00484 bool get_recursive_has_changed() const { return recursive_has_changed; };
00485
00486 void recursive_has_changed_update() const;
00487
00488 entree *clone() const { return new directory(*this); };
00489
00490 #ifdef LIBDAR_SPECIAL_ALLOC
00491 USE_SPECIAL_ALLOC(directory);
00492 #endif
00493 private :
00494 directory *parent;
00495 std::vector<nomme *> fils;
00496 std::vector<nomme *>::iterator it;
00497 bool recursive_has_changed;
00498
00499 void clear();
00500 };
00501
00503 class device : public inode
00504 {
00505 public :
00506 device(U_16 uid, U_16 gid, U_16 perm,
00507 const infinint & last_access,
00508 const infinint & last_modif,
00509 const std::string & name,
00510 U_16 major,
00511 U_16 minor,
00512 const infinint & fs_device);
00513 device(user_interaction & dialog,
00514 generic_file & f,
00515 const dar_version & reading_ver,
00516 saved_status saved,
00517 generic_file *ea_loc);
00518
00519 void dump(user_interaction & dialog, generic_file & f) const;
00520 int get_major() const { if(get_saved_status() != s_saved) throw SRC_BUG; else return xmajor; };
00521 int get_minor() const { if(get_saved_status() != s_saved) throw SRC_BUG; else return xminor; };
00522 void set_major(int x) { xmajor = x; };
00523 void set_minor(int x) { xminor = x; };
00524
00525
00526
00527
00528
00529 #ifdef LIBDAR_SPECIAL_ALLOC
00530 USE_SPECIAL_ALLOC(device);
00531 #endif
00532
00533 protected :
00534 void sub_compare(user_interaction & dialog, const inode & other) const;
00535
00536 private :
00537 U_16 xmajor, xminor;
00538 };
00539
00541 class chardev : public device
00542 {
00543 public:
00544 chardev(U_16 uid, U_16 gid, U_16 perm,
00545 const infinint & last_access,
00546 const infinint & last_modif,
00547 const std::string & name,
00548 U_16 major,
00549 U_16 minor,
00550 const infinint & fs_device) : device(uid, gid, perm, last_access,
00551 last_modif, name,
00552 major, minor, fs_device) {};
00553 chardev(user_interaction & dialog,
00554 generic_file & f,
00555 const dar_version & reading_ver,
00556 saved_status saved,
00557 generic_file *ea_loc) : device(dialog, f, reading_ver, saved, ea_loc) {};
00558
00559
00560
00561
00562 unsigned char signature() const { return mk_signature('c', get_saved_status()); };
00563 entree *clone() const { return new chardev(*this); };
00564
00565 #ifdef LIBDAR_SPECIAL_ALLOC
00566 USE_SPECIAL_ALLOC(chardev);
00567 #endif
00568 };
00569
00571 class blockdev : public device
00572 {
00573 public:
00574 blockdev(U_16 uid, U_16 gid, U_16 perm,
00575 const infinint & last_access,
00576 const infinint & last_modif,
00577 const std::string & name,
00578 U_16 major,
00579 U_16 minor,
00580 const infinint & fs_device) : device(uid, gid, perm, last_access,
00581 last_modif, name,
00582 major, minor, fs_device) {};
00583 blockdev(user_interaction & dialog,
00584 generic_file & f,
00585 const dar_version & reading_ver,
00586 saved_status saved,
00587 generic_file *ea_loc) : device(dialog, f, reading_ver, saved, ea_loc) {};
00588
00589
00590
00591
00592 unsigned char signature() const { return mk_signature('b', get_saved_status()); };
00593 entree *clone() const { return new blockdev(*this); };
00594
00595 #ifdef LIBDAR_SPECIAL_ALLOC
00596 USE_SPECIAL_ALLOC(blockdev);
00597 #endif
00598 };
00599
00601 class tube : public inode
00602 {
00603 public :
00604 tube(U_16 xuid, U_16 xgid, U_16 xperm,
00605 const infinint & last_access,
00606 const infinint & last_modif,
00607 const std::string & xname,
00608 const infinint & fs_device) : inode(xuid, xgid, xperm, last_access, last_modif, xname, fs_device) { set_saved_status(s_saved); };
00609 tube(user_interaction & dialog,
00610 generic_file & f,
00611 const dar_version & reading_ver,
00612 saved_status saved,
00613 generic_file *ea_loc) : inode(dialog, f, reading_ver, saved, ea_loc) {};
00614
00615
00616
00617
00618 unsigned char signature() const { return mk_signature('p', get_saved_status()); };
00619 entree *clone() const { return new tube(*this); };
00620
00621 #ifdef LIBDAR_SPECIAL_ALLOC
00622 USE_SPECIAL_ALLOC(tube);
00623 #endif
00624 };
00625
00627 class prise : public inode
00628 {
00629 public :
00630 prise(U_16 xuid, U_16 xgid, U_16 xperm,
00631 const infinint & last_access,
00632 const infinint & last_modif,
00633 const std::string & xname,
00634 const infinint & fs_device) : inode(xuid, xgid, xperm, last_access, last_modif, xname, fs_device) { set_saved_status(s_saved); };
00635 prise(user_interaction & dialog,
00636 generic_file & f,
00637 const dar_version & reading_ver,
00638 saved_status saved,
00639 generic_file *ea_loc) : inode(dialog, f, reading_ver, saved, ea_loc) {};
00640
00641
00642
00643
00644 unsigned char signature() const { return mk_signature('s', get_saved_status()); };
00645 entree *clone() const { return new prise(*this); };
00646
00647 #ifdef LIBDAR_SPECIAL_ALLOC
00648 USE_SPECIAL_ALLOC(prise);
00649 #endif
00650 };
00651
00653 class detruit : public nomme
00654 {
00655 public :
00656 detruit(const std::string & name, unsigned char firm) : nomme(name) { signe = firm; };
00657 detruit(generic_file & f) : nomme(f) { if(f.read((char *)&signe, 1) != 1) throw Erange("detruit::detruit", gettext("missing data to build")); };
00658
00659 void dump(user_interaction & dialog, generic_file & f) const { nomme::dump(dialog, f); f.write((char *)&signe, 1); };
00660 unsigned char get_signature() const { return signe; };
00661 void set_signature(unsigned char x) { signe = x; };
00662 unsigned char signature() const { return 'x'; };
00663 entree *clone() const { return new detruit(*this); };
00664
00665 #ifdef LIBDAR_SPECIAL_ALLOC
00666 USE_SPECIAL_ALLOC(detruit);
00667 #endif
00668 private :
00669 unsigned char signe;
00670 };
00671
00673 class ignored : public nomme
00674 {
00675 public :
00676 ignored(const std::string & name) : nomme(name) {};
00677 ignored(generic_file & f) : nomme(f) { throw SRC_BUG; };
00678
00679 void dump(user_interaction & dialog, generic_file & f) const { throw SRC_BUG; };
00680 unsigned char signature() const { return 'i'; };
00681 entree *clone() const { return new ignored(*this); };
00682 #ifdef LIBDAR_SPECIAL_ALLOC
00683 USE_SPECIAL_ALLOC(ignored);
00684 #endif
00685 };
00686
00688 class ignored_dir : public inode
00689 {
00690 public:
00691 ignored_dir(const directory &target) : inode(target) {};
00692 ignored_dir(user_interaction & dialog,
00693 generic_file & f,
00694 const dar_version & reading_ver,
00695 generic_file *ea_loc) : inode(dialog, f, reading_ver, s_not_saved, ea_loc) { throw SRC_BUG; };
00696
00697 void dump(user_interaction & dialog, generic_file & f) const;
00698 unsigned char signature() const { return 'j'; };
00699 entree *clone() const { return new ignored_dir(*this); };
00700 #ifdef LIBDAR_SPECIAL_ALLOC
00701 USE_SPECIAL_ALLOC(ignored_dir);
00702 #endif
00703 };
00704
00706 class catalogue
00707 {
00708 public :
00709 catalogue(user_interaction & dialog);
00710 catalogue(user_interaction & dialog,
00711 generic_file & f,
00712 const dar_version & reading_ver,
00713 compression default_algo,
00714 generic_file *data_loc,
00715 generic_file *ea_loc);
00716 catalogue(const catalogue & ref) : out_compare(ref.out_compare) { partial_copy_from(ref); };
00717 catalogue & operator = (const catalogue &ref);
00718 ~catalogue() { detruire(); };
00719
00720 void reset_read();
00721 void skip_read_to_parent_dir();
00722
00723
00724 bool read(const entree * & ref);
00725
00726 bool read_if_present(std::string *name, const nomme * & ref);
00727
00728
00729
00730
00731
00732 void reset_sub_read(const path &sub);
00733 bool sub_read(const entree * &ref);
00734
00735
00736
00737 void reset_add();
00738 void add(entree *ref);
00739 void add_in_current_read(nomme *ref);
00740
00741 void reset_compare();
00742 bool compare(const entree * name, const entree * & extracted);
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755 bool direct_read(const path & ref, const nomme * &ret);
00756
00757 infinint update_destroyed_with(catalogue & ref);
00758
00759
00760 void dump(generic_file & ref) const;
00761 void listing(const mask &m = bool_mask(true), bool filter_unsaved = false, std::string marge = "") const;
00762 void tar_listing(const mask & m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const;
00763 void xml_listing(const mask & m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const;
00764 entree_stats get_stats() const { return stats; };
00765
00766 const directory *get_contenu() const { return contenu; };
00767
00768 #ifdef LIBDAR_SPECIAL_ALLOC
00769 USE_SPECIAL_ALLOC(catalogue);
00770 #endif
00771
00772 private :
00773 directory *contenu;
00774 path out_compare;
00775 directory *current_compare;
00776 directory *current_add;
00777 directory *current_read;
00778 path *sub_tree;
00779 signed int sub_count;
00780 entree_stats stats;
00781
00782 user_interaction *cat_ui;
00783
00784 void partial_copy_from(const catalogue &ref);
00785 void detruire();
00786
00787 static const eod r_eod;
00788 };
00789
00791
00792 }
00793
00794 #endif