]> git.ipfire.org Git - pakfire.git/commitdiff
archive: Read metadata only when needed
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 7 Apr 2021 15:37:57 +0000 (15:37 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 7 Apr 2021 15:37:57 +0000 (15:37 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/archive.c

index d488ebd5bd72629cd0018f277880c1be92a5f891..e764e8c9539cf8e14a629d8e0ff42188c48f1ff9 100644 (file)
@@ -368,19 +368,9 @@ static int pakfire_archive_create(PakfireArchive* archive, Pakfire pakfire) {
 
        STAILQ_INIT(&a->chksums);
 
-       // Setup the parser
-       a->parser = pakfire_parser_create(pakfire, NULL, NULL, 0);
-       if (!a->parser)
-               goto ERROR;
-
        *archive = a;
 
        return 0;
-
-ERROR:
-       pakfire_archive_free(a);
-
-       return 1;
 }
 
 PAKFIRE_EXPORT PakfireArchive pakfire_archive_ref(PakfireArchive archive) {
@@ -402,6 +392,69 @@ PAKFIRE_EXPORT Pakfire pakfire_archive_get_pakfire(PakfireArchive archive) {
        return pakfire_ref(archive->pakfire);
 }
 
+// Metadata
+
+static int pakfire_archive_parse_metadata(PakfireArchive archive) {
+       struct archive* a = NULL;
+       struct archive_entry* entry = NULL;
+
+       char* data = NULL;
+       size_t size;
+
+       // Do nothing if this has already been loaded
+       if (archive->parser)
+               return 0;
+
+       // Open the archive
+       int r = archive_open(archive, &a);
+       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;
+       }
+
+       // Allocate a new parser
+       archive->parser = pakfire_parser_create(archive->pakfire, NULL, NULL, 0);
+       if (!archive->parser)
+               goto ERROR;
+
+       // Parse the metadata
+       r = pakfire_parser_parse_data(archive->parser, data, size, NULL);
+       if (r) {
+               ERROR(archive->pakfire, "Error parsing metadata\n");
+               goto ERROR;
+       }
+
+       // Success
+       r = 0;
+       goto CLEANUP;
+
+ERROR:
+       if (archive->parser) {
+               pakfire_parser_unref(archive->parser);
+               archive->parser = NULL;
+       }
+
+CLEANUP:
+       if (data)
+               free(data);
+       if (a)
+               archive_read_free(a);
+
+       return r;
+}
+
 static int pakfire_archive_parse_entry_format(PakfireArchive archive,
                struct archive* a, struct archive_entry* e) {
        char format[10];
@@ -416,22 +469,6 @@ static int pakfire_archive_parse_entry_format(PakfireArchive archive,
        return (archive->format < 0);
 }
 
-static int pakfire_archive_parse_entry_metadata(PakfireArchive archive,
-               struct archive* a, struct archive_entry* e) {
-       char* data;
-       size_t data_size;
-
-       int r = pakfire_archive_copy_data_to_buffer(archive->pakfire, a, e, &data, &data_size);
-       if (r)
-               return r;
-
-       // Parse metadata file
-       r = pakfire_parser_parse_data(archive->parser, data, data_size, NULL);
-       free(data);
-
-       return r;
-}
-
 static int pakfire_archive_parse_entry_filelist(PakfireArchive archive,
                struct archive* a, struct archive_entry* e) {
        char* data;
@@ -595,14 +632,8 @@ static int pakfire_archive_read_metadata_entry(PakfireArchive archive, struct ar
 
        // If the format is set, we can go on...
        } else {
-               // Parse the metadata
-               if (strcmp(PAKFIRE_ARCHIVE_FN_METADATA, entry_name) == 0) {
-                       ret = pakfire_archive_parse_entry_metadata(archive, a, e);
-                       if (ret)
-                               return EINVAL;
-
                // Parse the filelist
-               } else if (strcmp(PAKFIRE_ARCHIVE_FN_FILELIST, entry_name) == 0) {
+               if (strcmp(PAKFIRE_ARCHIVE_FN_FILELIST, entry_name) == 0) {
                        ret = pakfire_archive_parse_entry_filelist(archive, a, e);
                        if (ret)
                                return EINVAL;
@@ -679,6 +710,10 @@ ERROR:
 
 
 PAKFIRE_EXPORT char* pakfire_archive_get(PakfireArchive archive, const char* namespace, const char* key) {
+       int r = pakfire_archive_parse_metadata(archive);
+       if (r)
+               return NULL;
+
        return pakfire_parser_get(archive->parser, namespace, key);
 }