Commit bd2debc0 authored by Bastien Nocera's avatar Bastien Nocera Committed by Daniel Drake
Browse files

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.
parent 96b444ed
......@@ -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
......@@ -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"
......
......@@ -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=$@
......
......@@ -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);
......
......@@ -47,11 +47,6 @@
<arg type="i" name="result" />
</signal>
<method name="SetStorageType">
<arg type="u" name="storage_id" direction="in" />
<annotation name="org.freedesktop.DBus.GLib.Async" value="" />
</method>
<method name="SetUsername">
<arg type="s" name="username" direction="in" />
<annotation name="org.freedesktop.DBus.GLib.Async" value="" />
......
......@@ -27,8 +27,11 @@
#include <glib/gi18n.h>
#include <libfprint/fprint.h>
#include <glib-object.h>
#include <gmodule.h>
#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);
......
......@@ -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
......@@ -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=$@
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment