int nrefs;
};
-struct payload_archive_data {
- struct archive* archive;
- char buffer[1024 * 1024];
-};
-
-static void configure_archive(struct archive* a) {
- // All of our packages are tar balls
- archive_read_support_format_tar(a);
-
- // They are compressed using XZ or ZSTD
- archive_read_support_filter_xz(a);
- archive_read_support_filter_zstd(a);
-}
-
static int archive_open(PakfireArchive archive, struct archive** a) {
*a = archive_read_new();
if (!*a)
return 1;
}
-static ssize_t payload_archive_read(struct archive* a, void* client_data, const void** buf) {
- struct payload_archive_data* data = client_data;
- *buf = data->buffer;
+static la_ssize_t pakfire_archive_read_callback(struct archive* a,
+ void* client_data, const void** buffer) {
+ struct archive* archive = (struct archive*)client_data;
- return archive_read_data(data->archive, data->buffer, sizeof(data->buffer));
-}
+ size_t len = 0;
+ off_t offset = 0;
-static int payload_archive_close(struct archive* a, void* client_data) {
- struct payload_archive_data* data = client_data;
+ // Try reading the next block (without copying it)
+ int r = archive_read_data_block(archive, buffer, &len, &offset);
- free(data);
+ switch (r) {
+ case ARCHIVE_OK:
+ return len;
+
+ // Return zero to signal that everything was read
+ case ARCHIVE_EOF:
+ return 0;
- return ARCHIVE_OK;
+ // Return -1 on any other errors
+ default:
+ return -1;
+ }
}
-static int payload_archive_open(struct archive** a, struct archive* source_archive) {
- *a = archive_read_new();
- configure_archive(*a);
+static struct archive* pakfire_archive_open_payload(PakfireArchive archive, struct archive* a) {
+ // Find the payload
+ struct archive_entry* entry;
+ int r = find_archive_entry(&entry, a, PAKFIRE_ARCHIVE_FN_PAYLOAD);
+ if (r)
+ return NULL;
- struct payload_archive_data* data = calloc(1, sizeof(*data));
- data->archive = source_archive;
+ // Allocate a new archive object
+ struct archive* payload = archive_read_new();
+ if (!payload)
+ return NULL;
- archive_read_set_callback_data(*a, data);
- archive_read_set_read_callback(*a, payload_archive_read);
- archive_read_set_close_callback(*a, payload_archive_close);
+ // All of our packages are tar balls
+ archive_read_support_format_tar(payload);
- return archive_read_open1(*a);
+ // They are compressed using XZ or ZSTD
+ archive_read_support_filter_xz(payload);
+ archive_read_support_filter_zstd(payload);
+
+ // Try opening the payload archive
+ r = archive_read_open2(payload, a, NULL, pakfire_archive_read_callback, NULL, NULL);
+ if (r) {
+ ERROR(archive->pakfire, "Could not open payload archive: %s\n",
+ archive_error_string(payload));
+ archive_read_free(payload);
+ return NULL;
+ }
+
+ return payload;
}
// Checksum Stuff
}
static int archive_extract(PakfireArchive archive, struct archive* a, const char* prefix) {
- struct archive_entry* entry;
+ if (!a)
+ return EINVAL;
+
+ struct archive_entry* entry = NULL;
int r;
PakfireFile file;
return r;
}
-static struct archive* archive_open_payload(struct archive* a) {
- struct archive_entry* entry;
- int r;
-
- r = find_archive_entry(&entry, a, PAKFIRE_ARCHIVE_FN_PAYLOAD);
- if (r)
- return NULL;
-
- struct archive* payload_archive;
- r = payload_archive_open(&payload_archive, a);
- if (r)
- return NULL;
-
- return payload_archive;
-}
-
PAKFIRE_EXPORT int pakfire_archive_read(PakfireArchive archive, const char* filename,
char** data, size_t* data_size, int flags) {
struct archive* a;
int use_payload = (flags & PAKFIRE_ARCHIVE_USE_PAYLOAD);
if (use_payload) {
- pa = archive_open_payload(a);
+ pa = pakfire_archive_open_payload(archive, a);
// Strip leading / from filenames, because the payload does
// not have leading slashes.
DEBUG(archive->pakfire, "Extracting %s to %s\n", archive->path, prefix);
if (use_payload)
- pa = archive_open_payload(a);
+ pa = pakfire_archive_open_payload(archive, a);
r = archive_extract(archive, use_payload ? pa : a,
prefix ? prefix : pakfire_get_path(archive->pakfire));