|
Disk ARchive
2.4.12
|
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
1.7.6.1