Disk ARchive 2.3.11

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.6 2010/09/12 16:32:51 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,
00203                      const inode &other,
00204                      const mask & ea_mask,
00205                      comparison_fields what_to_check,
00206                      const infinint & hourshift) const;
00207             // throw Erange exception if a difference has been detected
00208             // this is not a symetrical comparison, but all what is present
00209             // in the current object is compared against the argument
00210             // which may contain supplementary informations
00211             // used for DIFFERENCE
00212 
00213 
00214 
00216             // EXTENDED ATTRIBUTS Methods
00217             //
00218 
00219         enum ea_status { ea_none, ea_partial, ea_fake, ea_full };
00220             // ea_none    : no EA present for this inode in filesystem
00221             // ea_partial : EA present in filesystem but not stored (ctime used to check changes)
00222             // ea_fake    : EA present in filesystem but not attached to this inode (isolation context)
00223             // ea_full    : EA present in filesystem and attached to this inode
00224 
00225             // I : to know whether EA data is present or not for this object
00226         void ea_set_saved_status(ea_status status);
00227         ea_status ea_get_saved_status() const { return ea_saved; };
00228 
00229             // II : to associate EA list to an inode object (mainly for backup operation) #EA_FULL only#
00230         void ea_attach(ea_attributs *ref);
00231         const ea_attributs *get_ea(user_interaction & dialog) const;
00232         void ea_detach() const; //discards any future call to get_ea() !
00233 
00234             // III : to record where is dump the EA in the archive #EA_FULL only#
00235         void ea_set_offset(const infinint & pos) { *ea_offset = pos; };
00236         void ea_set_crc(const crc & val) { copy_crc(ea_crc, val); };
00237         void ea_get_crc(crc & val) const { copy_crc(val, ea_crc); };
00238 
00239             // IV : to know/record if EA have been modified #EA_FULL,  EA_PARTIAL or EA_FAKE#
00240         infinint get_last_change() const;
00241         void set_last_change(const infinint & x_time);
00242 
00243             // V : for archive migration (merging)
00244         void change_ea_location(generic_file *loc) { storage = loc; };
00245 
00247 
00248 #ifdef LIBDAR_SPECIAL_ALLOC
00249         USE_SPECIAL_ALLOC(inode);
00250 #endif
00251 
00252     protected:
00253         virtual void sub_compare(user_interaction & dialog, const inode & other) const {};
00254 
00255     private :
00256         U_16 uid;
00257         U_16 gid;
00258         U_16 perm;
00259         infinint *last_acc, *last_mod;
00260         saved_status xsaved;
00261         ea_status ea_saved;
00262             //  the following is used only if ea_saved == full
00263         infinint *ea_offset;
00264         ea_attributs *ea;
00265             // the following is used if ea_saved == full or ea_saved == partial
00266         infinint *last_cha;
00267         crc ea_crc;
00268         infinint *fs_dev;
00269         generic_file *storage; // where are stored EA
00270         dar_version edit;   // need to know EA format used in archive file
00271     };
00272 
00274     class file : public inode
00275     {
00276     public :
00277         file(U_16 xuid, U_16 xgid, U_16 xperm,
00278              const infinint & last_access,
00279              const infinint & last_modif,
00280              const std::string & src,
00281              const path & che,
00282              const infinint & taille,
00283              const infinint & fs_device);
00284         file(const file & ref);
00285         file(user_interaction & dialog,
00286              generic_file & f,
00287              const dar_version & reading_ver,
00288              saved_status saved,
00289              compression default_algo,
00290              generic_file *data_loc,
00291              generic_file *ea_loc);
00292         ~file() { detruit(); };
00293 
00294         void dump(user_interaction & dialog, generic_file & f) const;
00295         bool has_changed_since(const inode & ref, const infinint & hourshift, inode::comparison_fields what_to_check) const;
00296         infinint get_size() const { return *size; };
00297         infinint get_storage_size() const { return *storage_size; };
00298         void set_storage_size(const infinint & s) { *storage_size = s; };
00299         generic_file *get_data(user_interaction & dialog, bool keep_compressed = false) const; // return a newly alocated object in read_only mode
00300         void clean_data(); // partially free memory (but get_data() becomes disabled)
00301         void set_offset(const infinint & r);
00302         unsigned char signature() const { return mk_signature('f', get_saved_status()); };
00303 
00304         void set_crc(const crc &c) { copy_crc(check, c); };
00305         bool get_crc(crc & c) const;
00306         entree *clone() const { return new file(*this); };
00307 
00308         compression get_compression_algo_used() const { return algo; };
00309 
00310             // object migration methods (merging)
00311         void change_compression_algo_used(compression x) { algo = x; };
00312         void change_location(generic_file *x) { loc = x; };
00313 
00314 
00315 #ifdef LIBDAR_SPECIAL_ALLOC
00316         USE_SPECIAL_ALLOC(file);
00317 #endif
00318 
00319     protected :
00320         void sub_compare(user_interaction & dialog, const inode & other) const;
00321 
00322     private :
00323         enum { empty, from_path, from_cat } status;
00324         path chemin;
00325         infinint *offset;
00326         infinint *size;
00327         infinint *storage_size;
00328 
00329         bool available_crc;
00330         crc check;
00331 
00332         generic_file *loc;
00333         compression algo;
00334 
00335         void detruit();
00336     };
00337 
00339     class etiquette
00340     {
00341     public:
00342         virtual infinint get_etiquette() const = 0;
00343         virtual const file_etiquette *get_inode() const = 0;
00344         virtual ~etiquette() {};
00345 
00346 #ifdef LIBDAR_SPECIAL_ALLOC
00347         USE_SPECIAL_ALLOC(etiquette);
00348 #endif
00349     };
00350 
00352     class file_etiquette : public file, public etiquette
00353     {
00354     public :
00355         file_etiquette(U_16 xuid, U_16 xgid, U_16 xperm,
00356                        const infinint & last_access,
00357                        const infinint & last_modif,
00358                        const std::string & src,
00359                        const path & che,
00360                        const infinint & taille,
00361                        const infinint & fs_device,
00362                        const infinint & etiquette_number);
00363         file_etiquette(const file_etiquette & ref);
00364         file_etiquette(user_interaction & dialog,
00365                        generic_file & f,
00366                        const dar_version & reading_ver,
00367                        saved_status saved,
00368                        compression default_algo,
00369                        generic_file *data_loc,
00370                        generic_file *ea_loc);
00371 
00372         void dump(user_interaction & dialog, generic_file &f) const;
00373         unsigned char signature() const { return mk_signature('e', get_saved_status()); };
00374         entree *clone() const { return new file_etiquette(*this); };
00375 
00376         void change_etiquette(const infinint & new_val) { etiquette = new_val; };
00377 
00378             // inherited from etiquette
00379         infinint get_etiquette() const { return etiquette; };
00380         const file_etiquette *get_inode() const { return this; };
00381 
00382 #ifdef LIBDAR_SPECIAL_ALLOC
00383         USE_SPECIAL_ALLOC(file_etiquette);
00384 #endif
00385 
00386     private :
00387         infinint etiquette;
00388     };
00389 
00391     class hard_link : public nomme, public etiquette
00392     {
00393     public :
00394         hard_link(const std::string & name, file_etiquette *ref);
00395         hard_link(generic_file & f, infinint & etiquette); // with etiquette, a call to set_reference() follows
00396 
00397         void dump(user_interaction & dialog, generic_file &f) const;
00398         unsigned char signature() const { return 'h'; };
00399         entree *clone() const { return new hard_link(*this); };
00400         void set_reference(file_etiquette *ref);
00401 
00402             // inherited from etiquette
00403         infinint get_etiquette() const;
00404         const file_etiquette *get_inode() const { return x_ref; };
00405 
00406 #ifdef LIBDAR_SPECIAL_ALLOC
00407         USE_SPECIAL_ALLOC(hard_link);
00408 #endif
00409     private :
00410         file_etiquette *x_ref;
00411     };
00412 
00414     class lien : public inode
00415     {
00416     public :
00417         lien(U_16 uid, U_16 gid, U_16 perm,
00418              const infinint & last_access,
00419              const infinint & last_modif,
00420              const std::string & name,
00421              const std::string & target,
00422              const infinint & fs_device);
00423         lien(user_interaction & dialog,
00424              generic_file & f,
00425              const dar_version & reading_ver,
00426              saved_status saved,
00427              generic_file *ea_loc);
00428 
00429         void dump(user_interaction & dialog, generic_file & f) const;
00430         const std::string & get_target() const;
00431         void set_target(std::string x);
00432 
00433             // using the method is_more_recent_than() from inode
00434             // using method has_changed_since() from inode class
00435         unsigned char signature() const { return mk_signature('l', get_saved_status()); };
00436         entree *clone() const { return new lien(*this); };
00437 
00438 #ifdef LIBDAR_SPECIAL_ALLOC
00439         USE_SPECIAL_ALLOC(lien);
00440 #endif
00441     protected :
00442         void sub_compare(user_interaction & dialog, const inode & other) const;
00443 
00444     private :
00445         std::string points_to;
00446     };
00447 
00449     class directory : public inode
00450     {
00451     public :
00452         directory(U_16 xuid, U_16 xgid, U_16 xperm,
00453                   const infinint & last_access,
00454                   const infinint & last_modif,
00455                   const std::string & xname,
00456                   const infinint & device);
00457         directory(const directory &ref); // only the inode part is build, no children is duplicated (empty dir)
00458         directory(user_interaction & dialog,
00459                   generic_file & f,
00460                   const dar_version & reading_ver,
00461                   saved_status saved,
00462                   entree_stats & stats,
00463                   std::map <infinint, file_etiquette *> & corres,
00464                   compression default_algo,
00465                   generic_file *data_loc,
00466                   generic_file *ea_loc);
00467         ~directory(); // detruit aussi tous les fils et se supprime de son 'parent'
00468 
00469         void dump(user_interaction & dialog, generic_file & f) const;
00470         void add_children(nomme *r); // when r is a directory, 'parent' is set to 'this'
00471         bool has_children() const { return fils.size() != 0; };
00472         void reset_read_children() const;
00473         bool read_children(const nomme * &r) const; // read the direct children of the directory, returns false if no more is available
00474         void listing(user_interaction & dialog,
00475                      const mask &m = bool_mask(true), bool filter_unsaved = false, const std::string & marge = "") const;
00476         void tar_listing(user_interaction & dialog,
00477                          const mask &m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const;
00478         void xml_listing(user_interaction & dialog,
00479                          const mask &m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const;
00480         directory * get_parent() const { return parent; };
00481         bool search_children(const std::string &name, nomme *&ref);
00482         bool callback_for_children_of(user_interaction & dialog, const std::string & sdir) const;
00483 
00484             // using is_more_recent_than() from inode class
00485             // using method has_changed_since() from inode class
00486         unsigned char signature() const { return mk_signature('d', get_saved_status()); };
00487 
00488             // some data has changed since archive of reference in this directory or subdirectories
00489         bool get_recursive_has_changed() const { return recursive_has_changed; };
00490             // update the recursive_has_changed field
00491         void recursive_has_changed_update() const;
00492 
00493         entree *clone() const { return new directory(*this); };
00494 
00495  #ifdef LIBDAR_SPECIAL_ALLOC
00496         USE_SPECIAL_ALLOC(directory);
00497 #endif
00498     private :
00499         directory *parent;
00500         std::vector<nomme *> fils;
00501         std::vector<nomme *>::iterator it;
00502         bool recursive_has_changed;
00503 
00504         void clear();
00505     };
00506 
00508     class device : public inode
00509     {
00510     public :
00511         device(U_16 uid, U_16 gid, U_16 perm,
00512                const infinint & last_access,
00513                const infinint & last_modif,
00514                const std::string & name,
00515                U_16 major,
00516                U_16 minor,
00517                const infinint & fs_device);
00518         device(user_interaction & dialog,
00519                generic_file & f,
00520                const dar_version & reading_ver,
00521                saved_status saved,
00522                generic_file *ea_loc);
00523 
00524         void dump(user_interaction & dialog, generic_file & f) const;
00525         int get_major() const { if(get_saved_status() != s_saved) throw SRC_BUG; else return xmajor; };
00526         int get_minor() const { if(get_saved_status() != s_saved) throw SRC_BUG; else return xminor; };
00527         void set_major(int x) { xmajor = x; };
00528         void set_minor(int x) { xminor = x; };
00529 
00530             // using method is_more_recent_than() from inode class
00531             // using method has_changed_since() from inode class
00532             // signature is left pure abstract
00533 
00534 #ifdef LIBDAR_SPECIAL_ALLOC
00535         USE_SPECIAL_ALLOC(device);
00536 #endif
00537 
00538     protected :
00539         void sub_compare(user_interaction & dialog, const inode & other) const;
00540 
00541     private :
00542         U_16 xmajor, xminor;
00543     };
00544 
00546     class chardev : public device
00547     {
00548     public:
00549         chardev(U_16 uid, U_16 gid, U_16 perm,
00550                 const infinint & last_access,
00551                 const infinint & last_modif,
00552                 const std::string & name,
00553                 U_16 major,
00554                 U_16 minor,
00555                 const infinint & fs_device) : device(uid, gid, perm, last_access,
00556                                      last_modif, name,
00557                                      major, minor, fs_device) {};
00558         chardev(user_interaction & dialog,
00559                 generic_file & f,
00560                 const dar_version & reading_ver,
00561                 saved_status saved,
00562                 generic_file *ea_loc) : device(dialog, f, reading_ver, saved, ea_loc) {};
00563 
00564             // using dump from device class
00565             // using method is_more_recent_than() from device class
00566             // using method has_changed_since() from device class
00567         unsigned char signature() const { return mk_signature('c', get_saved_status()); };
00568         entree *clone() const { return new chardev(*this); };
00569 
00570 #ifdef LIBDAR_SPECIAL_ALLOC
00571         USE_SPECIAL_ALLOC(chardev);
00572 #endif
00573     };
00574 
00576     class blockdev : public device
00577     {
00578     public:
00579         blockdev(U_16 uid, U_16 gid, U_16 perm,
00580                  const infinint & last_access,
00581                  const infinint & last_modif,
00582                  const std::string & name,
00583                  U_16 major,
00584                  U_16 minor,
00585                  const infinint & fs_device) : device(uid, gid, perm, last_access,
00586                                                       last_modif, name,
00587                                                       major, minor, fs_device) {};
00588         blockdev(user_interaction & dialog,
00589                  generic_file & f,
00590                  const dar_version & reading_ver,
00591                  saved_status saved,
00592                  generic_file *ea_loc) : device(dialog, f, reading_ver, saved, ea_loc) {};
00593 
00594             // using dump from device class
00595             // using method is_more_recent_than() from device class
00596             // using method has_changed_since() from device class
00597         unsigned char signature() const { return mk_signature('b', get_saved_status()); };
00598         entree *clone() const { return new blockdev(*this); };
00599 
00600 #ifdef LIBDAR_SPECIAL_ALLOC
00601         USE_SPECIAL_ALLOC(blockdev);
00602 #endif
00603     };
00604 
00606     class tube : public inode
00607     {
00608     public :
00609         tube(U_16 xuid, U_16 xgid, U_16 xperm,
00610              const infinint & last_access,
00611              const infinint & last_modif,
00612              const std::string & xname,
00613              const infinint & fs_device) : inode(xuid, xgid, xperm, last_access, last_modif, xname, fs_device) { set_saved_status(s_saved); };
00614         tube(user_interaction & dialog,
00615              generic_file & f,
00616              const dar_version & reading_ver,
00617              saved_status saved,
00618              generic_file *ea_loc) : inode(dialog, f, reading_ver, saved, ea_loc) {};
00619 
00620             // using dump from inode class
00621             // using method is_more_recent_than() from inode class
00622             // using method has_changed_since() from inode class
00623         unsigned char signature() const { return mk_signature('p', get_saved_status()); };
00624         entree *clone() const { return new tube(*this); };
00625 
00626 #ifdef LIBDAR_SPECIAL_ALLOC
00627         USE_SPECIAL_ALLOC(tube);
00628 #endif
00629     };
00630 
00632     class prise : public inode
00633     {
00634     public :
00635         prise(U_16 xuid, U_16 xgid, U_16 xperm,
00636               const infinint & last_access,
00637               const infinint & last_modif,
00638               const std::string & xname,
00639               const infinint & fs_device) : inode(xuid, xgid, xperm, last_access, last_modif, xname, fs_device) { set_saved_status(s_saved); };
00640         prise(user_interaction & dialog,
00641               generic_file & f,
00642               const dar_version & reading_ver,
00643               saved_status saved,
00644               generic_file *ea_loc) : inode(dialog, f, reading_ver, saved, ea_loc) {};
00645 
00646             // using dump from inode class
00647             // using method is_more_recent_than() from inode class
00648             // using method has_changed_since() from inode class
00649         unsigned char signature() const { return mk_signature('s', get_saved_status()); };
00650         entree *clone() const { return new prise(*this); };
00651 
00652 #ifdef LIBDAR_SPECIAL_ALLOC
00653         USE_SPECIAL_ALLOC(prise);
00654 #endif
00655     };
00656 
00658     class detruit : public nomme
00659     {
00660     public :
00661         detruit(const std::string & name, unsigned char firm) : nomme(name) { signe = firm; };
00662         detruit(generic_file & f) : nomme(f) { if(f.read((char *)&signe, 1) != 1) throw Erange("detruit::detruit", gettext("missing data to build")); };
00663 
00664         void dump(user_interaction & dialog, generic_file & f) const { nomme::dump(dialog, f); f.write((char *)&signe, 1); };
00665         unsigned char get_signature() const { return signe; };
00666         void set_signature(unsigned char x) { signe = x; };
00667         unsigned char signature() const { return 'x'; };
00668         entree *clone() const { return new detruit(*this); };
00669 
00670 #ifdef LIBDAR_SPECIAL_ALLOC
00671         USE_SPECIAL_ALLOC(detruit);
00672 #endif
00673     private :
00674         unsigned char signe;
00675     };
00676 
00678     class ignored : public nomme
00679     {
00680     public :
00681         ignored(const std::string & name) : nomme(name) {};
00682         ignored(generic_file & f) : nomme(f) { throw SRC_BUG; };
00683 
00684         void dump(user_interaction & dialog, generic_file & f) const { throw SRC_BUG; };
00685         unsigned char signature() const { return 'i'; };
00686         entree *clone() const { return new ignored(*this); };
00687 #ifdef LIBDAR_SPECIAL_ALLOC
00688         USE_SPECIAL_ALLOC(ignored);
00689 #endif
00690     };
00691 
00693     class ignored_dir : public inode
00694     {
00695     public:
00696         ignored_dir(const directory &target) : inode(target) {};
00697         ignored_dir(user_interaction & dialog,
00698                     generic_file & f,
00699                     const dar_version & reading_ver,
00700                     generic_file *ea_loc) : inode(dialog, f, reading_ver, s_not_saved, ea_loc) { throw SRC_BUG; };
00701 
00702         void dump(user_interaction & dialog, generic_file & f) const; // behaves like an empty directory
00703         unsigned char signature() const { return 'j'; };
00704         entree *clone() const { return new ignored_dir(*this); };
00705 #ifdef LIBDAR_SPECIAL_ALLOC
00706         USE_SPECIAL_ALLOC(ignored_dir);
00707 #endif
00708     };
00709 
00711     class catalogue
00712     {
00713     public :
00714         catalogue(user_interaction & dialog);
00715         catalogue(user_interaction & dialog,
00716                   generic_file & f,
00717                   const dar_version & reading_ver,
00718                   compression default_algo,
00719                   generic_file *data_loc,
00720                   generic_file *ea_loc);
00721         catalogue(const catalogue & ref) : out_compare(ref.out_compare) { partial_copy_from(ref); };
00722         catalogue & operator = (const catalogue &ref);
00723         ~catalogue() { detruire(); };
00724 
00725         void reset_read();
00726         void skip_read_to_parent_dir();
00727             // skip all items of the current dir and of any subdir, the next call will return
00728             // next item of the parent dir (no eod to exit from the current dir !)
00729         bool read(const entree * & ref);
00730             // sequential read (generates eod) and return false when all files have been read
00731         bool read_if_present(std::string *name, const nomme * & ref);
00732             // pseudo-sequential read (reading a directory still
00733             // implies that following read are located in this subdirectory up to the next EOD) but
00734             // it returns false if no entry of this name are present in the current directory
00735             // a call with NULL as first argument means to set the current dir the parent directory
00736 
00737         void reset_sub_read(const path &sub); // return false if the path do not exists in catalogue
00738         bool sub_read(const entree * &ref); // sequential read of the catalogue, ignoring all that
00739             // is not part of the subdirectory specified with reset_sub_read
00740             // the read include the inode leading to the sub_tree as well as the pending eod
00741 
00742         void reset_add();
00743         void add(entree *ref); // add at end of catalogue (sequential point of view)
00744         void add_in_current_read(nomme *ref); // add in currently read directory
00745 
00746         void reset_compare();
00747         bool compare(const entree * name, const entree * & extracted);
00748             // returns true if the ref exists, and gives it back in second argument as it is in the current catalogue.
00749             // returns false is no entry of that nature exists in the catalogue (in the current directory)
00750             // if ref is a directory, the operation is normaly relative to the directory itself, but
00751             // such a call implies a chdir to that directory. thus, a call with an EOD is necessary to
00752             // change to the parent directory.
00753             // note :
00754             // if a directory is not present, returns false, but records the inexistant subdirectory
00755             // structure defined by the following calls to this routine, this to be able to know when
00756             // the last available directory is back the current one when changing to parent directory,
00757             // and then proceed with normal comparison of inode. In this laps of time, the call will
00758             // always return false, while it temporary stores the missing directory structure
00759 
00760         bool direct_read(const path & ref, const nomme * &ret);
00761 
00762         infinint update_destroyed_with(catalogue & ref);
00763             // ref must have the same root, else the operation generates an exception
00764 
00765         void update_absent_with(catalogue & ref);
00766             // in case of abortion, complete missing files as if what could not be
00767             // inspected had not changed since the reference was done
00768 
00769         void dump(generic_file & ref) const;
00770         void listing(const mask &m = bool_mask(true), bool filter_unsaved = false, const std::string & marge = "") const;
00771         void tar_listing(const mask & m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const;
00772         void xml_listing(const mask & m = bool_mask(true), bool filter_unsaved = false, const std::string & beginning = "") const;
00773         entree_stats get_stats() const { return stats; };
00774 
00775         const directory *get_contenu() const { return contenu; }; // used by data_tree
00776 
00777 #ifdef LIBDAR_SPECIAL_ALLOC
00778         USE_SPECIAL_ALLOC(catalogue);
00779 #endif
00780 
00781     private :
00782         directory *contenu;
00783         path out_compare;                 // stores the missing directory structure, when extracting
00784         directory *current_compare;       // points to the current directory when extracting
00785         directory *current_add;           // points to the directory where to add the next file with add_file;
00786         directory *current_read;          // points to the directory where the next item will be read
00787         path *sub_tree;                   // path to sub_tree
00788         signed int sub_count;             // count the depth in of read routine in the sub_tree
00789         entree_stats stats;               // statistics catalogue contents
00790 
00791         user_interaction *cat_ui;
00792 
00793         void partial_copy_from(const catalogue &ref);
00794         void detruire();
00795 
00796         static const eod r_eod;           // needed to return eod reference, without taking risk of saturating memory
00797     };
00798 
00800 
00801 } // end of namespace
00802 
00803 #endif
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Defines