20 #include <ripple/basics/Archive.h>
21 #include <ripple/basics/contract.h>
24 #include <archive_entry.h>
30 boost::filesystem::path
const& src,
31 boost::filesystem::path
const& dst)
33 if (!is_regular_file(src))
34 Throw<std::runtime_error>(
"Invalid source file");
38 archive_ptr ar {archive_read_new(),
44 Throw<std::runtime_error>(
"Failed to allocate archive");
46 if (archive_read_support_format_tar(ar.get()) < ARCHIVE_OK)
47 Throw<std::runtime_error>(archive_error_string(ar.get()));
49 if (archive_read_support_filter_lz4(ar.get()) < ARCHIVE_OK)
50 Throw<std::runtime_error>(archive_error_string(ar.get()));
53 if (archive_read_open_filename(
54 ar.get(), src.string().c_str(), 10240) < ARCHIVE_OK)
56 Throw<std::runtime_error>(archive_error_string(ar.get()));
59 archive_ptr aw {archive_write_disk_new(),
62 archive_write_free(a);
65 Throw<std::runtime_error>(
"Failed to allocate archive");
67 if (archive_write_disk_set_options(
69 ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_PERM |
70 ARCHIVE_EXTRACT_ACL | ARCHIVE_EXTRACT_FFLAGS) < ARCHIVE_OK)
72 Throw<std::runtime_error>(archive_error_string(aw.get()));
75 if(archive_write_disk_set_standard_lookup(aw.get()) < ARCHIVE_OK)
76 Throw<std::runtime_error>(archive_error_string(aw.get()));
79 struct archive_entry* entry;
82 result = archive_read_next_header(ar.get(), &entry);
83 if (result == ARCHIVE_EOF)
85 if (result < ARCHIVE_OK)
86 Throw<std::runtime_error>(archive_error_string(ar.get()));
88 archive_entry_set_pathname(
89 entry, (dst / archive_entry_pathname(entry)).
string().c_str());
90 if (archive_write_header(aw.get(), entry) < ARCHIVE_OK)
91 Throw<std::runtime_error>(archive_error_string(aw.get()));
93 if (archive_entry_size(entry) > 0)
100 result = archive_read_data_block(ar.get(), &buf, &sz, &offset);
101 if (result == ARCHIVE_EOF)
103 if (result < ARCHIVE_OK)
104 Throw<std::runtime_error>(archive_error_string(ar.get()));
106 if (archive_write_data_block(
107 aw.get(), buf, sz, offset) < ARCHIVE_OK)
109 Throw<std::runtime_error>(archive_error_string(aw.get()));
114 if (archive_write_finish_entry(aw.get()) < ARCHIVE_OK)
115 Throw<std::runtime_error>(archive_error_string(aw.get()));