From: Michael Tremer Date: Tue, 13 Jul 2021 12:23:15 +0000 (+0000) Subject: archive: Refactor loading scriptlets X-Git-Tag: 0.9.28~1032 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e49b6359e60f919bebcdf62dc4d7d89f6f0bddd8;p=pakfire.git archive: Refactor loading scriptlets Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/archive.c b/src/libpakfire/archive.c index 40474e96b..f739e8ed0 100644 --- a/src/libpakfire/archive.c +++ b/src/libpakfire/archive.c @@ -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;