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 virtual bool is_more_recent_than(const inode & ref, const infinint & hourshift,
00197 comparison_fields what_to_check) const;
00198 virtual bool has_changed_since(const inode & ref, const infinint & hourshift, comparison_fields what_to_check) const;
00199
00200
00201 void compare(user_interaction & dialog, const inode &other, const mask & ea_mask, comparison_fields what_to_check) const;
00202
00203
00204
00205
00206
00207
00208
00210
00211
00212
00213 enum ea_status { ea_none, ea_partial, ea_fake, ea_full };
00214
00215
00216
00217
00218
00219
00220 void ea_set_saved_status(ea_status status);
00221 ea_status ea_get_saved_status() const { return ea_saved; };
00222
00223
00224 void ea_attach(ea_attributs *ref);
00225 const ea_attributs *get_ea(user_interaction & dialog) const;
00226 void ea_detach() const;
00227
00228
00229 void ea_set_offset(const infinint & pos) { *ea_offset = pos; };
00230 void ea_set_crc(const crc & val) { copy_crc(ea_crc, val); };
00231 void ea_get_crc(crc & val) const { copy_crc(val, ea_crc); };
00232
00233
00234 infinint get_last_change() const;
00235 void set_last_change(const infinint & x_time);
00236
00237
00238 void change_ea_location(generic_file *loc) { storage = loc; };
00239
00241
00242 #ifdef LIBDAR_SPECIAL_ALLOC
00243 USE_SPECIAL_ALLOC(inode);
00244 #endif
00245
00246 protected:
00247 virtual void sub_compare(user_interaction & dialog, const inode & other) const {};
00248
00249 private :
00250 U_16 uid;
00251 U_16 gid;
00252 U_16 perm;
00253 infinint *last_acc, *last_mod;
00254 saved_status xsaved;
00255 ea_status ea_saved;
00256
00257 infinint *ea_offset;
00258 ea_attributs *ea;
00259
00260 infinint *last_cha;
00261 crc ea_crc;
00262 infinint *fs_dev;
00263 generic_file *storage;
00264 dar_version edit;
00265 };
00266
00268 class file : public inode
00269 {
00270 public :
00271 file(U_16 xuid, U_16 xgid, U_16 xperm,
00272 const infinint & last_access,
00273 const infinint & last_modif,
00274 const std::string & src,
00275 const path & che,
00276 const infinint & taille,
00277 const infinint & fs_device);
00278 file(const file & ref);
00279 file(user_interaction & dialog,
00280 generic_file & f,
00281 const dar_version & reading_ver,
00282 saved_status saved,
00283 compression default_algo,
00284 generic_file *data_loc,
00285 generic_file *ea_loc);
00286 ~file() { detruit(); };
00287
00288 void dump(user_interaction & dialog, generic_file & f) const;
00289 bool is_more_recent_than(const inode & ref, const infinint & hourshift, inode::comparison_fields what_to_check) const;
00290 bool has_changed_since(const inode & ref, const infinint & hourshift, inode::comparison_fields what_to_check) const;
00291 infinint get_size() const { return *size; };
00292 infinint get_storage_size() const { return *storage_size; };
00293 void set_storage_size(const infinint & s) { *storage_size = s; };
00294 generic_file *get_data(user_interaction & dialog, bool keep_compressed = false) const;
00295 void clean_data();
00296 void set_offset(const infinint & r);
00297 unsigned char signature() const { return mk_signature('f', get_saved_status()); };
00298
00299 void set_crc(const crc &c) { copy_crc(check, c); };
00300 bool get_crc(crc & c) const;
00301 entree *clone() const { return new file(*this); };
00302
00303 compression get_compression_algo_used() const { return algo; };
00304
00305
00306 void change_compression_algo_used(compression x) { algo = x; };
00307 void change_location(generic_file *x) { loc = x; };
00308
00309
00310 #ifdef LIBDAR_SPECIAL_ALLOC
00311 USE_SPECIAL_ALLOC(file);
00312 #endif
00313
00314 protected :
00315 void sub_compare(user_interaction & dialog, const inode & other) const;
00316
00317 private :
00318 enum { empty, from_path, from_cat } status;
00319 path chemin;
00320 infinint *offset;
00321 infinint *size;
00322 infinint *storage_size;
00323
00324 bool available_crc;
00325 crc check;
00326
00327 generic_file *loc;
00328 compression algo;
00329
00330 void detruit();
00331 };
00332
00334 class etiquette
00335 {
00336 public:
00337 virtual infinint get_etiquette() const = 0;
00338 virtual const file_etiquette *get_inode() const = 0;
00339
00340 #ifdef LIBDAR_SPECIAL_ALLOC
00341 USE_SPECIAL_ALLOC(etiquette);
00342 #endif
00343 };
00344
00346 class file_etiquette : public file, public etiquette
00347 {
00348 public :
00349 file_etiquette(U_16 xuid, U_16 xgid, U_16 xperm,
00350 const infinint & last_access,
00351 const infinint & last_modif,
00352 const std::string & src,
00353 const path & che,
00354 const infinint & taille,
00355 const infinint & fs_device,
00356 const infinint & etiquette_number);
00357 file_etiquette(const file_etiquette & ref);
00358 file_etiquette(user_interaction & dialog,
00359 generic_file & f,
00360 const dar_version & reading_ver,
00361 saved_status saved,
00362 compression default_algo,
00363 generic_file *data_loc,
00364 generic_file *ea_loc);
00365
00366 void dump(user_interaction & dialog, generic_file &f) const;
00367 unsigned char signature() const { return mk_signature('e', get_saved_status()); };
00368 entree *clone() const { return new file_etiquette(*this); };
00369
00370 void change_etiquette(const infinint & new_val) { etiquette = new_val; };
00371
00372
00373 infinint get_etiquette() const { return etiquette; };
00374 const file_etiquette *get_inode() const { return this; };
00375
00376 #ifdef LIBDAR_SPECIAL_ALLOC
00377 USE_SPECIAL_ALLOC(file_etiquette);
00378 #endif
00379
00380 private :
00381 infinint etiquette;
00382 };
00383
00385 class hard_link : public nomme, public etiquette
00386 {
00387 public :
00388 hard_link(const std::string & name, file_etiquette *ref);
00389 hard_link(generic_file & f, infinint & etiquette);
00390
00391 void dump(user_interaction & dialog, generic_file &f) const;
00392 unsigned char signature() const { return 'h'; };
00393 entree *clone() const { return new hard_link(*this); };
00394 void set_reference(file_etiquette *ref);
00395
00396
00397 infinint get_etiquette() const;
00398 const file_etiquette *get_inode() const { return x_ref; };
00399
00400 #ifdef LIBDAR_SPECIAL_ALLOC
00401 USE_SPECIAL_ALLOC(hard_link);
00402 #endif
00403 private :
00404 file_etiquette *x_ref;
00405 };
00406
00408 class lien : public inode
00409 {
00410 public :
00411 lien(U_16 uid, U_16 gid, U_16 perm,
00412 const infinint & last_access,
00413 const infinint & last_modif,
00414 const std::string & name,
00415 const std::string & target,
00416 const infinint & fs_device);
00417 lien(user_interaction & dialog,
00418 generic_file & f,
00419 const dar_version & reading_ver,
00420 saved_status saved,
00421 generic_file *ea_loc);
00422
00423 void dump(user_interaction & dialog, generic_file & f) const;
00424 std::string get_target() const;
00425 void set_target(std::string x);
00426
00427
00428
00429 unsigned char signature() const { return mk_signature('l', get_saved_status()); };
00430 entree *clone() const { return new lien(*this); };
00431
00432 #ifdef LIBDAR_SPECIAL_ALLOC
00433 USE_SPECIAL_ALLOC(lien);
00434 #endif
00435 protected :
00436 void sub_compare(user_interaction & dialog, const inode & other) const;
00437
00438 private :
00439 std::string points_to;
00440 };
00441
00443 class directory : public inode
00444 {
00445 public :
00446 directory(U_16 xuid, U_16 xgid, U_16 xperm,
00447 const infinint & last_access,
00448 const infinint & last_modif,
00449 const std::string & xname,
00450 const infinint & device);
00451 directory(const directory &ref);
00452 directory(user_interaction & dialog,
00453 generic_file & f,
00454 const dar_version & reading_ver,
00455 saved_status saved,
00456 entree_stats & stats,
00457 std::map <infinint, file_etiquette *> & corres,
00458 compression default_algo,
00459 generic_file *data_loc,
00460 generic_file *ea_loc);
00461 ~directory();
00462
00463 void dump(user_interaction & dialog, generic_file & f) const;
00464 void add_children(nomme *r);
00465 bool has_children() const { return fils.size() != 0; };
00466 void reset_read_children() const;
00467 bool read_children(const nomme * &r) const;
00468 void listing(user_interaction & dialog,
00469 const mask &m = bool_mask(true), bool filter_unsaved = false, std::string marge = "") const;
00470 void tar_listing(user_interaction & dialog,
00471 const mask &m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const;
00472 void xml_listing(user_interaction & dialog,
00473 const mask &m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const;
00474 directory * get_parent() const { return parent; };
00475 bool search_children(const std::string &name, nomme *&ref);
00476 bool callback_for_children_of(user_interaction & dialog, const std::string & sdir) const;
00477
00478
00479
00480 unsigned char signature() const { return mk_signature('d', get_saved_status()); };
00481
00482
00483 bool get_recursive_has_changed() const { return recursive_has_changed; };
00484
00485 void recursive_has_changed_update() const;
00486
00487 entree *clone() const { return new directory(*this); };
00488
00489 #ifdef LIBDAR_SPECIAL_ALLOC
00490 USE_SPECIAL_ALLOC(directory);
00491 #endif
00492 private :
00493 directory *parent;
00494 std::vector<nomme *> fils;
00495 std::vector<nomme *>::iterator it;
00496 bool recursive_has_changed;
00497
00498 void clear();
00499 };
00500
00502 class device : public inode
00503 {
00504 public :
00505 device(U_16 uid, U_16 gid, U_16 perm,
00506 const infinint & last_access,
00507 const infinint & last_modif,
00508 const std::string & name,
00509 U_16 major,
00510 U_16 minor,
00511 const infinint & fs_device);
00512 device(user_interaction & dialog,
00513 generic_file & f,
00514 const dar_version & reading_ver,
00515 saved_status saved,
00516 generic_file *ea_loc);
00517
00518 void dump(user_interaction & dialog, generic_file & f) const;
00519 int get_major() const { if(get_saved_status() != s_saved) throw SRC_BUG; else return xmajor; };
00520 int get_minor() const { if(get_saved_status() != s_saved) throw SRC_BUG; else return xminor; };
00521 void set_major(int x) { xmajor = x; };
00522 void set_minor(int x) { xminor = x; };
00523
00524
00525
00526
00527
00528 #ifdef LIBDAR_SPECIAL_ALLOC
00529 USE_SPECIAL_ALLOC(device);
00530 #endif
00531
00532 protected :
00533 void sub_compare(user_interaction & dialog, const inode & other) const;
00534
00535 private :
00536 U_16 xmajor, xminor;
00537 };
00538
00540 class chardev : public device
00541 {
00542 public:
00543 chardev(U_16 uid, U_16 gid, U_16 perm,
00544 const infinint & last_access,
00545 const infinint & last_modif,
00546 const std::string & name,
00547 U_16 major,
00548 U_16 minor,
00549 const infinint & fs_device) : device(uid, gid, perm, last_access,
00550 last_modif, name,
00551 major, minor, fs_device) {};
00552 chardev(user_interaction & dialog,
00553 generic_file & f,
00554 const dar_version & reading_ver,
00555 saved_status saved,
00556 generic_file *ea_loc) : device(dialog, f, reading_ver, saved, ea_loc) {};
00557
00558
00559
00560
00561 unsigned char signature() const { return mk_signature('c', get_saved_status()); };
00562 entree *clone() const { return new chardev(*this); };
00563
00564 #ifdef LIBDAR_SPECIAL_ALLOC
00565 USE_SPECIAL_ALLOC(chardev);
00566 #endif
00567 };
00568
00570 class blockdev : public device
00571 {
00572 public:
00573 blockdev(U_16 uid, U_16 gid, U_16 perm,
00574 const infinint & last_access,
00575 const infinint & last_modif,
00576 const std::string & name,
00577 U_16 major,
00578 U_16 minor,
00579 const infinint & fs_device) : device(uid, gid, perm, last_access,
00580 last_modif, name,
00581 major, minor, fs_device) {};
00582 blockdev(user_interaction & dialog,
00583 generic_file & f,
00584 const dar_version & reading_ver,
00585 saved_status saved,
00586 generic_file *ea_loc) : device(dialog, f, reading_ver, saved, ea_loc) {};
00587
00588
00589
00590
00591 unsigned char signature() const { return mk_signature('b', get_saved_status()); };
00592 entree *clone() const { return new blockdev(*this); };
00593
00594 #ifdef LIBDAR_SPECIAL_ALLOC
00595 USE_SPECIAL_ALLOC(blockdev);
00596 #endif
00597 };
00598
00600 class tube : public inode
00601 {
00602 public :
00603 tube(U_16 xuid, U_16 xgid, U_16 xperm,
00604 const infinint & last_access,
00605 const infinint & last_modif,
00606 const std::string & xname,
00607 const infinint & fs_device) : inode(xuid, xgid, xperm, last_access, last_modif, xname, fs_device) { set_saved_status(s_saved); };
00608 tube(user_interaction & dialog,
00609 generic_file & f,
00610 const dar_version & reading_ver,
00611 saved_status saved,
00612 generic_file *ea_loc) : inode(dialog, f, reading_ver, saved, ea_loc) {};
00613
00614
00615
00616
00617 unsigned char signature() const { return mk_signature('p', get_saved_status()); };
00618 entree *clone() const { return new tube(*this); };
00619
00620 #ifdef LIBDAR_SPECIAL_ALLOC
00621 USE_SPECIAL_ALLOC(tube);
00622 #endif
00623 };
00624
00626 class prise : public inode
00627 {
00628 public :
00629 prise(U_16 xuid, U_16 xgid, U_16 xperm,
00630 const infinint & last_access,
00631 const infinint & last_modif,
00632 const std::string & xname,
00633 const infinint & fs_device) : inode(xuid, xgid, xperm, last_access, last_modif, xname, fs_device) { set_saved_status(s_saved); };
00634 prise(user_interaction & dialog,
00635 generic_file & f,
00636 const dar_version & reading_ver,
00637 saved_status saved,
00638 generic_file *ea_loc) : inode(dialog, f, reading_ver, saved, ea_loc) {};
00639
00640
00641
00642
00643 unsigned char signature() const { return mk_signature('s', get_saved_status()); };
00644 entree *clone() const { return new prise(*this); };
00645
00646 #ifdef LIBDAR_SPECIAL_ALLOC
00647 USE_SPECIAL_ALLOC(prise);
00648 #endif
00649 };
00650
00652 class detruit : public nomme
00653 {
00654 public :
00655 detruit(const std::string & name, unsigned char firm) : nomme(name) { signe = firm; };
00656 detruit(generic_file & f) : nomme(f) { if(f.read((char *)&signe, 1) != 1) throw Erange("detruit::detruit", gettext("missing data to build")); };
00657
00658 void dump(user_interaction & dialog, generic_file & f) const { nomme::dump(dialog, f); f.write((char *)&signe, 1); };
00659 unsigned char get_signature() const { return signe; };
00660 void set_signature(unsigned char x) { signe = x; };
00661 unsigned char signature() const { return 'x'; };
00662 entree *clone() const { return new detruit(*this); };
00663
00664 #ifdef LIBDAR_SPECIAL_ALLOC
00665 USE_SPECIAL_ALLOC(detruit);
00666 #endif
00667 private :
00668 unsigned char signe;
00669 };
00670
00672 class ignored : public nomme
00673 {
00674 public :
00675 ignored(const std::string & name) : nomme(name) {};
00676 ignored(generic_file & f) : nomme(f) { throw SRC_BUG; };
00677
00678 void dump(user_interaction & dialog, generic_file & f) const { throw SRC_BUG; };
00679 unsigned char signature() const { return 'i'; };
00680 entree *clone() const { return new ignored(*this); };
00681 #ifdef LIBDAR_SPECIAL_ALLOC
00682 USE_SPECIAL_ALLOC(ignored);
00683 #endif
00684 };
00685
00687 class ignored_dir : public inode
00688 {
00689 public:
00690 ignored_dir(const directory &target) : inode(target) {};
00691 ignored_dir(user_interaction & dialog,
00692 generic_file & f,
00693 const dar_version & reading_ver,
00694 generic_file *ea_loc) : inode(dialog, f, reading_ver, s_not_saved, ea_loc) { throw SRC_BUG; };
00695
00696 void dump(user_interaction & dialog, generic_file & f) const;
00697 unsigned char signature() const { return 'j'; };
00698 entree *clone() const { return new ignored_dir(*this); };
00699 #ifdef LIBDAR_SPECIAL_ALLOC
00700 USE_SPECIAL_ALLOC(ignored_dir);
00701 #endif
00702 };
00703
00705 class catalogue
00706 {
00707 public :
00708 catalogue(user_interaction & dialog);
00709 catalogue(user_interaction & dialog,
00710 generic_file & f,
00711 const dar_version & reading_ver,
00712 compression default_algo,
00713 generic_file *data_loc,
00714 generic_file *ea_loc);
00715 catalogue(const catalogue & ref) : out_compare(ref.out_compare) { partial_copy_from(ref); };
00716 catalogue & operator = (const catalogue &ref);
00717 ~catalogue() { detruire(); };
00718
00719 void reset_read();
00720 void skip_read_to_parent_dir();
00721
00722
00723 bool read(const entree * & ref);
00724
00725 bool read_if_present(std::string *name, const nomme * & ref);
00726
00727
00728
00729
00730
00731 void reset_sub_read(const path &sub);
00732 bool sub_read(const entree * &ref);
00733
00734
00735
00736 void reset_add();
00737 void add(entree *ref);
00738 void add_in_current_read(nomme *ref);
00739
00740 void reset_compare();
00741 bool compare(const entree * name, const entree * & extracted);
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754 bool direct_read(const path & ref, const nomme * &ret);
00755
00756 infinint update_destroyed_with(catalogue & ref);
00757
00758
00759 void dump(generic_file & ref) const;
00760 void listing(const mask &m = bool_mask(true), bool filter_unsaved = false, std::string marge = "") const;
00761 void tar_listing(const mask & m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const;
00762 void xml_listing(const mask & m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const;
00763 entree_stats get_stats() const { return stats; };
00764
00765 const directory *get_contenu() const { return contenu; };
00766
00767 #ifdef LIBDAR_SPECIAL_ALLOC
00768 USE_SPECIAL_ALLOC(catalogue);
00769 #endif
00770
00771 private :
00772 directory *contenu;
00773 path out_compare;
00774 directory *current_compare;
00775 directory *current_add;
00776 directory *current_read;
00777 path *sub_tree;
00778 signed int sub_count;
00779 entree_stats stats;
00780
00781 user_interaction *cat_ui;
00782
00783 void partial_copy_from(const catalogue &ref);
00784 void detruire();
00785
00786 static const eod r_eod;
00787 };
00788
00790
00791 }
00792
00793 #endif