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.
This commit is contained in:
Bastien Nocera 2008-10-29 18:34:38 +00:00 committed by Daniel Drake
parent 96b444ed3e
commit bd2debc01e
8 changed files with 110 additions and 71 deletions

7
TODO
View file

@ -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

View file

@ -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"

View file

@ -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=$@

View file

@ -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);

View file

@ -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="" />

View file

@ -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);

View file

@ -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

View file

@ -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=$@