Disk ARchive  2.4.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
header_version.hpp
Go to the documentation of this file.
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 // $Id: header_version.hpp,v 1.22.2.1 2012/02/12 20:43:34 edrusb Rel $
22 //
23 /*********************************************************************/
24 
28 
29 #ifndef HEADER_VERSION_HPP
30 #define HEADER_VERSION_HPP
31 
32 #include "../my_config.h"
33 #include "infinint.hpp"
34 #include "generic_file.hpp"
35 #include "tools.hpp"
36 #include "archive_version.hpp"
37 
38 namespace libdar
39 {
40 
43 
44  const U_I VERSION_FLAG_SAVED_EA_ROOT = 0x80; //< no more used since version "05"
45  const U_I VERSION_FLAG_SAVED_EA_USER = 0x40; //< no more used since version "05"
46  const U_I VERSION_FLAG_SCRAMBLED = 0x20; //< scrambled or strong encryption used
47  const U_I VERSION_FLAG_SEQUENCE_MARK = 0x10; //< escape sequence marks present for sequential reading
48  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.
49  const U_I VERSION_FLAG_HAS_AN_EXTENDED_SIZE = 0x01; //< reserved for future use
50  const U_I VERSION_SIZE = 3; //< size of the version field
51  const U_I HEADER_CRC_SIZE = 2; //< size of the CRC (deprecated, now only used when reading old archives)
52 
53 
56  {
57  archive_version edition;
58  char algo_zip;
59  std::string cmd_line; // used long ago to store cmd_line, then abandonned, then recycled as a user comment field
60  unsigned char flag; // added at edition 02
61  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)
62 
64  {
65  algo_zip = ' ';
66  cmd_line = "";
67  flag = 0;
68  initial_offset = 0;
69  }
70 
71  void read(generic_file &f)
72  {
73  crc *ctrl = NULL;
74 
75  f.reset_crc(HEADER_CRC_SIZE);
76  edition.read(f);
77  f.read(&algo_zip, sizeof(algo_zip));
78  tools_read_string(f, cmd_line);
79  if(edition > 1)
80  f.read((char *)&flag, 1);
81  else
82  flag = 0;
83  if((flag & VERSION_FLAG_INITIAL_OFFSET) != 0)
84  initial_offset.read(f);
85  else
86  initial_offset = 0;
87 
88  ctrl = f.get_crc();
89  if(ctrl == NULL)
90  throw SRC_BUG;
91  try
92  {
93  if((edition == empty_archive_version()))
94  throw Erange("header_version::read", gettext("Consistency check failed for archive header"));
95  if(edition > 7)
96  {
97  crc *coh = create_crc_from_file(f);
98 
99  if(coh == NULL)
100  throw SRC_BUG;
101  try
102  {
103  if(typeid(*coh) != typeid(*ctrl))
104  {
105  if(coh->get_size() != ctrl->get_size())
106  throw SRC_BUG;
107  else
108  throw SRC_BUG; // both case lead to a bug, but we need to know which one is met
109  }
110  if(*coh != *ctrl)
111  throw Erange("header_version::read", gettext("Consistency check failed for archive header"));
112  }
113  catch(...)
114  {
115  if(coh != NULL)
116  delete coh;
117  throw;
118  }
119  if(coh != NULL)
120  delete coh;
121  }
122  if(initial_offset == 0)
123  initial_offset = f.get_position();
124  }
125  catch(...)
126  {
127  if(ctrl != NULL)
128  delete ctrl;
129  throw;
130  }
131 
132  if(ctrl != NULL)
133  delete ctrl;
134  };
135 
136  void write(generic_file &f)
137  {
138  crc *ctrl = NULL;
139 
140  // preparing the data
141 
142  if(initial_offset != 0)
143  flag |= VERSION_FLAG_INITIAL_OFFSET; // adding it to the flag
144  else
145  flag &= ~VERSION_FLAG_INITIAL_OFFSET; // removing it from the flag
146 
147  // writing down the data
148 
149  f.reset_crc(HEADER_CRC_SIZE);
150  edition.dump(f);
151  f.write(&algo_zip, sizeof(algo_zip));
152  tools_write_string(f, cmd_line);
153  f.write((char *)&flag, 1);
154  if(initial_offset != 0)
155  initial_offset.dump(f);
156 
157  ctrl = f.get_crc();
158  if(ctrl == NULL)
159  throw SRC_BUG;
160  try
161  {
162  ctrl->dump(f);
163  }
164  catch(...)
165  {
166  if(ctrl != NULL)
167  delete ctrl;
168  throw;
169  }
170  if(ctrl != NULL)
171  delete ctrl;
172  };
173  };
174 
175 } // end of namespace
176 
177 #endif