aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/tarfile.cc
diff options
context:
space:
mode:
authorYorick van Pelt <yorick@yorickvanpelt.nl>2019-12-10 15:47:38 +0700
committerLars Jellema <lars.jellema@gmail.com>2021-03-10 22:34:29 +0100
commit8a0c00b85600991cdb9aa05902defec6ac44b777 (patch)
tree79ec2c00b1c0131abbdb8d9e433274d51d8a5e95 /src/libutil/tarfile.cc
parentb19aec7eeb8353be6c59b2967a511a5072612d99 (diff)
Use libarchive for all compression
Diffstat (limited to 'src/libutil/tarfile.cc')
-rw-r--r--src/libutil/tarfile.cc104
1 files changed, 47 insertions, 57 deletions
diff --git a/src/libutil/tarfile.cc b/src/libutil/tarfile.cc
index 2da169ba7..b5e1cb4c0 100644
--- a/src/libutil/tarfile.cc
+++ b/src/libutil/tarfile.cc
@@ -2,83 +2,73 @@
#include <archive_entry.h>
#include "serialise.hh"
+#include "tarfile.hh"
namespace nix {
+static int callback_open(struct archive *, void *self) {
+ return ARCHIVE_OK;
+}
+
+static ssize_t callback_read(struct archive * archive, void * _self, const void * * buffer) {
+ TarArchive *self = (TarArchive *)_self;
+ *buffer = self->buffer.data();
-struct TarArchive {
- struct archive * archive;
- Source * source;
- std::vector<unsigned char> buffer;
+ try {
+ return self->source->read((char *) self->buffer.data(), 4096);
+ } catch (EndOfFile &) {
+ return 0;
+ } catch (std::exception &err) {
+ archive_set_error(archive, EIO, "Source threw exception: %s", err.what());
+
+ return -1;
+ }
+}
+
+static int callback_close(struct archive *, void *self) {
+ return ARCHIVE_OK;
+}
- void check(int err, const char * reason = "failed to extract archive: %s")
- {
+void TarArchive::check(int err, const char *reason)
+{
if (err == ARCHIVE_EOF)
throw EndOfFile("reached end of archive");
else if (err != ARCHIVE_OK)
throw Error(reason, archive_error_string(this->archive));
}
- TarArchive(Source & source) : buffer(4096)
- {
- this->archive = archive_read_new();
- this->source = &source;
+TarArchive::TarArchive(Source& source, bool raw) : buffer(4096)
+{
+ this->archive = archive_read_new();
+ this->source = &source;
+ if (!raw) {
archive_read_support_filter_all(archive);
archive_read_support_format_all(archive);
- check(archive_read_open(archive,
- (void *)this,
- TarArchive::callback_open,
- TarArchive::callback_read,
- TarArchive::callback_close),
- "failed to open archive: %s");
- }
-
- TarArchive(const Path & path)
- {
- this->archive = archive_read_new();
-
+ } else {
archive_read_support_filter_all(archive);
- archive_read_support_format_all(archive);
- check(archive_read_open_filename(archive, path.c_str(), 16384), "failed to open archive: %s");
- }
-
- TarArchive(const TarArchive &) = delete;
-
- void close()
- {
- check(archive_read_close(archive), "failed to close archive: %s");
+ archive_read_support_format_raw(archive);
+ archive_read_support_format_empty(archive);
}
+ check(archive_read_open(archive, (void *)this, callback_open, callback_read, callback_close), "Failed to open archive (%s)");
+}
- ~TarArchive()
- {
- if (this->archive) archive_read_free(this->archive);
- }
-private:
+TarArchive::TarArchive(const Path &path)
+{
+ this->archive = archive_read_new();
- static int callback_open(struct archive *, void * self) {
- return ARCHIVE_OK;
- }
+ archive_read_support_filter_all(archive);
+ archive_read_support_format_all(archive);
+ check(archive_read_open_filename(archive, path.c_str(), 16384), "failed to open archive: %s");
+}
- static ssize_t callback_read(struct archive * archive, void * _self, const void * * buffer)
- {
- auto self = (TarArchive *)_self;
- *buffer = self->buffer.data();
-
- try {
- return self->source->read((char *) self->buffer.data(), 4096);
- } catch (EndOfFile &) {
- return 0;
- } catch (std::exception & err) {
- archive_set_error(archive, EIO, "source threw exception: %s", err.what());
- return -1;
- }
- }
+void TarArchive::close() {
+ check(archive_read_close(this->archive), "Failed to close archive (%s)");
+}
- static int callback_close(struct archive *, void * self) {
- return ARCHIVE_OK;
- }
-};
+TarArchive::~TarArchive() {
+ if (this->archive) archive_read_free(this->archive);
+}
static void extract_archive(TarArchive & archive, const Path & destDir)
{