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

Generated on Wed Jul 2 12:57:56 2008 for Disk ARchive by  doxygen 1.5.6