From: Michael Tremer Date: Thu, 20 May 2021 18:12:28 +0000 (+0000) Subject: archive: Refactor reading files from the archive X-Git-Tag: 0.9.28~1285^2~117 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9e339d9c0c8e4290626119bbb08980caeaca9759;p=pakfire.git archive: Refactor reading files from the archive Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/archive.c b/src/libpakfire/archive.c index d29846642..cd5988721 100644 --- a/src/libpakfire/archive.c +++ b/src/libpakfire/archive.c @@ -149,6 +149,37 @@ static int find_archive_entry(struct archive_entry** entry, struct archive* a, c return 1; } +/* + A helper function that opens the archive and finds a certain file in it +*/ +static int open_archive_and_find(PakfireArchive archive, struct archive** a, + struct archive_entry** entry, const char* filename) { + int r = open_archive(archive, a); + if (r) + return r; + + return find_archive_entry(entry, *a, filename); +} + +static int open_archive_and_read(PakfireArchive archive, const char* filename, + char** data, size_t* size) { + struct archive* a = NULL; + struct archive_entry* e = NULL; + + // Open the archive and find the right file + int r = open_archive_and_find(archive, &a, &e, filename); + if (r) + return r; + + // Read the file into memory + r = pakfire_archive_copy_data_to_buffer(archive->pakfire, a, e, data, size); + + // Close the archive + 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; @@ -174,10 +205,11 @@ static la_ssize_t pakfire_archive_read_callback(struct archive* a, } static struct archive* pakfire_archive_open_payload(PakfireArchive archive, - struct archive* a, size_t* size) { + struct archive** a, size_t* size) { + struct archive_entry* entry = NULL; + // Find the payload - struct archive_entry* entry; - int r = find_archive_entry(&entry, a, PAKFIRE_ARCHIVE_FN_PAYLOAD); + int r = open_archive_and_find(archive, a, &entry, PAKFIRE_ARCHIVE_FN_PAYLOAD); if (r) return NULL; @@ -202,11 +234,17 @@ static struct archive* pakfire_archive_open_payload(PakfireArchive archive, if (r) { ERROR(archive->pakfire, "Could not open payload archive: %s\n", archive_error_string(payload)); - archive_read_free(payload); - return NULL; + goto ERROR; } return payload; + +ERROR: + archive_read_free(payload); + close_archive(archive, *a); + *a = NULL; + + return NULL; } // Checksum Stuff @@ -441,9 +479,6 @@ static PakfirePackage pakfire_archive_get_package(PakfireArchive archive) { // Metadata static int pakfire_archive_parse_metadata(PakfireArchive archive) { - struct archive* a = NULL; - struct archive_entry* entry = NULL; - char* data = NULL; size_t size; @@ -451,24 +486,10 @@ static int pakfire_archive_parse_metadata(PakfireArchive archive) { if (archive->parser) return 0; - // Open the archive - int r = open_archive(archive, &a); + // Read the metadata file + int r = open_archive_and_read(archive, PAKFIRE_ARCHIVE_FN_METADATA, &data, &size); if (r) - goto ERROR; - - // Find the metadata file - r = find_archive_entry(&entry, a, PAKFIRE_ARCHIVE_FN_METADATA); - if (r) { - ERROR(archive->pakfire, "Could not find metadata in %s\n", archive->path); - goto ERROR; - } - - // Read the data into memory - r = pakfire_archive_copy_data_to_buffer(archive->pakfire, a, entry, &data, &size); - if (r) { - ERROR(archive->pakfire, "Could not read metadata: %s\n", archive_error_string(a)); - goto ERROR; - } + return r; // Allocate a new parser archive->parser = pakfire_parser_create(archive->pakfire, NULL, NULL, 0); @@ -495,8 +516,6 @@ ERROR: CLEANUP: if (data) free(data); - if (a) - archive_read_free(a); return r; } @@ -634,7 +653,7 @@ static int pakfire_archive_walk(PakfireArchive archive, r = pakfire_archive_walk_entries(archive, a, callback, data); // Close the archive - archive_read_free(a); + close_archive(archive, a); return r; } @@ -705,6 +724,8 @@ ERROR: } static int pakfire_archive_try_open(PakfireArchive archive, const char* path) { + struct archive* a = NULL; + if (!path) return EINVAL; @@ -719,7 +740,6 @@ static int pakfire_archive_try_open(PakfireArchive archive, const char* path) { return 1; // Open the archive file for reading. - struct archive* a = NULL; int r = open_archive(archive, &a); if (r) goto ERROR; @@ -729,14 +749,15 @@ static int pakfire_archive_try_open(PakfireArchive archive, const char* path) { if (r) goto ERROR; - // Close archive - archive_read_free(a); + // Success + r = 0; - return 0; + // Reset errno + errno = 0; ERROR: if (a) - archive_read_free(a); + close_archive(archive, a); return r; } @@ -769,27 +790,21 @@ PAKFIRE_EXPORT char* pakfire_archive_get(PakfireArchive archive, const char* nam PAKFIRE_EXPORT int pakfire_archive_read(PakfireArchive archive, const char* filename, char** data, size_t* data_size) { - struct archive* a; - struct archive* payload = NULL; - struct archive_entry* entry; + struct archive* a = NULL; + struct archive_entry* entry = NULL; // Strip leading / from filenames, because the payload does // not have leading slashes. while (*filename == '/') filename++; - int r = open_archive(archive, &a); - if (r) - goto ERROR; - - payload = pakfire_archive_open_payload(archive, a, NULL); + struct archive* payload = pakfire_archive_open_payload(archive, &a, NULL); if (!payload) goto ERROR; - r = find_archive_entry(&entry, payload, filename); - if (r) { + int r = find_archive_entry(&entry, payload, filename); + if (r) goto ERROR; - } r = pakfire_archive_copy_data_to_buffer(archive->pakfire, payload, entry, data, data_size); @@ -797,7 +812,7 @@ PAKFIRE_EXPORT int pakfire_archive_read(PakfireArchive archive, const char* file ERROR: if (payload) archive_read_free(payload); - archive_read_free(a); + close_archive(archive, a); return r; } @@ -980,13 +995,8 @@ PAKFIRE_EXPORT int pakfire_archive_extract(PakfireArchive archive, const char* p if (r) goto ERROR; - // Open the archive - r = open_archive(archive, &a); - if (r) - goto ERROR; - // Open payload - payload = pakfire_archive_open_payload(archive, a, &size); + payload = pakfire_archive_open_payload(archive, &a, &size); if (!payload) goto ERROR; @@ -1028,7 +1038,7 @@ ERROR: archive_write_free(writer); if (payload) archive_read_free(payload); - archive_read_free(a); + close_archive(archive, a); return r; } @@ -1041,63 +1051,28 @@ PAKFIRE_EXPORT unsigned int pakfire_archive_get_format(PakfireArchive archive) { return archive->format; } -static int pakfire_archive_parse_filelist(PakfireArchive archive, - struct archive* a, struct archive_entry* entry) { - int r; +static int pakfire_archive_load_filelist(PakfireArchive archive) { char* data = NULL; size_t size; - // Read the data into memory - r = pakfire_archive_copy_data_to_buffer(archive->pakfire, a, entry, &data, &size); - if (r) { - ERROR(archive->pakfire, "Could not read filelist: %s\n", archive_error_string(a)); - goto ERROR; - } + // Read filelist + int r = open_archive_and_read(archive, "filelist", &data, &size); + if (r) + return r; DEBUG(archive->pakfire, "Read filelist:\n%.*s\n", (int)size, data); r = pakfire_filelist_create_from_file(&archive->filelist, archive->pakfire, data, archive->format); -ERROR: - if (data) - free(data); - - return r; -} - -static int pakfire_archive_load_filelist(PakfireArchive archive) { - struct archive* a = NULL; - struct archive_entry* entry = NULL; - size_t size; - int r; - - // Open the archive - r = open_archive(archive, &a); - if (r) - goto ERROR; - - // Find the filelist file - r = find_archive_entry(&entry, a, "filelist"); - if (r) { - ERROR(archive->pakfire, "Could not find filelist in %s\n", archive->path); - goto ERROR; - } - - // Parse the filelist - r = pakfire_archive_parse_filelist(archive, a, entry); - if (r) - goto ERROR; + free(data); -ERROR: // Destroy the filelist on error if (r && archive->filelist) { pakfire_filelist_unref(archive->filelist); archive->filelist = NULL; } - archive_read_free(a); - return r; } @@ -1401,7 +1376,7 @@ PAKFIRE_EXPORT pakfire_archive_verify_status_t pakfire_archive_verify(PakfireArc DEBUG(archive->pakfire, "Archive %p has been successfully verified\n", archive); END: - archive_read_free(a); + close_archive(archive, a); return status; }