[Fingerforce-commits] r123 - in /packages/fprint/fprintd/trunk: ./ .git/ .git/logs/ .git/logs/refs/heads/ .git/logs/refs/remotes/origin/ .git/objects/pack/ .git/refs/heads/ .git/refs/remotes/origin/ data/ pam/ src/ tests/

dererk-guest at users.alioth.debian.org dererk-guest at users.alioth.debian.org
Thu Nov 6 17:18:40 UTC 2008


Author: dererk-guest
Date: Thu Nov  6 17:18:39 2008
New Revision: 123

URL: http://svn.debian.org/wsvn/fingerforce/?sc=1&rev=123
Log:
Updated to last git commit and added respective tarball.

Added:
    packages/fprint/fprintd/trunk/.git/FETCH_HEAD
    packages/fprint/fprintd/trunk/.git/ORIG_HEAD
    packages/fprint/fprintd/trunk/.git/objects/pack/pack-c3c651a7d792f6b0da4aab47d64c9ff0568fec29.idx   (with props)
    packages/fprint/fprintd/trunk/.git/objects/pack/pack-c3c651a7d792f6b0da4aab47d64c9ff0568fec29.pack   (with props)
    packages/fprint/fprintd/trunk/data/fprintd.conf
    packages/fprint/fprintd/trunk/pam/
    packages/fprint/fprintd/trunk/pam/Makefile.am
    packages/fprint/fprintd/trunk/pam/pam_fprintd.c
    packages/fprint/fprintd/trunk/src/egg-dbus-monitor.c
    packages/fprint/fprintd/trunk/src/egg-dbus-monitor.h
    packages/fprint/fprintd/trunk/tests/list.c
Modified:
    packages/fprint/fprintd/trunk/.git/index
    packages/fprint/fprintd/trunk/.git/logs/HEAD
    packages/fprint/fprintd/trunk/.git/logs/refs/heads/master
    packages/fprint/fprintd/trunk/.git/logs/refs/remotes/origin/master
    packages/fprint/fprintd/trunk/.git/refs/heads/master
    packages/fprint/fprintd/trunk/.git/refs/remotes/origin/master
    packages/fprint/fprintd/trunk/AUTHORS
    packages/fprint/fprintd/trunk/Makefile.am
    packages/fprint/fprintd/trunk/README
    packages/fprint/fprintd/trunk/TODO
    packages/fprint/fprintd/trunk/acinclude.m4
    packages/fprint/fprintd/trunk/configure.ac
    packages/fprint/fprintd/trunk/data/Makefile.am
    packages/fprint/fprintd/trunk/src/Makefile.am
    packages/fprint/fprintd/trunk/src/device.c
    packages/fprint/fprintd/trunk/src/device.xml
    packages/fprint/fprintd/trunk/src/file_storage.c
    packages/fprint/fprintd/trunk/src/file_storage.h
    packages/fprint/fprintd/trunk/src/fprintd.h
    packages/fprint/fprintd/trunk/src/main.c
    packages/fprint/fprintd/trunk/src/manager.c
    packages/fprint/fprintd/trunk/src/storage.h
    packages/fprint/fprintd/trunk/tests/Makefile.am
    packages/fprint/fprintd/trunk/tests/enroll.c
    packages/fprint/fprintd/trunk/tests/verify.c

Added: packages/fprint/fprintd/trunk/.git/FETCH_HEAD
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/.git/FETCH_HEAD?rev=123&op=file
==============================================================================
--- packages/fprint/fprintd/trunk/.git/FETCH_HEAD (added)
+++ packages/fprint/fprintd/trunk/.git/FETCH_HEAD Thu Nov  6 17:18:39 2008
@@ -1,0 +1,1 @@
+f93d8cbce2e66682ba77ad701b5855c699e3959d		branch 'master' of git://projects.reactivated.net/~dsd/fprintd

Added: packages/fprint/fprintd/trunk/.git/ORIG_HEAD
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/.git/ORIG_HEAD?rev=123&op=file
==============================================================================
--- packages/fprint/fprintd/trunk/.git/ORIG_HEAD (added)
+++ packages/fprint/fprintd/trunk/.git/ORIG_HEAD Thu Nov  6 17:18:39 2008
@@ -1,0 +1,1 @@
+46a9783be650758eb1617a200a0d3866abc30c55

Modified: packages/fprint/fprintd/trunk/.git/index
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/.git/index?rev=123&op=diff
==============================================================================
Binary files - no diff available.

Modified: packages/fprint/fprintd/trunk/.git/logs/HEAD
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/.git/logs/HEAD?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/.git/logs/HEAD (original)
+++ packages/fprint/fprintd/trunk/.git/logs/HEAD Thu Nov  6 17:18:39 2008
@@ -1,1 +1,2 @@
 0000000000000000000000000000000000000000 46a9783be650758eb1617a200a0d3866abc30c55 vlady <vlady at melee.(none)> 1221808814 -0300	clone: from git://projects.reactivated.net/~dsd/fprintd.git
+46a9783be650758eb1617a200a0d3866abc30c55 f93d8cbce2e66682ba77ad701b5855c699e3959d dererk <dererk at acheron.dererk.com.ar> 1225991455 -0200	pull : Fast forward

Modified: packages/fprint/fprintd/trunk/.git/logs/refs/heads/master
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/.git/logs/refs/heads/master?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/.git/logs/refs/heads/master (original)
+++ packages/fprint/fprintd/trunk/.git/logs/refs/heads/master Thu Nov  6 17:18:39 2008
@@ -1,1 +1,2 @@
 0000000000000000000000000000000000000000 46a9783be650758eb1617a200a0d3866abc30c55 vlady <vlady at melee.(none)> 1221808814 -0300	clone: from git://projects.reactivated.net/~dsd/fprintd.git
+46a9783be650758eb1617a200a0d3866abc30c55 f93d8cbce2e66682ba77ad701b5855c699e3959d dererk <dererk at acheron.dererk.com.ar> 1225991455 -0200	pull : Fast forward

Modified: packages/fprint/fprintd/trunk/.git/logs/refs/remotes/origin/master
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/.git/logs/refs/remotes/origin/master?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/.git/logs/refs/remotes/origin/master (original)
+++ packages/fprint/fprintd/trunk/.git/logs/refs/remotes/origin/master Thu Nov  6 17:18:39 2008
@@ -1,1 +1,2 @@
 0000000000000000000000000000000000000000 46a9783be650758eb1617a200a0d3866abc30c55 vlady <vlady at melee.(none)> 1221808814 -0300	clone: from git://projects.reactivated.net/~dsd/fprintd.git
+46a9783be650758eb1617a200a0d3866abc30c55 f93d8cbce2e66682ba77ad701b5855c699e3959d dererk <dererk at acheron.dererk.com.ar> 1225991455 -0200	pull : fast forward

Added: packages/fprint/fprintd/trunk/.git/objects/pack/pack-c3c651a7d792f6b0da4aab47d64c9ff0568fec29.idx
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/.git/objects/pack/pack-c3c651a7d792f6b0da4aab47d64c9ff0568fec29.idx?rev=123&op=file
==============================================================================
Binary file - no diff available.

Propchange: packages/fprint/fprintd/trunk/.git/objects/pack/pack-c3c651a7d792f6b0da4aab47d64c9ff0568fec29.idx
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: packages/fprint/fprintd/trunk/.git/objects/pack/pack-c3c651a7d792f6b0da4aab47d64c9ff0568fec29.pack
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/.git/objects/pack/pack-c3c651a7d792f6b0da4aab47d64c9ff0568fec29.pack?rev=123&op=file
==============================================================================
Binary file - no diff available.

Propchange: packages/fprint/fprintd/trunk/.git/objects/pack/pack-c3c651a7d792f6b0da4aab47d64c9ff0568fec29.pack
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: packages/fprint/fprintd/trunk/.git/refs/heads/master
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/.git/refs/heads/master?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/.git/refs/heads/master (original)
+++ packages/fprint/fprintd/trunk/.git/refs/heads/master Thu Nov  6 17:18:39 2008
@@ -1,1 +1,1 @@
-46a9783be650758eb1617a200a0d3866abc30c55
+f93d8cbce2e66682ba77ad701b5855c699e3959d

Modified: packages/fprint/fprintd/trunk/.git/refs/remotes/origin/master
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/.git/refs/remotes/origin/master?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/.git/refs/remotes/origin/master (original)
+++ packages/fprint/fprintd/trunk/.git/refs/remotes/origin/master Thu Nov  6 17:18:39 2008
@@ -1,1 +1,1 @@
-46a9783be650758eb1617a200a0d3866abc30c55
+f93d8cbce2e66682ba77ad701b5855c699e3959d

Modified: packages/fprint/fprintd/trunk/AUTHORS
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/AUTHORS?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/AUTHORS (original)
+++ packages/fprint/fprintd/trunk/AUTHORS Thu Nov  6 17:18:39 2008
@@ -1,2 +1,3 @@
 Daniel Drake <dsd at gentoo.org>
+Bastien Nocera <hadess at hadess.net>
 

Modified: packages/fprint/fprintd/trunk/Makefile.am
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/Makefile.am?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/Makefile.am (original)
+++ packages/fprint/fprintd/trunk/Makefile.am Thu Nov  6 17:18:39 2008
@@ -1,4 +1,4 @@
 AUTOMAKE_OPTIONS = dist-bzip2
-SUBDIRS = src data tests po
+SUBDIRS = src data tests pam po
 EXTRA_DIST = TODO intltool-extract.in intltool-merge.in intltool-update.in
 

Modified: packages/fprint/fprintd/trunk/README
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/README?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/README (original)
+++ packages/fprint/fprintd/trunk/README Thu Nov  6 17:18:39 2008
@@ -10,3 +10,27 @@
 
 Licensed under the GPL version 2 (see COPYING).
 
+An experimental PAM login module is included in the 'pam' directory.
+This will be moved to a separate package once the system has matured.
+
+API use cases
+=============
+
+- User wants to use the fingerprint reader, and enroll
+  his fingerprints, or remove some fingerprints from the database
+
+- Administrator wants to enroll fingerprints for a particular user,
+  or remove fingerprints for a particular user
+
+- Laptop/desktop authentication:
+  * Check for fingerprint devices
+  * Check whether a particular user has any fingerprints enrolled
+  * Verify a fingerprint for a particular user, or, if the device
+  supports it, verify that the fingerprint matches against
+  any of the fingerprints enrolled
+
+- Point Of Sale authentication (in a bar, the fingerprint reader is
+  used to see who accesses a particular point of sale/till, in place
+  of PIN code authentication and/or tokens)
+  * Given a list of users, verify which one has scanned their finger
+

Modified: packages/fprint/fprintd/trunk/TODO
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/TODO?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/TODO (original)
+++ packages/fprint/fprintd/trunk/TODO Thu Nov  6 17:18:39 2008
@@ -10,9 +10,11 @@
  only allow VerifyStop during a verification
  etc
 
+Add Device Properties:
+- device name
 
-- 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
+Rethink enums and results passed, should be strings and D-Bus errors
+
+Register fprintd' po file with Transifex, Rosetta or the Translation Project
+
+

Modified: packages/fprint/fprintd/trunk/acinclude.m4
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/acinclude.m4?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/acinclude.m4 (original)
+++ packages/fprint/fprintd/trunk/acinclude.m4 Thu Nov  6 17:18:39 2008
@@ -39,3 +39,144 @@
   exec_prefix=$exec_prefix_save
 ])
 
+dnl GNOME_COMPILE_WARNINGS
+dnl Turn on many useful compiler warnings
+dnl For now, only works on GCC
+AC_DEFUN([GNOME_COMPILE_WARNINGS],[
+    dnl ******************************
+    dnl More compiler warnings
+    dnl ******************************
+
+    AC_ARG_ENABLE(compile-warnings, 
+                  AC_HELP_STRING([--enable-compile-warnings=@<:@no/minimum/yes/maximum/error@:>@],
+                                 [Turn on compiler warnings]),,
+                  [enable_compile_warnings="m4_default([$1],[yes])"])
+
+    warnCFLAGS=
+    if test "x$GCC" != xyes; then
+	enable_compile_warnings=no
+    fi
+
+    warning_flags=
+    realsave_CFLAGS="$CFLAGS"
+
+    case "$enable_compile_warnings" in
+    no)
+	warning_flags=
+	;;
+    minimum)
+	warning_flags="-Wall"
+	;;
+    yes)
+	warning_flags="-Wall -Wmissing-prototypes"
+	;;
+    maximum|error)
+	warning_flags="-Wall -Wmissing-prototypes -Wnested-externs -Wpointer-arith"
+	CFLAGS="$warning_flags $CFLAGS"
+	for option in -Wno-sign-compare; do
+		SAVE_CFLAGS="$CFLAGS"
+		CFLAGS="$CFLAGS $option"
+		AC_MSG_CHECKING([whether gcc understands $option])
+		AC_TRY_COMPILE([], [],
+			has_option=yes,
+			has_option=no,)
+		CFLAGS="$SAVE_CFLAGS"
+		AC_MSG_RESULT($has_option)
+		if test $has_option = yes; then
+		  warning_flags="$warning_flags $option"
+		fi
+		unset has_option
+		unset SAVE_CFLAGS
+	done
+	unset option
+	if test "$enable_compile_warnings" = "error" ; then
+	    warning_flags="$warning_flags -Werror"
+	fi
+	;;
+    *)
+	AC_MSG_ERROR(Unknown argument '$enable_compile_warnings' to --enable-compile-warnings)
+	;;
+    esac
+    CFLAGS="$realsave_CFLAGS"
+    AC_MSG_CHECKING(what warning flags to pass to the C compiler)
+    AC_MSG_RESULT($warning_flags)
+
+    AC_ARG_ENABLE(iso-c,
+                  AC_HELP_STRING([--enable-iso-c],
+                                 [Try to warn if code is not ISO C ]),,
+                  [enable_iso_c=no])
+
+    AC_MSG_CHECKING(what language compliance flags to pass to the C compiler)
+    complCFLAGS=
+    if test "x$enable_iso_c" != "xno"; then
+	if test "x$GCC" = "xyes"; then
+	case " $CFLAGS " in
+	    *[\ \	]-ansi[\ \	]*) ;;
+	    *) complCFLAGS="$complCFLAGS -ansi" ;;
+	esac
+	case " $CFLAGS " in
+	    *[\ \	]-pedantic[\ \	]*) ;;
+	    *) complCFLAGS="$complCFLAGS -pedantic" ;;
+	esac
+	fi
+    fi
+    AC_MSG_RESULT($complCFLAGS)
+
+    WARN_CFLAGS="$warning_flags $complCFLAGS"
+    AC_SUBST(WARN_CFLAGS)
+])
+
+dnl For C++, do basically the same thing.
+
+AC_DEFUN([GNOME_CXX_WARNINGS],[
+  AC_ARG_ENABLE(cxx-warnings,
+                AC_HELP_STRING([--enable-cxx-warnings=@<:@no/minimum/yes@:>@]
+                               [Turn on compiler warnings.]),,
+                [enable_cxx_warnings="m4_default([$1],[minimum])"])
+
+  AC_MSG_CHECKING(what warning flags to pass to the C++ compiler)
+  warnCXXFLAGS=
+  if test "x$GXX" != xyes; then
+    enable_cxx_warnings=no
+  fi
+  if test "x$enable_cxx_warnings" != "xno"; then
+    if test "x$GXX" = "xyes"; then
+      case " $CXXFLAGS " in
+      *[\ \	]-Wall[\ \	]*) ;;
+      *) warnCXXFLAGS="-Wall -Wno-unused" ;;
+      esac
+
+      ## -W is not all that useful.  And it cannot be controlled
+      ## with individual -Wno-xxx flags, unlike -Wall
+      if test "x$enable_cxx_warnings" = "xyes"; then
+	warnCXXFLAGS="$warnCXXFLAGS -Wshadow -Woverloaded-virtual"
+      fi
+    fi
+  fi
+  AC_MSG_RESULT($warnCXXFLAGS)
+
+   AC_ARG_ENABLE(iso-cxx,
+                 AC_HELP_STRING([--enable-iso-cxx],
+                                [Try to warn if code is not ISO C++ ]),,
+                 [enable_iso_cxx=no])
+
+   AC_MSG_CHECKING(what language compliance flags to pass to the C++ compiler)
+   complCXXFLAGS=
+   if test "x$enable_iso_cxx" != "xno"; then
+     if test "x$GXX" = "xyes"; then
+      case " $CXXFLAGS " in
+      *[\ \	]-ansi[\ \	]*) ;;
+      *) complCXXFLAGS="$complCXXFLAGS -ansi" ;;
+      esac
+
+      case " $CXXFLAGS " in
+      *[\ \	]-pedantic[\ \	]*) ;;
+      *) complCXXFLAGS="$complCXXFLAGS -pedantic" ;;
+      esac
+     fi
+   fi
+  AC_MSG_RESULT($complCXXFLAGS)
+
+  WARN_CXXFLAGS="$CXXFLAGS $warnCXXFLAGS $complCXXFLAGS"
+  AC_SUBST(WARN_CXXFLAGS)
+])

Modified: packages/fprint/fprintd/trunk/configure.ac
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/configure.ac?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/configure.ac (original)
+++ packages/fprint/fprintd/trunk/configure.ac Thu Nov  6 17:18:39 2008
@@ -17,17 +17,32 @@
 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(DAEMON, glib-2.0 dbus-glib-1 gmodule-2.0 polkit >= 0.8 polkit-dbus)
+AC_SUBST(DAEMON_LIBS)
+AC_SUBST(DAEMON_CFLAGS)
 
-PKG_CHECK_MODULES(POLKIT, "polkit polkit-dbus")
-AC_SUBST(POLKIT_LIBS)
-AC_SUBST(POLKIT_CFLAGS)
+AC_ARG_ENABLE(pam, AC_HELP_STRING([--enable-pam],[Build the fprintd PAM module]), enable_pam="$enableval", enable_pam=yes)
+has_pam=no
+if test x$enable_pam = xyes; then
+	has_pam=yes
+	AC_CHECK_HEADER([security/pam_modules.h], [has_pam=yes] , [has_pam=no])
+	if test x$has_pam = xyes; then
+		has_pam=no
+		AC_CHECK_LIB(pam, pam_start, [PAM_LIBS="-lpam"
+					      has_pam=yes],
+			has_pam=no)
+	fi
+	AC_SUBST(PAM_LIBS)
+fi
+AM_CONDITIONAL(HAVE_PAM, test "x$has_pam" = "xyes")
+
+AC_MSG_CHECKING(for PAM headers and library)
+AC_MSG_RESULT([$has_pam])
+
 
 AC_CHECK_PROG([POLKIT_POLICY_FILE_VALIDATE],
 	      [polkit-policy-file-validate], [polkit-policy-file-validate])
@@ -38,15 +53,10 @@
 AC_SUBST(DBUS_SERVICES_DIR)
 AC_DEFINE_UNQUOTED(DBUS_SERVICES_DIR, "$DBUS_SERVICES_DIR", [Where services dir for DBUS is])
 
-# Restore gnu89 inline semantics on gcc 4.3 and newer
-saved_cflags="$CFLAGS"
-CFLAGS="$CFLAGS -fgnu89-inline"
-AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]), inline_cflags="-fgnu89-inline", inline_cflags="")
-CFLAGS="$saved_cflags"
+AC_DEFINE_UNQUOTED(SYSCONFDIR, "$sysconfdir", [Where the configuration file will be located])
 
-AM_CFLAGS="-std=gnu99 $inline_cflags -Wall -Wundef -Wunused -Wstrict-prototypes -Werror-implicit-function-declaration -Wno-pointer-sign -Wshadow"
-AC_SUBST(AM_CFLAGS)
+GNOME_COMPILE_WARNINGS
 
-AC_CONFIG_FILES([Makefile] [src/Makefile] [data/Makefile] [tests/Makefile] [po/Makefile.in])
+AC_CONFIG_FILES([Makefile] [src/Makefile] [data/Makefile] [tests/Makefile] [pam/Makefile] [po/Makefile.in])
 AC_OUTPUT
 

Modified: packages/fprint/fprintd/trunk/data/Makefile.am
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/data/Makefile.am?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/data/Makefile.am (original)
+++ packages/fprint/fprintd/trunk/data/Makefile.am Thu Nov  6 17:18:39 2008
@@ -15,6 +15,9 @@
 @INTLTOOL_POLICY_RULE@
 polkit_DATA = $(polkit_in_files:.policy.in=.policy)
 
+confdir = $(sysconfdir)/
+conf_DATA = fprintd.conf
+
 check:
 	$(POLKIT_POLICY_FILE_VALIDATE) $(polkit_DATA)
 

Added: packages/fprint/fprintd/trunk/data/fprintd.conf
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/data/fprintd.conf?rev=123&op=file
==============================================================================
--- packages/fprint/fprintd/trunk/data/fprintd.conf (added)
+++ packages/fprint/fprintd/trunk/data/fprintd.conf Thu Nov  6 17:18:39 2008
@@ -1,0 +1,2 @@
+[storage]
+type=file

Added: packages/fprint/fprintd/trunk/pam/Makefile.am
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/pam/Makefile.am?rev=123&op=file
==============================================================================
--- packages/fprint/fprintd/trunk/pam/Makefile.am (added)
+++ packages/fprint/fprintd/trunk/pam/Makefile.am Thu Nov  6 17:18:39 2008
@@ -1,0 +1,13 @@
+if HAVE_PAM
+
+pammod_PROGRAMS = pam_fprintd.so
+pammoddir=/lib/security
+
+pam_fprintd_so_SOURCES = pam_fprintd.c
+pam_fprintd_so_CFLAGS = -fPIC $(WARN_CFLAGS) $(GLIB_CFLAGS)
+pam_fprintd_so_LDFLAGS = -shared
+pam_fprintd_so_LDADD = $(PAM_LIBS) $(GLIB_LIBS)
+
+endif
+
+EXTRA_DIST = pam_fprint.c

Added: packages/fprint/fprintd/trunk/pam/pam_fprintd.c
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/pam/pam_fprintd.c?rev=123&op=file
==============================================================================
--- packages/fprint/fprintd/trunk/pam/pam_fprintd.c (added)
+++ packages/fprint/fprintd/trunk/pam/pam_fprintd.c Thu Nov  6 17:18:39 2008
@@ -1,0 +1,381 @@
+/*
+ * pam_fprint: PAM module for fingerprint authentication through fprintd
+ * Copyright (C) 2007 Daniel Drake <dsd at gentoo.org>
+ * Copyright (C) 2008 Bastien Nocera <hadess at hadess.net>
+ * 
+ * Experimental code. This will be moved out of fprintd into it's own
+ * package once the system has matured.
+ *
+ * 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 2 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <string.h>
+
+#include <dbus/dbus-glib-bindings.h>
+
+#define PAM_SM_AUTH
+#include <security/pam_modules.h>
+
+#define MAX_TRIES 3
+#define TIMEOUT 30
+
+enum fp_verify_result {
+	VERIFY_NO_MATCH = 0,
+	VERIFY_MATCH = 1,
+	VERIFY_RETRY = 100,
+	VERIFY_RETRY_TOO_SHORT = 101,
+	VERIFY_RETRY_CENTER_FINGER = 102,
+	VERIFY_RETRY_REMOVE_FINGER = 103,
+};
+
+static const char *verify_result_str(int result)
+{
+	switch (result) {
+	case VERIFY_NO_MATCH:
+		return "No match";
+	case VERIFY_MATCH:
+		return "Match!";
+	case VERIFY_RETRY:
+		return "Retry scan";
+	case VERIFY_RETRY_TOO_SHORT:
+		return "Swipe too short, please retry";
+	case VERIFY_RETRY_CENTER_FINGER:
+		return "Finger not centered, please retry";
+	case VERIFY_RETRY_REMOVE_FINGER:
+		return "Please remove finger and retry";
+	default:
+		return "Unknown";
+	}
+}
+
+enum fp_finger {
+	LEFT_THUMB = 1, /** thumb (left hand) */
+	LEFT_INDEX, /** index finger (left hand) */
+	LEFT_MIDDLE, /** middle finger (left hand) */
+	LEFT_RING, /** ring finger (left hand) */
+	LEFT_LITTLE, /** little finger (left hand) */
+	RIGHT_THUMB, /** thumb (right hand) */
+	RIGHT_INDEX, /** index finger (right hand) */
+	RIGHT_MIDDLE, /** middle finger (right hand) */
+	RIGHT_RING, /** ring finger (right hand) */
+	RIGHT_LITTLE, /** little finger (right hand) */
+};
+
+static gboolean send_info_msg(pam_handle_t *pamh, const char *msg)
+{
+	const struct pam_message mymsg = {
+		.msg_style = PAM_TEXT_INFO,
+		.msg = msg,
+	};
+	const struct pam_message *msgp = &mymsg;
+	const struct pam_conv *pc;
+	struct pam_response *resp;
+	int r;
+
+	r = pam_get_item(pamh, PAM_CONV, (const void **) &pc);
+	if (r != PAM_SUCCESS)
+		return FALSE;
+
+	if (!pc || !pc->conv)
+		return FALSE;
+
+	return (pc->conv(1, &msgp, &resp, pc->appdata_ptr) == PAM_SUCCESS);
+}
+
+static gboolean send_err_msg(pam_handle_t *pamh, const char *msg)
+{
+	const struct pam_message mymsg = {
+		.msg_style = PAM_ERROR_MSG,
+		.msg = msg,
+	};
+	const struct pam_message *msgp = &mymsg;
+	const struct pam_conv *pc;
+	struct pam_response *resp;
+	int r;
+
+	r = pam_get_item(pamh, PAM_CONV, (const void **) &pc);
+	if (r != PAM_SUCCESS)
+		return FALSE;
+
+	if (!pc || !pc->conv)
+		return FALSE;
+
+	return (pc->conv(1, &msgp, &resp, pc->appdata_ptr) == PAM_SUCCESS);
+}
+
+
+static const char *fingerstr(enum fp_finger finger)
+{
+	const char *names[] = {
+		[LEFT_THUMB] = "left thumb",
+		[LEFT_INDEX] = "left index",
+		[LEFT_MIDDLE] = "left middle",
+		[LEFT_RING] = "left ring",
+		[LEFT_LITTLE] = "left little",
+		[RIGHT_THUMB] = "right thumb",
+		[RIGHT_INDEX] = "right index",
+		[RIGHT_MIDDLE] = "right middle",
+		[RIGHT_RING] = "right ring",
+		[RIGHT_LITTLE] = "right little",
+	};
+	if (finger < LEFT_THUMB || finger > RIGHT_LITTLE)
+		return "UNKNOWN";
+	return names[finger];
+}
+
+static DBusGProxy *create_manager (DBusGConnection **ret_conn)
+{
+	GError *error = NULL;
+	DBusGConnection *connection;
+	DBusGProxy *manager;
+
+	connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
+	if (connection == NULL) {
+		g_error_free (error);
+		return NULL;
+	}
+
+	manager = dbus_g_proxy_new_for_name(connection,
+					    "net.reactivated.Fprint", "/net/reactivated/Fprint/Manager",
+					    "net.reactivated.Fprint.Manager");
+	*ret_conn = connection;
+
+	return manager;
+}
+
+static DBusGProxy *open_device(DBusGConnection *connection, DBusGProxy *manager, const char *username)
+{
+	GError *error = NULL;
+	GPtrArray *devices;
+	gchar *path;
+	DBusGProxy *dev;
+
+	if (!dbus_g_proxy_call (manager, "GetDevices", &error,
+				G_TYPE_INVALID, dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
+				&devices, G_TYPE_INVALID)) {
+		//g_print("list_devices failed: %s", error->message);
+		g_error_free (error);
+		return NULL;
+	}
+	
+	if (devices->len == 0) {
+		//g_print("No devices found\n");
+		return NULL;
+	}
+
+	//g_print("found %d devices\n", devices->len);
+	path = g_ptr_array_index(devices, 0);
+	//g_print("Using device %s\n", path);
+
+	dev = dbus_g_proxy_new_for_name(connection,
+					"net.reactivated.Fprint",
+					path,
+					"net.reactivated.Fprint.Device");
+	
+	g_ptr_array_foreach(devices, (GFunc) g_free, NULL);
+	g_ptr_array_free(devices, TRUE);
+
+	if (!dbus_g_proxy_call (dev, "Claim", &error, G_TYPE_STRING, username, G_TYPE_INVALID, G_TYPE_INVALID)) {
+		//g_print("failed to claim device: %s\n", error->message);
+		g_error_free (error);
+		g_object_unref (dev);
+		return NULL;
+	}
+	return dev;
+}
+
+typedef struct {
+	guint max_tries;
+	int result;
+	gboolean verify_completed;
+	gboolean timed_out;
+	pam_handle_t *pamh;
+} verify_data;
+
+static void verify_result(GObject *object, int result, gpointer user_data)
+{
+	verify_data *data = user_data;
+
+	//g_print("Verify result: %s (%d)\n", verify_result_str(result), result);
+	if (result == VERIFY_NO_MATCH || result == VERIFY_MATCH) {
+		data->verify_completed = TRUE;
+		data->result = result;
+	}
+}
+
+static void verify_finger_selected(GObject *object, int finger, gpointer user_data)
+{
+	verify_data *data = user_data;
+	char *msg;
+	//FIXME
+	const char *driver_name = "Fingerprint reader";
+
+	if (finger == -1) {
+		msg = g_strdup_printf ("Scan finger on %s", driver_name);
+	} else {
+		msg = g_strdup_printf ("Scan %s finger on %s", fingerstr(finger), driver_name);
+	}
+	send_info_msg (data->pamh, msg);
+	g_free (msg);
+}
+
+static gboolean verify_timeout_cb (gpointer user_data)
+{
+	verify_data *data = user_data;
+
+	data->timed_out = TRUE;
+	data->verify_completed = TRUE;
+
+	send_info_msg (data->pamh, "Verification timed out");
+
+	return FALSE;
+}
+
+static int do_verify(pam_handle_t *pamh, DBusGProxy *dev)
+{
+	GError *error;
+	verify_data *data;
+	int ret;
+
+	data = g_new0 (verify_data, 1);
+	data->max_tries = MAX_TRIES;
+	data->pamh = pamh;
+
+	dbus_g_proxy_add_signal(dev, "VerifyStatus", G_TYPE_INT, NULL);
+	dbus_g_proxy_add_signal(dev, "VerifyFingerSelected", G_TYPE_INT, NULL);
+	dbus_g_proxy_connect_signal(dev, "VerifyStatus", G_CALLBACK(verify_result),
+				    data, NULL);
+	dbus_g_proxy_connect_signal(dev, "VerifyFingerSelected", G_CALLBACK(verify_finger_selected),
+				    data, NULL);
+
+
+	ret = PAM_AUTH_ERR;
+
+	while (ret == PAM_AUTH_ERR && data->max_tries > 0) {
+		guint timeout_id;
+
+		timeout_id = g_timeout_add_seconds (TIMEOUT, verify_timeout_cb, data);
+
+		if (!dbus_g_proxy_call (dev, "VerifyStart", &error, G_TYPE_UINT, -1, G_TYPE_INVALID, G_TYPE_INVALID)) {
+			//g_print("VerifyStart failed: %s", error->message);
+			g_error_free (error);
+			break;
+		}
+
+		while (!data->verify_completed)
+			g_main_context_iteration(NULL, TRUE);
+
+		/* Ignore errors from VerifyStop */
+		dbus_g_proxy_call (dev, "VerifyStop", NULL, G_TYPE_INVALID, G_TYPE_INVALID);
+
+		g_source_remove (timeout_id);
+
+		if (data->timed_out)
+			ret = PAM_AUTHINFO_UNAVAIL;
+		else {
+			if (data->result == VERIFY_NO_MATCH)
+				ret = PAM_AUTH_ERR;
+			else if (data->result == VERIFY_MATCH)
+				ret = PAM_SUCCESS;
+			else if (data->result < 0)
+				ret = PAM_AUTHINFO_UNAVAIL;
+			else {
+				send_info_msg (data->pamh, verify_result_str (data->result));
+				ret = PAM_AUTH_ERR;
+			}
+		}
+		data->max_tries--;
+	}
+
+	dbus_g_proxy_disconnect_signal(dev, "VerifyStatus", G_CALLBACK(verify_result), data);
+	dbus_g_proxy_disconnect_signal(dev, "VerifyFingerSelected", G_CALLBACK(verify_finger_selected), data);
+
+	g_free (data);
+
+	return ret;
+}
+
+static void release_device(DBusGProxy *dev)
+{
+	GError *error = NULL;
+	if (!dbus_g_proxy_call (dev, "Release", &error, G_TYPE_INVALID, G_TYPE_INVALID)) {
+		//g_print ("ReleaseDevice failed: %s\n", error->message);
+		g_error_free (error);
+	}
+}
+
+static int do_auth(pam_handle_t *pamh, const char *username)
+{
+	DBusGProxy *manager;
+	DBusGConnection *connection;
+	GMainLoop *loop;
+	DBusGProxy *dev;
+	int ret;
+
+	loop = g_main_loop_new(NULL, FALSE);
+	manager = create_manager (&connection);
+	if (manager == NULL)
+		return PAM_AUTHINFO_UNAVAIL;
+
+	dev = open_device(connection, manager, username);
+	g_object_unref (manager);
+	if (!dev)
+		return PAM_AUTHINFO_UNAVAIL;
+	ret = do_verify(pamh, dev);
+	release_device(dev);
+	g_object_unref (dev);
+
+	return ret;
+}
+
+PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
+				   const char **argv)
+{
+	const char *rhost = NULL;
+	const char *username;
+	int r;
+
+	g_type_init ();
+
+	pam_get_item(pamh, PAM_RHOST, (const void **)(const void*) &rhost);
+	if (rhost != NULL && strlen(rhost) > 0) {
+		/* remote login (e.g. over SSH) */
+		return PAM_AUTHINFO_UNAVAIL;
+	}
+
+	r = pam_get_user(pamh, &username, NULL);
+	if (r != PAM_SUCCESS)
+		return PAM_AUTHINFO_UNAVAIL;
+
+	r = do_auth(pamh, username);
+
+	return r;
+}
+
+PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc,
+			      const char **argv)
+{
+	return PAM_SUCCESS;
+}
+
+PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc,
+				const char **argv)
+{
+	return PAM_SUCCESS;
+}
+

Modified: packages/fprint/fprintd/trunk/src/Makefile.am
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/src/Makefile.am?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/src/Makefile.am (original)
+++ packages/fprint/fprintd/trunk/src/Makefile.am Thu Nov  6 17:18:39 2008
@@ -6,9 +6,9 @@
 
 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_SOURCES = main.c manager.c device.c file_storage.c egg-dbus-monitor.c egg-dbus-monitor.h
+fprintd_LDADD = $(FPRINT_LIBS) $(DAEMON_LIBS)
+fprintd_CFLAGS = $(WARN_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=$@

Modified: packages/fprint/fprintd/trunk/src/device.c
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/src/device.c?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/src/device.c (original)
+++ packages/fprint/fprintd/trunk/src/device.c Thu Nov  6 17:18:39 2008
@@ -31,18 +31,15 @@
 
 #include "fprintd.h"
 #include "storage.h"
+#include "egg-dbus-monitor.h"
 
 extern DBusGConnection *fprintd_dbus_conn;
 
-static void fprint_device_set_username(FprintDevice *rdev,
-	const char *username,
-	DBusGMethodInvocation *context);
 static void fprint_device_claim(FprintDevice *rdev,
-	DBusGMethodInvocation *context);
+				const char *username,
+				DBusGMethodInvocation *context);
 static void fprint_device_release(FprintDevice *rdev,
 	DBusGMethodInvocation *context);
-static void fprint_device_unload_print_data(FprintDevice *rdev,
-	guint32 print_id, DBusGMethodInvocation *context);
 static void fprint_device_verify_start(FprintDevice *rdev,
 	guint32 print_id, DBusGMethodInvocation *context);
 static void fprint_device_verify_stop(FprintDevice *rdev,
@@ -51,14 +48,21 @@
 	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_load_print_data(FprintDevice *rdev,
-	guint32 finger_num, DBusGMethodInvocation *context);
+						const char *username,
+						DBusGMethodInvocation *context);
+static void fprint_device_delete_enrolled_fingers(FprintDevice *rdev,
+						  const char *username,
+						  DBusGMethodInvocation *context);
 
 #include "device-dbus-glue.h"
+
+typedef enum {
+	ACTION_NONE = 0,
+	ACTION_IDENTIFY,
+	ACTION_VERIFY,
+	ACTION_ENROLL
+} FprintDeviceAction;
 
 struct session_data {
 	/* finger being enrolled */
@@ -69,15 +73,6 @@
 
 	/* method invocation for async ReleaseDevice() */
 	DBusGMethodInvocation *context_release_device;
-
-	/* a list of loaded prints */
-	GSList *loaded_prints;
-
-};
-
-struct loaded_print {
-	guint32 id;
-	struct fp_print_data *data;
 };
 
 struct FprintDevicePrivate {
@@ -91,12 +86,18 @@
 	/* The current user of the device, if claimed */
 	char *sender;
 
-	/* Either the current user of the device, or if allowed,
-	 * what was set using SetUsername */
+	/* The current user of the device, or if allowed,
+	 * what was passed as a username argument */
 	char *username;
 
 	/* type of storage */
 	int storage_type;
+
+	/* Hashtable of connected clients */
+	GHashTable *clients;
+
+	/* whether we're running an identify, or a verify */
+	FprintDeviceAction current_action;
 };
 
 typedef struct FprintDevicePrivate FprintDevicePrivate;
@@ -105,10 +106,12 @@
 
 enum fprint_device_properties {
 	FPRINT_DEVICE_CONSTRUCT_DDEV = 1,
+	FPRINT_DEVICE_IN_USE,
 };
 
 enum fprint_device_signals {
 	SIGNAL_VERIFY_STATUS,
+	SIGNAL_VERIFY_FINGER_SELECTED,
 	SIGNAL_ENROLL_STATUS,
 	NUM_SIGNALS,
 };
@@ -119,6 +122,10 @@
 
 static void fprint_device_finalize(GObject *object)
 {
+	FprintDevice *self = (FprintDevice *) object;
+	FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(self);
+
+	g_hash_table_destroy (priv->clients);
 	/* FIXME close and stuff */
 }
 
@@ -138,6 +145,22 @@
 	}
 }
 
+static void fprint_device_get_property(GObject *object, guint property_id,
+				       GValue *value, GParamSpec *pspec)
+{
+	FprintDevice *self = (FprintDevice *) object;
+	FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(self);
+
+	switch (property_id) {
+	case FPRINT_DEVICE_IN_USE:
+		g_value_set_boolean(value, g_hash_table_size (priv->clients) != 0);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
+		break;
+	}
+}
+
 static void fprint_device_class_init(FprintDeviceClass *klass)
 {
 	GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
@@ -149,6 +172,7 @@
 
 	gobject_class->finalize = fprint_device_finalize;
 	gobject_class->set_property = fprint_device_set_property;
+	gobject_class->get_property = fprint_device_get_property;
 	g_type_class_add_private(klass, sizeof(FprintDevicePrivate));
 
 	pspec = g_param_spec_pointer("discovered-dev", "Discovered device",
@@ -156,11 +180,19 @@
 		G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
 	g_object_class_install_property(gobject_class,
 		FPRINT_DEVICE_CONSTRUCT_DDEV, pspec);
+	pspec = g_param_spec_boolean("in-use", "In use",
+				 "Whether the device is currently in use", FALSE,
+				 G_PARAM_READABLE);
+	g_object_class_install_property(gobject_class,
+					FPRINT_DEVICE_IN_USE, pspec);
 
 	signals[SIGNAL_VERIFY_STATUS] = g_signal_new("verify-status",
 		G_TYPE_FROM_CLASS(gobject_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL,
 		g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
 	signals[SIGNAL_ENROLL_STATUS] = g_signal_new("enroll-status",
+		G_TYPE_FROM_CLASS(gobject_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL,
+		g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
+	signals[SIGNAL_VERIFY_FINGER_SELECTED] = g_signal_new("verify-finger-selected",
 		G_TYPE_FROM_CLASS(gobject_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL,
 		g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT);
 }
@@ -203,8 +235,6 @@
 {
 	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 ();
@@ -214,6 +244,10 @@
 		polkit_context_unref (priv->pol_ctx);
 		priv->pol_ctx = NULL;
 	}
+	priv->clients = g_hash_table_new_full (g_str_hash,
+					       g_str_equal,
+					       g_free,
+					       g_object_unref);
 }
 
 G_DEFINE_TYPE(FprintDevice, fprint_device, G_TYPE_OBJECT);
@@ -320,93 +354,174 @@
 	return _fprint_device_check_polkit_for_action (rdev, context, action2, error);
 }
 
-static void
-fprint_device_set_username (FprintDevice *rdev,
-			    const char *username,
-			    DBusGMethodInvocation *context)
-{
-	FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev);
-	GError *error = NULL;
-	struct session_data *session = priv->session;
-	GSList *elem = session->loaded_prints;
-
-	if (_fprint_device_check_claimed(rdev, context, &error) == FALSE) {
-		dbus_g_method_return_error (context, error);
-		return;
-	}
-
-	if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.setusername", &error) == FALSE) {
-		dbus_g_method_return_error (context, error);
-		return;
-	}
-
-	if (username == NULL) {
-		dbus_g_method_return (context);
-		return;
-	}
-
-	/* We already have a username, check if the one we're
-	 * setting is the same */
-	if (g_str_equal (username, priv->username) != FALSE) {
-		dbus_g_method_return (context);
-		return;
-	}
-
-	g_free (priv->username);
-	priv->username = g_strdup (username);
-
-	/* Any fingerprints to unload? */
-	if (!elem) {
-		dbus_g_method_return (context);
-		return;
-	}
-
-	/* Empty the fingerprints, as we have a different user */
-	do {
-		struct loaded_print *print = elem->data;
-
-		session->loaded_prints = g_slist_delete_link(session->loaded_prints,
-			elem);
-		g_slice_free(struct loaded_print, print);
-	} while ((elem = g_slist_next(elem)) != NULL);
-
-	dbus_g_method_return (context);
-}
-
-static void dev_open_cb(struct fp_dev *dev, int status, void *user_data)
-{
-	FprintDevice *rdev = user_data;
-	FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev);
-	struct session_data *session = priv->session;
-
-	g_message("device %d claim status %d", priv->id, status);
-
-	if (status != 0) {
-		GError *error;
-
-		g_free (priv->sender);
-		priv->sender = NULL;
-
-		g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_CLAIM_DEVICE,
-			"Open failed with error %d", status);
-		dbus_g_method_return_error(session->context_claim_device, error);
-		return;
-	}
-
-	priv->dev = dev;
-	dbus_g_method_return(session->context_claim_device);
-}
-
-static void fprint_device_claim(FprintDevice *rdev,
-	DBusGMethodInvocation *context)
-{
-	FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev);
-	GError *error = NULL;
+static char *
+_fprint_device_check_for_username (FprintDevice *rdev,
+				   DBusGMethodInvocation *context,
+				   const char *username,
+				   char **ret_sender,
+				   GError **error)
+{
 	DBusConnection *conn;
 	DBusError dbus_error;
 	char *sender;
 	unsigned long uid;
 	struct passwd *user;
+	char *client_username;
+
+	/* Get details about the current sender, and username/uid */
+	conn = dbus_g_connection_get_connection (fprintd_dbus_conn);
+	sender = dbus_g_method_get_sender (context);
+	dbus_error_init (&dbus_error);
+	uid = dbus_bus_get_unix_user (conn, sender, &dbus_error);
+
+	if (dbus_error_is_set(&dbus_error)) {
+		g_free (sender);
+		dbus_set_g_error (error, &dbus_error);
+		return NULL;
+	}
+
+	user = getpwuid (uid);
+	if (user == NULL) {
+		g_free (sender);
+		g_set_error(error, FPRINT_ERROR, FPRINT_ERROR_CLAIM_DEVICE,
+			    "Failed to get information about user UID %lu", uid);
+		return NULL;
+	}
+	client_username = g_strdup (user->pw_name);
+
+	/* The current user is usually allowed to access their
+	 * own data, this should be followed by PolicyKit checks
+	 * anyway */
+	if (username == NULL || *username == '\0' || g_str_equal (username, client_username)) {
+		if (ret_sender != NULL)
+			*ret_sender = sender;
+		else
+			g_free (sender);
+		return client_username;
+	}
+
+	/* If we're not allowed to set a different username,
+	 * then fail */
+	if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.setusername", error) == FALSE) {
+		g_free (sender);
+		return NULL;
+	}
+
+	if (ret_sender != NULL)
+		*ret_sender = sender;
+	else
+		g_free (sender);
+
+	return g_strdup (username);
+}
+
+static void action_stop_cb(struct fp_dev *dev, void *user_data)
+{
+	gboolean *done = (gboolean *) user_data;
+	*done = TRUE;
+}
+
+static void
+_fprint_device_client_disconnected (EggDbusMonitor *monitor, gboolean connected, FprintDevice *rdev)
+{
+	FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev);
+
+	if (connected == FALSE) {
+		const char *sender;
+		sender = egg_dbus_monitor_get_service (monitor);
+
+		/* Was that the client that claimed the device? */
+		if (priv->sender != NULL) {
+			gboolean done = FALSE;
+			switch (priv->current_action) {
+			case ACTION_NONE:
+				break;
+			case ACTION_IDENTIFY:
+				fp_async_identify_stop(priv->dev, action_stop_cb, &done);
+				while (done == FALSE)
+					g_main_context_iteration (NULL, TRUE);
+				break;
+			case ACTION_VERIFY:
+				fp_async_verify_stop(priv->dev, action_stop_cb, &done);
+				while (done == FALSE)
+					g_main_context_iteration (NULL, TRUE);
+				break;
+			case ACTION_ENROLL:
+				fp_async_enroll_stop(priv->dev, action_stop_cb, &done);
+				while (done == FALSE)
+					g_main_context_iteration (NULL, TRUE);
+				break;
+			}
+			priv->current_action = ACTION_NONE;
+			done = FALSE;
+
+			/* Close the claimed device as well */
+			fp_async_dev_close (priv->dev, action_stop_cb, &done);
+			while (done == FALSE)
+				g_main_context_iteration (NULL, TRUE);
+
+			g_free (priv->sender);
+			priv->sender = NULL;
+			g_free (priv->username);
+			priv->username = NULL;
+		}
+		g_hash_table_remove (priv->clients, sender);
+	}
+
+	if (g_hash_table_size (priv->clients) == 0) {
+		g_object_notify (G_OBJECT (rdev), "in-use");
+	}
+}
+
+static void
+_fprint_device_add_client (FprintDevice *rdev, const char *sender)
+{
+	EggDbusMonitor *monitor;
+	FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev);
+
+	monitor = g_hash_table_lookup (priv->clients, sender);
+	if (monitor == NULL) {
+		monitor = egg_dbus_monitor_new ();
+		egg_dbus_monitor_assign (monitor, fprintd_dbus_conn, sender);
+		//FIXME handle replaced
+		g_signal_connect (G_OBJECT (monitor), "connection-changed",
+					 G_CALLBACK (_fprint_device_client_disconnected), rdev);
+		g_hash_table_insert (priv->clients, g_strdup (sender), monitor);
+		g_object_notify (G_OBJECT (rdev), "in-use");
+	}
+}
+
+static void dev_open_cb(struct fp_dev *dev, int status, void *user_data)
+{
+	FprintDevice *rdev = user_data;
+	FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev);
+	struct session_data *session = priv->session;
+
+	g_message("device %d claim status %d", priv->id, status);
+
+	if (status != 0) {
+		GError *error;
+
+		g_free (priv->sender);
+		priv->sender = NULL;
+
+		g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_CLAIM_DEVICE,
+			"Open failed with error %d", status);
+		dbus_g_method_return_error(session->context_claim_device, error);
+		return;
+	}
+
+	priv->dev = dev;
+	dbus_g_method_return(session->context_claim_device);
+}
+
+static void fprint_device_claim(FprintDevice *rdev,
+				const char *username,
+				DBusGMethodInvocation *context)
+{
+	FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev);
+	GError *error = NULL;
+	char *sender, *user;
 	int r;
 
 	/* Is it already claimed? */
@@ -417,44 +532,39 @@
 		return;
 	}
 
+	g_assert (priv->username == NULL);
+	g_assert (priv->sender == NULL);
+
+	sender = NULL;
+	user = _fprint_device_check_for_username (rdev,
+						  context,
+						  username,
+						  &sender,
+						  &error);
+	if (user == NULL) {
+		g_free (sender);
+		dbus_g_method_return_error (context, error);
+		g_error_free (error);
+		return;
+	}
+
 	if (_fprint_device_check_polkit_for_actions (rdev, context,
 						     "net.reactivated.fprint.device.verify",
 						     "net.reactivated.fprint.device.enroll",
 						     &error) == FALSE) {
-		dbus_g_method_return_error (context, error);
-		return;
-	}
-
-	/* Get details about the current sender, and username/uid */
-	conn = dbus_g_connection_get_connection (fprintd_dbus_conn);
-	sender = dbus_g_method_get_sender (context);
-	dbus_error_init (&dbus_error);
-	uid = dbus_bus_get_unix_user (conn, sender, &dbus_error);
-
-	if (dbus_error_is_set(&dbus_error)) {
 		g_free (sender);
-		dbus_set_g_error (&error, &dbus_error);
-		dbus_g_method_return_error(context, error);
-		g_error_free (error);
-		return;
-	}
-
-	user = getpwuid (uid);
-	if (user == NULL) {
-		g_free (sender);
-		g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_CLAIM_DEVICE,
-			"Failed to get information about user UID %lu", uid);
-		dbus_g_method_return_error(context, error);
-		return;
-	}
-
-	priv->username = g_strdup (user->pw_name);
+		g_free (user);
+		dbus_g_method_return_error (context, error);
+		return;
+	}
+
+	_fprint_device_add_client (rdev, sender);
+
+	priv->username = user;
 	priv->sender = sender;
 
-	g_message ("user claiming the device: %s (%ld)", priv->username, uid);
-	/* FIXME call polkit to check whether allowed */
-
-	g_message("claiming device %d", priv->id);
+	g_message ("user '%s' claiming the device: %d", priv->username, priv->id);
+
 	priv->session = g_slice_new0(struct session_data);
 	priv->session->context_claim_device = context;
 
@@ -462,6 +572,12 @@
 	if (r < 0) {
 		g_slice_free(struct session_data, priv->session);
 		priv->session = NULL;
+
+		g_free (priv->username);
+		priv->username = NULL;
+		g_free (priv->sender);
+		priv->sender = NULL;
+
 		g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_CLAIM_DEVICE,
 			"Could not attempt device open, error %d", r);
 		dbus_g_method_return_error(context, error);
@@ -494,7 +610,6 @@
 {
 	FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev);
 	struct session_data *session = priv->session;
-	GSList *elem = session->loaded_prints;
 	GError *error = NULL;
 
 	if (_fprint_device_check_claimed(rdev, context, &error) == FALSE) {
@@ -511,63 +626,12 @@
 		return;
 	}
 
-	/* Unload any loaded prints */
-	if (elem) {
-		do
-			g_slice_free(struct loaded_print, elem->data);
-		while ((elem = g_slist_next(elem)) != NULL);
-		g_slist_free(session->loaded_prints);
-	}
-
 	session->context_release_device = context;
 	fp_async_dev_close(priv->dev, dev_close_cb, rdev);
 }
 
-static void fprint_device_unload_print_data(FprintDevice *rdev,
-	guint32 print_id, DBusGMethodInvocation *context)
-{
-	FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev);
-	struct session_data *session = priv->session;
-	GSList *elem = session->loaded_prints;
-	GError *error = NULL;
-
-	if (_fprint_device_check_claimed(rdev, context, &error) == FALSE) {
-		dbus_g_method_return_error (context, error);
-		return;
-	}
-
-	if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.verify", &error) == FALSE) {
-		dbus_g_method_return_error (context, error);
-		return;
-	}
-
-	g_message("unload print data %d for device %d", print_id, priv->id);
-	if (!elem) {
-		g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_NO_SUCH_LOADED_PRINT,
-			"No such loaded print %d", print_id);
-		dbus_g_method_return_error(context, error);
-		return;
-	}
-
-	do {
-		struct loaded_print *print = elem->data;
-		if (print->id != print_id)
-			continue;
-
-		session->loaded_prints = g_slist_delete_link(session->loaded_prints,
-			elem);
-		g_slice_free(struct loaded_print, print);
-		dbus_g_method_return(context);
-		return;
-	} while ((elem = g_slist_next(elem)) != NULL);
-
-	g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_NO_SUCH_LOADED_PRINT,
-		"No such loaded print %d", print_id);
-	dbus_g_method_return_error(context, error);
-}
-
 static void verify_cb(struct fp_dev *dev, int r, struct fp_img *img,
-	void *user_data)
+		      void *user_data)
 {
 	struct FprintDevice *rdev = user_data;
 	g_message("verify_cb: result %d", r);
@@ -576,52 +640,133 @@
 	fp_img_free(img);
 }
 
+static void identify_cb(struct fp_dev *dev, int r,
+			 size_t match_offset, struct fp_img *img, void *user_data)
+{
+	struct FprintDevice *rdev = user_data;
+	g_message("identify_cb: result %d", r);
+
+	g_signal_emit(rdev, signals[SIGNAL_VERIFY_STATUS], 0, r);
+	fp_img_free(img);
+}
+
 static void fprint_device_verify_start(FprintDevice *rdev,
-	guint32 print_id, DBusGMethodInvocation *context)
-{
-	FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev);
-	struct session_data *session = priv->session;
-	GSList *elem = session->loaded_prints;
+	guint32 finger_num, DBusGMethodInvocation *context)
+{
+	FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev);
+	struct fp_print_data **gallery = NULL;
 	struct fp_print_data *data = NULL;
 	GError *error = NULL;
 	int r;
 
 	if (_fprint_device_check_claimed(rdev, context, &error) == FALSE) {
 		dbus_g_method_return_error (context, error);
+		g_error_free (error);
 		return;
 	}
 
 	if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.verify", &error) == FALSE) {
 		dbus_g_method_return_error (context, error);
-		return;
-	}
-
-	g_message("start verification device %d print %d", priv->id, print_id);
-	if (!elem) {
-		g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_NO_SUCH_LOADED_PRINT,
-			"No such loaded print %d", print_id);
+		g_error_free (error);
+		return;
+	}
+
+	if (priv->current_action != ACTION_NONE) {
+		if (priv->current_action == ACTION_ENROLL) {
+			g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_ALREADY_IN_USE,
+				    "Enrollment in progress");
+		} else {
+			g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_ALREADY_IN_USE,
+				    "Verification already in progress");
+		}
 		dbus_g_method_return_error(context, error);
-		return;
-	}
-	
-	do {
-		struct loaded_print *print = elem->data;
-		if (print->id == print_id) {
-			data = print->data;
-			break;
+		g_error_free (error);
+		return;
+	}
+
+	if (finger_num == -1) {
+		GSList *prints;
+
+		prints = store.discover_prints(priv->ddev, priv->username);
+		if (prints == NULL) {
+			g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_NO_SUCH_LOADED_PRINT,
+				    "No fingerprints enrolled");
+			dbus_g_method_return_error(context, error);
+			return;
 		}
-	} while ((elem = g_slist_next(elem)) != NULL);
-
-	if (!data) {
-		g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_NO_SUCH_LOADED_PRINT,
-			"No such loaded print %d", print_id);
-		dbus_g_method_return_error(context, error);
-		return;
-	}
-
-	/* FIXME check freeing/copying of data */
-	r = fp_async_verify_start(priv->dev, data, verify_cb, rdev);
+		if (fp_dev_supports_identification(priv->dev)) {
+			GSList *l;
+			GPtrArray *array;
+
+			array = g_ptr_array_new ();
+
+			for (l = prints; l != NULL; l = l->next) {
+				g_message ("adding finger %d to the gallery", GPOINTER_TO_INT (l->data));
+				r = store.print_data_load(priv->dev, GPOINTER_TO_INT (l->data),
+							  &data, priv->username);
+				//FIXME r < 0 ?
+				g_ptr_array_add (array, data);
+			}
+			data = NULL;
+
+			if (array->len > 0) {
+				g_ptr_array_add (array,  NULL);
+				gallery = (struct fp_print_data **) g_ptr_array_free (array, FALSE);
+			} else {
+				gallery = NULL;
+			}
+		} else {
+			finger_num = GPOINTER_TO_INT (prints->data);
+		}
+		g_slist_free(prints);
+	}
+
+	if (fp_dev_supports_identification(priv->dev) && finger_num == -1) {
+		if (gallery == NULL) {
+			g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_NO_SUCH_LOADED_PRINT,
+				    "No fingerprints on that device");
+			dbus_g_method_return_error(context, error);
+			g_error_free (error);
+			return;
+		}
+		priv->current_action = ACTION_IDENTIFY;
+
+		g_message ("start identification device %d", priv->id);
+		//FIXME we're supposed to free the gallery here?
+		r = fp_async_identify_start (priv->dev, gallery, identify_cb, rdev);
+	} else {
+		priv->current_action = ACTION_VERIFY;
+
+		g_message("start verification device %d finger %d", priv->id, finger_num);
+
+		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,
+				    "No such print %d", finger_num);
+			dbus_g_method_return_error(context, error);
+			return;
+		}
+
+		/* FIXME fp_async_verify_start should copy the fp_print_data */
+		r = fp_async_verify_start(priv->dev, data, verify_cb, rdev);
+	}
+
+	/* Emit VerifyFingerSelected telling the front-end which finger
+	 * we selected for auth */
+	g_signal_emit(rdev, signals[SIGNAL_VERIFY_FINGER_SELECTED], 0, finger_num);
+
+
 	if (r < 0) {
+		if (data != NULL) {
+			fp_print_data_free (data);
+		} else if (gallery != NULL) {
+			guint i;
+			for (i = 0; gallery[i] != NULL; i++)
+				fp_print_data_free(gallery[i]);
+			g_free (gallery);
+		}
 		g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_VERIFY_START,
 			"Verify start failed with error %d", r);
 		dbus_g_method_return_error(context, error);
@@ -636,6 +781,11 @@
 	dbus_g_method_return((DBusGMethodInvocation *) user_data);
 }
 
+static void identify_stop_cb(struct fp_dev *dev, void *user_data)
+{
+	dbus_g_method_return((DBusGMethodInvocation *) user_data);
+}
+
 static void fprint_device_verify_stop(FprintDevice *rdev,
 	DBusGMethodInvocation *context)
 {
@@ -653,12 +803,26 @@
 		return;
 	}
 
-	r = fp_async_verify_stop(priv->dev, verify_stop_cb, context);
+	if (priv->current_action == ACTION_VERIFY) {
+		r = fp_async_verify_stop(priv->dev, verify_stop_cb, context);
+	} else if (priv->current_action == ACTION_IDENTIFY) {
+		r = fp_async_identify_stop(priv->dev, identify_stop_cb, context);
+	} else {
+		g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_VERIFY_STOP,
+			    "No verification in progress");
+		dbus_g_method_return_error(context, error);
+		g_error_free (error);
+		return;
+	}
+
 	if (r < 0) {
 		g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_VERIFY_STOP,
 			"Verify stop failed with error %d", r);
 		dbus_g_method_return_error(context, error);
-	}
+		g_error_free (error);
+	}
+
+	priv->current_action = ACTION_NONE;
 }
 
 static void enroll_stage_cb(struct fp_dev *dev, int result,
@@ -671,7 +835,7 @@
 
 	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;
 	}
@@ -696,6 +860,19 @@
 
 	if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.enroll", &error) == FALSE) {
 		dbus_g_method_return_error (context, error);
+		return;
+	}
+
+	if (priv->current_action != ACTION_NONE) {
+		if (priv->current_action == ACTION_ENROLL) {
+			g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_ALREADY_IN_USE,
+				    "Enrollment already in progress");
+		} else {
+			g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_ALREADY_IN_USE,
+				    "Verification in progress");
+		}
+		dbus_g_method_return_error(context, error);
+		g_error_free (error);
 		return;
 	}
 
@@ -710,6 +887,8 @@
 		return;
 	}
 
+	priv->current_action = ACTION_ENROLL;
+
 	dbus_g_method_return(context);
 }
 
@@ -732,6 +911,14 @@
 
 	if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.enroll", &error) == FALSE) {
 		dbus_g_method_return_error (context, error);
+		return;
+	}
+
+	if (priv->current_action != ACTION_ENROLL) {
+		g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_ENROLL_STOP,
+			    "No enrollment in progress");
+		dbus_g_method_return_error(context, error);
+		g_error_free (error);
 		return;
 	}
 
@@ -740,44 +927,46 @@
 		g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_ENROLL_STOP,
 			"Enroll stop failed with error %d", r);
 		dbus_g_method_return_error(context, error);
-		return;
-	}
-}
-
-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;
+		g_error_free (error);
+	}
+
+	priv->current_action = ACTION_NONE;
 }
 
 static void fprint_device_list_enrolled_fingers(FprintDevice *rdev,
-	DBusGMethodInvocation *context)
+						const char *username,
+						DBusGMethodInvocation *context)
 {
 	FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev);
 	GError *error = NULL;
 	GSList *prints;
 	GSList *item;
 	GArray *ret;
-
-	if (_fprint_device_check_claimed(rdev, context, &error) == FALSE) {
-		dbus_g_method_return_error (context, error);
+	char *user, *sender;
+
+	user = _fprint_device_check_for_username (rdev,
+						  context,
+						  username,
+						  NULL,
+						  &error);
+	if (user == NULL) {
+		dbus_g_method_return_error (context, error);
+		g_error_free (error);
 		return;
 	}
 
 	if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.verify", &error) == FALSE) {
-		dbus_g_method_return_error (context, error);
-		return;
-	}
-
-	prints = storages[priv->storage_type].discover_prints(priv->dev, priv->username);
+		g_free (user);
+		dbus_g_method_return_error (context, error);
+		return;
+	}
+
+	sender = dbus_g_method_get_sender (context);
+	_fprint_device_add_client (rdev, sender);
+	g_free (sender);
+
+	prints = store.discover_prints(priv->ddev, user);
+	g_free (user);
 	if (!prints) {
 		g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_DISCOVER_PRINTS,
 			"Failed to discover prints");
@@ -787,8 +976,7 @@
 
 	ret = g_array_new(FALSE, FALSE, sizeof(int));
 	for (item = prints; item; item = item->next) {
-		int *fingerptr = (int *)item->data;
-		ret = g_array_append_val(ret, *fingerptr);
+		ret = g_array_append_val(ret, item->data);
 	}
 
 	g_slist_free(prints);
@@ -796,44 +984,41 @@
 	dbus_g_method_return(context, ret);
 }
 
-static void fprint_device_load_print_data(FprintDevice *rdev,
-	guint32 finger_num, DBusGMethodInvocation *context)
-{
-	FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev);
-	struct session_data *session = priv->session;
-	struct loaded_print *lprint;
-	struct fp_print_data *data;
+static void fprint_device_delete_enrolled_fingers(FprintDevice *rdev,
+						  const char *username,
+						  DBusGMethodInvocation *context)
+{
+	FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev);
 	GError *error = NULL;
-	int r;
-
-	if (_fprint_device_check_claimed(rdev, context, &error) == FALSE) {
-		dbus_g_method_return_error (context, error);
-		return;
-	}
-
-	if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.verify", &error) == FALSE) {
-		dbus_g_method_return_error (context, error);
-		return;
-	}
-
-	r = storages[priv->storage_type].print_data_load(priv->dev, (enum fp_finger)finger_num, 
-		&data, priv->username);
-
-	if (r < 0) {
-		g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_PRINT_LOAD,
-			"Print load failed with error %d", r);
-		dbus_g_method_return_error(context, error);
-		return;
-	}
-
-	lprint = g_slice_new(struct loaded_print);
-	lprint->data = data;
-	lprint->id = ++last_id;
-	session->loaded_prints = g_slist_prepend(session->loaded_prints, lprint);
-
-	g_message("load print data finger %d for device %d = %d",
-		finger_num, priv->id, lprint->id);
-
-	dbus_g_method_return(context, lprint->id);
-}
-
+	guint i;
+	char *user, *sender;
+
+	user = _fprint_device_check_for_username (rdev,
+						  context,
+						  username,
+						  NULL,
+						  &error);
+	if (user == NULL) {
+		dbus_g_method_return_error (context, error);
+		g_error_free (error);
+		return;
+	}
+
+	if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.enroll", &error) == FALSE) {
+		g_free (user);
+		dbus_g_method_return_error (context, error);
+		return;
+	}
+
+	sender = dbus_g_method_get_sender (context);
+	_fprint_device_add_client (rdev, sender);
+	g_free (sender);
+
+	for (i = LEFT_THUMB; i <= RIGHT_LITTLE; i++) {
+		store.print_data_delete(priv->ddev, i, user);
+	}
+	g_free (user);
+
+	dbus_g_method_return(context);
+}
+

Modified: packages/fprint/fprintd/trunk/src/device.xml
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/src/device.xml?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/src/device.xml (original)
+++ packages/fprint/fprintd/trunk/src/device.xml Thu Nov  6 17:18:39 2008
@@ -4,28 +4,23 @@
 		<annotation name="org.freedesktop.DBus.GLib.CSymbol"
 			value="fprint_device" />
 
+		<method name="ListEnrolledFingers">
+			<arg type="s" name="username" direction="in" />
+			<arg type="au" name="enrolled_fingers" direction="out" />
+			<annotation name="org.freedesktop.DBus.GLib.Async" value="" />
+		</method>
+
+		<method name="DeleteEnrolledFingers">
+			<arg type="s" name="username" direction="in" />
+			<annotation name="org.freedesktop.DBus.GLib.Async" value="" />
+		</method>
+
 		<method name="Claim">
+			<arg type="s" name="username" direction="in" />
 			<annotation name="org.freedesktop.DBus.GLib.Async" value="" />
 		</method>
 
 		<method name="Release">
-			<annotation name="org.freedesktop.DBus.GLib.Async" value="" />
-		</method>
-
-		<method name="ListEnrolledFingers">
-			<arg type="au" name="enrolled_fingers" direction="out" />
-			<annotation name="org.freedesktop.DBus.GLib.Async" value="" />
-		</method>
-
-		<!-- FIXME make OO -->
-		<method name="LoadPrintData">
-			<arg type="u" name="finger_num" direction="in" />
-			<arg type="u" name="print_id" direction="out" />
-			<annotation name="org.freedesktop.DBus.GLib.Async" value="" />
-		</method>
-
-		<method name="UnloadPrintData">
-			<arg type="u" name="print_id" direction="in" />
 			<annotation name="org.freedesktop.DBus.GLib.Async" value="" />
 		</method>
 
@@ -37,6 +32,10 @@
 		<method name="VerifyStop">
 			<annotation name="org.freedesktop.DBus.GLib.Async" value="" />
 		</method>
+
+		<signal name="VerifyFingerSelected">
+			<arg type="i" name="finger_num" />
+		</signal>
 
 		<signal name="VerifyStatus">
 			<arg type="i" name="result" />
@@ -55,16 +54,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="" />
-		</method>
-
 	</interface>
 </node>
 

Added: packages/fprint/fprintd/trunk/src/egg-dbus-monitor.c
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/src/egg-dbus-monitor.c?rev=123&op=file
==============================================================================
--- packages/fprint/fprintd/trunk/src/egg-dbus-monitor.c (added)
+++ packages/fprint/fprintd/trunk/src/egg-dbus-monitor.c Thu Nov  6 17:18:39 2008
@@ -1,0 +1,265 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2006-2008 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include <dbus/dbus.h>
+
+#include "egg-dbus-monitor.h"
+
+static void     egg_dbus_monitor_class_init	(EggDbusMonitorClass	*klass);
+static void     egg_dbus_monitor_init		(EggDbusMonitor		*dbus_monitor);
+static void     egg_dbus_monitor_finalize	(GObject		*object);
+
+#define EGG_DBUS_MONITOR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_TYPE_DBUS_MONITOR, EggDbusMonitorPrivate))
+
+struct EggDbusMonitorPrivate
+{
+	gchar			*service;
+	DBusGProxy		*proxy;
+	DBusGConnection		*connection;
+	const gchar		*unique_name;
+};
+
+enum {
+	EGG_DBUS_MONITOR_CONNECTION_CHANGED,
+	EGG_DBUS_MONITOR_CONNECTION_REPLACED,
+	EGG_DBUS_MONITOR_LAST_SIGNAL
+};
+
+static guint signals [EGG_DBUS_MONITOR_LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (EggDbusMonitor, egg_dbus_monitor, G_TYPE_OBJECT)
+
+/**
+ * egg_dbus_monitor_name_owner_changed_cb:
+ **/
+static void
+egg_dbus_monitor_name_owner_changed_cb (DBusGProxy *proxy, const gchar *name,
+				       const gchar *prev, const gchar *new,
+				       EggDbusMonitor *monitor)
+{
+	guint new_len;
+	guint prev_len;
+
+	g_return_if_fail (EGG_IS_DBUS_MONITOR (monitor));
+	if (monitor->priv->proxy == NULL)
+		return;
+
+	/* not us */
+	if (strcmp (name, monitor->priv->service) != 0)
+		return;
+
+	/* ITS4: ignore, not used for allocation */
+	new_len = strlen (new);
+	/* ITS4: ignore, not used for allocation */
+	prev_len = strlen (prev);
+
+	/* something --> nothing */
+	if (prev_len != 0 && new_len == 0) {
+		g_signal_emit (monitor, signals [EGG_DBUS_MONITOR_CONNECTION_CHANGED], 0, FALSE);
+		return;
+	}
+
+	/* nothing --> something */
+	if (prev_len == 0 && new_len != 0) {
+		g_signal_emit (monitor, signals [EGG_DBUS_MONITOR_CONNECTION_CHANGED], 0, TRUE);
+		return;
+	}
+
+	/* something --> something (we've replaced the old process) */
+	if (prev_len != 0 && new_len != 0) {
+		/* only send this to the prev client */
+		if (strcmp (monitor->priv->unique_name, prev) == 0)
+			g_signal_emit (monitor, signals [EGG_DBUS_MONITOR_CONNECTION_REPLACED], 0);
+		return;
+	}
+}
+
+/**
+ * egg_dbus_monitor_assign:
+ * @monitor: This class instance
+ * @connection: The bus connection
+ * @service: The EGG_DBUS_MONITOR service name
+ * Return value: success
+ *
+ * Emits connection-changed(TRUE) if connection is alive - this means you
+ * have to connect up the callback before this function is called.
+ **/
+gboolean
+egg_dbus_monitor_assign (EggDbusMonitor *monitor, DBusGConnection *connection, const gchar *service)
+{
+	GError *error = NULL;
+	gboolean connected;
+	DBusConnection *conn;
+
+	g_return_val_if_fail (EGG_IS_DBUS_MONITOR (monitor), FALSE);
+	g_return_val_if_fail (service != NULL, FALSE);
+	g_return_val_if_fail (connection != NULL, FALSE);
+
+	if (monitor->priv->proxy != NULL) {
+		g_warning ("already assigned!");
+		return FALSE;
+	}
+
+	monitor->priv->service = g_strdup (service);
+	monitor->priv->connection = connection;
+	monitor->priv->proxy = dbus_g_proxy_new_for_name_owner (monitor->priv->connection,
+								DBUS_SERVICE_DBUS,
+								DBUS_PATH_DBUS,
+						 		DBUS_INTERFACE_DBUS,
+								&error);
+	if (error != NULL) {
+		g_warning ("Cannot connect to DBUS: %s", error->message);
+		g_error_free (error);
+		return FALSE;
+	}
+	dbus_g_proxy_add_signal (monitor->priv->proxy, "NameOwnerChanged",
+				 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
+	dbus_g_proxy_connect_signal (monitor->priv->proxy, "NameOwnerChanged",
+				     G_CALLBACK (egg_dbus_monitor_name_owner_changed_cb),
+				     monitor, NULL);
+
+	/* coldplug */
+	connected = egg_dbus_monitor_is_connected (monitor);
+	if (connected)
+		g_signal_emit (monitor, signals [EGG_DBUS_MONITOR_CONNECTION_CHANGED], 0, TRUE);
+
+	/* save this for the replaced check */
+	conn = dbus_g_connection_get_connection (monitor->priv->connection);
+	monitor->priv->unique_name = dbus_bus_get_unique_name (conn);
+	return TRUE;
+}
+
+/**
+ * egg_dbus_monitor_is_connected:
+ * @monitor: This class instance
+ * Return value: if we are connected to a valid watch
+ **/
+gboolean
+egg_dbus_monitor_is_connected (EggDbusMonitor *monitor)
+{
+	DBusError error;
+	DBusConnection *conn;
+	gboolean ret;
+	g_return_val_if_fail (EGG_IS_DBUS_MONITOR (monitor), FALSE);
+
+	/* get raw connection */
+	conn = dbus_g_connection_get_connection (monitor->priv->connection);
+	dbus_error_init (&error);
+	ret = dbus_bus_name_has_owner (conn, monitor->priv->service, &error);
+	if (dbus_error_is_set (&error)) {
+		g_debug ("error: %s", error.message);
+		dbus_error_free (&error);
+	}
+
+	return ret;
+}
+
+/**
+ * egg_dbus_monitor_get_service:
+ * @monitor: This class instance
+ * Return value: the service name being monitored
+ **/
+const gchar *
+egg_dbus_monitor_get_service (EggDbusMonitor *monitor)
+{
+	g_return_val_if_fail (EGG_IS_DBUS_MONITOR (monitor), FALSE);
+
+	return monitor->priv->service;
+}
+
+/**
+ * egg_dbus_monitor_class_init:
+ * @klass: The EggDbusMonitorClass
+ **/
+static void
+egg_dbus_monitor_class_init (EggDbusMonitorClass *klass)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = egg_dbus_monitor_finalize;
+	g_type_class_add_private (klass, sizeof (EggDbusMonitorPrivate));
+	signals [EGG_DBUS_MONITOR_CONNECTION_CHANGED] =
+		g_signal_new ("connection-changed",
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (EggDbusMonitorClass, connection_changed),
+			      NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN,
+			      G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+	signals [EGG_DBUS_MONITOR_CONNECTION_REPLACED] =
+		g_signal_new ("connection-replaced",
+			      G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (EggDbusMonitorClass, connection_replaced),
+			      NULL, NULL, g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE, 0);
+}
+
+/**
+ * egg_dbus_monitor_init:
+ * @monitor: This class instance
+ **/
+static void
+egg_dbus_monitor_init (EggDbusMonitor *monitor)
+{
+	monitor->priv = EGG_DBUS_MONITOR_GET_PRIVATE (monitor);
+	monitor->priv->service = NULL;
+	monitor->priv->connection = NULL;
+	monitor->priv->proxy = NULL;
+}
+
+/**
+ * egg_dbus_monitor_finalize:
+ * @object: The object to finalize
+ **/
+static void
+egg_dbus_monitor_finalize (GObject *object)
+{
+	EggDbusMonitor *monitor;
+
+	g_return_if_fail (EGG_IS_DBUS_MONITOR (object));
+
+	monitor = EGG_DBUS_MONITOR (object);
+
+	g_return_if_fail (monitor->priv != NULL);
+	if (monitor->priv->proxy != NULL)
+		g_object_unref (monitor->priv->proxy);
+
+	G_OBJECT_CLASS (egg_dbus_monitor_parent_class)->finalize (object);
+}
+
+/**
+ * egg_dbus_monitor_new:
+ *
+ * Return value: a new EggDbusMonitor object.
+ **/
+EggDbusMonitor *
+egg_dbus_monitor_new (void)
+{
+	EggDbusMonitor *monitor;
+	monitor = g_object_new (EGG_TYPE_DBUS_MONITOR, NULL);
+	return EGG_DBUS_MONITOR (monitor);
+}
+

Added: packages/fprint/fprintd/trunk/src/egg-dbus-monitor.h
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/src/egg-dbus-monitor.h?rev=123&op=file
==============================================================================
--- packages/fprint/fprintd/trunk/src/egg-dbus-monitor.h (added)
+++ packages/fprint/fprintd/trunk/src/egg-dbus-monitor.h Thu Nov  6 17:18:39 2008
@@ -1,0 +1,66 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Richard Hughes <richard at hughsie.com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EGG_DBUS_MONITOR_H
+#define __EGG_DBUS_MONITOR_H
+
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+
+G_BEGIN_DECLS
+
+#define EGG_TYPE_DBUS_MONITOR		(egg_dbus_monitor_get_type ())
+#define EGG_DBUS_MONITOR(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), EGG_TYPE_DBUS_MONITOR, EggDbusMonitor))
+#define EGG_DBUS_MONITOR_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST((k), EGG_TYPE_DBUS_MONITOR, EggDbusMonitorClass))
+#define EGG_IS_DBUS_MONITOR(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), EGG_TYPE_DBUS_MONITOR))
+#define EGG_IS_DBUS_MONITOR_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), EGG_TYPE_DBUS_MONITOR))
+#define EGG_DBUS_MONITOR_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS ((o), EGG_TYPE_DBUS_MONITOR, EggDbusMonitorClass))
+#define EGG_DBUS_MONITOR_ERROR		(egg_dbus_monitor_error_quark ())
+#define EGG_DBUS_MONITOR_TYPE_ERROR	(egg_dbus_monitor_error_get_type ())
+
+typedef struct EggDbusMonitorPrivate EggDbusMonitorPrivate;
+
+typedef struct
+{
+	 GObject		 parent;
+	 EggDbusMonitorPrivate	*priv;
+} EggDbusMonitor;
+
+typedef struct
+{
+	GObjectClass	parent_class;
+	void		(* connection_changed)		(EggDbusMonitor	*watch,
+							 gboolean	 connected);
+	void		(* connection_replaced)		(EggDbusMonitor	*watch);
+} EggDbusMonitorClass;
+
+GType		 egg_dbus_monitor_get_type	  	(void) G_GNUC_CONST;
+EggDbusMonitor	*egg_dbus_monitor_new			(void);
+gboolean	 egg_dbus_monitor_assign		(EggDbusMonitor	*monitor,
+							 DBusGConnection *connection,
+							 const gchar	*service);
+const gchar	*egg_dbus_monitor_get_service		(EggDbusMonitor	*monitor);
+gboolean	 egg_dbus_monitor_is_connected		(EggDbusMonitor	*monitor);
+
+G_END_DECLS
+
+#endif /* __EGG_DBUS_MONITOR_H */
+

Modified: packages/fprint/fprintd/trunk/src/file_storage.c
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/src/file_storage.c?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/src/file_storage.c (original)
+++ packages/fprint/fprintd/trunk/src/file_storage.c Thu Nov  6 17:18:39 2008
@@ -37,6 +37,8 @@
 
 #include <libfprint/fprint.h>
 
+#include "file_storage.h"
+
 #define DIR_PERMS 0700
 
 #ifndef FILE_STORAGE_PATH
@@ -78,6 +80,12 @@
 		fp_dev_get_devtype(dev), finger, base_store);
 }
 
+static char *get_path_to_print_dscv(struct fp_dscv_dev *dev, enum fp_finger finger, char *base_store)
+{
+	return __get_path_to_print(fp_driver_get_driver_id(fp_dscv_dev_get_driver(dev)), 
+		fp_dscv_dev_get_devtype(dev), finger, base_store);
+}
+
 static int file_storage_get_basestore_for_username(const char *username, char **base_store)
 {
 	char *dirpath = FILE_STORAGE_PATH;
@@ -91,9 +99,7 @@
 	enum fp_finger finger, const char *username)
 {
 	GError *err = NULL;
-	char *path;
-	char *dirpath;
-	unsigned char *buf;
+	char *path, *dirpath, *buf;
 	size_t len;
 	int r;
 	char *base_store = NULL;
@@ -104,7 +110,7 @@
 		return r;
 	}
 
-	len = fp_print_data_get_data(data, &buf);
+	len = fp_print_data_get_data(data, (guchar **) &buf);
 	if (!len) {
 		g_free(base_store);
 		return -ENOMEM;
@@ -139,7 +145,7 @@
 static int load_from_file(char *path, struct fp_print_data **data)
 {
 	gsize length;
-	gchar *contents;
+	char *contents;
 	GError *err = NULL;
 	struct fp_print_data *fdata;
 
@@ -155,7 +161,7 @@
 			return r;
 	}
 
-	fdata = fp_print_data_from_data(contents, length);
+	fdata = fp_print_data_from_data((guchar *) contents, length);
 	g_free(contents);
 	if (!fdata)
 		return -EIO;
@@ -193,7 +199,7 @@
 	return 0;
 }
 
-int file_storage_print_data_delete(struct fp_dev *dev,
+int file_storage_print_data_delete(struct fp_dscv_dev *dev,
 	enum fp_finger finger, const char *username)
 {
 	int r;
@@ -205,7 +211,7 @@
 		return r;
 	}
 
-	gchar *path = get_path_to_print(dev, finger, base_store);
+	gchar *path = get_path_to_print_dscv(dev, finger, base_store);
 
 	r = g_unlink(path);
 	g_free(path);
@@ -231,7 +237,6 @@
 	while ((ent = g_dir_read_name(dir))) {
 		/* ent is an 1 hex character fp_finger code */
 		guint64 val;
-		int *list_item;
 		gchar *endptr;
 
 		if (*ent == 0 || strlen(ent) != 1)
@@ -243,16 +248,14 @@
 			continue;
 		}
 
-		list_item = g_slice_new(int);
-		*list_item = val;
-		list = g_slist_prepend(list, list_item);
+		list = g_slist_prepend(list, GINT_TO_POINTER(val));
 	}
 
 	g_dir_close(dir);
 	return list;
 }
 
-GSList *file_storage_discover_prints(struct fp_dev *dev, const char *username)
+GSList *file_storage_discover_prints(struct fp_dscv_dev *dev, const char *username)
 {
 	//GDir *dir;
 	//const gchar *ent;
@@ -270,12 +273,12 @@
 		return NULL;
 	}
 
-	storedir = get_path_to_storedir(fp_driver_get_driver_id(fp_dev_get_driver(dev)), 
-		fp_dev_get_devtype(dev), base_store);
+	storedir = get_path_to_storedir(fp_driver_get_driver_id(fp_dscv_dev_get_driver(dev)), 
+		fp_dscv_dev_get_devtype(dev), base_store);
 
 	g_message("Entering %s", storedir);
-	list = scan_dev_storedir(storedir, fp_driver_get_driver_id(fp_dev_get_driver(dev)), 
-		fp_dev_get_devtype(dev), list);
+	list = scan_dev_storedir(storedir, fp_driver_get_driver_id(fp_dscv_dev_get_driver(dev)), 
+		fp_dscv_dev_get_devtype(dev), list);
 
 	g_free(base_store);
 	g_free(storedir);

Modified: packages/fprint/fprintd/trunk/src/file_storage.h
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/src/file_storage.h?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/src/file_storage.h (original)
+++ packages/fprint/fprintd/trunk/src/file_storage.h Thu Nov  6 17:18:39 2008
@@ -29,13 +29,13 @@
 int file_storage_print_data_load(struct fp_dev *dev,
 	enum fp_finger finger, struct fp_print_data **data, const char *username);
 
-int file_storage_print_data_delete(struct fp_dev *dev,
+int file_storage_print_data_delete(struct fp_dscv_dev *dev,
 	enum fp_finger finger, const char *username);
 
 int file_storage_init(void);
 
 int file_storage_deinit(void);
 
-GSList *file_storage_discover_prints(struct fp_dev *dev, const char *username);
+GSList *file_storage_discover_prints(struct fp_dscv_dev *dev, const char *username);
 
 #endif

Modified: packages/fprint/fprintd/trunk/src/fprintd.h
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/src/fprintd.h?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/src/fprintd.h (original)
+++ packages/fprint/fprintd/trunk/src/fprintd.h Thu Nov  6 17:18:39 2008
@@ -24,8 +24,10 @@
 #include <dbus/dbus-glib.h>
 
 /* General */
+#define TIMEOUT 30
 #define FPRINT_SERVICE_NAME "net.reactivated.Fprint"
 extern DBusGConnection *fprintd_dbus_conn;
+extern gboolean no_timeout;
 GQuark fprint_error_quark(void);
 
 /* Errors */

Modified: packages/fprint/fprintd/trunk/src/main.c
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/src/main.c?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/src/main.c (original)
+++ packages/fprint/fprintd/trunk/src/main.c Thu Nov  6 17:18:39 2008
@@ -27,10 +27,14 @@
 #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;
+gboolean no_timeout = FALSE;
 static gboolean g_fatal_warnings = FALSE;
 
 GQuark fprint_error_quark(void)
@@ -200,8 +204,91 @@
 	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},
+	{"no-timeout", 't', 0, G_OPTION_ARG_NONE, &no_timeout, "Do not exit after unused for a while", NULL},
 	{ NULL }
 };
 
@@ -236,6 +323,12 @@
 		fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
 		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) {

Modified: packages/fprint/fprintd/trunk/src/manager.c
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/src/manager.c?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/src/manager.c (original)
+++ packages/fprint/fprintd/trunk/src/manager.c Thu Nov  6 17:18:39 2008
@@ -17,6 +17,8 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#include <unistd.h>
+#include <stdlib.h>
 #include <dbus/dbus-glib-bindings.h>
 #include <glib.h>
 #include <glib/gi18n.h>
@@ -38,6 +40,7 @@
 {
 	GError *last_error;
 	GSList *dev_registry;
+	guint timeout_id;
 } FprintManagerPrivate;
 
 #define FPRINT_MANAGER_GET_PRIVATE(o)  \
@@ -71,6 +74,40 @@
 		_fprint_device_get_id(rdev));
 }
 
+static gboolean
+fprint_manager_timeout_cb (FprintManager *manager)
+{
+	g_message ("No devices in use, exit");
+	//FIXME kill all the devices
+	exit(0);
+	return FALSE;
+}
+
+static void
+fprint_manager_in_use_notified (FprintDevice *rdev, GParamSpec *spec, FprintManager *manager)
+{
+	FprintManagerPrivate *priv = FPRINT_MANAGER_GET_PRIVATE (manager);
+	guint num_devices_used = 0;
+	GSList *l;
+	gboolean in_use;
+
+	if (priv->timeout_id > 0) {
+		g_source_remove (priv->timeout_id);
+		priv->timeout_id = 0;
+	}
+
+	for (l = priv->dev_registry; l != NULL; l = l->next) {
+		FprintDevice *dev = l->data;
+
+		g_object_get (G_OBJECT(dev), "in-use", &in_use, NULL);
+		if (in_use != FALSE)
+			num_devices_used++;
+	}
+
+	if (num_devices_used == 0 && !no_timeout)
+		priv->timeout_id = g_timeout_add_seconds (TIMEOUT, (GSourceFunc) fprint_manager_timeout_cb, manager);
+}
+
 static void
 fprint_manager_init (FprintManager *manager)
 {
@@ -92,12 +129,18 @@
 		FprintDevice *rdev = fprint_device_new(ddev);
 		gchar *path;
 
+		g_signal_connect (G_OBJECT(rdev), "notify::in-use",
+				  G_CALLBACK (fprint_manager_in_use_notified), manager);
+
 		priv->dev_registry = g_slist_prepend(priv->dev_registry, rdev);
 		path = get_device_path(rdev);
 		dbus_g_connection_register_g_object(fprintd_dbus_conn, path,
 			G_OBJECT(rdev));
 		g_free(path);
 	}
+
+	if (!no_timeout)
+		priv->timeout_id = g_timeout_add_seconds (TIMEOUT, (GSourceFunc) fprint_manager_timeout_cb, manager);
 }
 
 FprintManager *fprint_manager_new(void)

Modified: packages/fprint/fprintd/trunk/src/storage.h
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/src/storage.h?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/src/storage.h (original)
+++ packages/fprint/fprintd/trunk/src/storage.h Thu Nov  6 17:18:39 2008
@@ -22,15 +22,13 @@
 
 #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,
 	enum fp_finger finger, struct fp_print_data **data, const char *username);
-typedef int (*storage_print_data_delete)(struct fp_dev *dev,
+typedef int (*storage_print_data_delete)(struct fp_dscv_dev *dev,
 	enum fp_finger finger, const char *username);
-typedef GSList *(*storage_discover_prints)(struct fp_dev *dev, const char *username);
+typedef GSList *(*storage_discover_prints)(struct fp_dscv_dev *dev, const char *username);
 typedef int (*storage_init)(void);
 typedef int (*storage_deinit)(void);
 
@@ -45,26 +43,8 @@
 
 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
 

Modified: packages/fprint/fprintd/trunk/tests/Makefile.am
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/tests/Makefile.am?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/tests/Makefile.am (original)
+++ packages/fprint/fprintd/trunk/tests/Makefile.am Thu Nov  6 17:18:39 2008
@@ -2,15 +2,19 @@
 noinst_HEADERS = $(BUILT_SOURCES)
 CLEANFILES = $(BUILT_SOURCES)
 
-bin_PROGRAMS = verify enroll
+bin_PROGRAMS = verify enroll list
 
 verify_SOURCES = verify.c
-verify_CFLAGS = $(AM_CFLAGS) $(DBUS_GLIB_CFLAGS)
-verify_LDADD = $(DBUS_GLIB_LIBS)
+verify_CFLAGS = $(WARN_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 = $(WARN_CFLAGS) $(GLIB_CFLAGS)
+enroll_LDADD = $(GLIB_LIBS)
+
+list_SOURCES = list.c
+list_CFLAGS = $(WARN_CFLAGS) $(GLIB_CFLAGS)
+list_LDADD = $(GLIB_LIBS)
 
 manager-dbus-glue.h: ../src/manager.xml
 	dbus-binding-tool --prefix=fprint_manager --mode=glib-client $< --output=$@

Modified: packages/fprint/fprintd/trunk/tests/enroll.c
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/tests/enroll.c?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/tests/enroll.c (original)
+++ packages/fprint/fprintd/trunk/tests/enroll.c Thu Nov  6 17:18:39 2008
@@ -83,7 +83,7 @@
 		"net.reactivated.Fprint.Manager");
 }
 
-static DBusGProxy *open_device(void)
+static DBusGProxy *open_device(const char *username)
 {
 	GError *error = NULL;
 	GPtrArray *devices;
@@ -115,7 +115,7 @@
 	g_ptr_array_foreach(devices, (GFunc) g_free, NULL);
 	g_ptr_array_free(devices, TRUE);
 
-	if (!net_reactivated_Fprint_Device_claim(dev, &error))
+	if (!net_reactivated_Fprint_Device_claim(dev, username, &error))
 		g_error("failed to claim device: %s", error->message);
 	return dev;
 }
@@ -162,12 +162,16 @@
 {
 	GMainLoop *loop;
 	DBusGProxy *dev;
+	char *username;
 
 	g_type_init();
 	loop = g_main_loop_new(NULL, FALSE);
 	create_manager();
 
-	dev = open_device();
+	username = NULL;
+	if (argc == 2)
+		username = argv[1];
+	dev = open_device(username);
 	do_enroll(dev);
 	release_device(dev);
 	return 0;

Added: packages/fprint/fprintd/trunk/tests/list.c
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/tests/list.c?rev=123&op=file
==============================================================================
--- packages/fprint/fprintd/trunk/tests/list.c (added)
+++ packages/fprint/fprintd/trunk/tests/list.c Thu Nov  6 17:18:39 2008
@@ -1,0 +1,165 @@
+/*
+ * fprintd example to verify a fingerprint
+ * Copyright (C) 2008 Daniel Drake <dsd at gentoo.org>
+ *
+ * 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 2 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dbus/dbus-glib-bindings.h>
+#include "manager-dbus-glue.h"
+#include "device-dbus-glue.h"
+
+static DBusGProxy *manager = NULL;
+static DBusGConnection *connection = NULL;
+
+enum fp_finger {
+	LEFT_THUMB = 1, /** thumb (left hand) */
+	LEFT_INDEX, /** index finger (left hand) */
+	LEFT_MIDDLE, /** middle finger (left hand) */
+	LEFT_RING, /** ring finger (left hand) */
+	LEFT_LITTLE, /** little finger (left hand) */
+	RIGHT_THUMB, /** thumb (right hand) */
+	RIGHT_INDEX, /** index finger (right hand) */
+	RIGHT_MIDDLE, /** middle finger (right hand) */
+	RIGHT_RING, /** ring finger (right hand) */
+	RIGHT_LITTLE, /** little finger (right hand) */
+};
+
+static const char *fingerstr(guint32 fingernum)
+{
+	switch (fingernum) {
+	case LEFT_THUMB:
+		return "Left thumb";
+	case LEFT_INDEX:
+		return "Left index finger";
+	case LEFT_MIDDLE:
+		return "Left middle finger";
+	case LEFT_RING:
+		return "Left ring finger";
+	case LEFT_LITTLE:
+		return "Left little finger";
+	case RIGHT_THUMB:
+		return "Right thumb";
+	case RIGHT_INDEX:
+		return "Right index finger";
+	case RIGHT_MIDDLE:
+		return "Right middle finger";
+	case RIGHT_RING:
+		return "Right ring finger";
+	case RIGHT_LITTLE:
+		return "Right little finger";
+	default:
+		return "Unknown finger";
+	}
+}
+
+static void create_manager(void)
+{
+	GError *error = NULL;
+
+	connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
+	if (connection == NULL)
+		g_error("Failed to connect to session bus: %s", error->message);
+
+	manager = dbus_g_proxy_new_for_name(connection,
+		"net.reactivated.Fprint", "/net/reactivated/Fprint/Manager",
+		"net.reactivated.Fprint.Manager");
+}
+
+static DBusGProxy *open_device(void)
+{
+	GError *error = NULL;
+	GPtrArray *devices;
+	gchar *path;
+	DBusGProxy *dev;
+	guint i;
+
+	if (!net_reactivated_Fprint_Manager_get_devices(manager, &devices, &error))
+		g_error("list_devices failed: %s", error->message);
+	
+	if (devices->len == 0) {
+		g_print("No devices found\n");
+		exit(1);
+	}
+
+	g_print("found %d devices\n", devices->len);
+	for (i = 0; i < devices->len; i++) {
+		path = g_ptr_array_index(devices, i);
+		g_print("Device at %s\n", path);
+	}
+
+	path = g_ptr_array_index(devices, 0);
+	g_print("Using device %s\n", path);
+
+	/* FIXME use for_name_owner?? */
+	dev = dbus_g_proxy_new_for_name(connection, "net.reactivated.Fprint",
+		path, "net.reactivated.Fprint.Device");
+	
+	g_ptr_array_foreach(devices, (GFunc) g_free, NULL);
+	g_ptr_array_free(devices, TRUE);
+
+	return dev;
+}
+
+static void list_fingerprints(DBusGProxy *dev, const char *username)
+{
+	GError *error = NULL;
+	GArray *fingers;
+	guint i;
+	int fingernum;
+
+	if (!net_reactivated_Fprint_Device_list_enrolled_fingers(dev, username, &fingers, &error))
+		g_error("ListEnrolledFingers failed: %s", error->message);
+
+	if (fingers->len == 0) {
+		g_print("User %s has no fingers enrolled for this device.\n", username);
+		return;
+	}
+
+	g_print("Fingerprints for user %s:\n", username);
+	for (i = 0; i < fingers->len; i++) {
+		fingernum = g_array_index(fingers, guint32, i);
+		g_print(" - #%d: %s\n", fingernum, fingerstr(fingernum));
+	}
+
+	fingernum = g_array_index(fingers, guint32, 0);
+	g_array_free(fingers, TRUE);
+}
+
+int main(int argc, char **argv)
+{
+	GMainLoop *loop;
+	DBusGProxy *dev;
+	guint32 i;
+
+	g_type_init();
+	loop = g_main_loop_new(NULL, FALSE);
+	create_manager();
+
+	if (argc < 2) {
+		g_print ("Usage: %s <username> [usernames...]\n", argv[0]);
+		return 1;
+	}
+
+	dev = open_device();
+	for (i = 1; argv[i] != NULL; i++) {
+		list_fingerprints (dev, argv[i]);
+	}
+
+	return 0;
+}
+

Modified: packages/fprint/fprintd/trunk/tests/verify.c
URL: http://svn.debian.org/wsvn/fingerforce/packages/fprint/fprintd/trunk/tests/verify.c?rev=123&op=diff
==============================================================================
--- packages/fprint/fprintd/trunk/tests/verify.c (original)
+++ packages/fprint/fprintd/trunk/tests/verify.c Thu Nov  6 17:18:39 2008
@@ -25,6 +25,9 @@
 
 static DBusGProxy *manager = NULL;
 static DBusGConnection *connection = NULL;
+static int finger_num = -1;
+static gboolean g_fatal_warnings = FALSE;
+static char **usernames = NULL;
 
 enum fp_verify_result {
 	VERIFY_NO_MATCH = 0,
@@ -91,6 +94,8 @@
 		return "Right ring finger";
 	case RIGHT_LITTLE:
 		return "Right little finger";
+	case -1:
+		return "First fingerprint available";
 	default:
 		return "Unknown finger";
 	}
@@ -109,7 +114,7 @@
 		"net.reactivated.Fprint.Manager");
 }
 
-static DBusGProxy *open_device(void)
+static DBusGProxy *open_device(const char *username)
 {
 	GError *error = NULL;
 	GPtrArray *devices;
@@ -141,20 +146,20 @@
 	g_ptr_array_foreach(devices, (GFunc) g_free, NULL);
 	g_ptr_array_free(devices, TRUE);
 
-	if (!net_reactivated_Fprint_Device_claim(dev, &error))
+	if (!net_reactivated_Fprint_Device_claim(dev, username, &error))
 		g_error("failed to claim device: %s", error->message);
+
 	return dev;
 }
 
-static guint32 find_finger(DBusGProxy *dev)
+static void find_finger(DBusGProxy *dev, const char *username)
 {
 	GError *error = NULL;
 	GArray *fingers;
 	guint i;
 	int fingernum;
-	guint32 print_id;
-
-	if (!net_reactivated_Fprint_Device_list_enrolled_fingers(dev, &fingers, &error))
+
+	if (!net_reactivated_Fprint_Device_list_enrolled_fingers(dev, username, &fingers, &error))
 		g_error("ListEnrolledFingers failed: %s", error->message);
 
 	if (fingers->len == 0) {
@@ -170,12 +175,6 @@
 
 	fingernum = g_array_index(fingers, guint32, 0);
 	g_array_free(fingers, TRUE);
-
-	g_print("Verifying: %s\n", fingerstr(fingernum));
-	if (!net_reactivated_Fprint_Device_load_print_data(dev, fingernum, &print_id, &error))
-		g_error("LoadPrintData failed: %s", error->message);
-
-	return print_id;
 }
 
 static void verify_result(GObject *object, int result, void *user_data)
@@ -186,34 +185,36 @@
 		*verify_completed = TRUE;
 }
 
-static void do_verify(DBusGProxy *dev, guint32 print_id)
+static void verify_finger_selected(GObject *object, int finger, void *user_data)
+{
+	g_print("Verifying: %s\n", fingerstr(finger));
+}
+
+static void do_verify(DBusGProxy *dev)
 {
 	GError *error;
 	gboolean verify_completed = FALSE;
 
 	dbus_g_proxy_add_signal(dev, "VerifyStatus", G_TYPE_INT, NULL);
+	dbus_g_proxy_add_signal(dev, "VerifyFingerSelected", G_TYPE_INT, NULL);
 	dbus_g_proxy_connect_signal(dev, "VerifyStatus", G_CALLBACK(verify_result),
 		&verify_completed, NULL);
-
-	if (!net_reactivated_Fprint_Device_verify_start(dev, print_id, &error))
+	dbus_g_proxy_connect_signal(dev, "VerifyFingerSelected", G_CALLBACK(verify_finger_selected),
+		NULL, NULL);
+
+	if (!net_reactivated_Fprint_Device_verify_start(dev, finger_num, &error))
 		g_error("VerifyStart failed: %s", error->message);
 
 	while (!verify_completed)
 		g_main_context_iteration(NULL, TRUE);
 
 	dbus_g_proxy_disconnect_signal(dev, "VerifyStatus", G_CALLBACK(verify_result), &verify_completed);
+	dbus_g_proxy_disconnect_signal(dev, "VerifyFingerSelected", G_CALLBACK(verify_finger_selected), NULL);
 
 	if (!net_reactivated_Fprint_Device_verify_stop(dev, &error))
 		g_error("VerifyStop failed: %s", error->message);
 }
 
-static void unload_print(DBusGProxy *dev, guint32 print_id)
-{
-	GError *error = NULL;
-	if (!net_reactivated_Fprint_Device_unload_print_data(dev, print_id, &error))
-		g_error("UnloadPrint failed: %s", error->message);
-}
-
 static void release_device(DBusGProxy *dev)
 {
 	GError *error = NULL;
@@ -221,20 +222,52 @@
 		g_error("ReleaseDevice failed: %s", error->message);
 }
 
+static const GOptionEntry entries[] = {
+	{ "finger", 'f',  0, G_OPTION_ARG_INT, &finger_num, "Finger selected to verify (default is automatic)", NULL },
+	{"g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, "Make all warnings fatal", NULL},
+ 	{ G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &usernames, NULL, "[username]" },
+	{ NULL }
+};
+
 int main(int argc, char **argv)
 {
+	GOptionContext *context;
 	GMainLoop *loop;
+	GError *err = NULL;
 	DBusGProxy *dev;
-	guint32 print_id;
+	char *username;
 
 	g_type_init();
+
+	context = g_option_context_new ("Verify a fingerprint");
+	g_option_context_add_main_entries (context, entries, NULL);
+
+	if (g_option_context_parse (context, &argc, &argv, &err) == FALSE) {
+		g_print ("couldn't parse command-line options: %s\n", err->message);
+		g_error_free (err);
+		return 1;
+	}
+
+	if (usernames == NULL) {
+		username = "";
+	} else {
+		username = usernames[0];
+	}
+
+	if (g_fatal_warnings) {
+		GLogLevelFlags fatal_mask;
+
+		fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
+		fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
+		g_log_set_always_fatal (fatal_mask);
+	}
+
 	loop = g_main_loop_new(NULL, FALSE);
 	create_manager();
 
-	dev = open_device();
-	print_id = find_finger(dev);
-	do_verify(dev, print_id);
-	unload_print(dev, print_id);
+	dev = open_device(username);
+	find_finger(dev, username);
+	do_verify(dev);
 	release_device(dev);
 	return 0;
 }




More information about the Fingerforce-commits mailing list