libpakfire_la_SOURCES = \
src/libpakfire/arch.c \
src/libpakfire/archive.c \
+ src/libpakfire/db.c \
src/libpakfire/errno.c \
src/libpakfire/execute.c \
src/libpakfire/file.c \
src/libpakfire/include/pakfire/arch.h \
src/libpakfire/include/pakfire/archive.h \
src/libpakfire/include/pakfire/constants.h \
+ src/libpakfire/include/pakfire/db.h \
src/libpakfire/include/pakfire/errno.h \
src/libpakfire/include/pakfire/execute.h \
src/libpakfire/include/pakfire/file.h \
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2021 Pakfire development team #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include <lmdb.h>
+
+#include <pakfire/db.h>
+#include <pakfire/pakfire.h>
+#include <pakfire/logging.h>
+#include <pakfire/types.h>
+#include <pakfire/util.h>
+
+struct pakfire_db {
+ Pakfire pakfire;
+ int nrefs;
+};
+
+/*
+ This function initialises the database environment, but stores it in the main pakfire
+ object so that we do not have to create a circle-reference between pakfire and the
+ database object.
+*/
+int pakfire_db_env_init(Pakfire pakfire, MDB_env** env) {
+ DEBUG(pakfire, "Initialising database environment\n");
+
+ // Allocate database environment
+ int r = mdb_env_create(env);
+ if (r) {
+ ERROR(pakfire, "Could not allocate database environment\n");
+ return r;
+ }
+
+ const char* root = pakfire_get_path(pakfire);
+ char* path = pakfire_path_join(root, "var/lib/pakfire/database.db");
+
+ // Ensure the directory exists
+ pakfire_mkdir(pakfire, path, 0);
+
+ // Open the database environment
+ r = mdb_env_open(*env, path, 0, 0660);
+ if (r) {
+ switch (r) {
+ case MDB_VERSION_MISMATCH:
+ ERROR(pakfire, "The database is of an incompatible version\n");
+ errno = EINVAL;
+ break;
+
+ case MDB_INVALID:
+ errno = EINVAL;
+ break;
+
+ default:
+ ERROR(pakfire, "Could not open database %s: %s\n", path, strerror(errno));
+ errno = r;
+ }
+
+ // Reset r to non-zero
+ r = 1;
+ goto ERROR;
+ }
+
+ERROR:
+ free(path);
+
+ return r;
+}
+
+void pakfire_db_env_free(Pakfire pakfire, MDB_env* env) {
+ DEBUG(pakfire, "Freeing database environment\n");
+
+ if (env)
+ mdb_env_close(env);
+}
+
+int pakfire_db_open(struct pakfire_db** db, Pakfire pakfire) {
+ struct pakfire_db* o = pakfire_calloc(1, sizeof(*o));
+ if (!o)
+ return -ENOMEM;
+
+ DEBUG(pakfire, "Allocated database at %p\n", o);
+
+ o->pakfire = pakfire_ref(pakfire);
+ o->nrefs = 1;
+
+ *db = o;
+
+ return 0;
+}
+
+struct pakfire_db* pakfire_db_ref(struct pakfire_db* db) {
+ db->nrefs++;
+
+ return db;
+}
+
+static void pakfire_db_free(struct pakfire_db* db) {
+ DEBUG(db->pakfire, "Releasing database at %p\n", db);
+
+ pakfire_unref(db->pakfire);
+
+ pakfire_free(db);
+}
+
+struct pakfire_db* pakfire_db_unref(struct pakfire_db* db) {
+ if (--db->nrefs > 0)
+ return db;
+
+ pakfire_db_free(db);
+
+ return NULL;
+}
--- /dev/null
+/*#############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2021 Pakfire development team #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+# #
+#############################################################################*/
+
+#ifndef PAKFIRE_DB_H
+#define PAKFIRE_DB_H
+
+#ifdef PAKFIRE_PRIVATE
+
+#include <lmdb.h>
+
+#include <pakfire/types.h>
+
+struct pakfire_db;
+
+int pakfire_db_env_init(Pakfire pakfire, MDB_env** env);
+void pakfire_db_env_free(Pakfire pakfire, MDB_env* env);
+
+int pakfire_db_open(struct pakfire_db** db, Pakfire pakfire);
+
+struct pakfire_db* pakfire_db_ref(struct pakfire_db* db);
+struct pakfire_db* pakfire_db_unref(struct pakfire_db* db);
+
+#endif
+
+#endif /* PAKFIRE_DB_H */
#include <syslog.h>
#include <unistd.h>
+#include <lmdb.h>
+
#include <solv/evr.h>
#include <solv/pool.h>
#include <solv/poolarch.h>
#include <pakfire/arch.h>
#include <pakfire/constants.h>
+#include <pakfire/db.h>
#include <pakfire/logging.h>
#include <pakfire/package.h>
#include <pakfire/packagelist.h>
char* cache_path;
char* arch;
+ // Database Environment
+ MDB_env* mdb_env;
+
// Pool stuff
Pool* pool;
int pool_ready;
return 0;
}
+// A utility function is already called pakfire_free
+static void _pakfire_free(Pakfire pakfire) {
+ DEBUG(pakfire, "Releasing Pakfire at %p\n", pakfire);
+
+ pakfire_repo_free_all(pakfire);
+
+ if (pakfire->mdb_env)
+ pakfire_db_env_free(pakfire, pakfire->mdb_env);
+
+ if (pakfire->pool)
+ pool_free(pakfire->pool);
+
+ queue_free(&pakfire->installonly);
+
+ if (pakfire->arch)
+ pakfire_free(pakfire->arch);
+
+ if (pakfire->path)
+ pakfire_free(pakfire->path);
+
+ if (pakfire->cache_path)
+ pakfire_free(pakfire->cache_path);
+
+ pakfire_free(pakfire);
+}
+
PAKFIRE_EXPORT int pakfire_create(Pakfire* pakfire, const char* path, const char* arch) {
// Default to the native architecture
if (!arch)
DEBUG(p, " arch = %s\n", pakfire_get_arch(p));
DEBUG(p, " path = %s\n", pakfire_get_path(p));
+ // Initialise the database environment
+ int r = pakfire_db_env_init(p, &p->mdb_env);
+ if (r) {
+ _pakfire_free(p);
+
+ return r;
+ }
+
// Initialize the pool
p->pool = pool_create();
pool_setdisttype(p->pool, DISTTYPE_RPM);
}
PAKFIRE_EXPORT Pakfire pakfire_unref(Pakfire pakfire) {
- if (!pakfire)
- return NULL;
-
if (--pakfire->nrefs > 0)
return pakfire;
- DEBUG(pakfire, "Releasing Pakfire at %p\n", pakfire);
-
- pakfire_repo_free_all(pakfire);
- pool_free(pakfire->pool);
- queue_free(&pakfire->installonly);
-
- pakfire_free(pakfire->path);
- pakfire_free(pakfire->cache_path);
- pakfire_free(pakfire->arch);
-
- pakfire_free(pakfire);
+ _pakfire_free(pakfire);
return NULL;
}