]> git.ipfire.org Git - pakfire.git/commitdiff
archive: Refactor reading files from the archive
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 20 May 2021 18:12:28 +0000 (18:12 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 20 May 2021 18:12:28 +0000 (18:12 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/archive.c

index d29846642a563c79c8f089470db5d74101f8796d..cd5988721a460f4cec5a424d0f9c5e2ff6dc865d 100644 (file)
@@ -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;
 }