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.2 2006/10/22 19:16:03 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         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 
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             // inherited from etiquette
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); // with etiquette, a call to set_reference() follows
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             // inherited from etiquette
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             // using the method is_more_recent_than() from inode
00429             // using method has_changed_since() from inode class
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); // only the inode part is build, no children is duplicated (empty dir)
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(); // detruit aussi tous les fils et se supprime de son 'parent'
00463 
00464         void dump(user_interaction & dialog, generic_file & f) const;
00465         void add_children(nomme *r); // when r is a directory, 'parent' is set to 'this'
00466         bool has_children() const { return fils.size() != 0; };
00467         void reset_read_children() const;
00468         bool read_children(const nomme * &r) const; // read the direct children of the directory, returns false if no more is available
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             // using is_more_recent_than() from inode class
00480             // using method has_changed_since() from inode class
00481         unsigned char signature() const { return mk_signature('d', get_saved_status()); };
00482 
00483             // some data has changed since archive of reference in this directory or subdirectories
00484         bool get_recursive_has_changed() const { return recursive_has_changed; };
00485             // update the recursive_has_changed field
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             // using method is_more_recent_than() from inode class
00526             // using method has_changed_since() from inode class
00527             // signature is left pure abstract
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             // using dump from device class
00560             // using method is_more_recent_than() from device class
00561             // using method has_changed_since() from device class
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             // using dump from device class
00590             // using method is_more_recent_than() from device class
00591             // using method has_changed_since() from device class
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             // using dump from inode class
00616             // using method is_more_recent_than() from inode class
00617             // using method has_changed_since() from inode class
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             // using dump from inode class
00642             // using method is_more_recent_than() from inode class
00643             // using method has_changed_since() from inode class
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; // behaves like an empty directory
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             // skip all items of the current dir and of any subdir, the next call will return
00723             // next item of the parent dir (no eod to exit from the current dir !)
00724         bool read(const entree * & ref);
00725             // sequential read (generates eod) and return false when all files have been read
00726         bool read_if_present(std::string *name, const nomme * & ref);
00727             // pseudo-sequential read (reading a directory still
00728             // implies that following read are located in this subdirectory up to the next EOD) but
00729             // it returns false if no entry of this name are present in the current directory
00730             // a call with NULL as first argument means to set the current dir the parent directory
00731 
00732         void reset_sub_read(const path &sub); // return false if the path do not exists in catalogue
00733         bool sub_read(const entree * &ref); // sequential read of the catalogue, ignoring all that
00734             // is not part of the subdirectory specified with reset_sub_read
00735             // the read include the inode leading to the sub_tree as well as the pending eod
00736 
00737         void reset_add();
00738         void add(entree *ref); // add at end of catalogue (sequential point of view)
00739         void add_in_current_read(nomme *ref); // add in currently read directory
00740 
00741         void reset_compare();
00742         bool compare(const entree * name, const entree * & extracted);
00743             // returns true if the ref exists, and gives it back in second argument as it is in the current catalogue.
00744             // returns false is no entry of that nature exists in the catalogue (in the current directory)
00745             // if ref is a directory, the operation is normaly relative to the directory itself, but
00746             // such a call implies a chdir to that directory. thus, a call with an EOD is necessary to
00747             // change to the parent directory.
00748             // note :
00749             // if a directory is not present, returns false, but records the inexistant subdirectory
00750             // structure defined by the following calls to this routine, this to be able to know when
00751             // the last available directory is back the current one when changing to parent directory,
00752             // and then proceed with normal comparison of inode. In this laps of time, the call will
00753             // always return false, while it temporary stores the missing directory structure
00754 
00755         bool direct_read(const path & ref, const nomme * &ret);
00756 
00757         infinint update_destroyed_with(catalogue & ref);
00758             // ref must have the same root, else the operation generates an exception
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; }; // used by data_tree
00767 
00768 #ifdef LIBDAR_SPECIAL_ALLOC
00769         USE_SPECIAL_ALLOC(catalogue);
00770 #endif
00771 
00772     private :
00773         directory *contenu;
00774         path out_compare;                 // stores the missing directory structure, when extracting
00775         directory *current_compare;       // points to the current directory when extracting
00776         directory *current_add;           // points to the directory where to add the next file with add_file;
00777         directory *current_read;          // points to the directory where the next item will be read
00778         path *sub_tree;                   // path to sub_tree
00779         signed int sub_count;             // count the depth in of read routine in the sub_tree
00780         entree_stats stats;               // statistics catalogue contents
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;           // needed to return eod reference, without taking risk of saturating memory
00788     };
00789 
00791 
00792 } // end of namespace
00793 
00794 #endif

Generated on Tue Apr 10 07:56:11 2007 for Disk ARchive by  doxygen 1.5.1