Fix folder compression
Some checks failed
continuous-integration/drone/push Build is failing

This commit is contained in:
Armin Friedl 2021-02-21 12:02:01 +01:00
parent 12afa628d0
commit 24f1407ed9
Signed by: armin
GPG key ID: 48C726EEE7FBCBC8

View file

@ -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());
}
} }
} }
@ -81,12 +109,14 @@ void LibArchiver::extract(fs::path archive_in, fs::path out) {
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) {