diff --git a/TODO b/TODO
index 15a77d2..92e6ff3 100644
--- a/TODO
+++ b/TODO
@@ -11,13 +11,6 @@ Enforce command sequences:
etc
-- Make storage handling a GObject interface, would make plugging in new
- backends easier, even handling plugins?
-- Make storage per-manager
-- Move storage setting to a configuration file
-- Kill FromStorage variants, we should always load/read from our custom storage
-
-- Handle the client disconnecting without releasing the device
- Check whether we actually want claim to open the device, or allow
some operations to not require claiming the device
diff --git a/configure.ac b/configure.ac
index 1d39427..d7f8ebb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -17,17 +17,13 @@ PKG_CHECK_MODULES(FPRINT, [libfprint > 0.1.0])
AC_SUBST(FPRINT_LIBS)
AC_SUBST(FPRINT_CFLAGS)
-PKG_CHECK_MODULES(GLIB, "glib-2.0")
+PKG_CHECK_MODULES(GLIB, glib-2.0 dbus-glib-1)
AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
-PKG_CHECK_MODULES(DBUS_GLIB, "dbus-glib-1")
-AC_SUBST(DBUS_GLIB_LIBS)
-AC_SUBST(DBUS_GLIB_CFLAGS)
-
-PKG_CHECK_MODULES(POLKIT, polkit >= 0.8 polkit-dbus)
-AC_SUBST(POLKIT_LIBS)
-AC_SUBST(POLKIT_CFLAGS)
+PKG_CHECK_MODULES(DAEMON, glib-2.0 dbus-glib-1 gmodule-2.0 polkit >= 0.8 polkit-dbus)
+AC_SUBST(DAEMON_LIBS)
+AC_SUBST(DAEMON_CFLAGS)
AC_CHECK_PROG([POLKIT_POLICY_FILE_VALIDATE],
[polkit-policy-file-validate], [polkit-policy-file-validate])
@@ -38,6 +34,8 @@ DBUS_SERVICES_DIR="$DATADIR/dbus-1/services"
AC_SUBST(DBUS_SERVICES_DIR)
AC_DEFINE_UNQUOTED(DBUS_SERVICES_DIR, "$DBUS_SERVICES_DIR", [Where services dir for DBUS is])
+AC_DEFINE_UNQUOTED(SYSCONFDIR, "$sysconfdir", [Where the configuration file will be located])
+
# Restore gnu89 inline semantics on gcc 4.3 and newer
saved_cflags="$CFLAGS"
CFLAGS="$CFLAGS -fgnu89-inline"
diff --git a/src/Makefile.am b/src/Makefile.am
index 447c623..49ec91d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -7,8 +7,8 @@ EXTRA_DIST = fprintd.xml
libexec_PROGRAMS = fprintd
fprintd_SOURCES = main.c manager.c device.c file_storage.c
-fprintd_LDADD = $(DBUS_GLIB_LIBS) $(FPRINT_LIBS) $(POLKIT_LIBS)
-fprintd_CFLAGS = $(AM_CFLAGS) $(DBUS_GLIB_CFLAGS) $(FPRINT_CFLAGS) $(POLKIT_CFLAGS) -DLOCALEDIR=\""$(datadir)/locale"\"
+fprintd_LDADD = $(FPRINT_LIBS) $(DAEMON_LIBS)
+fprintd_CFLAGS = $(AM_CFLAGS) $(FPRINT_CFLAGS) $(DAEMON_CFLAGS) -DLOCALEDIR=\""$(datadir)/locale"\" -DPLUGINDIR=\""$(libdir)/fprintd/modules"\"
manager-dbus-glue.h: manager.xml
dbus-binding-tool --prefix=fprint_manager --mode=glib-server $< --output=$@
diff --git a/src/device.c b/src/device.c
index ccda7b1..332df1d 100644
--- a/src/device.c
+++ b/src/device.c
@@ -49,8 +49,6 @@ static void fprint_device_enroll_start(FprintDevice *rdev,
guint32 finger_num, DBusGMethodInvocation *context);
static void fprint_device_enroll_stop(FprintDevice *rdev,
DBusGMethodInvocation *context);
-static gboolean fprint_device_set_storage_type(FprintDevice *rdev,
- gint type);
static void fprint_device_list_enrolled_fingers(FprintDevice *rdev,
DBusGMethodInvocation *context);
static void fprint_device_delete_enrolled_fingers(FprintDevice *rdev,
@@ -197,8 +195,6 @@ static void fprint_device_init(FprintDevice *device)
{
FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(device);
priv->id = ++last_id;
- priv->storage_type = FP_FILE_STORAGE;
- storages[priv->storage_type].init();
/* Setup PolicyKit */
priv->pol_ctx = polkit_context_new ();
@@ -514,8 +510,8 @@ static void fprint_device_verify_start(FprintDevice *rdev,
g_message("start verification device %d finger %d", priv->id, finger_num);
- r = storages[priv->storage_type].print_data_load(priv->dev, (enum fp_finger)finger_num,
- &data, priv->username);
+ r = store.print_data_load(priv->dev, (enum fp_finger)finger_num,
+ &data, priv->username);
if (r < 0 || !data) {
g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_NO_SUCH_LOADED_PRINT,
@@ -577,7 +573,7 @@ static void enroll_stage_cb(struct fp_dev *dev, int result,
g_message("enroll_stage_cb: result %d", result);
if (result == FP_ENROLL_COMPLETE) {
- r = storages[priv->storage_type].print_data_save(print, session->enroll_finger, priv->username);
+ r = store.print_data_save(print, session->enroll_finger, priv->username);
if (r < 0)
result = FP_ENROLL_FAIL;
}
@@ -650,20 +646,6 @@ static void fprint_device_enroll_stop(FprintDevice *rdev,
}
}
-static gboolean fprint_device_set_storage_type(FprintDevice *rdev,
- gint type)
-{
- FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev);
-
- if (type >= FP_STORAGES_COUNT) return FALSE;
-
- storages[priv->storage_type].deinit();
- priv->storage_type = type;
- storages[priv->storage_type].init();
-
- return TRUE;
-}
-
static void fprint_device_list_enrolled_fingers(FprintDevice *rdev,
DBusGMethodInvocation *context)
{
@@ -683,7 +665,7 @@ static void fprint_device_list_enrolled_fingers(FprintDevice *rdev,
return;
}
- prints = storages[priv->storage_type].discover_prints(priv->dev, priv->username);
+ prints = store.discover_prints(priv->dev, priv->username);
if (!prints) {
g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_DISCOVER_PRINTS,
"Failed to discover prints");
@@ -720,7 +702,7 @@ static void fprint_device_delete_enrolled_fingers(FprintDevice *rdev,
}
for (i = LEFT_THUMB; i <= RIGHT_LITTLE; i++) {
- storages[priv->storage_type].print_data_delete(priv->dev, i, priv->username);
+ store.print_data_delete(priv->dev, i, priv->username);
}
dbus_g_method_return(context);
diff --git a/src/device.xml b/src/device.xml
index e87d680..64177db 100644
--- a/src/device.xml
+++ b/src/device.xml
@@ -47,11 +47,6 @@
-
-
-
-
-
diff --git a/src/main.c b/src/main.c
index e1d04aa..2a6bd61 100644
--- a/src/main.c
+++ b/src/main.c
@@ -27,8 +27,11 @@
#include
#include
#include
+#include
#include "fprintd.h"
+#include "storage.h"
+#include "file_storage.h"
DBusGConnection *fprintd_dbus_conn = NULL;
static gboolean g_fatal_warnings = FALSE;
@@ -200,6 +203,88 @@ static int setup_pollfds(void)
return 0;
}
+static void
+set_storage_file (void)
+{
+ store.init = &file_storage_init;
+ store.deinit = &file_storage_deinit;
+ store.print_data_save = &file_storage_print_data_save;
+ store.print_data_load = &file_storage_print_data_load;
+ store.print_data_delete = &file_storage_print_data_delete;
+ store.discover_prints = &file_storage_discover_prints;
+}
+
+static gboolean
+load_storage_module (const char *module_name)
+{
+ GModule *module;
+ char *filename;
+
+ filename = g_module_build_path (PLUGINDIR, module_name);
+ module = g_module_open (filename, 0);
+ g_free (filename);
+ if (module == NULL)
+ return FALSE;
+
+ if (!g_module_symbol (module, "init", (gpointer *) &store.init) ||
+ !g_module_symbol (module, "deinit", (gpointer *) &store.deinit) ||
+ !g_module_symbol (module, "print_data_save", (gpointer *) &store.print_data_save) ||
+ !g_module_symbol (module, "print_data_load", (gpointer *) &store.print_data_load) ||
+ !g_module_symbol (module, "print_data_delete", (gpointer *) &store.print_data_delete) ||
+ !g_module_symbol (module, "discover_prints", (gpointer *) &store.discover_prints)) {
+ g_module_close (module);
+ return FALSE;
+ }
+
+ g_module_make_resident (module);
+
+ return TRUE;
+}
+
+static gboolean
+load_conf (void)
+{
+ GKeyFile *file;
+ char *filename;
+ char *module_name;
+ GError *error = NULL;
+ gboolean ret;
+
+ filename = g_build_filename (SYSCONFDIR, "fprintd.conf", NULL);
+ file = g_key_file_new ();
+ if (!g_key_file_load_from_file (file, filename, G_KEY_FILE_NONE, &error)) {
+ g_print ("Could not open fprintd.conf: %s\n", error->message);
+ goto bail;
+ }
+
+ g_free (filename);
+ filename = NULL;
+
+ module_name = g_key_file_get_string (file, "storage", "type", &error);
+ if (module_name == NULL)
+ goto bail;
+
+ g_key_file_free (file);
+
+ if (g_str_equal (module_name, "file")) {
+ g_free (module_name);
+ set_storage_file ();
+ return TRUE;
+ }
+
+ ret = load_storage_module (module_name);
+ g_free (module_name);
+
+ return ret;
+
+bail:
+ g_key_file_free (file);
+ g_free (filename);
+ g_error_free (error);
+
+ return FALSE;
+}
+
static const GOptionEntry entries[] = {
{"g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, "Make all warnings fatal", NULL},
{ NULL }
@@ -237,6 +322,12 @@ int main(int argc, char **argv)
g_log_set_always_fatal (fatal_mask);
}
+ /* Load the configuration file,
+ * and the default storage plugin */
+ if (!load_conf())
+ set_storage_file ();
+ store.init ();
+
r = fp_init();
if (r < 0) {
g_error("fprint init failed with error %d\n", r);
diff --git a/src/storage.h b/src/storage.h
index a593985..76e7acd 100644
--- a/src/storage.h
+++ b/src/storage.h
@@ -22,8 +22,6 @@
#define STORAGE_H
-#include "file_storage.h"
-
typedef int (*storage_print_data_save)(struct fp_print_data *data,
enum fp_finger finger, const char *username);
typedef int (*storage_print_data_load)(struct fp_dev *dev,
@@ -45,26 +43,8 @@ struct storage {
typedef struct storage fp_storage;
-enum storage_type {
- FP_FILE_STORAGE = 0,
-
- FP_STORAGES_COUNT,
-};
-
-typedef enum storage_type fp_storage_type;
-
-fp_storage storages[FP_STORAGES_COUNT] = {
- {
- .init = &file_storage_init,
- .deinit = &file_storage_deinit,
- .print_data_save = &file_storage_print_data_save,
- .print_data_load = &file_storage_print_data_load,
- .print_data_delete = &file_storage_print_data_delete,
- .discover_prints = &file_storage_discover_prints,
- },
-
-};
-
+/* The currently setup store */
+fp_storage store;
#endif
diff --git a/tests/Makefile.am b/tests/Makefile.am
index aebfb16..0ddd29e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -5,12 +5,12 @@ CLEANFILES = $(BUILT_SOURCES)
bin_PROGRAMS = verify enroll
verify_SOURCES = verify.c
-verify_CFLAGS = $(AM_CFLAGS) $(DBUS_GLIB_CFLAGS)
-verify_LDADD = $(DBUS_GLIB_LIBS)
+verify_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS)
+verify_LDADD = $(GLIB_LIBS)
enroll_SOURCES = enroll.c
-enroll_CFLAGS = $(AM_CFLAGS) $(DBUS_GLIB_CFLAGS)
-enroll_LDADD = $(DBUS_GLIB_LIBS)
+enroll_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS)
+enroll_LDADD = $(GLIB_LIBS)
manager-dbus-glue.h: ../src/manager.xml
dbus-binding-tool --prefix=fprint_manager --mode=glib-client $< --output=$@