| Disk ARchive 2.8.3 Full featured and portable backup and archiving tool

Loading...
Searching...
No Matches
i_archive.hpp
Go to the documentation of this file.
1/*********************************************************************/
2// dar - disk archive - a backup/restoration program
3// Copyright (C) 2002-2026 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18//
19// to contact the author, see the AUTHOR file
20/*********************************************************************/
21
25
26
27#ifndef I_ARCHIVE_HPP
28#define I_ARCHIVE_HPP
29
30#include "../my_config.h"
31#include <vector>
32#include <string>
33#include <memory>
34
35#include "erreurs.hpp"
36#include "path.hpp"
37#include "statistics.hpp"
38#include "archive_options.hpp"
39#include "pile.hpp"
40#include "list_entry.hpp"
41#include "crypto.hpp"
42#include "slice_layout.hpp"
43#include "mem_ui.hpp"
44#include "archive_summary.hpp"
45#include "archive_listing_callback.hpp"
46#include "catalogue.hpp"
47#include "archive.hpp"
48#include "header_version.hpp"
49
50 namespace libdar
51{
52
55
57
58 class archive::i_archive: public mem_ui
59 {
60 public:
61
63
64 i_archive(const std::shared_ptr<user_interaction> & dialog,
65 const path & chem,
66 const std::string & basename,
67 const std::string & extension,
68 const archive_options_read & options);
69
70
72
73 i_archive(const std::shared_ptr<user_interaction> & dialog,
74 const path & fs_root,
75 const path & sauv_path,
76 const std::string & filename,
77 const std::string & extension,
78 const archive_options_create & options,
79 statistics * progressive_report);
80
82
83 i_archive(const std::shared_ptr<user_interaction> & dialog,
84 const path & sauv_path,
85 std::shared_ptr<archive> ref_arch1,
86 const std::string & filename,
87 const std::string & extension,
88 const archive_options_merge & options,
89 statistics * progressive_report);
90
92
93 i_archive(const std::shared_ptr<user_interaction> & dialog,
94 const path & chem_src,
95 const std::string & basename_src,
96 const std::string & extension_src,
97 const archive_options_read & options_read,
98 const path & chem_dst,
99 const std::string & basename_dst,
100 const std::string & extension_dst,
101 const archive_options_repair & options_repair,
102 statistics * progressive_report);
103
105
106 i_archive(const i_archive & ref) = delete;
107 i_archive(i_archive && ref) = delete;
108 i_archive & operator = (const i_archive & ref) = delete;
109 i_archive & operator = (i_archive && ref) = delete;
110
112
113 ~i_archive() { free_mem(); };
114
115
117
118 statistics op_extract(const path &fs_root,
119 const archive_options_extract & options,
120 statistics *progressive_report);
121
123
124 void summary();
125
127 archive_summary summary_data();
128
129
131
132 void op_listing(archive_listing_callback callback,
133 void *context,
134 const archive_options_listing & options) const;
135
137
138 statistics op_diff(const path & fs_root,
139 const archive_options_diff & options,
140 statistics * progressive_report);
141
142
144
145 statistics op_test(const archive_options_test & options,
146 bool reparing,
147 statistics * progressive_report
148 );
149
150
152
153 void op_isolate(const path &sauv_path,
154 const std::string & filename,
155 const std::string & extension,
156 const archive_options_isolate & options);
157
158
160
161 bool get_children_of(archive_listing_callback callback,
162 void *context,
163 const std::string & dir,
164 bool fetch_ea = false);
165
167
168 const std::vector<list_entry> get_children_in_table(const std::string & dir, bool fetch_ea = false) const;
169
171 bool has_subdirectory(const std::string & dir) const;
172
174 const entree_stats get_stats() const { if(cat == nullptr) throw SRC_BUG; return cat->get_stats(); };
175
177 const std::list<signator> & get_signatories() const { return gnupg_signed; };
178
181 void init_catalogue() const;
182
184
185 const catalogue & get_catalogue() const;
186
188
189 void drop_all_filedescriptors(bool repairing);
190
192 void set_to_unsaved_data_and_FSA() { if(cat == nullptr) throw SRC_BUG; cat->set_to_unsaved_data_and_FSA(); };
193
195
196 bool get_catalogue_slice_layout(slice_layout & slicing) const;
197
199
200 U_64 get_first_slice_header_size() const;
201
203
204 U_64 get_non_first_slice_header_size() const;
205
206
207 private:
208 enum operation { oper_create, oper_isolate, oper_merge, oper_repair };
209
210 pile stack;
211 header_version ver;
212 catalogue *cat;
213 infinint local_cat_size;
214 bool exploitable;
215 bool lax_read_mode;
216 bool sequential_read;
217 std::list<signator> gnupg_signed;
218 slice_layout slices;
219
220 void free_mem();
221 void check_gnupg_signed() const;
222
223 const catalogue & get_cat() const { if(cat == nullptr) throw SRC_BUG; else return *cat; };
224 const header_version & get_header() const { return ver; };
225
226 bool get_sar_param(infinint & sub_file_size,
227 infinint & first_file_size,
228 infinint & last_file_size,
229 infinint & total_file_number);
230 std::shared_ptr<entrepot> get_entrepot();
231 infinint get_level2_size();
232 infinint get_cat_size() const { return local_cat_size; };
233
234 statistics op_create_in(operation op,
235 const path & fs_root,
236 const std::shared_ptr<entrepot> & sauv_path_t,
237 archive *ref_arch,
238 const mask & selection,
239 const mask & subtree,
240 const std::string & filename,
241 const std::string & extension,
242 bool allow_over,
243 bool warn_over,
244 bool info_details,
245 bool display_treated,
246 bool display_treated_only_dir,
247 bool display_skipped,
248 bool display_finished,
249 const infinint & pause,
250 bool empty_dir,
251 compression algo,
252 U_I compression_level,
253 U_I compression_block_size,
254 const infinint & file_size,
255 const infinint & first_file_size,
256 const mask & ea_mask,
257 const std::string & execute,
258 crypto_algo crypto,
259 const secu_string & pass,
260 U_32 crypto_size,
261 const std::vector<std::string> & gnupg_recipients,
262 const std::vector<std::string> & gnupg_signatories,
263 const mask & compr_mask,
264 const infinint & min_compr_size,
265 bool nodump,
266 const std::string & exclude_by_ea,
267 const infinint & hourshift,
268 bool empty,
269 bool alter_atime,
270 bool furtive_read_mode,
271 const filesystem_ids & same_fs,
272 comparison_fields what_to_check,
273 bool snapshot,
274 bool cache_directory_tagging,
275 const infinint & fixed_date,
276 const std::string & slice_permission,
277 const infinint & repeat_count,
278 const infinint & repeat_byte,
279 bool add_marks_for_sequential_reading,
280 bool security_check,
281 const infinint & sparse_file_min_size,
282 const std::string & user_comment,
283 hash_algo hash,
284 const infinint & slice_min_digits,
285 const std::string & backup_hook_file_execute,
286 const mask & backup_hook_file_mask,
287 bool ignore_unknown,
288 const fsa_scope & scope,
289 U_I multi_threaded_crypto,
290 U_I multi_threaded_compress,
291 bool delta_signature,
292 bool build_delta_sig,
293 const mask & delta_mask,
294 const infinint & delta_sig_min_size,
295 bool delta_diff,
296 bool zeroing_neg_date,
297 const std::set<std::string> & ignored_symlinks,
298 modified_data_detection mod_data_detect,
299 const infinint & iteration_count,
300 hash_algo kdf_hash,
301 const delta_sig_block_size & sig_block_len,
302 bool never_resave_uncompressed,
303 statistics * progressive_report);
304
305 void op_create_in_sub(operation op,
306 const path & fs_root,
307 const std::shared_ptr<entrepot> & sauv_path_t,
308 catalogue * ref_cat1,
309 const catalogue * ref_cat2,
310 bool initial_pause,
311 const mask & selection,
312 const mask & subtree,
313 const std::string & filename,
314 const std::string & extension,
315 bool allow_over,
316 const crit_action & overwrite,
317 bool warn_over,
318 bool info_details,
319 bool display_treated,
320 bool display_treated_only_dir,
321 bool display_skipped,
322 bool display_finished,
323 const infinint & pause,
324 bool empty_dir,
325 compression algo,
326 U_I compression_level,
327 U_I compression_block_size,
328 const infinint & file_size,
329 const infinint & first_file_size,
330 const mask & ea_mask,
331 const std::string & execute,
332 crypto_algo crypto,
333 const secu_string & pass,
334 U_32 crypto_size,
335 const std::vector<std::string> & gnupg_recipients,
336 const std::vector<std::string> & gnupg_signatories,
337 const mask & compr_mask,
338 const infinint & min_compr_size,
339 bool nodump,
340 const std::string & exclude_by_ea,
341 const infinint & hourshift,
342 bool empty,
343 bool alter_atime,
344 bool furtive_read_mode,
345 const filesystem_ids & same_fs,
346 comparison_fields what_to_check,
347 bool snapshot,
348 bool cache_directory_tagging,
349 bool keep_compressed,
350 const infinint & fixed_date,
351 const std::string & slice_permission,
352 const infinint & repeat_count,
353 const infinint & repeat_byte,
354 bool decremental,
355 bool add_marks_for_sequential_reading,
356 bool security_check,
357 const infinint & sparse_file_min_size,
358 const std::string & user_comment,
359 hash_algo hash,
360 const infinint & slice_min_digits,
361 const std::string & backup_hook_file_execute,
362 const mask & backup_hook_file_mask,
363 bool ignore_unknown,
364 const fsa_scope & scope,
365 U_I multi_threaded_crypto,
366 U_I multi_threaded_compress,
367 bool delta_signature,
368 bool build_delta_sig,
369 const mask & delta_mask,
370 const infinint & delta_sig_min_size,
371 bool delta_diff,
372 bool zeroing_neg_date,
373 const std::set<std::string> & ignored_symlinks,
374 modified_data_detection mod_data_detect,
375 const infinint & iteration_count,
376 hash_algo kdf_hash,
377 const delta_sig_block_size & sign_block_len,
378 bool never_resave_uncompressed,
379 statistics * st_ptr
380 );
381
382 void disable_natural_destruction();
383 void enable_natural_destruction();
384 const label & get_layer1_data_name() const;
385 const label & get_catalogue_data_name() const;
386 bool only_contains_an_isolated_catalogue() const;
387 void check_against_isolation(bool lax) const;
388 const cat_directory *get_dir_object(const std::string & dir) const;
389 void load_catalogue(bool repairing);
390 };
391
392} // end of namespace
393
394#endif
catalogue.hpp
here is defined the classe used to manage catalogue of archives
libdar::archive::i_archive
the archive::i_archive class implements the most general operations on archives
Definition i_archive.hpp:59
libdar::archive_options_create
class holding optional parameters used to create an archive
Definition dar64-2.8.3-win64/include/dar/archive_options.hpp:305
libdar::archive_options_extract
class holding optional parameters used to extract files from an existing archive
Definition dar64-2.8.3-win64/include/dar/archive_options.hpp:1351
libdar::archive_options_isolate
class holding optional parameters used to isolate an existing archive
Definition dar64-2.8.3-win64/include/dar/archive_options.hpp:781
libdar::archive_options_listing
class holding optional parameters used to list the contents of an existing archive
Definition dar64-2.8.3-win64/include/dar/archive_options.hpp:1514
libdar::archive_options_merge
class holding optional parameters used to proceed to the merge operation
Definition dar64-2.8.3-win64/include/dar/archive_options.hpp:1024
libdar::archive_options_read
class holding optional parameters used to read an existing archive
Definition dar64-2.8.3-win64/include/dar/archive_options.hpp:70
libdar::archive_options_repair
class holding optional parameters used to create an archive
Definition dar64-2.8.3-win64/include/dar/archive_options.hpp:1821
libdar::archive_options_test
class holding optional parameters used to test the structure coherence of an existing archive
Definition dar64-2.8.3-win64/include/dar/archive_options.hpp:1738
libdar::archive_summary
the archive_summary class provides information about a given archive
Definition dar64-2.8.3-win64/include/dar/archive_summary.hpp:45
libdar::cat_directory
the cat_directory inode class
Definition cat_directory.hpp:52
libdar::catalogue
the catalogue class which gather all objects contained in a give archive
Definition catalogue.hpp:60
libdar::crit_action
the global action for overwriting
Definition dar64-2.8.3-win64/include/dar/crit_action.hpp:81
libdar::header_version
manages the archive header and trailer
Definition header_version.hpp:48
libdar::infinint
the arbitrary large positive integer class
Definition dar64-2.8.3-win64/include/dar/real_infinint.hpp:62
libdar::label
manage label data structure used in archive slice headers
Definition label.hpp:43
libdar::mask
the generic class, parent of all masks
Definition dar64-2.8.3-win64/include/dar/mask.hpp:62
libdar::mem_ui::mem_ui
mem_ui(const std::shared_ptr< user_interaction > &dialog)
constructor
libdar::path
the class path is here to manipulate paths in the Unix notation: using'/'
Definition dar64-2.8.3-win64/include/dar/path.hpp:51
libdar::pile
stores a stack of generic_files writing/reading on each others
Definition pile.hpp:44
libdar::secu_string
class secu_string
Definition dar64-2.8.3-win64/include/dar/secu_string.hpp:54
libdar::statistics
class used by libdar::archive class to give a summary of treated file during and after an operation
Definition dar64-2.8.3-win64/include/dar/statistics.hpp:70
libdar::modified_data_detection
modified_data_detection
how to detect data has changed when some fields
Definition dar64-2.8.3-win64/include/dar/archive_aux.hpp:44
libdar::comparison_fields
comparison_fields
how to consider file change during comparison and incremental backup
Definition dar64-2.8.3-win64/include/dar/archive_aux.hpp:53
libdar::archive::i_archive::get_catalogue
const catalogue & get_catalogue() const
gives access to internal catalogue (not to be used from the API)
libdar::archive::i_archive::cat
catalogue * cat
archive contents
Definition i_archive.hpp:212
libdar::archive::i_archive::i_archive
i_archive(const std::shared_ptr< user_interaction > &dialog, const path &sauv_path, std::shared_ptr< archive > ref_arch1, const std::string &filename, const std::string &extension, const archive_options_merge &options, statistics *progressive_report)
this constructor builds an archive from two given archive [this is the "merge" constructor]
libdar::archive::i_archive::only_contains_an_isolated_catalogue
bool only_contains_an_isolated_catalogue() const
true if the current archive only contains an isolated catalogue
libdar::archive_listing_callback
void(*)(const std::string &the_path, const list_entry &entry, void *context) archive_listing_callback
callback function type expected for archive::op_listing and archive::get_children_of()
Definition dar64-2.8.3-win64/include/dar/archive_listing_callback.hpp:40
libdar::archive::i_archive::ver
header_version ver
information for the archive header
Definition i_archive.hpp:211
libdar::archive::i_archive::stack
pile stack
the different layer through which the archive contents is read or wrote
Definition i_archive.hpp:210
libdar::archive::i_archive::i_archive
i_archive(const std::shared_ptr< user_interaction > &dialog, const path &fs_root, const path &sauv_path, const std::string &filename, const std::string &extension, const archive_options_create &options, statistics *progressive_report)
this constuctor create an archive (full or differential) [this is the "create" constructor]
libdar::archive::i_archive::exploitable
bool exploitable
is false if only the catalogue is available (for reference backup or isolation).
Definition i_archive.hpp:214
libdar::archive::i_archive::op_diff
statistics op_diff(const path &fs_root, const archive_options_diff &options, statistics *progressive_report)
archive comparison with filesystem
libdar::archive::i_archive::get_first_slice_header_size
U_64 get_first_slice_header_size() const
get the first slice header
libdar::archive::i_archive::i_archive
i_archive(const std::shared_ptr< user_interaction > &dialog, const path &chem, const std::string &basename, const std::string &extension, const archive_options_read &options)
this constructor opens an already existing archive (for reading) [this is the "read" constructor]
libdar::archive::i_archive::set_to_unsaved_data_and_FSA
void set_to_unsaved_data_and_FSA()
change all inode as unsaved (equal to differential backup with no change met)
Definition i_archive.hpp:192
libdar::archive::i_archive::sequential_read
bool sequential_read
whether the archive is read in sequential mode
Definition i_archive.hpp:216
libdar::fsa_scope
std::set< fsa_family > fsa_scope
set of fsa families
Definition dar64-2.8.3-win64/include/dar/fsa_family.hpp:70
libdar::archive::i_archive::drop_all_filedescriptors
void drop_all_filedescriptors(bool repairing)
closes all filedescriptors and associated even when in sequential read mode
libdar::archive::i_archive::op_isolate
void op_isolate(const path &sauv_path, const std::string &filename, const std::string &extension, const archive_options_isolate &options)
this methodes isolates the catalogue of a the current archive into a separated archive
libdar::archive::i_archive::get_signatories
const std::list< signator > & get_signatories() const
retrieving signature information about the archive
Definition i_archive.hpp:177
libdar::archive::i_archive::op_listing
void op_listing(archive_listing_callback callback, void *context, const archive_options_listing &options) const
listing of the archive contents
libdar::archive::i_archive::summary
void summary()
display a summary of the archive
libdar::hash_algo
hash_algo
hashing algorithm available
Definition dar64-2.8.3-win64/include/dar/archive_aux.hpp:63
libdar::archive::i_archive::get_catalogue_slice_layout
bool get_catalogue_slice_layout(slice_layout &slicing) const
returns the slice layout of the archive, or of the archive of reference in case of isolated catalogue
libdar::archive::i_archive::get_stats
const entree_stats get_stats() const
retrieving statistics about archive contents
Definition i_archive.hpp:174
libdar::archive::i_archive::lax_read_mode
bool lax_read_mode
whether the archive has been openned in lax mode (unused for creation/merging/isolation)
Definition i_archive.hpp:215
libdar::archive::i_archive::i_archive
i_archive(const i_archive &ref)=delete
copy constructor (not implemented, throw an exception if called explicitely or implicitely)
libdar::archive::i_archive::get_non_first_slice_header_size
U_64 get_non_first_slice_header_size() const
get the non first slice header
libdar::archive::i_archive::init_catalogue
void init_catalogue() const
libdar::archive::i_archive::check_against_isolation
void check_against_isolation(bool lax) const
throw Erange exception if the archive only contains an isolated catalogue
libdar::archive::i_archive::summary_data
archive_summary summary_data()
same information as summary() but as broken out data
libdar::compression
compression
the different compression algorithm available
Definition dar64-2.8.3-win64/include/dar/compression.hpp:46
libdar::archive::i_archive::get_children_in_table
const std::vector< list_entry > get_children_in_table(const std::string &dir, bool fetch_ea=false) const
getting information about the given directory (alternative to get_children_of)
libdar::archive::i_archive::op_extract
statistics op_extract(const path &fs_root, const archive_options_extract &options, statistics *progressive_report)
extraction of data from an archive
libdar::archive::i_archive::~i_archive
~i_archive()
the destructor
Definition i_archive.hpp:113
libdar::archive::i_archive::i_archive
i_archive(const std::shared_ptr< user_interaction > &dialog, const path &chem_src, const std::string &basename_src, const std::string &extension_src, const archive_options_read &options_read, const path &chem_dst, const std::string &basename_dst, const std::string &extension_dst, const archive_options_repair &options_repair, statistics *progressive_report)
this constructor create a new archive from a damaged one [this is the "repair" constructor]
libdar::crypto_algo
crypto_algo
the different cypher available for encryption (strong or weak)
Definition dar64-2.8.3-win64/include/dar/crypto.hpp:50
libdar::archive::archive
archive(const std::shared_ptr< user_interaction > &dialog, const path &chem, const std::string &basename, const std::string &extension, const archive_options_read &options)
this constructor opens an already existing archive (for reading) [this is the "read" constructor]
libdar::archive::i_archive::op_test
statistics op_test(const archive_options_test &options, bool reparing, statistics *progressive_report)
test the archive integrity
libdar::archive::i_archive::slices
slice_layout slices
slice layout, archive is not sliced <=> first_size or other_size fields are set to zero (in practice ...
Definition i_archive.hpp:218
libdar::archive::i_archive::gnupg_signed
std::list< signator > gnupg_signed
list of signature found in the archive (reading an existing archive)
Definition i_archive.hpp:217
libdar::archive::i_archive::local_cat_size
infinint local_cat_size
size of the catalogue on disk
Definition i_archive.hpp:213
libdar::archive::i_archive::get_entrepot
std::shared_ptr< entrepot > get_entrepot()
this method may return nullptr if no entrepot is used (pipes used for archive building,...
libdar::archive::i_archive::get_children_of
bool get_children_of(archive_listing_callback callback, void *context, const std::string &dir, bool fetch_ea=false)
getting information about a given directory
libdar::archive::i_archive::op_create_in_sub
void op_create_in_sub(operation op, const path &fs_root, const std::shared_ptr< entrepot > &sauv_path_t, catalogue *ref_cat1, const catalogue *ref_cat2, bool initial_pause, const mask &selection, const mask &subtree, const std::string &filename, const std::string &extension, bool allow_over, const crit_action &overwrite, bool warn_over, bool info_details, bool display_treated, bool display_treated_only_dir, bool display_skipped, bool display_finished, const infinint &pause, bool empty_dir, compression algo, U_I compression_level, U_I compression_block_size, const infinint &file_size, const infinint &first_file_size, const mask &ea_mask, const std::string &execute, crypto_algo crypto, const secu_string &pass, U_32 crypto_size, const std::vector< std::string > &gnupg_recipients, const std::vector< std::string > &gnupg_signatories, const mask &compr_mask, const infinint &min_compr_size, bool nodump, const std::string &exclude_by_ea, const infinint &hourshift, bool empty, bool alter_atime, bool furtive_read_mode, const filesystem_ids &same_fs, comparison_fields what_to_check, bool snapshot, bool cache_directory_tagging, bool keep_compressed, const infinint &fixed_date, const std::string &slice_permission, const infinint &repeat_count, const infinint &repeat_byte, bool decremental, bool add_marks_for_sequential_reading, bool security_check, const infinint &sparse_file_min_size, const std::string &user_comment, hash_algo hash, const infinint &slice_min_digits, const std::string &backup_hook_file_execute, const mask &backup_hook_file_mask, bool ignore_unknown, const fsa_scope &scope, U_I multi_threaded_crypto, U_I multi_threaded_compress, bool delta_signature, bool build_delta_sig, const mask &delta_mask, const infinint &delta_sig_min_size, bool delta_diff, bool zeroing_neg_date, const std::set< std::string > &ignored_symlinks, modified_data_detection mod_data_detect, const infinint &iteration_count, hash_algo kdf_hash, const delta_sig_block_size &sign_block_len, bool never_resave_uncompressed, statistics *st_ptr)
libdar::archive::i_archive::has_subdirectory
bool has_subdirectory(const std::string &dir) const
returns true if the pointed directory has one or more subdirectories
header_version.hpp
archive global header/trailer structure is defined here
my_config.h
include macro defined by the configure script and some specific additional ones
libdar
libdar namespace encapsulate all libdar symbols
Definition dar64-2.8.3-win64/include/dar/archive.hpp:47
pile.hpp
class pile definition. Used to manage a stack of generic_file objects
slice_layout.hpp
object describing the slicing of an archive
archive.hpp
the archive class is defined in this module
archive_listing_callback.hpp
definition of the user defined callback function used for archive listing
archive_options.hpp
this file contains a set of classes used to transmit options to archive operation
archive_summary.hpp
datastructure returned by archive::summary_data
crypto.hpp
the crypto algoritm definition
erreurs.hpp
contains all the excetion class thrown by libdar
list_entry.hpp
class of objects describing an entry in the archive, used by archive::get_children_in_table
mem_ui.hpp
class mem_ui definition. This class is to be used as parent class to handle user_interaction object m...
path.hpp
here is the definition of the path class
statistics.hpp
class handling access to the data summary of treated files after and during each operation
libdar::delta_sig_block_size
defines how to calculate delta signature block size based of file size to delta sign
Definition dar64-2.8.3-win64/include/dar/delta_sig_block_size.hpp:50
libdar::entree_stats
holds the statistics contents of a catalogue
Definition dar64-2.8.3-win64/include/dar/entree_stats.hpp:49