Disk ARchive  2.4.12
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
sar.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 : http://dar.linux.free.fr/email.html
00020 /*********************************************************************/
00021 
00025 
00026 #ifndef SAR_HPP
00027 #define SAR_HPP
00028 
00029 #include "../my_config.h"
00030 
00031 #include <string>
00032 #include "infinint.hpp"
00033 #include "generic_file.hpp"
00034 #include "header.hpp"
00035 #include "path.hpp"
00036 #include "integers.hpp"
00037 #include "hash_fichier.hpp"
00038 
00039 namespace libdar
00040 {
00041         // contextual is defined in generic_file module
00042 
00045 
00047 
00052     class sar : public generic_file, public contextual, protected mem_ui
00053     {
00054     public:
00055 
00057 
00070         sar(user_interaction & dialog,
00071             const std::string & base_name,
00072             const std::string & extension,
00073             const path & dir,
00074             bool by_the_end,
00075             const infinint & x_min_digits,
00076             bool lax = false,
00077             const std::string & execute = "");
00078 
00079 
00081 
00103         sar(user_interaction  & dialog,
00104             const std::string & base_name,
00105             const std::string & extension,
00106             const infinint & file_size,
00107             const infinint & first_file_size,
00108             bool x_warn_overwrite,
00109             bool x_allow_overwrite,
00110             const infinint & pause,
00111             const path & dir,
00112             const label & data_name,
00113             const std::string & slice_permission,
00114             const std::string & slice_user_ownership,
00115             const std::string & slice_group_ownership,
00116             hash_algo x_hash,
00117             const infinint & x_min_digits,
00118             bool format_07_compatible,
00119             const std::string & execute = "");
00120 
00122 
00123         sar(const sar & ref) : generic_file(ref), mem_ui(ref), archive_dir(ref.archive_dir) { throw Efeature("class sar's copy constructor is not implemented"); };
00124 
00126         ~sar();
00127 
00128             // inherited from generic_file
00129         bool skip(const infinint &pos);
00130         bool skip_to_eof();
00131         bool skip_relative(S_I x);
00132         infinint get_position();
00133 
00134             // informational routines
00135         infinint get_sub_file_size() const { return size; };
00136         infinint get_first_sub_file_size() const { return first_size; };
00137         bool get_total_file_number(infinint &num) const { num = of_last_file_num; return of_last_file_known; };
00138         bool get_last_file_size(infinint &num) const { num = of_last_file_size; return of_last_file_known; };
00139 
00140             // disable execution of user command when destroying the current object
00141         void disable_natural_destruction() { natural_destruction = false; };
00142 
00143             // enable back execution of user command when destroying the current object
00144         void enable_natural_destruction() { natural_destruction = true; };
00145 
00146             // true if sar's header is from an old archive format (<= "07")
00147         bool is_an_old_start_end_archive() const { return old_sar; };
00148 
00149             // return the internal_name used to link slices toghether
00150         const label & get_internal_name_used() const { return of_internal_name; };
00151 
00152             // return the data_name used to link slices toghether
00153         const label & get_data_name() const { return of_data_name; };
00154 
00155     protected :
00156         U_I inherited_read(char *a, U_I size);
00157         void inherited_write(const char *a, U_I size);
00158         void inherited_sync_write() {}; // nothing to do
00159         void inherited_terminate();
00160 
00161     private :
00162         path archive_dir;            //< path where to look for slices
00163         std::string base;            //< archive base name
00164         std::string ext;             //< archive extension
00165         std::string hook;            //< command line to execute between slices
00166         infinint size;               //< size of slices
00167         infinint first_size;         //< size of first slice
00168         infinint first_file_offset;  //< where data start in the first slice
00169         infinint other_file_offset;  //< where data start in the slices other than the first
00170         infinint file_offset;        //< current reading/writing position in the current slice (relative to the whole slice file, including headers)
00171         bool force_perm;             //< enforce slice permission with perm field value below
00172         U_I perm;                    //< permission to set when creating slices
00173         std::string slice_user;      //< user for new slices
00174         std::string slice_group;     //< group for new slice
00175         hash_algo hash;              //< whether to build a hashing when creating slices, and if so, which algorithm to use
00176         infinint min_digits;         //< minimum number of digits the slices number is stored with in the filename
00177         bool natural_destruction;    //< whether to execute commands between slices on object destruction
00178 
00179             // these following variables are modified by open_file / open_file_init
00180             // else the are used only for reading
00181         infinint of_current;         //< number of the open slice
00182         infinint size_of_current;    //< size of the current slice (used in reading mode only)
00183         infinint of_max_seen;        //< highest slice number seen so far
00184         bool of_last_file_known;     //< whether the T terminal slice has been met
00185         infinint of_last_file_num;   //< number of the last slice (if met)
00186         infinint of_last_file_size;  //< size of the last slice (if met)
00187         label of_internal_name;      //< internal name shared in all slice header
00188         label of_data_name;          //< internal name linked to data (transparent to dar_xform and used by isolated catalogue as reference)
00189         fichier *of_fd;              //< file object currently openned
00190         char of_flag;                //< flags of the open file
00191         bool initial;                //< do not launch hook command-line during sar initialization
00192         bool lax;                    //< whether to try to go further reading problems
00193 
00194             // these are the option flags
00195         bool opt_warn_overwrite;     //<  a warning must be issued before overwriting a slice
00196         bool opt_allow_overwrite;    //< is slice overwriting allowed
00197 
00198             //
00199         infinint pause;              //< do we pause between slices
00200         bool old_sar;                //< in read-mode, is true if the read sar has an old header (format <= "07"), in write mode, is true if it is requested to build old slice headers
00201 
00202         bool skip_forward(U_I x);                                  //< skip forward in sar global contents
00203         bool skip_backward(U_I x);                                 //< skip backward in sar global contents
00204         void close_file(bool terminal);                            //< close current openned file, adding (in write mode only) a terminal mark (last slice) or not
00205         void open_readonly(const char *fic, const infinint &num);  //< open file of name "filename" for read only "num" is the slice number
00206         void open_writeonly(const char *fic, const infinint &num); //< open file of name "filename" for write only "num" is the slice number
00207         void open_file_init();            //< initialize some of_* fields
00208         void open_file(infinint num);     //< close current slice and open the slice 'num'
00209         void set_offset(infinint offset); //< skip to current slice relative offset
00210         void open_last_file();            //< open the last slice, ask the user, test, until last slice available
00211         bool is_current_eof_a_normal_end_of_slice() const;  //< return true if current reading position is at end of slice
00212         infinint bytes_still_to_read_in_slice() const;  //< returns the number of bytes expected before the end of slice
00213         header make_write_header(const infinint &num, char flag);
00214 
00215             // function to lauch the eventually existing command to execute after/before each slice
00216         void hook_execute(const infinint &num);
00217     };
00218 
00219 
00221 
00222     class trivial_sar : public generic_file , public contextual, protected mem_ui
00223     {
00224     public:
00226         trivial_sar(user_interaction & dialog,         //< how to interact with the user
00227                     const std::string & base_name,     //< archive basename to create
00228                     const std::string & extension,     //< archive extension
00229                     const path & dir,                  //< where to store the archive
00230                     const label & data_name,           //< tag that follows the data when archive is dar_xform'ed
00231                     const std::string & execute,       //< command line to execute at end of slice creation
00232                     bool allow_over,                   //< whether to allow overwriting
00233                     bool warn_over,                    //< whether to warn before overwriting
00234                     const std::string & slice_permission,        //< slice permission
00235                     const std::string & slice_user_ownership,    //< slice user
00236                     const std::string & slice_group_ownership,   //< slice group
00237                     hash_algo x_hash,                  //< whether to build a hash of the slice, and which algo to use for that
00238                     const infinint & min_digits,       //< is the minimum number of digits the slices number is stored with in the filename
00239                     bool format_07_compatible);        //< build a slice header backward compatible with 2.3.x
00240 
00241 
00243         trivial_sar(user_interaction & dialog,         //< how to interact with the user
00244                     const std::string & pipename,      //< if set to '-' the data are read from standard input, else the given file is expected to be named pipe to read data from
00245                     bool lax);                         //< whether to be laxist or follow the normal and strict controlled procedure
00246 
00247 
00249         trivial_sar(user_interaction & dialog,
00250                     generic_file * f, //< in case of exception the generic_file "f" is not released, this is the duty of the caller to do so, else (success), the object becomes owned by the trivial_sar and must not be released by the caller.
00251                     const label & data_name,
00252                     bool format_07_compatible,
00253                     const std::string & execute);
00254 
00256         trivial_sar(const trivial_sar & ref) : generic_file(ref), mem_ui(ref), archive_dir("/") { throw SRC_BUG; };
00257 
00259         ~trivial_sar();
00260 
00261         const trivial_sar & operator = (const trivial_sar & ref) { throw SRC_BUG; };
00262 
00263         bool skip(const infinint & pos) { if(is_terminated()) throw SRC_BUG; return reference->skip(pos + offset); };
00264         bool skip_to_eof() { if(is_terminated()) throw SRC_BUG; return reference->skip_to_eof(); };
00265         bool skip_relative(S_I x);
00266         infinint get_position();
00267 
00268             // contextual inherited method
00269         bool is_an_old_start_end_archive() const { return old_sar; };
00270         const label & get_data_name() const { return of_data_name; };
00271 
00272     protected:
00273         U_I inherited_read(char *a, U_I size);
00274         void inherited_write(const char *a, U_I size) { reference->write(a, size); };
00275         void inherited_sync_write() {};
00276         void inherited_terminate();
00277 
00278     private:
00279         generic_file *reference;  //< points to the underlying data, not owned by "this"
00280         infinint offset;          //< offset to apply to get the first byte of data out of SAR headers
00281         infinint end_of_slice;    //< when end of slice/archive is met, there is an offset by 1 compared to the offset of reference. end_of_slice is set to 1 in that situation, else it is always equal to zero
00282         std::string hook;         //< command to execute after slice writing (not used in read-only mode)
00283         std::string base;         //< basename of the archive (used for string susbstitution in hook)
00284         std::string ext;          //< extension of the archive (used for string substitution in hook)
00285         path archive_dir;         //< path of the archiv (used for string substitution in hook)
00286         label of_data_name;       //< archive's data name
00287         bool old_sar;             //< true if the read sar has an old header (format <= "07") or the to be written is must keep a version 07 format.
00288         infinint x_min_digits;    //< minimum number of digits in slice name
00289 
00290         void init();              //< write the slice header and set the offset field (write mode), or (read-mode) reads the slice header an set offset field
00291         void build(user_interaction & dialog,
00292                    generic_file *f,
00293                    const label & data_name,
00294                    const std::string & execute);
00295     };
00296 
00297 
00299 
00300     extern std::string sar_make_filename(const std::string & base_name, const infinint & num, const infinint & min_digits, const std::string & ext);
00301 
00303 
00304 } // end of namespace
00305 
00306 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines