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 generic_file.hpp
23     /// \brief class generic_file is defined here as well as class fichier
24     /// \ingroup Private
25     ///
26     /// the generic_file interface is widely used in libdar
27     /// it defines the standard way of transmitting data between different
28     /// part of the library
29     /// - compression engine
30     /// - encryption engine
31     /// - exchange through pipes
32     /// - slicing
33     /// - dry run operations
34     /// - file access
35     /// .
36 
37 
38 ///////////////////////////////////////////////////////////////////////
39 // IMPORTANT : THIS FILE MUST ALWAYS BE INCLUDE AFTER infinint.hpp   //
40 //             (and infinint.hpp must be included too, always)       //
41 ///////////////////////////////////////////////////////////////////////
42 #include "infinint.hpp"
43 ///////////////////////////////////////////////////////////////////////
44 
45 
46 
47 #ifndef GENERIC_FILE_HPP
48 #define GENERIC_FILE_HPP
49 
50 
51 #include "../my_config.h"
52 
53 extern "C"
54 {
55 #if HAVE_UNISTD_H
56 #include <unistd.h>
57 #endif
58 } // end extern "C"
59 
60 #include "path.hpp"
61 #include "integers.hpp"
62 #include "thread_cancellation.hpp"
63 #include "label.hpp"
64 #include "crc.hpp"
65 #include "user_interaction.hpp"
66 #include "on_pool.hpp"
67 
68 #include <string>
69 
70 namespace libdar
71 {
72 
73 	/// \addtogroup Private
74 	/// @{
75 
76 	/// generic_file openning modes
77     enum gf_mode
78     {
79 	gf_read_only,  ///< read only access
80 	gf_write_only, ///< write only access
81 	gf_read_write  ///< read and write access
82     };
83 
84 	/// provides a human readable string defining the gf_mode given in argument
85     extern const char * generic_file_get_name(gf_mode mode);
86 
87 	/// this is the interface class from which all other data transfer classes inherit
88 
89 	/// it provides mainly read and write operations,
90 	/// skip operations and few other functions.
91 	/// \note
92 	/// the read and write method are similar to the read and write system calls
93 	/// except that they never return negative values, but throw exception instead.
94 	/// returning zero means end of generic_file. The call is blocked if
95 	/// no data is available for reading.
96 	/// write returns the number of bytes written, and never make partial writtings.
97 	/// Thus, it is blocked until all bytes are written or occures an exception
98 	/// inconsequences the returned value is always the value of the argument
99 	/// "size".
100     class generic_file : public on_pool
101     {
102     public :
103 	    /// main constructor
generic_file(gf_mode m)104         generic_file(gf_mode m) { rw = m; terminated = no_read_ahead = false; enable_crc(false); checksum = nullptr; };
105 
106 	    /// copy constructor
generic_file(const generic_file & ref)107 	generic_file(const generic_file &ref) { copy_from(ref); };
108 
109 	    /// virtual destructor, this let inherited destructor to be called even from a generic_file pointer to an inherited class
~generic_file()110 	virtual ~generic_file() throw(Ebug) { destroy(); };
111 
112 	    /// destructor-like call, except that it is allowed to throw exceptions
113 	void terminate() const;
114 
115 
116 	    /// assignment operator
operator =(const generic_file & ref)117 	const generic_file & operator = (const generic_file & ref) { destroy(); copy_from(ref); return *this; };
118 
119 	    /// retreive the openning mode for this object
get_mode() const120         gf_mode get_mode() const { return rw; };
121 
122 	    /// read ahead information
123 	    ///
124 	    /// \param[in] amount is the expected amount of data the caller will read, if zero is given the object shall prepare as much as possible data for reading until a skip request, write request or a new read_ahead request
125 	    /// \note after sanity checks, the protected inherited_read_ahead() method is called
126 	virtual void read_ahead(const infinint & amount);
127 
128 	    /// ignore read ahead requests
129 	    ///
130 	    /// \param [in] mode if set to true read_ahead requests are ignored: inherited_read_ahead() of the inherited class
131 	    /// is not called
132 	    /// \note read_ahead is useful in multi-thread environement when a slave thread can work in advanced and asynchronously
133 	    /// to provide read content to reader thread. However, read_ahead is a waste of CPU cycle for in a single threading model
ignore_read_ahead(bool mode)134 	void ignore_read_ahead(bool mode) { no_read_ahead = mode; };
135 
136 	    /// read data from the generic_file
137 
138 	    /// \param[in, out] a is where to put the data to read
139 	    /// \param[in] size is how much data to read
140 	    /// \return the exact number of byte read.
141 	    /// \note read as much as requested data, unless EOF is met (only EOF can lead to reading less than requested data)
142 	    /// \note EOF is met if read() returns less than size
143         U_I read(char *a, U_I size);
144 
145 	    /// write data to the generic_file
146 
147 	    /// \note throws a exception if not all data could be written as expected
148         void write(const char *a, U_I size);
149 
150 	    /// write a string to the generic_file
151 
152 	    /// \note throws a exception if not all data could be written as expected
153         void write(const std::string & arg);
154 
155 	    /// skip back one char, read on char and skip back one char
156         S_I read_back(char &a);
157 
158 	    /// read one char
read_forward(char & a)159 	S_I read_forward(char &a) { if(terminated) throw SRC_BUG; return read(&a, 1); };
160 
161 
162 	enum skippability { skip_backward, skip_forward };
163 
164 	    /// whether the implementation is able to skip
165 	    /// \note the capability to skip does not mean that skip_relative() or
166 	    /// skip() will succeed, but rather that the inherited class implementation
167 	    /// does not by construction forbid the requested skip (like inherited class
168 	    /// providing a generic_file interface of an anonymous pipe for example)
169 	virtual bool skippable(skippability direction, const infinint & amount) = 0;
170 
171 	    /// skip at the absolute position
172 	    ///
173 	    /// \param[in] pos the offset in byte where next read/write operation must start
174 	    /// \return true if operation was successfull and false if the requested position is not valid (after end of file)
175 	    /// \note if requested position is not valid the reading/writing cursor must be set to the closest valid position
176         virtual bool skip(const infinint & pos) = 0;
177 
178 	    /// skip to the end of file
179         virtual bool skip_to_eof() = 0;
180 
181 	    /// skip relatively to the current position
182         virtual bool skip_relative(S_I x) = 0;
183 
184 	    /// get the current read/write position
185         virtual infinint get_position() const = 0;
186 
187 	    /// copy all data from current position to the object in argument
188         virtual void copy_to(generic_file &ref);
189 
190 	    /// copy all data from the current position to the object in argument and computes a CRC value of the transmitted data
191 
192 	    /// \param[in] ref defines where to copy the data to
193 	    /// \param[in] crc_size tell the width of the crc to compute on the copied data
194 	    /// \param[out] value points to a newly allocated crc object containing the crc value
195 	    /// \note value has to be deleted by the caller when no more needed
196         virtual void copy_to(generic_file &ref, const infinint & crc_size, crc * & value);
197 
198 	    /// small copy (up to 4GB) with CRC calculation
199         U_32 copy_to(generic_file &ref, U_32 size); // returns the number of byte effectively copied
200 
201 	    /// copy the given amount to the object in argument
202         infinint copy_to(generic_file &ref, infinint size); // returns the number of byte effectively copied
203 
204 	    /// compares the contents with the object in argument
205 
206 	    /// \param[in] f is the file to compare the current object with
207 	    /// \param[in] me_read_ahead is the amount of data to read ahead from "*this" (0 for no limit, up to end of eof)
208 	    /// \param[in] you_read_ahead is the amount of data to read ahead from f (0 for no limit, up to end of file
209 	    /// \param[in] crc_size is the width of the CRC to use for calculation
210 	    /// \param[out] value is the computed checksum, its value can be used for additional
211 	    /// testing if this method returns false (no difference between files). The given checksum
212 	    /// has to be set to the expected width by the caller.
213 	    /// \return true if arg differ from "this"
214 	    /// \note value has to be deleted by the caller when no more needed
215         bool diff(generic_file & f,
216 		  const infinint & me_read_ahead,
217 		  const infinint & you_read_ahead,
218 		  const infinint & crc_size,
219 		  crc * & value);
220 
221 	    /// compare the contents with the object in argument, also providing the offset of the first difference met
222 	    /// \param[in] f is the file to compare the current object with
223 	    /// \param[in] me_read_ahead is the amount of data to read ahead from "*this" (0 for no limit, up to end of eof)
224 	    /// \param[in] you_read_ahead is the amount of data to read ahead from f (0 for no limit, up to end of file
225 	    /// \param[in] crc_size is the width of the CRC to use for calculation
226 	    /// \param[out] value is the computed checksum, its value can be used for additional
227 	    /// \param[out] err_offset in case of difference, holds the offset of the first difference met
228 	    /// testing if this method returns false (no difference between files). The given checksum
229 	    /// has to be set to the expected width by the caller.
230 	    /// \return true if arg differ from "this", else false is returned and err_offset is set
231 	    /// \note value has to be deleted by the caller when no more needed
232 	bool diff(generic_file & f,
233 		  const infinint & me_read_ahead,
234 		  const infinint & you_read_ahead,
235 		  const infinint & crc_size,
236 		  crc * & value,
237 		  infinint & err_offset);
238 
239             /// reset CRC on read or writen data
240 
241 	    /// \param[in] width is the width to use for the CRC
242         void reset_crc(const infinint & width);
243 
244 	    /// to known whether CRC calculation is activated or not
crc_status() const245 	bool crc_status() const { return active_read == &generic_file::read_crc; };
246 
247 	    /// get CRC of the transfered date since last reset
248 
249 	    /// \return a newly allocated crc object, that the caller has the responsibility to delete
250 	    /// \note does also ends checksum calculation, which if needed again
251 	    /// have to be re-enabled calling reset_crc() method
252         crc *get_crc();
253 
254 	    /// write any pending data
255 	void sync_write();
256 
257 	    /// be ready to read at current position, reseting all pending data for reading, cached and in compression engine for example
258 	void flush_read();
259 
260 
261     protected :
set_mode(gf_mode x)262         void set_mode(gf_mode x) { rw = x; };
263 
264 	    /// tells the object that several calls to read() will follow to probably obtain at least the given amount of data
265 	    ///
266 	    /// \param[in] amount is the maximum expected amount of data that is known to be read
267 	    /// \note this call may be implemented as a do-nothing call, its presence is only
268 	    /// to allow optimization when possible, like in multi-threaded environment
269 	virtual void inherited_read_ahead(const infinint & amount) = 0;
270 
271 
272 	    /// implementation of read() operation
273 
274 	    /// \param[in,out] a where to put the data to read
275 	    /// \param[in] size says how much data to read
276 	    /// \return the exact amount of data read and put into 'a'
277 	    /// \note read as much byte as requested, up to end of file
278 	    /// stays blocked if not enough data is available and EOF not
279 	    /// yet met. May return less data than requested only if EOF as been reached.
280 	    /// in other worlds, EOF is reached when returned data is stricly less than the requested data
281 	    /// Any problem shall be reported by throwing an exception.
282         virtual U_I inherited_read(char *a, U_I size) = 0;
283 
284 	    /// implementation of the write() operation
285 
286 	    /// \param[in] a what data to write
287 	    /// \param[in] size amount of data to write
288 	    /// \note must either write all data or report an error by throwing an exception
289         virtual void inherited_write(const char *a, U_I size) = 0;
290 
291 
292 	    /// write down any pending data
293 
294 	    /// \note called after sanity checks from generic_file::sync_write()
295 	    /// this method's role is to write down any data pending for writing in the current object
296 	    /// it has not to be propagated to other gneric_file object this object could rely on
297 	virtual void inherited_sync_write() = 0;
298 
299 	    /// reset internal engine, flush caches in order to read the data at current position
300 	    ///
301 	    /// \note when the object relies on external object or system object to fetch the data from for reading,
302 	    /// when a call to (inherited_)flush_read() occurs, the current object must not assume that any previously read
303 	    /// data is still valid if it has internal buffers or the like and it should flush them asap. This call must
304 	    /// not propagate the flush_read to any other gneric_file object it could rely on
305 	virtual void inherited_flush_read() = 0;
306 
307 	    /// destructor-like call, except that it is allowed to throw exceptions
308 
309 	    /// \note this method must never be called directly but using terminate() instead,
310 	    /// generic_file class manages it to never be called more than once
311 	virtual void inherited_terminate() = 0;
312 
313 
314 	    /// is some specific call (skip() & Co.) need to be forbidden when the object
315 	    /// has been terminated, one can use this call to check the terminated status
is_terminated() const316 	bool is_terminated() const { return terminated; };
317 
318     private :
319         gf_mode rw;
320         crc *checksum;
321 	bool terminated;
322 	bool no_read_ahead;
323         U_I (generic_file::* active_read)(char *a, U_I size);
324         void (generic_file::* active_write)(const char *a, U_I size);
325 
326         void enable_crc(bool mode);
327 
328         U_I read_crc(char *a, U_I size);
329         void write_crc(const char *a, U_I size);
330 	void destroy();
331 	void copy_from(const generic_file & ref);
332     };
333 
334 #define CONTEXT_INIT "init"
335 #define CONTEXT_OP   "operation"
336 #define CONTEXT_LAST_SLICE  "last_slice"
337 
338 	/// the contextual class adds the information of phases in the generic_file
339 
340 	/// several phases are defined like for example
341 	/// - INIT phase
342 	/// - OPERATIONAL phase
343 	/// - LAST SLICE phase
344 	/// .
345 	/// these are used to help the command launched between slices to
346 	/// decide the action to do depending on the context when reading an archive
347 	/// (first slice / last slice read, ...)
348 	/// the context must also be transfered to dar_slave through the pair of tuyau objects
349 	///
350 	/// this class also support some additional informations common to all 'level1' layer of
351 	/// archive, such as:
352 	/// - the data_name information
353 	///
354 
355     class label;
356 
357     class contextual
358     {
359     public :
contextual()360 	contextual() { status = ""; };
~contextual()361 	virtual ~contextual() throw(Ebug) {};
362 
363 	    /// defines the new contextual value
364 	    ///
365 	    /// \note inherited class may redefine this call but
366 	    /// but must call the parent method to set the value
367 	    /// contextual:set_info_status()
set_info_status(const std::string & s)368 	virtual void set_info_status(const std::string & s) { status = s; };
369 
370 	    /// get the current contextual value
get_info_status() const371         virtual std::string get_info_status() const { return status; };
372 
373 	    /// returns whether the archive is a old archive (format < 8)
374 	virtual bool is_an_old_start_end_archive() const = 0;
375 
376 	    /// obtain the data_name of the archive (label associated with the archive's data)
377 	    ///
378 	    /// \note label are conserved with dar_xform and archive isolation, but are
379 	    /// not with archive merging or archive creation (full or differential backup)
380 	virtual const label & get_data_name() const = 0;
381 
382     private:
383 	std::string status;
384     };
385 
386 	/// @}
387 
388 } // end of namespace
389 
390 #endif
391