Disk ARchive  2.4.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
data_tree.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: data_tree.hpp,v 1.5.2.5 2012/02/19 17:25:08 edrusb Rel $
22 //
23 /*********************************************************************/
24 
28 
29 
30 #ifndef DATA_TREE_HPP
31 #define DATA_TREE_HPP
32 
33 #include "../my_config.h"
34 
35 #include <map>
36 #include <string>
37 #include <list>
38 #include "infinint.hpp"
39 #include "generic_file.hpp"
40 #include "infinint.hpp"
41 #include "catalogue.hpp"
42 #include "special_alloc.hpp"
43 #include "user_interaction.hpp"
44 #include "path.hpp"
45 
46 namespace libdar
47 {
48 
51 
52  typedef U_16 archive_num;
53 #define ARCHIVE_NUM_MAX 65534
54 
56 
60  class data_tree
61  {
62  public:
63  enum lookup { found_present, found_removed, not_found, not_restorable };
64  enum etat
65  {
66  et_saved, //< data/EA present in the archive
67  et_present, //< file/EA present in the archive but data not saved (differential backup)
68  et_removed, //< file/EA stored as deleted since archive of reference of file/EA not present in the archive
69  et_absent //< file not even mentionned in the archive, This entry is equivalent to et_removed, but is required to be able to properly re-order the archive when user asks to do so. The dates associated to this state are computed from neighbor archives in the database
70  };
71 
72  data_tree(const std::string &name);
73  data_tree(generic_file &f, unsigned char db_version);
74  virtual ~data_tree() {};
75 
76  virtual void dump(generic_file & f) const;
77  std::string get_name() const { return filename; };
78  void set_name(const std::string & name) { filename = name; };
79 
81  lookup get_data(archive_num & archive, const infinint & date, bool even_when_removed) const;
82 
84  lookup get_EA(archive_num & archive, const infinint & date, bool even_when_removed) const;
85 
87  bool read_data(archive_num num, infinint & val, etat & present) const;
88 
90  bool read_EA(archive_num num, infinint & val, etat & present) const;
91 
92  void set_data(const archive_num & archive, const infinint & date, etat present) { status sta = { date, present }; last_mod[archive] = sta; };
93  void set_EA(const archive_num & archive, const infinint & date, etat present) { status sta = { date, present }; last_change[archive] = sta; };
94 
96  virtual bool check_order(user_interaction & dialog, const path & current_path, bool & initial_warn) const { return check_map_order(dialog, last_mod, current_path, "data", initial_warn) && check_map_order(dialog, last_change, current_path, "EA", initial_warn); };
97 
99 
107  virtual void finalize(const archive_num & archive,
108  const infinint & deleted_date,
109  const archive_num & ignore_archive_greater_or_equal);
110 
112  virtual bool remove_all_from(const archive_num & archive_to_remove, const archive_num & last_archive);
113 
115  void listing(user_interaction & dialog) const;
116  virtual void apply_permutation(archive_num src, archive_num dst);
117 
119  virtual void skip_out(archive_num num);
120  virtual void compute_most_recent_stats(std::vector<infinint> & data,
121  std::vector<infinint> & ea,
122  std::vector<infinint> & total_data,
123  std::vector<infinint> & total_ea) const;
124 
125  virtual char obj_signature() const { return signature(); };
126  static char signature() { return 't'; };
127 
128 #ifdef LIBDAR_SPECIAL_ALLOC
129  USE_SPECIAL_ALLOC(data_tree);
130 #endif
131  private:
132  struct status
133  {
134  infinint date; //< date of the event
135  etat present; //< file's status in the archive
136  void dump(generic_file & f) const; //< write the struct to file
137  void read(generic_file &f); //< set the struct from file
138  };
139 
140 
141  std::string filename;
142  std::map<archive_num, status> last_mod; //< key is archive number ; value is last_mod time
143  std::map<archive_num, status> last_change; //< key is archive number ; value is last_change time
144 
145 
146  // when false is returned, this means that the user wants to ignore subsequent error of the same type
147  // else either no error yet met or user want to continue receiving the same type of error for other files
148  // in that later case initial_warn is set to false (first warning has been shown).
149  bool check_map_order(user_interaction & dialog,
150  const std::map<archive_num, status> the_map,
151  const path & current_path,
152  const std::string & field_nature,
153  bool & initial_warn) const;
154  };
155 
157 
159  class data_dir : public data_tree
160  {
161  public:
162  data_dir(const std::string &name);
163  data_dir(generic_file &f, unsigned char db_version);
164  data_dir(const data_dir & ref);
165  data_dir(const data_tree & ref);
166  ~data_dir();
167 
168  void dump(generic_file & f) const;
169 
170  void add(const inode *entry, const archive_num & archive);
171  void add(const detruit *entry, const archive_num & archive);
172  const data_tree *read_child(const std::string & name) const;
173  void read_all_children(std::vector<std::string> & fils) const;
174  virtual void finalize_except_self(const archive_num & archive,
175  const infinint & deleted_date,
176  const archive_num & ignore_archives_greater_or_equal);
177 
178  // inherited methods
179  bool check_order(user_interaction & dialog, const path & current_path, bool & initial_warn) const;
180  void finalize(const archive_num & archive, const infinint & deleted_date, const archive_num & ignore_archives_greater_or_equal);
181  bool remove_all_from(const archive_num & archive_to_remove, const archive_num & last_archive);
182 
184  void show(user_interaction & dialog, archive_num num, std::string marge = "") const;
185  void apply_permutation(archive_num src, archive_num dst);
186  void skip_out(archive_num num);
187  void compute_most_recent_stats(std::vector<infinint> & data, std::vector<infinint> & ea,
188  std::vector<infinint> & total_data, std::vector<infinint> & total_ea) const;
189 
190  char obj_signature() const { return signature(); };
191  static char signature() { return 'd'; };
192 
193 #ifdef LIBDAR_SPECIAL_ALLOC
194  USE_SPECIAL_ALLOC(data_dir);
195 #endif
196  private:
197  std::list<data_tree *> rejetons; //< subdir and subfiles of the current dir
198 
199  void add_child(data_tree *fils); //< "this" is now responsible of "fils" disalocation
200  void remove_child(const std::string & name);
201  data_tree *find_or_addition(const std::string & name, bool is_dir, const archive_num & archive);
202  };
203 
204  extern data_dir *data_tree_read(generic_file & f, unsigned char db_version);
205 
207 
212  extern bool data_tree_find(path chemin, const data_dir & racine, const data_tree *& ptr);
213  extern void data_tree_update_with(const directory *dir, archive_num archive, data_dir *racine);
214  extern archive_num data_tree_permutation(archive_num src, archive_num dst, archive_num x);
215 
217 
218 } // end of namespace
219 
220 #endif