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