From 5bd17ccf9a8125fd3b3a7e36ccc4b7c7fe8eff70 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Thu, 6 Feb 2025 16:20:41 +0000 Subject: [PATCH] archive: Untangle reading the filelist and extraction The idea here was to re-use existing code, but I am not sure this is currently very helpful to anyone. Signed-off-by: Michael Tremer --- src/pakfire/archive.c | 159 +++++++++++++++++++++++------------------ src/pakfire/compress.h | 7 -- 2 files changed, 89 insertions(+), 77 deletions(-) diff --git a/src/pakfire/archive.c b/src/pakfire/archive.c index fcec0ead..2513635a 100644 --- a/src/pakfire/archive.c +++ b/src/pakfire/archive.c @@ -1214,17 +1214,9 @@ static int pakfire_archive_extract_one(struct pakfire_archive* archive, // Generate a file object r = pakfire_file_create_from_archive_entry(&file, archive->pakfire, entry); - if (r) + if (r < 0) goto ERROR; - // Add entry to filelist (if requested) - if (archive->filelist) { - // Append the file to the list - r = pakfire_filelist_add(archive->filelist, file); - if (r) - goto ERROR; - } - const int configfile = pakfire_file_has_flag(file, PAKFIRE_FILE_CONFIG); // Prepend the prefix @@ -1273,45 +1265,44 @@ static int pakfire_archive_extract_one(struct pakfire_archive* archive, } // Write the file... - if (state->writer) { - // Fetch path again since we changed it - path = archive_entry_pathname(entry); - DEBUG(archive->ctx, "Extracting %s\n", path); + // Fetch path again since we changed it + path = archive_entry_pathname(entry); - // Remove any extended attributes which we never write to disk - archive_entry_xattr_clear(entry); + DEBUG(archive->ctx, "Extracting %s\n", path); - // Set capabilities - if (pakfire_file_has_caps(file)) { - r = pakfire_file_write_fcaps(file, &cap_data); - if (r) - goto ERROR; + // Remove any extended attributes which we never write to disk + archive_entry_xattr_clear(entry); - // Store capabilities in archive entry - archive_entry_xattr_add_entry(entry, - "security.capability", &cap_data, sizeof(cap_data)); - } + // Set capabilities + if (pakfire_file_has_caps(file)) { + r = pakfire_file_write_fcaps(file, &cap_data); + if (r) + goto ERROR; - // Write payload - r = archive_read_extract2(state->a, entry, state->writer); - switch (r) { - case ARCHIVE_OK: - r = 0; - break; + // Store capabilities in archive entry + archive_entry_xattr_add_entry(entry, + "security.capability", &cap_data, sizeof(cap_data)); + } - case ARCHIVE_WARN: - ERROR(archive->ctx, "%s\n", archive_error_string(state->writer)); + // Write payload + r = archive_read_extract2(state->a, entry, state->writer); + switch (r) { + case ARCHIVE_OK: + r = 0; + break; - // Pretend everything has been okay - r = 0; - break; + case ARCHIVE_WARN: + ERROR(archive->ctx, "%s\n", archive_error_string(state->writer)); - case ARCHIVE_FATAL: - ERROR(archive->ctx, "%s\n", archive_error_string(state->writer)); - r = 1; - break; - } + // Pretend everything has been okay + r = 0; + break; + + case ARCHIVE_FATAL: + ERROR(archive->ctx, "%s\n", archive_error_string(state->writer)); + r = 1; + break; } ERROR: @@ -1330,16 +1321,6 @@ static int __pakfire_archive_extract(struct pakfire_archive* archive, const char DEBUG(archive->ctx, "Extracting %s\n", archive->path); - int progress_flags = PAKFIRE_PROGRESS_SHOW_PERCENTAGE; - - // Should we show any progress? - if (flags & PAKFIRE_EXTRACT_NO_PROGRESS) - progress_flags |= PAKFIRE_PROGRESS_NO_PROGRESS; - - // Show throughput? - if (flags & PAKFIRE_EXTRACT_SHOW_THROUGHPUT) - progress_flags |= PAKFIRE_PROGRESS_SHOW_TRANSFER_SPEED; - // Fetch package pkg = pakfire_archive_get_package(archive); if (!pkg) { @@ -1352,20 +1333,19 @@ static int __pakfire_archive_extract(struct pakfire_archive* archive, const char if (r < 0) goto ERROR; - // Setup the writer if we are not running in dry mode - if (!(flags & PAKFIRE_EXTRACT_DRY_RUN)) { - writer = pakfire_get_disk_writer(archive->pakfire); - if (!writer) { - r = -errno; - goto ERROR; - } + // Setup the writer + writer = pakfire_get_disk_writer(archive->pakfire); + if (!writer) { + r = -errno; + goto ERROR; } // Fetch NEVRA const char* nevra = pakfire_package_get_string(pkg, PAKFIRE_PKG_NEVRA); // Create the progress indicator - r = pakfire_progress_create(&archive->progress, archive->ctx, progress_flags, NULL); + r = pakfire_progress_create(&archive->progress, + archive->ctx, PAKFIRE_PROGRESS_SHOW_PERCENTAGE, NULL); if (r < 0) goto ERROR; @@ -1393,13 +1373,6 @@ static int __pakfire_archive_extract(struct pakfire_archive* archive, const char goto ERROR; } - // Load the filelist (if not done already) - if (!archive->filelist) { - r = pakfire_filelist_create(&archive->filelist, archive->pakfire); - if (r < 0) - goto ERROR; - } - // Create state struct pakfire_extract_state state = { .archive = archive, @@ -1419,7 +1392,7 @@ static int __pakfire_archive_extract(struct pakfire_archive* archive, const char // Walk through the entire archive and extract everything r = pakfire_archive_walk(archive, a, pakfire_archive_extract_one, pakfire_archive_filter_payload, &state); - if (r) + if (r < 0) goto ERROR; ERROR: @@ -1447,10 +1420,56 @@ unsigned int pakfire_archive_get_format(struct pakfire_archive* archive) { return archive->format; } -static int pakfire_archive_load_filelist(struct pakfire_archive* archive) { - // Perform a dry-run extraction - return __pakfire_archive_extract(archive, NULL, - PAKFIRE_EXTRACT_DRY_RUN|PAKFIRE_EXTRACT_NO_PROGRESS); +static int __pakfire_archive_load_filelist(struct pakfire_archive* archive, + struct archive* a, struct archive_entry* entry, void* data) { + struct pakfire_filelist* filelist = data; + struct pakfire_file* file = NULL; + int r; + + // Generate a file object + r = pakfire_file_create_from_archive_entry(&file, archive->pakfire, entry); + if (r < 0) + goto ERROR; + + // Add entry to filelist + r = pakfire_filelist_add(filelist, file); + if (r < 0) + goto ERROR; + +ERROR: + if (file) + pakfire_file_unref(file); + + return r; +} + +static int pakfire_archive_load_filelist(struct pakfire_archive* self) { + struct pakfire_filelist* filelist = NULL; + int r; + + // Create a new filelist + r = pakfire_filelist_create(&filelist, self->pakfire); + if (r < 0) + goto ERROR; + + // Walk through the entire archive and extract everything + r = pakfire_archive_open_and_walk(self, + __pakfire_archive_load_filelist, pakfire_archive_filter_payload, filelist); + if (r < 0) + goto ERROR; + + // Free any previous data + if (self->filelist) + pakfire_filelist_unref(self->filelist); + + // Store the filelist + self->filelist = pakfire_filelist_ref(filelist); + +ERROR: + if (filelist) + pakfire_filelist_unref(filelist); + + return r; } int pakfire_archive_get_filelist(struct pakfire_archive* self, struct pakfire_filelist** filelist) { diff --git a/src/pakfire/compress.h b/src/pakfire/compress.h index 3f670300..d12d86bd 100644 --- a/src/pakfire/compress.h +++ b/src/pakfire/compress.h @@ -40,13 +40,6 @@ FILE* pakfire_xzfopen(FILE* f, const char* mode); // ZSTD FILE* pakfire_zstdfopen(FILE* f, const char* mode); -// Extract -enum pakfire_extract_flags { - PAKFIRE_EXTRACT_DRY_RUN = (1 << 0), - PAKFIRE_EXTRACT_NO_PROGRESS = (1 << 1), - PAKFIRE_EXTRACT_SHOW_THROUGHPUT = (1 << 2), -}; - // Algorithms enum pakfire_compressions { PAKFIRE_COMPRESS_ZSTD, -- 2.39.5