This commit is contained in:
parent
12afa628d0
commit
24f1407ed9
1 changed files with 49 additions and 19 deletions
|
@ -20,6 +20,8 @@ static int copy_data(shared_ptr<archive> reader, shared_ptr<archive> writer);
|
||||||
|
|
||||||
void LibArchiver::compress(set<fs::path> ins, fs::path archive_out) {
|
void LibArchiver::compress(set<fs::path> ins, fs::path archive_out) {
|
||||||
spdlog::debug("Compressing to {}", archive_out);
|
spdlog::debug("Compressing to {}", archive_out);
|
||||||
|
int r; // libarchive error handling
|
||||||
|
static char buff[16384]; // read buffer
|
||||||
|
|
||||||
// cannot use unique_ptr here since unique_ptr requires a
|
// cannot use unique_ptr here since unique_ptr requires a
|
||||||
// complete type. `archive` is forward declared only.
|
// complete type. `archive` is forward declared only.
|
||||||
|
@ -29,25 +31,51 @@ void LibArchiver::compress(set<fs::path> ins, fs::path archive_out) {
|
||||||
archive_write_set_format_pax_restricted(writer.get());
|
archive_write_set_format_pax_restricted(writer.get());
|
||||||
archive_write_open_filename(writer.get(), archive_out.c_str());
|
archive_write_open_filename(writer.get(), archive_out.c_str());
|
||||||
|
|
||||||
archive_entry *entry = archive_entry_new();
|
shared_ptr<archive> reader;
|
||||||
char buff[8192];
|
reader = shared_ptr<archive>(archive_read_disk_new(), archive_read_free);
|
||||||
|
archive_read_disk_set_standard_lookup(reader.get());
|
||||||
|
|
||||||
for(auto path: ins) {
|
shared_ptr<archive_entry> entry = shared_ptr<archive_entry>(archive_entry_new(), archive_entry_free);
|
||||||
archive_entry_set_pathname(entry, path.c_str());
|
|
||||||
archive_entry_set_size(entry, fs::file_size(path));
|
|
||||||
archive_entry_set_filetype(entry, AE_IFREG);
|
|
||||||
archive_entry_set_perm(entry, 0644);
|
|
||||||
archive_write_header(writer.get(), entry);
|
|
||||||
|
|
||||||
int fd = open(path.c_str(), O_RDONLY);
|
for (auto in : ins) {
|
||||||
int len = read(fd, buff, sizeof(buff));
|
spdlog::debug("Compressing {}", in);
|
||||||
|
|
||||||
|
r = archive_read_disk_open(reader.get(), in.c_str());
|
||||||
|
if (r != ARCHIVE_OK) {
|
||||||
|
throw XwimError{"Failed opening {}. {}", in,
|
||||||
|
archive_error_string(reader.get())};
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
r = archive_read_next_header2(reader.get(), entry.get());
|
||||||
|
|
||||||
|
if (r == ARCHIVE_EOF) break;
|
||||||
|
|
||||||
|
if (r != ARCHIVE_OK) {
|
||||||
|
throw XwimError{"Failed compressing archive entry. {}",
|
||||||
|
archive_error_string(reader.get())};
|
||||||
|
}
|
||||||
|
|
||||||
|
spdlog::debug("Compressing entry {}", archive_entry_pathname(entry.get()));
|
||||||
|
r = archive_write_header(writer.get(), entry.get());
|
||||||
|
if (r != ARCHIVE_OK) {
|
||||||
|
throw XwimError{"Failed writing archive entry. {}",
|
||||||
|
archive_error_string(writer.get())};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For now, we use a simpler loop to copy data
|
||||||
|
* into the target archive. */
|
||||||
|
int fd = open(archive_entry_sourcepath(entry.get()), O_RDONLY);
|
||||||
|
ssize_t len = read(fd, buff, sizeof(buff));
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
archive_write_data(writer.get(), buff, len);
|
archive_write_data(writer.get(), buff, len);
|
||||||
len = read(fd, buff, sizeof(buff));
|
len = read(fd, buff, sizeof(buff));
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
archive_entry_clear(entry);
|
|
||||||
|
archive_entry_clear(entry.get());
|
||||||
|
archive_read_disk_descend(reader.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,18 +103,20 @@ void LibArchiver::extract(fs::path archive_in, fs::path out) {
|
||||||
fs::path cur_path = fs::current_path();
|
fs::path cur_path = fs::current_path();
|
||||||
fs::current_path(out);
|
fs::current_path(out);
|
||||||
|
|
||||||
archive_entry* entry;
|
archive_entry *entry;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
r = archive_read_next_header(reader.get(), &entry);
|
r = archive_read_next_header(reader.get(), &entry);
|
||||||
if (r == ARCHIVE_EOF) break;
|
if (r == ARCHIVE_EOF) break;
|
||||||
|
|
||||||
if (r != ARCHIVE_OK) {
|
if (r != ARCHIVE_OK) {
|
||||||
throw XwimError{"Failed extracting archive entry. {}", archive_error_string(reader.get())};
|
throw XwimError{"Failed extracting archive entry. {}",
|
||||||
|
archive_error_string(reader.get())};
|
||||||
}
|
}
|
||||||
|
|
||||||
r = archive_write_header(writer.get(), entry);
|
r = archive_write_header(writer.get(), entry);
|
||||||
if (r != ARCHIVE_OK) {
|
if (r != ARCHIVE_OK) {
|
||||||
throw XwimError{"Failed writing archive entry header. {}", archive_error_string(writer.get())};
|
throw XwimError{"Failed writing archive entry header. {}",
|
||||||
|
archive_error_string(writer.get())};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (archive_entry_size(entry) > 0) {
|
if (archive_entry_size(entry) > 0) {
|
||||||
|
|
Loading…
Reference in a new issue