]> git.ipfire.org Git - pakfire.git/commitdiff
archive: Refactor loading scriptlets
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 13 Jul 2021 12:23:15 +0000 (12:23 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 13 Jul 2021 12:23:15 +0000 (12:23 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/archive.c

index 40474e96bfaaed8eb15b029bc8d147560367c2ac..f739e8ed0c120692fae0333d156b521ab5e1b5b5 100644 (file)
@@ -91,7 +91,7 @@ struct pakfire_archive {
 
        // Scriptlets
        struct pakfire_scriptlet** scriptlets;
-       size_t nscriptlets;
+       int scriptlets_loaded;
 
        // Verify Status
        int verify;
@@ -436,8 +436,8 @@ static void pakfire_archive_free(struct pakfire_archive* archive) {
 
        // Free scriptlets
        if (archive->scriptlets) {
-               for (unsigned int i = 0; i < archive->nscriptlets; i++)
-                       pakfire_scriptlet_unref(archive->scriptlets[i]);
+               for (struct pakfire_scriptlet** scriptlet = archive->scriptlets; *scriptlet; scriptlet++)
+                       pakfire_scriptlet_unref(*scriptlet);
                free(archive->scriptlets);
        }
 
@@ -608,76 +608,6 @@ ERROR:
        return 0;
 }
 
-static int pakfire_archive_parse_entry_scriptlet(struct pakfire_archive* archive,
-               struct archive* a, struct archive_entry* e, const char* filename) {
-       struct pakfire_scriptlet* scriptlet;
-       char* data = NULL;
-       size_t size = 0;
-       int r;
-
-       // Check if the filename matches
-       if (!pakfire_string_startswith(filename, "scriptlet/")) {
-               errno = EINVAL;
-               return 1;
-       }
-
-       const char* type = filename + strlen("scriptlet/");
-
-       // Fetch scriptlet
-       r = pakfire_archive_copy_data_to_buffer(archive->pakfire, a, e, &data, &size);
-       if (r)
-               return r;
-
-       // Allocate a scriptlet
-       r = pakfire_scriptlet_create(&scriptlet, archive->pakfire, type, data, size);
-       if (r)
-               goto ERROR;
-
-       // Make space for the new scriptlet
-       archive->scriptlets = reallocarray(archive->scriptlets, archive->nscriptlets + 1,
-               sizeof(*archive->scriptlets));
-       if (!archive->scriptlets) {
-               pakfire_scriptlet_unref(scriptlet);
-               r = 1;
-               goto ERROR;
-       }
-
-       // Append the new scriptlet
-       archive->scriptlets[archive->nscriptlets++] = scriptlet;
-
-ERROR:
-       if (data)
-               free(data);
-
-       return r;
-}
-
-static int pakfire_archive_read_metadata_entry(struct pakfire_archive* archive, struct archive* a,
-               struct archive_entry* e, int flags, void* data) {
-       int ret;
-
-       const char* entry_name = archive_entry_pathname(e);
-
-       // Parse the checksums
-       if (strcmp(PAKFIRE_ARCHIVE_FN_CHECKSUMS, entry_name) == 0) {
-               ret = pakfire_archive_parse_entry_checksums(archive, a, e);
-               if (ret)
-                       return EINVAL;
-
-       // Parse the scriptlets
-       } else if (pakfire_string_startswith(entry_name, "scriptlets/")) {
-               ret = pakfire_archive_parse_entry_scriptlet(archive, a, e, entry_name);
-               if (ret)
-                       return EINVAL;
-       }
-
-       return 0;
-}
-
-static int pakfire_archive_read_metadata(struct pakfire_archive* archive, struct archive* a) {
-       return pakfire_archive_walk(archive, pakfire_archive_read_metadata_entry, 0, NULL, NULL);
-}
-
 /*
        This function tries (very easily) to find out whether something is a valid
        archive or not.
@@ -2028,17 +1958,69 @@ PAKFIRE_EXPORT struct pakfire_package* pakfire_archive_make_package(struct pakfi
        return pkg;
 }
 
+static int pakfire_archive_load_scriptlet(struct pakfire_archive* archive,
+               struct archive* a, struct archive_entry* e, int flags, void* data) {
+       const char* path = archive_entry_pathname(e);
+
+       // Skip if this isn't a scriptlet
+       if (!pakfire_string_startswith(path, "scriptlet/"))
+               return 0;
+
+       char* buffer = NULL;
+       size_t size = 0;
+       int r;
+
+       // Fetch scriptlet
+       r = pakfire_archive_copy_data_to_buffer(archive->pakfire, a, e, &buffer, &size);
+       if (r)
+               goto ERROR;
+
+       struct pakfire_scriptlet* scriptlet = NULL;
+       const char* type = path + strlen("scriptlet/");
+
+       // Allocate a scriptlet
+       r = pakfire_scriptlet_create(&scriptlet, archive->pakfire, type, buffer, size);
+       if (r)
+               goto ERROR;
+
+       int* counter = (int*)data;
+
+       // Make space for the new scriptlet
+       archive->scriptlets = reallocarray(archive->scriptlets, *counter + 2,
+               sizeof(*archive->scriptlets));
+
+       archive->scriptlets[(*counter)++] = scriptlet;
+
+ERROR:
+       if (buffer)
+               free(buffer);
+
+       return r;
+}
+
+static int pakfire_archive_load_scriptlets(struct pakfire_archive* archive) {
+       // Nothing to do
+       if (archive->scriptlets_loaded)
+               return 0;
+
+       int counter = 0;
+
+       return pakfire_archive_walk(archive, pakfire_archive_load_scriptlet, 0, &counter, NULL);
+}
+
 struct pakfire_scriptlet* pakfire_archive_get_scriptlet(
                struct pakfire_archive* archive, const char* type) {
-       struct pakfire_scriptlet* scriptlet;
-
-       for (unsigned int i = 0; i < archive->nscriptlets; i++) {
-               scriptlet = archive->scriptlets[i];
+       int r = pakfire_archive_load_scriptlets(archive);
+       if (r) {
+               ERROR(archive->pakfire, "Could not load scriptlets: %m\n");
+               return NULL;
+       }
 
-               const char* t = pakfire_scriptlet_get_type(scriptlet);
+       for (struct pakfire_scriptlet** scriptlet = archive->scriptlets; *scriptlet; scriptlet++) {
+               const char* t = pakfire_scriptlet_get_type(*scriptlet);
 
                if (strcmp(t, type) == 0)
-                       return pakfire_scriptlet_ref(scriptlet);
+                       return pakfire_scriptlet_ref(*scriptlet);
        }
 
        return NULL;