From eb8ef94512478db71e26974ca86787b95fc01300 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Fri, 15 May 2026 13:36:18 +0800 Subject: [PATCH] fprintd-enroll: Prompt if finger already enrolled Check if the requested finger is enrolled already, if yes, then ask for confirmation to re-enroll it. Previously, running without arguments would always erase the right-index-finger without any confirmation from the user. Now it says: $ fprintd-enroll Using device /net/reactivated/Fprint/Device/0 'right-index-finger' is already enrolled. Overwrite? [y/N] Signed-off-by: Daniel Schaefer --- utils/enroll.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/utils/enroll.c b/utils/enroll.c index 9b438d4..b254778 100644 --- a/utils/enroll.c +++ b/utils/enroll.c @@ -32,6 +32,7 @@ static FprintDBusManager *manager = NULL; static GDBusConnection *connection = NULL; static char *finger_name = NULL; static char **usernames = NULL; +static gboolean force_overwrite = FALSE; typedef enum { ENROLL_INCOMPLETE, @@ -101,6 +102,47 @@ open_device (const char *username) return g_steal_pointer (&dev); } +static gboolean +confirm_overwrite (FprintDBusDevice *dev, const char *username) +{ + g_autoptr(GError) error = NULL; + g_auto(GStrv) enrolled = NULL; + char buf[8]; + + if (!fprint_dbus_device_call_list_enrolled_fingers_sync (dev, username, + G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION, + -1, &enrolled, NULL, + &error)) + { + if (g_dbus_error_is_remote_error (error)) + { + g_autofree char *dbus_error = + g_dbus_error_get_remote_error (error); + if (g_str_equal (dbus_error, + "net.reactivated.Fprint.Error.NoEnrolledPrints")) + return TRUE; + } + + g_print ("ListEnrolledFingers failed: %s\n", error->message); + exit (1); + } + + if (enrolled == NULL || + !g_strv_contains ((const char **) enrolled, finger_name)) + return TRUE; + + if (force_overwrite) + return TRUE; + + g_print ("'%s' is already enrolled. Overwrite? [y/N] ", finger_name); + fflush (stdout); + + if (!fgets (buf, sizeof (buf), stdin)) + return FALSE; + + return buf[0] == 'y' || buf[0] == 'Y'; +} + static void enroll_result (GObject *object, const char *result, gboolean done, void *user_data) { @@ -210,6 +252,7 @@ release_device (FprintDBusDevice *dev) static const GOptionEntry entries[] = { { "finger", 'f', 0, G_OPTION_ARG_STRING, &finger_name, "Finger selected to verify (default is automatic)", NULL }, + { "force", 'y', 0, G_OPTION_ARG_NONE, &force_overwrite, "Overwrite an existing enrollment without prompting", NULL }, { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &usernames, NULL, "[username]" }, { NULL } }; @@ -220,6 +263,7 @@ main (int argc, char **argv) g_autoptr(FprintDBusDevice) dev = NULL; GOptionContext *context; FprintEnrollStatus status; + const char *username; g_autoptr(GError) err = NULL; @@ -239,7 +283,16 @@ main (int argc, char **argv) create_manager (); - dev = open_device (usernames ? usernames[0] : ""); + username = usernames ? usernames[0] : ""; + dev = open_device (username); + if (!confirm_overwrite (dev, username)) + { + g_print ("Not overwriting existing enrollment.\n"); + release_device (dev); + g_free (finger_name); + g_strfreev (usernames); + return EXIT_FAILURE; + } status = do_enroll (dev); release_device (dev); g_free (finger_name);