# catalogue.hpp

Go to the documentation of this file.

    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