Disk ARchive  2.4.12
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
header_version.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 HEADER_VERSION_HPP
00027 #define HEADER_VERSION_HPP
00028 
00029 #include "../my_config.h"
00030 #include "infinint.hpp"
00031 #include "generic_file.hpp"
00032 #include "tools.hpp"
00033 #include "archive_version.hpp"
00034 
00035 namespace libdar
00036 {
00037 
00040 
00041     const U_I VERSION_FLAG_SAVED_EA_ROOT = 0x80;      //< no more used since version "05"
00042     const U_I VERSION_FLAG_SAVED_EA_USER = 0x40;      //< no more used since version "05"
00043     const U_I VERSION_FLAG_SCRAMBLED     = 0x20;      //< scrambled or strong encryption used
00044     const U_I VERSION_FLAG_SEQUENCE_MARK = 0x10;      //< escape sequence marks present for sequential reading
00045     const U_I VERSION_FLAG_INITIAL_OFFSET = 0x08;     //< whether the header contains the initial offset (size of clear data before encrypted) NOTE : This value is set internally by header_version, no need to set flag with it! But that's OK to set it or not, it will be updated according to initial_offset's value.
00046     const U_I VERSION_FLAG_HAS_AN_EXTENDED_SIZE = 0x01; //< reserved for future use
00047     const U_I VERSION_SIZE = 3;                       //< size of the version field
00048     const U_I HEADER_CRC_SIZE = 2;                    //< size of the CRC (deprecated, now only used when reading old archives)
00049 
00050 
00052     struct header_version
00053     {
00054         archive_version edition;
00055         char algo_zip;
00056         std::string cmd_line; // used long ago to store cmd_line, then abandonned, then recycled as a user comment field
00057         unsigned char flag; // added at edition 02
00058         infinint initial_offset; // not dropped to archive if set to zero (at dump() time, the flag is also updated with VERSION_FLAG_INITIAL_OFFSET accordingly to this value)
00059 
00060         header_version()
00061         {
00062             algo_zip = ' ';
00063             cmd_line = "";
00064             flag = 0;
00065             initial_offset = 0;
00066         }
00067 
00068         void read(generic_file &f)
00069         {
00070             crc *ctrl = NULL;
00071 
00072             f.reset_crc(HEADER_CRC_SIZE);
00073             edition.read(f);
00074             f.read(&algo_zip, sizeof(algo_zip));
00075             tools_read_string(f, cmd_line);
00076             if(edition > 1)
00077                 f.read((char *)&flag, 1);
00078             else
00079                 flag = 0;
00080             if((flag & VERSION_FLAG_INITIAL_OFFSET) != 0)
00081                 initial_offset.read(f);
00082             else
00083                 initial_offset = 0;
00084 
00085             ctrl = f.get_crc();
00086             if(ctrl == NULL)
00087                 throw SRC_BUG;
00088             try
00089             {
00090                 if((edition == empty_archive_version()))
00091                     throw Erange("header_version::read", gettext("Consistency check failed for archive header"));
00092                 if(edition > 7)
00093                 {
00094                     crc *coh = create_crc_from_file(f);
00095 
00096                     if(coh == NULL)
00097                         throw SRC_BUG;
00098                     try
00099                     {
00100                         if(typeid(*coh) != typeid(*ctrl))
00101                         {
00102                             if(coh->get_size() != ctrl->get_size())
00103                                 throw SRC_BUG;
00104                             else
00105                                 throw SRC_BUG; // both case lead to a bug, but we need to know which one is met
00106                         }
00107                         if(*coh != *ctrl)
00108                             throw Erange("header_version::read", gettext("Consistency check failed for archive header"));
00109                     }
00110                     catch(...)
00111                     {
00112                         if(coh != NULL)
00113                             delete coh;
00114                         throw;
00115                     }
00116                     if(coh != NULL)
00117                         delete coh;
00118                 }
00119                 if(initial_offset == 0)
00120                     initial_offset = f.get_position();
00121             }
00122             catch(...)
00123             {
00124                 if(ctrl != NULL)
00125                     delete ctrl;
00126                 throw;
00127             }
00128 
00129             if(ctrl != NULL)
00130                 delete ctrl;
00131         };
00132 
00133         void write(generic_file &f)
00134         {
00135             crc *ctrl = NULL;
00136 
00137                 // preparing the data
00138 
00139             if(initial_offset != 0)
00140                 flag |= VERSION_FLAG_INITIAL_OFFSET; // adding it to the flag
00141             else
00142                 flag &= ~VERSION_FLAG_INITIAL_OFFSET; // removing it from the flag
00143 
00144                 // writing down the data
00145 
00146             f.reset_crc(HEADER_CRC_SIZE);
00147             edition.dump(f);
00148             f.write(&algo_zip, sizeof(algo_zip));
00149             tools_write_string(f, cmd_line);
00150             f.write((char *)&flag, 1);
00151             if(initial_offset != 0)
00152                 initial_offset.dump(f);
00153 
00154             ctrl = f.get_crc();
00155             if(ctrl == NULL)
00156                 throw SRC_BUG;
00157             try
00158             {
00159                 ctrl->dump(f);
00160             }
00161             catch(...)
00162             {
00163                 if(ctrl != NULL)
00164                     delete ctrl;
00165                 throw;
00166             }
00167             if(ctrl != NULL)
00168                 delete ctrl;
00169         };
00170     };
00171 
00172 } // end of namespace
00173 
00174 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines