From bd2debc01ef7b54d8ee16c6c9bb6dcacc014dff0 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 29 Oct 2008 18:34:38 +0000 Subject: [PATCH] Update storage code to allow plugins Add naive plugin support to the storage code, it will load plugins from $(libdir)/fprintd/modules, given the configuration from /etc/fprintd.conf. --- TODO | 7 ---- configure.ac | 14 ++++---- src/Makefile.am | 4 +-- src/device.c | 28 +++------------ src/device.xml | 5 --- src/main.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++ src/storage.h | 24 ++----------- tests/Makefile.am | 8 ++--- 8 files changed, 110 insertions(+), 71 deletions(-) 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=$@