Disk ARchive  2.4.8
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
filesystem.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 
31 
32 #ifndef FILESYSTEM_HPP
33 #define FILESYSTEM_HPP
34 
35 #include "../my_config.h"
36 
37 extern "C"
38 {
39 #if HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif
42 
43 #if HAVE_SYS_STAT_H
44 #include <sys/stat.h>
45 #endif
46 } // end extern "C"
47 
48 #include <map>
49 #include <vector>
50 #include "catalogue.hpp"
51 #include "infinint.hpp"
52 #include "etage.hpp"
53 #include "criterium.hpp"
54 
55 namespace libdar
56 {
59 
61 
62  class filesystem_hard_link_read : virtual protected mem_ui
63  {
64  // this class is not to be used directly
65  // it only provides some routine for the inherited classes
66 
67  public:
69  bool x_furtive_read_mode) : mem_ui(dialog) { furtive_read_mode = x_furtive_read_mode; };
70 
71  // the copy of the current object would make copy of addresses in
72  // corres_read that could be released twice ... thus, copy constructor and
73  // assignement are forbidden for this class:
74 
75  filesystem_hard_link_read(const filesystem_hard_link_read & ref) : mem_ui(ref.get_ui()) { throw SRC_BUG; };
76  const filesystem_hard_link_read & operator = (const filesystem_hard_link_read & ref) { throw SRC_BUG; };
77 
78  // get the last assigned number for a hard linked inode
79  const infinint & get_last_etoile_ref() const { return etiquette_counter; };
80 
81  virtual ~filesystem_hard_link_read() {};
82 
83  protected:
84  // reset the whole list of hard linked inodes (hard linked inode stay alive but are no more referenced by the current object)
85  void corres_reset() { corres_read.clear(); etiquette_counter = 0; };
86 
87  // create and return a libdar object corresponding to one pointed to by its path
88  // during this operation, hard linked inode are recorded in a list to be easily pointed
89  // to by a new reference to it.
90  nomme *make_read_entree(path & lieu, //< path of the file to read
91  const std::string & name, //< name of the file to read
92  bool see_hard_link, //< whether we want to detect hard_link and eventually return a mirage object (not necessary when diffing an archive with filesystem)
93  const mask & ea_mask); //< which EA to consider when creating the object
94 
95  private:
96 
97  // private datastructure
98 
99  struct couple
100  {
101  nlink_t count; //< counts the number of hard link on that inode that have not yet been found in filesystem, once this count reaches zero, the "couple" structure can be dropped and the "holder" too (no more expected hard links to be found)
102  etoile *obj; //< the address of the corresponding etoile object for that inode
103  mirage holder; //< it increments by one the obj internal counters, thus, while this object is alive, the obj will not be destroyed
104 
105  couple(etoile *ptr, nlink_t ino_count) : holder("FAKE", ptr) { count = ino_count; obj = ptr; };
106  };
107 
108  struct node
109  {
110  node(ino_t num, dev_t dev) { numnode = num; device = dev; };
111 
112  // this operator is required to use the type node in a std::map
113  bool operator < (const node & ref) const { return numnode < ref.numnode || (numnode == ref.numnode && device < ref.device); };
114  ino_t numnode;
115  dev_t device;
116  };
117 
118  // private variable
119 
120  std::map <node, couple> corres_read;
121  infinint etiquette_counter;
122  bool furtive_read_mode;
123 
124  };
125 
126 
127 
129 
131  {
132  public:
134  const path &root,
135  bool x_info_details,
136  const mask & x_ea_mask,
137  bool check_no_dump_flag,
138  bool alter_atime,
139  bool furtive_read_mode,
140  bool x_cache_directory_tagging,
141  infinint & root_fs_device,
142  bool x_ignore_unknown);
143  filesystem_backup(const filesystem_backup & ref) : mem_ui(ref.get_ui()), filesystem_hard_link_read(ref.get_ui(), ref.furtive_read_mode) { copy_from(ref); };
144  const filesystem_backup & operator = (const filesystem_backup & ref) { detruire(); copy_from(ref); return *this; };
145  ~filesystem_backup() { detruire(); };
146 
147  void reset_read(infinint & root_fs_device);
148  bool read(entree * & ref, infinint & errors, infinint & skipped_dump);
149  void skip_read_to_parent_dir();
150  // continue reading in parent directory and
151  // ignore all entry not yet read of current directory
152  private:
153 
154  path *fs_root; //< filesystem's root to consider
155  bool info_details; //< detailed information returned to the user
156  mask *ea_mask; //< mask defining the EA to consider
157  bool no_dump_check; //< whether to check against the nodump flag presence
158  bool alter_atime; //< whether to set back atime or not
159  bool furtive_read_mode; //< whether to use furtive read mode (if true, alter_atime is ignored)
160  bool cache_directory_tagging; //< whether to consider cache directory taggin standard
161  path *current_dir; //< needed to translate from an hard linked inode to an already allocated object
162  std::vector<etage> pile; //< to store the contents of a directory
163  bool ignore_unknown; //< whether to ignore unknown inode types
164 
165  void detruire();
166  void copy_from(const filesystem_backup & ref);
167  };
168 
169 
171 
173  {
174  public:
176  const path &root,
177  bool x_info_details,
178  const mask & x_ea_mask,
179  bool alter_atime,
180  bool furtive_read_mode);
181  filesystem_diff(const filesystem_diff & ref) : mem_ui(ref.get_ui()), filesystem_hard_link_read(ref.get_ui(), ref.furtive_read_mode) { copy_from(ref); };
182  const filesystem_diff & operator = (const filesystem_diff & ref) { detruire(); copy_from(ref); return *this; };
183  ~filesystem_diff() { detruire(); };
184 
185  void reset_read();
186  bool read_filename(const std::string & name, nomme * &ref);
187  // looks for a file of name given in argument, in current reading directory
188  // if this is a directory, subsequent read take place in it
189 
190  void skip_read_filename_in_parent_dir();
191  // subsequent calls to read_filename will take place in parent directory.
192 
193  private:
194  struct filename_struct
195  {
196  infinint last_acc;
197  infinint last_mod;
198  };
199 
200  path *fs_root;
201  bool info_details;
202  mask *ea_mask;
203  bool alter_atime;
204  bool furtive_read_mode;
205  path *current_dir;
206  std::vector<filename_struct> filename_pile;
207 
208  void detruire();
209  void copy_from(const filesystem_diff & ref);
210  };
211 
213 
214  class filesystem_hard_link_write : virtual protected mem_ui
215  {
216  // this class is not to be used directly
217  // it only provides routines to its inherited classes
218 
219  public:
220  filesystem_hard_link_write(user_interaction & dialog) : mem_ui(dialog) { corres_write.clear(); };
221  filesystem_hard_link_write(const filesystem_hard_link_write & ref) : mem_ui(ref) { throw SRC_BUG; };
222  const filesystem_hard_link_write & operator = (const filesystem_hard_link_write & ref) { throw SRC_BUG; };
223 
224  void write_hard_linked_target_if_not_set(const mirage *ref, const std::string & chemin);
225  // if a hard linked inode has not been restored (no change, or less recent than the one on filesystem)
226  // it is necessary to inform filesystem, where to hard link on, any future hard_link
227  // that could be necessary to restore.
228 
229  bool known_etiquette(const infinint & eti);
230  // return true if an inode in filesystem has been seen for that hard linked inode
231 
235  void clear_corres_if_pointing_to(const infinint & ligne, const std::string & path);
236 
237  protected:
238  void corres_reset() { corres_write.clear(); };
239  void make_file(const nomme * ref, //< object to restore in filesystem
240  const path & ou, //< where to restore it
241  bool dir_perm, //< false for already existing directories, this makes dar set the minimum available permission to be able to restore files in that directory at a later time
242  inode::comparison_fields what_to_check); //< defines whether to restore permission, ownership, dates, etc.
243  // generate inode or make a hard link on an already restored or existing inode.
244 
245 
247 
253  bool raw_set_ea(const nomme *e,
254  const ea_attributs & list_ea,
255  const std::string & spot,
256  const mask & ea_mask);
257  // check whether the inode for which to restore EA is not a hard link to
258  // an already restored inode. if not, it calls the proper ea_filesystem call to restore EA
259 
261 
265  bool raw_clear_ea_set(const nomme *e, const std::string & path);
266 
267 
268  private:
269  struct corres_ino_ea
270  {
271  std::string chemin;
272  bool ea_restored;
273  };
274 
275  std::map <infinint, corres_ino_ea> corres_write;
276  };
277 
278 
280 
282  {
283  public:
286  const path & root,
287  bool x_warn_overwrite,
288  bool x_info_details,
289  const mask & x_ea_mask,
290  inode::comparison_fields what_to_check,
291  bool x_warn_remove_no_match,
292  bool empty,
293  const crit_action *x_overwrite,
294  bool x_only_overwrite);
298  const filesystem_restore & operator = (const filesystem_restore & ref) { throw SRC_BUG; };
300  ~filesystem_restore() { restore_stack_dir_ownership(); detruire(); };
301 
303  void reset_write();
304 
305  typedef enum
306  {
307  done_data_restored, //< data has been restored to filesystem
308  done_no_change_no_data, //< no change in filesystem because no data present in archive
309  done_no_change_policy, //< no change in filesystem because of overwiting policy decision
310  done_data_removed //< data (= whole inode) removed from filesystem
311  } action_done_for_data;
312 
314 
322  void write(const entree *x, action_done_for_data & data_restored, bool & ea_restored, bool & data_created, bool & hard_link);
323 
324 
329  void ignore_overwrite_restrictions_for_next_write() { ignore_over_restricts = true; };
330 
331 
332  private:
333  class stack_dir_t : public directory
334  {
335  public:
336  stack_dir_t(const directory & ref, bool restore) : directory(ref) { restore_date = restore; };
337 
338  bool get_restore_date() const { return restore_date; };
339  void set_restore_date(bool val) { restore_date = val; };
340 
341  private:
342  bool restore_date;
343  };
344 
345  path *fs_root;
346  bool info_details;
347  mask *ea_mask;
348  bool warn_overwrite;
349  inode::comparison_fields what_to_check;
350  bool warn_remove_no_match;
351  std::vector<stack_dir_t> stack_dir;
352  path *current_dir;
353  bool empty;
354  bool ignore_over_restricts;
355  const crit_action *overwrite;
356  bool only_overwrite;
357 
358  void detruire();
359  void restore_stack_dir_ownership();
360 
361  // subroutines of write()
362  void action_over_remove(const inode *in_place, const detruit *to_be_added, const std::string & spot, over_action_data action);
363  void action_over_data(const inode *in_place,
364  const nomme *to_be_added,
365  const std::string & spot,
366  over_action_data action,
367  action_done_for_data & data_done);
368  bool action_over_ea(const inode *in_place, const nomme *to_be_added, const std::string & spot, over_action_ea action);
369  };
370 
372 
373 } // end of namespace
374 
375 #endif