From: Michael Tremer Date: Sun, 8 May 2022 16:34:44 +0000 (+0000) Subject: db: Check for compatible architecture X-Git-Tag: 0.9.28~815 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=33b38daa584f147e8108e78aaa32fa66223349e4;p=pakfire.git db: Check for compatible architecture Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/db.c b/src/libpakfire/db.c index 8f24e0f58..9b21a8b15 100644 --- a/src/libpakfire/db.c +++ b/src/libpakfire/db.c @@ -108,6 +108,75 @@ ERROR: return val; } +static char* pakfire_db_get_string(struct pakfire_db* db, const char* key) { + char* s = NULL; + + // Fetch the value from the database + sqlite3_value* value = pakfire_db_get(db, key); + if (!value) + return NULL; + + // Extract the value as string + const char* p = (const char*)sqlite3_value_text(value); + if (!p) + goto ERROR; + + // Copy string to heap + s = strdup(p); + +ERROR: + if (value) + sqlite3_value_free(value); + + return s; +} + +static int pakfire_db_set_string(struct pakfire_db* db, const char* key, const char* val) { + sqlite3_stmt* stmt = NULL; + int r; + + DEBUG(db->pakfire, "Setting %s to '%s'\n", key, val); + + const char* sql = "INSERT INTO settings(key, val) VALUES(?, ?) \ + ON CONFLICT (key) DO UPDATE SET val = excluded.val"; + + // Prepare statement + r = sqlite3_prepare_v2(db->handle, sql, strlen(sql), &stmt, NULL); + if (r != SQLITE_OK) { + ERROR(db->pakfire, "Could not prepare SQL statement: %s: %s\n", + sql, sqlite3_errmsg(db->handle)); + return 1; + } + + // Bind key + r = sqlite3_bind_text(stmt, 1, key, strlen(key), NULL); + if (r != SQLITE_OK) { + ERROR(db->pakfire, "Could not bind key: %s\n", sqlite3_errmsg(db->handle)); + goto ERROR; + } + + // Bind val + r = sqlite3_bind_text(stmt, 2, val, strlen(val), NULL); + if (r != SQLITE_OK) { + ERROR(db->pakfire, "Could not bind val: %s\n", sqlite3_errmsg(db->handle)); + goto ERROR; + } + + // Execute the statement + do { + r = sqlite3_step(stmt); + } while (r == SQLITE_BUSY); + + // Set return code + r = (r == SQLITE_OK); + +ERROR: + if (stmt) + sqlite3_finalize(stmt); + + return r; +} + static int pakfire_db_set_int(struct pakfire_db* db, const char* key, int val) { sqlite3_stmt* stmt = NULL; int r; @@ -377,6 +446,15 @@ static int pakfire_db_create_schema(struct pakfire_db* db) { if (r) return 1; + const char* arch = pakfire_get_arch(db->pakfire); + + // Set architecture + r = pakfire_db_set_string(db, "arch", arch); + if (r) { + ERROR(db->pakfire, "Could not set architecture\n"); + return r; + } + return 0; } @@ -441,6 +519,32 @@ ROLLBACK: return 1; } +static int pakfire_db_check_arch(struct pakfire_db* db) { + int r = 1; + + // Fetch database architecture + char* db_arch = pakfire_db_get_string(db, "arch"); + if (!db_arch) { + ERROR(db->pakfire, "Database is of an unknown architecture\n"); + goto ERROR; + } + + // Fetch the running architecture + const char* arch = pakfire_get_arch(db->pakfire); + if (!arch) + goto ERROR; + + // They should match + if (strcmp(db_arch, arch) == 0) + r = 0; + +ERROR: + if (db_arch) + free(db_arch); + + return r; +} + static int pakfire_db_setup(struct pakfire_db* db) { int r; @@ -540,6 +644,11 @@ int pakfire_db_open(struct pakfire_db** db, struct pakfire* pakfire, int flags) if (r) goto END; + // Check for compatible architecture + r = pakfire_db_check_arch(o); + if (r) + goto END; + *db = o; r = 0;