From: Michael Tremer Date: Sun, 7 Feb 2021 18:30:19 +0000 (+0000) Subject: libpakfire: Run scriptlets from database X-Git-Tag: 0.9.28~1285^2~783 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f6942b342d97ca2eaa2617ab19620fae1b5b7137;p=pakfire.git libpakfire: Run scriptlets from database Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/archive.c b/src/libpakfire/archive.c index 4c34b8592..b2a1a6d97 100644 --- a/src/libpakfire/archive.c +++ b/src/libpakfire/archive.c @@ -508,7 +508,7 @@ static int pakfire_archive_parse_entry_checksums(PakfireArchive archive, static int pakfire_archive_parse_entry_scriptlet(PakfireArchive archive, struct archive* a, struct archive_entry* e, const char* filename) { // Allocate a scriptlet - struct pakfire_scriptlet* scriptlet = pakfire_scriptlet_create(archive->pakfire); + struct pakfire_scriptlet* scriptlet = pakfire_scriptlet_create(archive->pakfire, NULL, 0); if (!scriptlet) return -ENOMEM; diff --git a/src/libpakfire/db.c b/src/libpakfire/db.c index 36c85409d..bb1db554d 100644 --- a/src/libpakfire/db.c +++ b/src/libpakfire/db.c @@ -923,7 +923,7 @@ static int pakfire_db_add_scriptlets(struct pakfire_db* db, unsigned long id, Pa sqlite3_stmt* stmt = NULL; int r = 1; - struct pakfire_scriptlet_type* scriptlet_type = PAKFIRE_SCRIPTLET_TYPES; + const struct pakfire_scriptlet_type* scriptlet_type = PAKFIRE_SCRIPTLET_TYPES; struct pakfire_scriptlet* scriptlet; const char* sql = "INSERT INTO scriptlets(pkg, type, scriptlet) VALUES(?, ?, ?)"; @@ -1282,3 +1282,70 @@ ERROR: return r; } + +struct pakfire_scriptlet* pakfire_db_get_scriptlet(struct pakfire_db* db, + PakfirePackage pkg, pakfire_scriptlet_type type) { + struct pakfire_scriptlet* scriptlet = NULL; + sqlite3_stmt* stmt = NULL; + int r = 1; + + // Fetch the package's UUID + const char* uuid = pakfire_package_get_uuid(pkg); + if (!uuid) { + ERROR(db->pakfire, "Package has no UUID\n"); + goto ERROR; + } + + const char* sql = "SELECT scriptlet.scriptlet FROM packages \ + JOIN scriptlets ON packages.id = scriptlets.pkg \ + WHERE packages.uuid = ? AND scriptlets.type = ?"; + + r = sqlite3_prepare_v2(db->handle, sql, strlen(sql), &stmt, NULL); + if (r) { + ERROR(db->pakfire, "Could not prepare SQL statement: %s %s\n", + sql, sqlite3_errmsg(db->handle)); + goto ERROR; + } + + // Bind UUID + r = sqlite3_bind_text(stmt, 1, uuid, -1, NULL); + if (r) { + ERROR(db->pakfire, "Could not bind uuid: %s\n", sqlite3_errmsg(db->handle)); + goto ERROR; + } + + // Bind type + const char* handle = pakfire_scriptlet_handle_from_type(type); + if (!handle) + goto ERROR; + + r = sqlite3_bind_text(stmt, 2, handle, -1, NULL); + if (r) { + ERROR(db->pakfire, "Could not bind type: %s\n", sqlite3_errmsg(db->handle)); + goto ERROR; + } + + DEBUG(db->pakfire, "Searching for scriptlet for package %s of type %s\n", uuid, handle); + + // Execute query + do { + r = sqlite3_step(stmt); + } while (r == SQLITE_BUSY); + + // We have some payload + if (r == SQLITE_ROW) { + const void* data = sqlite3_column_blob(stmt, 1); + ssize_t size = sqlite3_column_bytes(stmt, 1); + + // Create a scriptlet object + scriptlet = pakfire_scriptlet_create(db->pakfire, data, size); + if (!scriptlet) + goto ERROR; + } + +ERROR: + if (stmt) + sqlite3_finalize(stmt); + + return scriptlet; +} diff --git a/src/libpakfire/include/pakfire/db.h b/src/libpakfire/include/pakfire/db.h index 7c0332196..b10301929 100644 --- a/src/libpakfire/include/pakfire/db.h +++ b/src/libpakfire/include/pakfire/db.h @@ -44,4 +44,13 @@ ssize_t pakfire_db_packages(struct pakfire_db* db); int pakfire_db_add_package(struct pakfire_db* db, PakfirePackage pkg, PakfireArchive archive); int pakfire_db_remove_package(struct pakfire_db* db, PakfirePackage pkg); +#ifdef PAKFIRE_PRIVATE + +#include + +struct pakfire_scriptlet* pakfire_db_get_scriptlet( + struct pakfire_db* db, PakfirePackage pkg, pakfire_scriptlet_type type); + +#endif + #endif /* PAKFIRE_DB_H */ diff --git a/src/libpakfire/include/pakfire/scriptlet.h b/src/libpakfire/include/pakfire/scriptlet.h index 4e2f8a7ea..dcaea6312 100644 --- a/src/libpakfire/include/pakfire/scriptlet.h +++ b/src/libpakfire/include/pakfire/scriptlet.h @@ -59,7 +59,7 @@ struct pakfire_scriptlet { size_t size; }; -struct pakfire_scriptlet* pakfire_scriptlet_create(Pakfire pakfire); +struct pakfire_scriptlet* pakfire_scriptlet_create(Pakfire pakfire, const void* data, size_t size); void pakfire_scriptlet_free(struct pakfire_scriptlet* scriptlet); pakfire_scriptlet_type pakfire_scriptlet_type_from_filename(const char* filename); diff --git a/src/libpakfire/scriptlet.c b/src/libpakfire/scriptlet.c index 2fd43b884..542b8cc54 100644 --- a/src/libpakfire/scriptlet.c +++ b/src/libpakfire/scriptlet.c @@ -41,13 +41,36 @@ const struct pakfire_scriptlet_type PAKFIRE_SCRIPTLET_TYPES[NUM_PAKFIRE_SCRIPTLE { PAKFIRE_SCRIPTLET_UNDEFINED, NULL, NULL }, }; -struct pakfire_scriptlet* pakfire_scriptlet_create(Pakfire pakfire) { +static int pakfire_scriptlet_set(struct pakfire_scriptlet* scriptlet, const void* data, size_t size) { + if (scriptlet->data) + free(scriptlet->data); + + // Allocate space for data + scriptlet->data = malloc(size); + if (!scriptlet->data) + return 1; + + // Copy data + memcpy(scriptlet->data, data, size); + + return 0; +} + +struct pakfire_scriptlet* pakfire_scriptlet_create(Pakfire pakfire, const void* data, size_t size) { struct pakfire_scriptlet* scriptlet = calloc(1, sizeof(*scriptlet)); if (!scriptlet) return NULL; DEBUG(pakfire, "Allocated scriptlet at %p\n", scriptlet); + if (data && size) { + int r = pakfire_scriptlet_set(scriptlet, data, size); + if (r) { + pakfire_scriptlet_free(scriptlet); + return NULL; + } + } + return scriptlet; }; diff --git a/src/libpakfire/step.c b/src/libpakfire/step.c index 03edf5ec6..33fa1d97c 100644 --- a/src/libpakfire/step.c +++ b/src/libpakfire/step.c @@ -301,9 +301,17 @@ out: return r; } -static int pakfire_step_run_script(PakfireStep step, pakfire_scriptlet_type type) { - // Fetch scriptlet from archive - struct pakfire_scriptlet* scriptlet = pakfire_archive_get_scriptlet(step->archive, type); +static int pakfire_step_run_script(PakfireStep step, + struct pakfire_db* db, pakfire_scriptlet_type type) { + struct pakfire_scriptlet* scriptlet = NULL; + + // Fetch scriptlet from archive if possible + if (step->archive) + scriptlet = pakfire_archive_get_scriptlet(step->archive, type); + else + scriptlet = pakfire_db_get_scriptlet(db, step->package, type); + + // Nothing to do if there are no scriptlets if (!scriptlet) return 0; @@ -382,17 +390,17 @@ PAKFIRE_EXPORT int pakfire_step_run(PakfireStep step, switch (type) { case PAKFIRE_STEP_INSTALL: case PAKFIRE_STEP_REINSTALL: - r = pakfire_step_run_script(step, PAKFIRE_SCRIPTLET_PRETRANSIN); + r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_PRETRANSIN); break; case PAKFIRE_STEP_UPGRADE: case PAKFIRE_STEP_DOWNGRADE: - r = pakfire_step_run_script(step, PAKFIRE_SCRIPTLET_PRETRANSUP); + r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_PRETRANSUP); break; case PAKFIRE_STEP_ERASE: case PAKFIRE_STEP_OBSOLETE: - r = pakfire_step_run_script(step, PAKFIRE_SCRIPTLET_PRETRANSUN); + r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_PRETRANSUN); break; case PAKFIRE_STEP_IGNORE: @@ -405,17 +413,17 @@ PAKFIRE_EXPORT int pakfire_step_run(PakfireStep step, switch (type) { case PAKFIRE_STEP_INSTALL: case PAKFIRE_STEP_REINSTALL: - r = pakfire_step_run_script(step, PAKFIRE_SCRIPTLET_POSTTRANSIN); + r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_POSTTRANSIN); break; case PAKFIRE_STEP_UPGRADE: case PAKFIRE_STEP_DOWNGRADE: - r = pakfire_step_run_script(step, PAKFIRE_SCRIPTLET_POSTTRANSUP); + r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_POSTTRANSUP); break; case PAKFIRE_STEP_ERASE: case PAKFIRE_STEP_OBSOLETE: - r = pakfire_step_run_script(step, PAKFIRE_SCRIPTLET_POSTTRANSUN); + r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_POSTTRANSUN); break; case PAKFIRE_STEP_IGNORE: @@ -428,7 +436,7 @@ PAKFIRE_EXPORT int pakfire_step_run(PakfireStep step, switch (type) { case PAKFIRE_STEP_INSTALL: case PAKFIRE_STEP_REINSTALL: - r = pakfire_step_run_script(step, PAKFIRE_SCRIPTLET_PREIN); + r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_PREIN); if (r) break; @@ -440,12 +448,12 @@ PAKFIRE_EXPORT int pakfire_step_run(PakfireStep step, if (r) break; - r = pakfire_step_run_script(step, PAKFIRE_SCRIPTLET_POSTIN); + r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_POSTIN); break; case PAKFIRE_STEP_UPGRADE: case PAKFIRE_STEP_DOWNGRADE: - r = pakfire_step_run_script(step, PAKFIRE_SCRIPTLET_PREUP); + r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_PREUP); if (r) break; @@ -457,12 +465,12 @@ PAKFIRE_EXPORT int pakfire_step_run(PakfireStep step, if (r) break; - r = pakfire_step_run_script(step, PAKFIRE_SCRIPTLET_POSTUP); + r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_POSTUP); break; case PAKFIRE_STEP_ERASE: case PAKFIRE_STEP_OBSOLETE: - r = pakfire_step_run_script(step, PAKFIRE_SCRIPTLET_PREUN); + r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_PREUN); if (r) break; @@ -474,7 +482,7 @@ PAKFIRE_EXPORT int pakfire_step_run(PakfireStep step, if (r) break; - r = pakfire_step_run_script(step, PAKFIRE_SCRIPTLET_POSTUN); + r = pakfire_step_run_script(step, db, PAKFIRE_SCRIPTLET_POSTUN); break; case PAKFIRE_STEP_IGNORE: