// Scriptlets
struct pakfire_scriptlet** scriptlets;
- size_t nscriptlets;
+ int scriptlets_loaded;
// Verify Status
int verify;
// 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);
}
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.
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;