/*
A helper function that opens the archive for reading
*/
-static int open_archive(struct pakfire_archive* archive, struct archive** a) {
- *a = archive_read_new();
- if (!*a)
- return ENOMEM;
+static struct archive* open_archive(struct pakfire_archive* archive) {
+ // Create a new archive object
+ struct archive* a = archive_read_new();
+ if (!a)
+ return NULL;
// Archives must be uncompressed tarballs
- archive_read_support_format_tar(*a);
+ archive_read_support_format_tar(a);
// Archives are either compressed using XZ or Zstandard
- archive_read_support_filter_xz(*a);
- archive_read_support_filter_zstd(*a);
+ archive_read_support_filter_xz(a);
+ archive_read_support_filter_zstd(a);
// Start reading from the beginning
rewind(archive->f);
// Try opening the archive file
- int r = archive_read_open_FILE(*a, archive->f);
+ int r = archive_read_open_FILE(a, archive->f);
if (r) {
ERROR(archive->pakfire, "Could not open archive %s: %s\n",
- archive->path, archive_error_string(*a));
+ archive->path, archive_error_string(a));
goto ERROR;
}
// Success
- return 0;
+ return a;
ERROR:
- close_archive(archive, *a);
- *a = NULL;
+ close_archive(archive, a);
- return r;
+ return NULL;
}
static int pakfire_archive_walk(struct pakfire_archive* archive,
pakfire_walk_callback callback, pakfire_walk_filter_callback filter_callback, void* data) {
- struct archive* a = NULL;
+ int r;
// Open the archive file
- int r = open_archive(archive, &a);
- if (r)
- return r;
+ struct archive* a = open_archive(archive);
+ if (!a)
+ return 1;
// Walk through the archive
r = pakfire_walk(archive->pakfire, a, callback, filter_callback, data);
return 1;
}
-/*
- A helper function that opens the archive and finds a certain file in it
-*/
-static int open_archive_and_find(struct pakfire_archive* archive, struct archive** a,
- struct archive_entry** entry, const char* filename) {
- int r = open_archive(archive, a);
- if (r)
- return r;
-
- r = find_archive_entry(archive, entry, *a, filename);
-
- // Close archive on error
- if (r)
- close_archive(archive, *a);
-
- return r;
-}
-
static la_ssize_t pakfire_archive_read_callback(struct archive* a,
void* client_data, const void** buffer) {
struct archive* archive = (struct archive*)client_data;
}
static struct archive* pakfire_archive_open_payload(struct pakfire_archive* archive,
- struct archive** a, size_t* size) {
+ struct archive* a, size_t* size) {
struct archive_entry* entry = NULL;
struct archive* payload = NULL;
// Find the payload
- int r = open_archive_and_find(archive, a, &entry, "data.img");
+ int r = find_archive_entry(archive, &entry, a, "data.img");
if (r)
goto ERROR;
archive_read_support_filter_xz(payload);
// Try opening the payload archive
- r = archive_read_open2(payload, *a, NULL, pakfire_archive_read_callback, NULL, NULL);
+ 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));
struct archive* a = NULL;
struct archive_entry* entry = NULL;
+ struct archive* payload = NULL;
+
+ // Open the archive
+ a = open_archive(archive);
+ if (!a) {
+ r = 1;
+ goto ERROR;
+ }
- struct archive* payload = pakfire_archive_open_payload(archive, &a, NULL);
+ payload = pakfire_archive_open_payload(archive, a, NULL);
if (!payload)
goto ERROR;
goto ERROR;
}
- // Open payload
- payload = pakfire_archive_open_payload(archive, &a, &size);
- if (!payload)
- goto ERROR;
-
// Load the filelist (if not done already)
if (!archive->filelist) {
r = pakfire_filelist_create(&filelist, archive->pakfire);
goto ERROR;
}
+ // Open the archive
+ a = open_archive(archive);
+ if (!a) {
+ r = 1;
+ goto ERROR;
+ }
+
+ // Open the internal tarball with the payload for older formats
+ if (archive->format < 6) {
+ payload = pakfire_archive_open_payload(archive, a, &size);
+ if (!payload)
+ goto ERROR;
+ }
+
// Extract
- r = pakfire_extract(archive->pakfire, payload, size, filelist, prefix, nevra, flags);
+ r = pakfire_extract(archive->pakfire, (payload) ? payload : a, size,
+ filelist, prefix, nevra, flags);
if (r)
goto ERROR;