1 /*********************************************************************/
2 // dar - disk archive - a backup/restoration program
3 // Copyright (C) 2002-2052 Denis Corbin
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 //
19 // to contact the author : http://dar.linux.free.fr/email.html
20 /*********************************************************************/
21 
22     /// \file cat_entree.hpp
23     /// \brief base class for all object contained in a catalogue
24     /// \ingroup Private
25 
26 #ifndef CAT_ENTREE_HPP
27 #define CAT_ENTREE_HPP
28 
29 #include "../my_config.h"
30 
31 extern "C"
32 {
33 } // end extern "C"
34 
35 #include "infinint.hpp"
36 #include "user_interaction.hpp"
37 #include "pile.hpp"
38 #include "escape.hpp"
39 #include "on_pool.hpp"
40 #include "archive_version.hpp"
41 #include "compressor.hpp"
42 #include "pile_descriptor.hpp"
43 #include "smart_pointer.hpp"
44 
45 namespace libdar
46 {
47     class cat_etoile;
48     class cat_entree;
49 
50 	/// \addtogroup Private
51 	/// @{
52 
53     enum saved_status
54     {
55 	s_saved,      //< inode is saved in the archive
56 	s_fake,       //< inode is not saved in the archive but is in the archive of reference (isolation context) s_fake is no more used in archive format "08" and above: isolated catalogue do keep the data pointers and s_saved stays a valid status in isolated catalogues.
57 	s_not_saved   //< inode is not saved in the archive
58     };
59 
60 	/// holds the statistics contents of a catalogue
61     struct entree_stats
62     {
63         infinint num_x;                  //< number of file referenced as destroyed since last backup
64         infinint num_d;                  //< number of directories
65         infinint num_f;                  //< number of plain files (hard link or not, thus file directory entries)
66 	infinint num_c;                  //< number of char devices
67 	infinint num_b;                  //< number of block devices
68 	infinint num_p;                  //< number of named pipes
69 	infinint num_s;                  //< number of unix sockets
70 	infinint num_l;                  //< number of symbolic links
71 	infinint num_D;                  //< number of Door
72 	infinint num_hard_linked_inodes; //< number of inode that have more than one link (inode with "hard links")
73         infinint num_hard_link_entries;  //< total number of hard links (file directory entry pointing to \an
74             //< inode already linked in the same or another directory (i.e. hard linked))
75         infinint saved; //< total number of saved inode (unix inode, not inode class) hard links do not count here
76         infinint total; //< total number of inode in archive (unix inode, not inode class) hard links do not count here
clearlibdar::entree_stats77         void clear() { num_x = num_d = num_f = num_c = num_b = num_p
78                 = num_s = num_l = num_D = num_hard_linked_inodes
79                 = num_hard_link_entries = saved = total = 0; };
80         void add(const cat_entree *ref);
81         void listing(user_interaction & dialog) const;
82     };
83 
84 	/// the root class from all other inherite for any entry in the catalogue
85     class cat_entree : public on_pool
86     {
87     public :
88 	    /// read and create an object of inherited class of class cat_entree
89 	    ///
90 	    /// \param[in] dialog for user interaction
91 	    /// \param[in] pool for memory allocation (nullptr if special_alloc not activated)
92 	    /// \param[in] f where from to read data in order to create the object
93 	    /// \param[in] reading_ver archive version format to use for reading
94 	    /// \param[in,out] stats updated statistical fields
95 	    /// \param[in,out] corres used to setup hard links
96 	    /// \param[in] default_algo default compression algorithm
97 	    /// \param[in] lax whether to use relax mode
98 	    /// \param[in] only_detruit whether to only consider detruit objects (in addition to the directory tree)
99 	    /// \param[in] small whether the dump() to read has been done with the small argument set
100         static cat_entree *read(user_interaction & dialog,
101 				memory_pool *pool,
102 				const smart_pointer<pile_descriptor> & f,
103 				const archive_version & reading_ver,
104 				entree_stats & stats,
105 				std::map <infinint, cat_etoile *> & corres,
106 				compression default_algo,
107 				bool lax,
108 				bool only_detruit,
109 				bool small);
110 
111 	    /// setup an object when read from an archive
112 	    ///
113 	    /// \param[in] pdesc points to an existing stack that will be read from to setup fields of inherited classes,
114 	    /// this pointed to pile object must survive the whole life of the cat_entree object
115 	    /// \param[in] small whether a small or a whole read is to be read, (inode has been dump() with small set to true)
116 	cat_entree(const smart_pointer<pile_descriptor> & pdesc, bool small);
117 
118 	    // copy constructor is fine as we only copy the address of pointers
119 
120 	    // assignment operator is fine too for the same reason
121 
122 	    /// setup an object when read from filesystem
cat_entree()123 	cat_entree() {};
124 
125 	    /// destructor
~cat_entree()126         virtual ~cat_entree() throw(Ebug) {};
127 
128 	    /// returns true if the two object have the same content
operator ==(const cat_entree & ref) const129 	virtual bool operator == (const cat_entree & ref) const { return true; };
operator !=(const cat_entree & ref) const130 	bool operator != (const cat_entree & ref) const { return ! (*this == ref); };
131 
132 	    /// write down the object information to a stack
133 	    ///
134 	    /// \param[in,out] pdesc is the stack where to write the data to
135 	    /// \param[in] small defines whether to do a small or normal dump
136         void dump(const pile_descriptor & pdesc, bool small) const;
137 
138 	    /// this call gives an access to inherited_dump
139 	    ///
140 	    /// \param[in,out] pdesc is the stack where to write the data to
141 	    /// \param[in] small defines whether to do a small or normal dump
specific_dump(const pile_descriptor & pdesc,bool small) const142 	void specific_dump(const pile_descriptor & pdesc, bool small) const { inherited_dump(pdesc, small); };
143 
144 	    /// let inherited classes build object's data after CRC has been read from file in small read mode
145 	    ///
146 	    /// \param[in] pdesc stack to read the data from
147 	    /// \note used from cat_entree::read to complete small read
148 	    /// \note this method is called by cat_entree::read and mirage::post_constructor only when contructing an object with small set to true
post_constructor(const pile_descriptor & pdesc)149 	virtual void post_constructor(const pile_descriptor & pdesc) {};
150 
151 	    /// inherited class signature
152         virtual unsigned char signature() const = 0;
153 
154 	    /// a way to copy the exact type of an object even if pointed to by a parent class pointer
155         virtual cat_entree *clone() const = 0;
156 
157 	    /// for archive merging, will let the object drop EA, FSA and Data to an alternate stack than the one it has been read from
158 	    ///
159 	    /// \note this is used when cloning an object from a catalogue to provide a merged archive. Such cloned object must point
160 	    /// the stack of the archive under construction, so we use this call for that need,
161 	    /// \note this is also used when opening a catalogue if an isolated catalogue in place of the internal catalogue of an archive
162 	    /// \note this method is virtual for cat_directory to overwrite it and propagate the change to all entries of the directory tree
163 	    /// as well for mirage to propagate the change to the hard linked inode
164 	virtual void change_location(const smart_pointer<pile_descriptor> & pdesc);
165 
166 
167     protected:
168 	    /// inherited class may overload this method but shall first call the parent's inherited_dump() in the overloaded method
169 	virtual void inherited_dump(const pile_descriptor & pdesc, bool small) const;
170 
171 
172 	    /// stack used to read object from (nullptr is returned for object created from filesystem)
get_pile() const173 	pile *get_pile() const { return pdesc.is_null() ? nullptr : pdesc->stack; };
174 
175 	    /// compressor generic_file relative methods
176 	    ///
177 	    /// \note CAUTION: the pointer to object is member of the get_pile() stack and may be managed by another thread
178 	    /// all precaution like get_pile()->flush_read_above(get_compressor_layer() shall be take to avoid
179 	    /// concurrent access to the compressor object by the current thread and the thread managing this object
get_compressor_layer() const180 	compressor *get_compressor_layer() const { return pdesc.is_null() ? nullptr : pdesc->compr; };
181 
182 	    /// escape generic_file relative methods
183 	    ///
184 	    /// \note CAUTION: the pointer to object is member of the get_pile() stack and may be managed by another thread
185 	    /// all precaution like get_pile()->flush_read_above(get_escape_layer() shall be take to avoid
186 	    /// concurrent access to the compressor object by the current thread and the thread managing this object
get_escape_layer() const187 	escape *get_escape_layer() const { return pdesc.is_null() ? nullptr : pdesc->esc; };
188 
189 	    /// return the adhoc layer in the stack to read from the catalogue objects (except the EA, FSA or Data part)
190 	generic_file *get_read_cat_layer(bool small) const;
191 
192     private:
193 	static const U_I ENTREE_CRC_SIZE;
194 
195 	smart_pointer<pile_descriptor> pdesc;
196     };
197 
198 	/// @}
199 
200 } // end of namespace
201 
202 #endif
203