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