diff --git a/0001-Detect-when-a-device-is-disconnected.patch b/0001-Detect-when-a-device-is-disconnected.patch new file mode 100644 index 0000000..6662bbb --- /dev/null +++ b/0001-Detect-when-a-device-is-disconnected.patch @@ -0,0 +1,228 @@ +From c94c8b437a9a1ce46fda7b14220a4737b30a8fae Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Tue, 27 Jan 2009 12:29:23 +0000 +Subject: [PATCH] Detect when a device is disconnected + +Pretty hacky way to detect whether the device we're handling has +been disconnected during a verify or enrollment. This should allow +us to avoid users having to wait when somebody pulls the plug. +--- + pam/pam_fprintd.c | 8 ++++++-- + src/device.c | 40 ++++++++++++++++++++++++++++++++++++---- + src/device.xml | 13 +++++++++++++ + tests/verify.c | 2 +- + 4 files changed, 56 insertions(+), 7 deletions(-) + +diff --git a/pam/pam_fprintd.c b/pam/pam_fprintd.c +index 9847f4a..5e8757c 100644 +--- a/pam/pam_fprintd.c ++++ b/pam/pam_fprintd.c +@@ -154,7 +154,7 @@ static DBusGProxy *create_manager (pam_handle_t *pamh, DBusGConnection **ret_con + return manager; + } + +-static close_and_unref (DBusGConnection *connection) ++static void close_and_unref (DBusGConnection *connection) + { + DBusConnection *conn; + +@@ -335,7 +335,11 @@ static int do_verify(GMainLoop *loop, pam_handle_t *pamh, DBusGProxy *dev) + ret = PAM_SUCCESS; + else if (g_str_equal (data->result, "verify-unknown-error")) + ret = PAM_AUTHINFO_UNAVAIL; +- else { ++ else if (g_str_equal (data->result, "verify-disconnected")) { ++ ret = PAM_AUTHINFO_UNAVAIL; ++ g_free (data->result); ++ break; ++ } else { + send_info_msg (data->pamh, "An unknown error occured"); + ret = PAM_AUTH_ERR; + g_free (data->result); +diff --git a/src/device.c b/src/device.c +index 68a0b52..e1127da 100644 +--- a/src/device.c ++++ b/src/device.c +@@ -28,6 +28,7 @@ + + #include + #include ++#include + + #include "fprintd-marshal.h" + #include "fprintd.h" +@@ -119,6 +120,8 @@ struct FprintDevicePrivate { + FprintDeviceAction current_action; + /* Whether we should ignore new signals on the device */ + gboolean action_done; ++ /* Whether the device was disconnected */ ++ gboolean disconnected; + }; + + typedef struct FprintDevicePrivate FprintDevicePrivate; +@@ -368,6 +371,8 @@ verify_result_to_name (int result) + return "verify-finger-not-centered"; + case FP_VERIFY_RETRY_REMOVE_FINGER: + return "verify-remove-and-retry"; ++ case -EPROTO: ++ return "verify-disconnected"; + default: + return "verify-unknown-error"; + } +@@ -391,11 +396,21 @@ enroll_result_to_name (int result) + return "enroll-finger-not-centered"; + case FP_ENROLL_RETRY_REMOVE_FINGER: + return "enroll-remove-and-retry"; ++ case -EPROTO: ++ return "enroll-disconnected"; + default: + return "enroll-unknown-error"; + } + } + ++static void ++set_disconnected (FprintDevicePrivate *priv, const char *res) ++{ ++ if (g_str_equal (res, "enroll-disconnected") || ++ g_str_equal (res, "verify-disconnected")) ++ priv->disconnected = TRUE; ++} ++ + static gboolean + _fprint_device_check_claimed (FprintDevice *rdev, + DBusGMethodInvocation *context, +@@ -790,6 +805,7 @@ static void verify_cb(struct fp_dev *dev, int r, struct fp_img *img, + + if (r == FP_VERIFY_NO_MATCH || r == FP_VERIFY_MATCH || r < 0) + priv->action_done = TRUE; ++ set_disconnected (priv, name); + g_signal_emit(rdev, signals[SIGNAL_VERIFY_STATUS], 0, name, priv->action_done); + fp_img_free(img); + +@@ -813,6 +829,7 @@ static void identify_cb(struct fp_dev *dev, int r, + + if (r == FP_VERIFY_NO_MATCH || r == FP_VERIFY_MATCH || r < 0) + priv->action_done = TRUE; ++ set_disconnected (priv, name); + g_signal_emit(rdev, signals[SIGNAL_VERIFY_STATUS], 0, name, priv->action_done); + fp_img_free(img); + +@@ -986,7 +1003,10 @@ static void fprint_device_verify_stop(FprintDevice *rdev, + fp_print_data_free (priv->verify_data); + priv->verify_data = NULL; + } +- r = fp_async_verify_stop(priv->dev, verify_stop_cb, context); ++ if (!priv->disconnected) ++ r = fp_async_verify_stop(priv->dev, verify_stop_cb, context); ++ else ++ r = 0; + } else if (priv->current_action == ACTION_IDENTIFY) { + if (priv->identify_data != NULL) { + guint i; +@@ -995,7 +1015,10 @@ static void fprint_device_verify_stop(FprintDevice *rdev, + g_free (priv->identify_data); + priv->identify_data = NULL; + } +- r = fp_async_identify_stop(priv->dev, identify_stop_cb, context); ++ if (!priv->disconnected) ++ r = fp_async_identify_stop(priv->dev, identify_stop_cb, context); ++ else ++ r = 0; + } else { + g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_NO_ACTION_IN_PROGRESS, + "No verification in progress"); +@@ -1010,6 +1033,8 @@ static void fprint_device_verify_stop(FprintDevice *rdev, + dbus_g_method_return_error(context, error); + g_error_free (error); + } ++ if (priv->disconnected) ++ dbus_g_method_return(context); + + priv->current_action = ACTION_NONE; + } +@@ -1020,6 +1045,7 @@ static void enroll_stage_cb(struct fp_dev *dev, int result, + struct FprintDevice *rdev = user_data; + FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev); + struct session_data *session = priv->session; ++ const char *name = enroll_result_to_name (result); + int r; + + /* We're done, ignore new events for the action */ +@@ -1035,8 +1061,9 @@ static void enroll_stage_cb(struct fp_dev *dev, int result, + + if (result == FP_ENROLL_COMPLETE || result == FP_ENROLL_FAIL || result < 0) + priv->action_done = TRUE; ++ set_disconnected (priv, name); + +- g_signal_emit(rdev, signals[SIGNAL_ENROLL_STATUS], 0, enroll_result_to_name (result), priv->action_done); ++ g_signal_emit(rdev, signals[SIGNAL_ENROLL_STATUS], 0, name, priv->action_done); + + fp_img_free(img); + fp_print_data_free(print); +@@ -1129,13 +1156,18 @@ static void fprint_device_enroll_stop(FprintDevice *rdev, + return; + } + +- r = fp_async_enroll_stop(priv->dev, enroll_stop_cb, context); ++ if (!priv->disconnected) ++ r = fp_async_enroll_stop(priv->dev, enroll_stop_cb, context); ++ else ++ r = 0; + if (r < 0) { + g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_INTERNAL, + "Enroll stop failed with error %d", r); + dbus_g_method_return_error(context, error); + g_error_free (error); + } ++ if (priv->disconnected) ++ dbus_g_method_return(context); + + priv->current_action = ACTION_NONE; + } +diff --git a/src/device.xml b/src/device.xml +index 402c44b..99912ad 100644 +--- a/src/device.xml ++++ b/src/device.xml +@@ -183,6 +183,12 @@ + + + ++ verify-disconnected ++ ++ The device was disconnected during the verification, no other actions should be taken, and you shouldn't use the device any more. ++ ++ ++ + verify-unknown-error + + An unknown error occurred (usually a driver problem), Device.VerifyStop should now be called. +@@ -240,6 +246,13 @@ + + + ++ enroll-disconnected ++ ++ The device was disconnected during the enrollment, no other actions should be taken, and you shouldn't use the device any more. ++ ++ ++ ++ + enroll-unknown-error + + An unknown error occurred (usually a driver problem), Device.EnrollStop should now be called. +diff --git a/tests/verify.c b/tests/verify.c +index 999c402..eb739cb 100644 +--- a/tests/verify.c ++++ b/tests/verify.c +@@ -100,7 +100,7 @@ static void find_finger(DBusGProxy *dev, const char *username) + static void verify_result(GObject *object, const char *result, gboolean done, void *user_data) + { + gboolean *verify_completed = user_data; +- g_print("Verify result: %s\n", result); ++ g_print("Verify result: %s (%s)\n", result, done ? "done" : "not done"); + if (done != FALSE) + *verify_completed = TRUE; + } +-- +1.6.0.6 + diff --git a/fprintd.spec b/fprintd.spec index 4783b87..b995c0b 100644 --- a/fprintd.spec +++ b/fprintd.spec @@ -3,7 +3,7 @@ Name: fprintd Version: 0.1 -Release: 6.git%{short_hash}%{?dist} +Release: 7.git%{short_hash}%{?dist} Summary: D-Bus service for Fingerprint reader access Group: System Environment/Daemons @@ -16,6 +16,7 @@ License: GPLv2+ Source0: fprintd-0.1-%{short_hash}.tar.bz2 # FIXME remove when we have a newer libfprint Patch0: old-libfprint.patch +Patch1: 0001-Detect-when-a-device-is-disconnected.patch Url: http://www.reactivated.net/fprint/wiki/Fprintd BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -58,6 +59,7 @@ fingerprint readers access. %prep %setup -q -n %{name}-%{version} %patch0 -p1 +%patch1 -p1 %build %configure --libdir=/%{_lib}/ --enable-gtk-doc --enable-pam @@ -94,6 +96,9 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/dbus-1/interfaces/net.reactivated.Fprint.Manager.xml %changelog +* Tue Jan 27 2009 - Bastien Nocera - 0.1-7.git04fd09cfa +- Add a patch to handle device disconnects + * Mon Jan 26 2009 - Bastien Nocera - 0.1-6.git04fd09cfa - Update to latest git, fixes some run-time warnings