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.1 2006/01/24 17:04:57 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         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             // signature() left as an abstract method
00200             // clone is abstract too
00201         void compare(user_interaction & dialog, const inode &other, const mask & ea_mask, comparison_fields what_to_check) const;
00202             // throw Erange exception if a difference has been detected
00203             // this is not a symetrical comparison, but all what is present
00204             // in the current object is compared against the argument
00205             // which may contain supplementary informations
00206 
00207 
00208 
00210             // EXTENDED ATTRIBUTS Methods
00211             //
00212 
00213         enum ea_status { ea_none, ea_partial, ea_fake, ea_full };
00214             // ea_none    : no EA present for this inode in filesystem
00215             // ea_partial : EA present in filesystem but not stored (ctime used to check changes)
00216             // ea_fake    : EA present in filesystem but not attached to this inode (isolation context)
00217             // ea_full    : EA present in filesystem and attached to this inode
00218 
00219             // I : to know whether EA data is present or not for this object
00220         void ea_set_saved_status(ea_status status);
00221         ea_status ea_get_saved_status() const { return ea_saved; };
00222 
00223             // II : to associate EA list to an inode object (mainly for backup operation) #EA_FULL only#
00224         void ea_attach(ea_attributs *ref);
00225         const ea_attributs *get_ea(user_interaction & dialog) const;
00226         void ea_detach() const; //discards any future call to get_ea() !
00227 
00228             // III : to record where is dump the EA in the archive #EA_FULL only#
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             // IV : to know/record if EA have been modified #EA_FULL,  EA_PARTIAL or EA_FAKE#
00234         infinint get_last_change() const;
00235         void set_last_change(const infinint & x_time);
00236 
00237             // V : for archive migration (merging)
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             //  the following is used only if ea_saved == full
00257         infinint *ea_offset;
00258         ea_attributs *ea;
00259             // the following is used if ea_saved == full or ea_saved == partial
00260         infinint *last_cha;
00261         crc ea_crc;
00262         infinint *fs_dev;
00263         generic_file *storage; // where are stored EA
00264         dar_version edit;   // need to know EA format used in archive file
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; // return a newly alocated object in read_only mode
00295         void clean_data(); // partially free memory (but get_data() becomes disabled)
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             // object migration methods (merging)
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             // inherited from etiquette
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); // with etiquette, a call to set_reference() follows
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             // inherited from etiquette
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             // using the method is_more_recent_than() from inode
00428             // using method has_changed_since() from inode class
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); // only the inode part is build, no children is duplicated (empty dir)
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(); // detruit aussi tous les fils et se supprime de son 'parent'
00462 
00463         void dump(user_interaction & dialog, generic_file & f) const;
00464         void add_children(nomme *r); // when r is a directory, 'parent' is set to 'this'
00465         bool has_children() const { return fils.size() != 0; };
00466         void reset_read_children() const;
00467         bool read_children(const nomme * &r) const; // read the direct children of the directory, returns false if no more is available
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             // using is_more_recent_than() from inode class
00479             // using method has_changed_since() from inode class
00480         unsigned char signature() const { return mk_signature('d', get_saved_status()); };
00481 
00482             // some data has changed since archive of reference in this directory or subdirectories
00483         bool get_recursive_has_changed() const { return recursive_has_changed; };
00484             // update the recursive_has_changed field
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             // using method is_more_recent_than() from inode class
00525             // using method has_changed_since() from inode class
00526             // signature is left pure abstract
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             // using dump from device class
00559             // using method is_more_recent_than() from device class
00560             // using method has_changed_since() from device class
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             // using dump from device class
00589             // using method is_more_recent_than() from device class
00590             // using method has_changed_since() from device class
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             // using dump from inode class
00615             // using method is_more_recent_than() from inode class
00616             // using method has_changed_since() from inode class
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             // using dump from inode class
00641             // using method is_more_recent_than() from inode class
00642             // using method has_changed_since() from inode class
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; // behaves like an empty directory
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             // skip all items of the current dir and of any subdir, the next call will return
00722             // next item of the parent dir (no eod to exit from the current dir !)
00723         bool read(const entree * & ref);
00724             // sequential read (generates eod) and return false when all files have been read
00725         bool read_if_present(std::string *name, const nomme * & ref);
00726             // pseudo-sequential read (reading a directory still
00727             // implies that following read are located in this subdirectory up to the next EOD) but
00728             // it returns false if no entry of this name are present in the current directory
00729             // a call with NULL as first argument means to set the current dir the parent directory
00730 
00731         void reset_sub_read(const path &sub); // return false if the path do not exists in catalogue
00732         bool sub_read(const entree * &ref); // sequential read of the catalogue, ignoring all that
00733             // is not part of the subdirectory specified with reset_sub_read
00734             // the read include the inode leading to the sub_tree as well as the pending eod
00735 
00736         void reset_add();
00737         void add(entree *ref); // add at end of catalogue (sequential point of view)
00738         void add_in_current_read(nomme *ref); // add in currently read directory
00739 
00740         void reset_compare();
00741         bool compare(const entree * name, const entree * & extracted);
00742             // returns true if the ref exists, and gives it back in second argument as it is in the current catalogue.
00743             // returns false is no entry of that nature exists in the catalogue (in the current directory)
00744             // if ref is a directory, the operation is normaly relative to the directory itself, but
00745             // such a call implies a chdir to that directory. thus, a call with an EOD is necessary to
00746             // change to the parent directory.
00747             // note :
00748             // if a directory is not present, returns false, but records the inexistant subdirectory
00749             // structure defined by the following calls to this routine, this to be able to know when
00750             // the last available directory is back the current one when changing to parent directory,
00751             // and then proceed with normal comparison of inode. In this laps of time, the call will
00752             // always return false, while it temporary stores the missing directory structure
00753 
00754         bool direct_read(const path & ref, const nomme * &ret);
00755 
00756         infinint update_destroyed_with(catalogue & ref);
00757             // ref must have the same root, else the operation generates an exception
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; }; // used by data_tree
00766 
00767 #ifdef LIBDAR_SPECIAL_ALLOC
00768         USE_SPECIAL_ALLOC(catalogue);
00769 #endif
00770 
00771     private :
00772         directory *contenu;
00773         path out_compare;                 // stores the missing directory structure, when extracting
00774         directory *current_compare;       // points to the current directory when extracting
00775         directory *current_add;           // points to the directory where to add the next file with add_file;
00776         directory *current_read;          // points to the directory where the next item will be read
00777         path *sub_tree;                   // path to sub_tree
00778         signed int sub_count;             // count the depth in of read routine in the sub_tree
00779         entree_stats stats;               // statistics catalogue contents
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;           // needed to return eod reference, without taking risk of saturating memory
00787     };
00788 
00790 
00791 } // end of namespace
00792 
00793 #endif

Generated on Mon Aug 14 13:23:03 2006 for Disk ARchive by  doxygen 1.4.7