fprintd: Reindent the source code following uncrustify rules

This commit is contained in:
Marco Trevisan (Treviño)
2020-12-03 23:55:48 +01:00
parent c18ebaf9da
commit f73429f062
14 changed files with 3589 additions and 3180 deletions

View File

@ -1,7 +1,7 @@
/* /*
* Helper functions to translate statuses and actions to strings * Helper functions to translate statuses and actions to strings
* Copyright (C) 2008 Bastien Nocera <hadess@hadess.net> * Copyright (C) 2008 Bastien Nocera <hadess@hadess.net>
* *
* Experimental code. This will be moved out of fprintd into it's own * Experimental code. This will be moved out of fprintd into it's own
* package once the system has matured. * package once the system has matured.
* *
@ -9,12 +9,12 @@
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * 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., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@ -28,115 +28,128 @@
#define GNUC_UNUSED __attribute__((__unused__)) #define GNUC_UNUSED __attribute__((__unused__))
static bool str_equal (const char *a, const char *b) static bool
str_equal (const char *a, const char *b)
{ {
if (a == NULL && b == NULL) if (a == NULL && b == NULL)
return true; return true;
if (a == NULL || b == NULL) if (a == NULL || b == NULL)
return false; return false;
return (strcmp (a, b) == 0); return strcmp (a, b) == 0;
} }
struct { struct
const char *dbus_name; {
const char *place_str_generic; const char *dbus_name;
const char *place_str_specific; const char *place_str_generic;
const char *swipe_str_generic; const char *place_str_specific;
const char *swipe_str_specific; const char *swipe_str_generic;
const char *swipe_str_specific;
} fingers[] = { } fingers[] = {
{ "any", { "any",
N_("Place your finger on the fingerprint reader"), N_("Place your finger on the fingerprint reader"),
N_("Place your finger on %s"), N_("Place your finger on %s"),
N_("Swipe your finger across the fingerprint reader"), N_("Swipe your finger across the fingerprint reader"),
N_("Swipe your finger across %s") }, N_("Swipe your finger across %s") },
{ "left-thumb", { "left-thumb",
N_("Place your left thumb on the fingerprint reader"), N_("Place your left thumb on the fingerprint reader"),
N_("Place your left thumb on %s"), N_("Place your left thumb on %s"),
N_("Swipe your left thumb across the fingerprint reader"), N_("Swipe your left thumb across the fingerprint reader"),
N_("Swipe your left thumb across %s") }, N_("Swipe your left thumb across %s") },
{ "left-index-finger", { "left-index-finger",
N_("Place your left index finger on the fingerprint reader"), N_("Place your left index finger on the fingerprint reader"),
N_("Place your left index finger on %s"), N_("Place your left index finger on %s"),
N_("Swipe your left index finger across the fingerprint reader"), N_("Swipe your left index finger across the fingerprint reader"),
N_("Swipe your left index finger across %s") }, N_("Swipe your left index finger across %s") },
{ "left-middle-finger", { "left-middle-finger",
N_("Place your left middle finger on the fingerprint reader"), N_("Place your left middle finger on the fingerprint reader"),
N_("Place your left middle finger on %s"), N_("Place your left middle finger on %s"),
N_("Swipe your left middle finger across the fingerprint reader"), N_("Swipe your left middle finger across the fingerprint reader"),
N_("Swipe your left middle finger across %s") }, N_("Swipe your left middle finger across %s") },
{ "left-ring-finger", { "left-ring-finger",
N_("Place your left ring finger on the fingerprint reader"), N_("Place your left ring finger on the fingerprint reader"),
N_("Place your left ring finger on %s"), N_("Place your left ring finger on %s"),
N_("Swipe your left ring finger across the fingerprint reader"), N_("Swipe your left ring finger across the fingerprint reader"),
N_("Swipe your left ring finger across %s") }, N_("Swipe your left ring finger across %s") },
{ "left-little-finger", { "left-little-finger",
N_("Place your left little finger on the fingerprint reader"), N_("Place your left little finger on the fingerprint reader"),
N_("Place your left little finger on %s"), N_("Place your left little finger on %s"),
N_("Swipe your left little finger across the fingerprint reader"), N_("Swipe your left little finger across the fingerprint reader"),
N_("Swipe your left little finger across %s") }, N_("Swipe your left little finger across %s") },
{ "right-thumb", { "right-thumb",
N_("Place your right thumb on the fingerprint reader"), N_("Place your right thumb on the fingerprint reader"),
N_("Place your right thumb on %s"), N_("Place your right thumb on %s"),
N_("Swipe your right thumb across the fingerprint reader"), N_("Swipe your right thumb across the fingerprint reader"),
N_("Swipe your right thumb across %s") }, N_("Swipe your right thumb across %s") },
{ "right-index-finger", { "right-index-finger",
N_("Place your right index finger on the fingerprint reader"), N_("Place your right index finger on the fingerprint reader"),
N_("Place your right index finger on %s"), N_("Place your right index finger on %s"),
N_("Swipe your right index finger across the fingerprint reader"), N_("Swipe your right index finger across the fingerprint reader"),
N_("Swipe your right index finger across %s") }, N_("Swipe your right index finger across %s") },
{ "right-middle-finger", { "right-middle-finger",
N_("Place your right middle finger on the fingerprint reader"), N_("Place your right middle finger on the fingerprint reader"),
N_("Place your right middle finger on %s"), N_("Place your right middle finger on %s"),
N_("Swipe your right middle finger across the fingerprint reader"), N_("Swipe your right middle finger across the fingerprint reader"),
N_("Swipe your right middle finger across %s") }, N_("Swipe your right middle finger across %s") },
{ "right-ring-finger", { "right-ring-finger",
N_("Place your right ring finger on the fingerprint reader"), N_("Place your right ring finger on the fingerprint reader"),
N_("Place your right ring finger on %s"), N_("Place your right ring finger on %s"),
N_("Swipe your right ring finger across the fingerprint reader"), N_("Swipe your right ring finger across the fingerprint reader"),
N_("Swipe your right ring finger across %s") }, N_("Swipe your right ring finger across %s") },
{ "right-little-finger", { "right-little-finger",
N_("Place your right little finger on the fingerprint reader"), N_("Place your right little finger on the fingerprint reader"),
N_("Place your right little finger on %s"), N_("Place your right little finger on %s"),
N_("Swipe your right little finger across the fingerprint reader"), N_("Swipe your right little finger across the fingerprint reader"),
N_("Swipe your right little finger across %s") }, N_("Swipe your right little finger across %s") },
{ NULL, NULL, NULL, NULL, NULL } { NULL, NULL, NULL, NULL, NULL }
}; };
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral" #pragma GCC diagnostic ignored "-Wformat-nonliteral"
GNUC_UNUSED static char *finger_str_to_msg(const char *finger_name, const char *driver_name, bool is_swipe) GNUC_UNUSED static char *
finger_str_to_msg (const char *finger_name, const char *driver_name, bool is_swipe)
{ {
int i; int i;
if (finger_name == NULL) if (finger_name == NULL)
return NULL; return NULL;
for (i = 0; fingers[i].dbus_name != NULL; i++) { for (i = 0; fingers[i].dbus_name != NULL; i++)
if (!str_equal (fingers[i].dbus_name, finger_name)) {
continue; if (!str_equal (fingers[i].dbus_name, finger_name))
if (is_swipe == false) { continue;
if (driver_name) { if (is_swipe == false)
char *s; {
int ret; if (driver_name)
ret = asprintf (&s, TR (fingers[i].place_str_specific), driver_name); {
return ret >= 0 ? s : NULL; char *s;
} else { int ret;
return strdup (TR (fingers[i].place_str_generic)); ret = asprintf (&s, TR (fingers[i].place_str_specific), driver_name);
} return ret >= 0 ? s : NULL;
} else { }
if (driver_name) { else
char *s; {
int ret; return strdup (TR (fingers[i].place_str_generic));
ret = asprintf (&s, TR (fingers[i].swipe_str_specific), driver_name); }
return ret >= 0 ? s : NULL; }
} else { else
return strdup (TR (fingers[i].swipe_str_generic)); {
} if (driver_name)
} {
} char *s;
int ret;
ret = asprintf (&s, TR (fingers[i].swipe_str_specific), driver_name);
return ret >= 0 ? s : NULL;
}
else
{
return strdup (TR (fingers[i].swipe_str_generic));
}
}
}
return NULL; return NULL;
} }
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
@ -146,25 +159,27 @@ GNUC_UNUSED static char *finger_str_to_msg(const char *finger_name, const char *
* verify-match * verify-match
* verify-unknown-error * verify-unknown-error
*/ */
GNUC_UNUSED static const char *verify_result_str_to_msg(const char *result, bool is_swipe) GNUC_UNUSED static const char *
verify_result_str_to_msg (const char *result, bool is_swipe)
{ {
if (result == NULL) if (result == NULL)
return NULL; return NULL;
if (strcmp (result, "verify-retry-scan") == 0) { if (strcmp (result, "verify-retry-scan") == 0)
if (is_swipe == false) {
return TR (N_("Place your finger on the reader again")); if (is_swipe == false)
else return TR (N_("Place your finger on the reader again"));
return TR (N_("Swipe your finger again")); else
} return TR (N_("Swipe your finger again"));
if (strcmp (result, "verify-swipe-too-short") == 0) }
return TR (N_("Swipe was too short, try again")); if (strcmp (result, "verify-swipe-too-short") == 0)
if (strcmp (result, "verify-finger-not-centered") == 0) return TR (N_("Swipe was too short, try again"));
return TR (N_("Your finger was not centered, try swiping your finger again")); if (strcmp (result, "verify-finger-not-centered") == 0)
if (strcmp (result, "verify-remove-and-retry") == 0) return TR (N_("Your finger was not centered, try swiping your finger again"));
return TR (N_("Remove your finger, and try swiping your finger again")); if (strcmp (result, "verify-remove-and-retry") == 0)
return TR (N_("Remove your finger, and try swiping your finger again"));
return NULL; return NULL;
} }
/* Cases not handled: /* Cases not handled:
@ -172,24 +187,25 @@ GNUC_UNUSED static const char *verify_result_str_to_msg(const char *result, bool
* enroll-failed * enroll-failed
* enroll-unknown-error * enroll-unknown-error
*/ */
GNUC_UNUSED static const char *enroll_result_str_to_msg(const char *result, bool is_swipe) GNUC_UNUSED static const char *
enroll_result_str_to_msg (const char *result, bool is_swipe)
{ {
if (result == NULL) if (result == NULL)
return NULL; return NULL;
if (strcmp (result, "enroll-retry-scan") == 0 || strcmp (result, "enroll-stage-passed") == 0) { if (strcmp (result, "enroll-retry-scan") == 0 || strcmp (result, "enroll-stage-passed") == 0)
if (is_swipe == false) {
return TR (N_("Place your finger on the reader again")); if (is_swipe == false)
else return TR (N_("Place your finger on the reader again"));
return TR (N_("Swipe your finger again")); else
} return TR (N_("Swipe your finger again"));
if (strcmp (result, "enroll-swipe-too-short") == 0) }
return TR (N_("Swipe was too short, try again")); if (strcmp (result, "enroll-swipe-too-short") == 0)
if (strcmp (result, "enroll-finger-not-centered") == 0) return TR (N_("Swipe was too short, try again"));
return TR (N_("Your finger was not centered, try swiping your finger again")); if (strcmp (result, "enroll-finger-not-centered") == 0)
if (strcmp (result, "enroll-remove-and-retry") == 0) return TR (N_("Your finger was not centered, try swiping your finger again"));
return TR (N_("Remove your finger, and try swiping your finger again")); if (strcmp (result, "enroll-remove-and-retry") == 0)
return TR (N_("Remove your finger, and try swiping your finger again"));
return NULL; return NULL;
} }

File diff suppressed because it is too large Load Diff

View File

@ -23,35 +23,36 @@
/* Define auto-pointers functions, based on GLib Macros */ /* Define auto-pointers functions, based on GLib Macros */
#define _CLEANUP_FUNC(func) __attribute__((cleanup(func))) #define _CLEANUP_FUNC(func) __attribute__((cleanup (func)))
#define _PF_AUTOPTR_FUNC_NAME(TypeName) pf_autoptr_cleanup_##TypeName #define _PF_AUTOPTR_FUNC_NAME(TypeName) pf_autoptr_cleanup_ ## TypeName
#define _PF_AUTOPTR_TYPENAME(TypeName) TypeName##_pf_autoptr #define _PF_AUTOPTR_TYPENAME(TypeName) TypeName ## _pf_autoptr
#define PF_DEFINE_AUTOPTR_CLEANUP_FUNC(TypeName, cleanup) \ #define PF_DEFINE_AUTOPTR_CLEANUP_FUNC(TypeName, cleanup) \
typedef TypeName *_PF_AUTOPTR_TYPENAME (TypeName); \ typedef TypeName *_PF_AUTOPTR_TYPENAME (TypeName); \
static __attribute__((__unused__)) inline void \ static __attribute__((__unused__)) inline void \
_PF_AUTOPTR_FUNC_NAME (TypeName) (TypeName **_ptr) \ _PF_AUTOPTR_FUNC_NAME (TypeName) (TypeName **_ptr) \
{ if (_ptr) (cleanup) (*_ptr); } { if (_ptr) (cleanup) (*_ptr); }
#define PF_DEFINE_AUTO_CLEAN_FUNC(TypeName, cleanup) \ #define PF_DEFINE_AUTO_CLEAN_FUNC(TypeName, cleanup) \
static __attribute__((__unused__)) inline void \ static __attribute__((__unused__)) inline void \
_PF_AUTOPTR_FUNC_NAME (TypeName) (TypeName *_ptr) \ _PF_AUTOPTR_FUNC_NAME (TypeName) (TypeName *_ptr) \
{ cleanup (_ptr); } { cleanup (_ptr); }
static inline void static inline void
autoptr_cleanup_generic_free (void *p) autoptr_cleanup_generic_free (void *p)
{ {
void **pp = (void**)p; void **pp = (void **) p;
free (*pp); free (*pp);
} }
#define pf_autofree _CLEANUP_FUNC (autoptr_cleanup_generic_free) #define pf_autofree _CLEANUP_FUNC (autoptr_cleanup_generic_free)
#define pf_autoptr(TypeName) \ #define pf_autoptr(TypeName) \
_CLEANUP_FUNC (_PF_AUTOPTR_FUNC_NAME (TypeName)) \ _CLEANUP_FUNC (_PF_AUTOPTR_FUNC_NAME (TypeName)) \
_PF_AUTOPTR_TYPENAME (TypeName) _PF_AUTOPTR_TYPENAME (TypeName)
#define pf_auto(TypeName) \ #define pf_auto(TypeName) \
_CLEANUP_FUNC (_PF_AUTOPTR_FUNC_NAME (TypeName)) TypeName _CLEANUP_FUNC (_PF_AUTOPTR_FUNC_NAME (TypeName)) TypeName
PF_DEFINE_AUTOPTR_CLEANUP_FUNC (sd_bus, sd_bus_unref) PF_DEFINE_AUTOPTR_CLEANUP_FUNC (sd_bus, sd_bus_unref)
PF_DEFINE_AUTOPTR_CLEANUP_FUNC (sd_bus_message, sd_bus_message_unref) PF_DEFINE_AUTOPTR_CLEANUP_FUNC (sd_bus_message, sd_bus_message_unref)

File diff suppressed because it is too large Load Diff

View File

@ -7,12 +7,12 @@
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * 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., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@ -44,271 +44,297 @@
static char *storage_path = NULL; static char *storage_path = NULL;
static const char *get_storage_path(void) static const char *
get_storage_path (void)
{ {
const char *path = NULL; const char *path = NULL;
if (storage_path != NULL) if (storage_path != NULL)
return storage_path; return storage_path;
/* set by systemd >= 240 to an absolute path /* set by systemd >= 240 to an absolute path
* taking into account the StateDirectory * taking into account the StateDirectory
* unit file setting */ * unit file setting */
path = g_getenv ("STATE_DIRECTORY"); path = g_getenv ("STATE_DIRECTORY");
if (path != NULL) { if (path != NULL)
/* If multiple directories are set, then in the environment variable {
* the paths are concatenated with colon (":"). */ /* If multiple directories are set, then in the environment variable
if (strchr (path, ':')) { * the paths are concatenated with colon (":"). */
g_auto(GStrv) elems = NULL; if (strchr (path, ':'))
elems = g_strsplit (path, ":", -1); {
storage_path = g_strdup (elems[0]); g_auto(GStrv) elems = NULL;
} elems = g_strsplit (path, ":", -1);
} storage_path = g_strdup (elems[0]);
}
}
if (storage_path == NULL) if (storage_path == NULL)
storage_path = g_strdup (FILE_STORAGE_PATH); storage_path = g_strdup (FILE_STORAGE_PATH);
return storage_path; return storage_path;
} }
static char *get_path_to_storedir(const char *driver, const char * device_id, char *base_store) static char *
get_path_to_storedir (const char *driver, const char * device_id, char *base_store)
{ {
return g_build_filename(base_store, driver, device_id, NULL); return g_build_filename (base_store, driver, device_id, NULL);
} }
static char *__get_path_to_print(const char *driver, const char * device_id, static char *
FpFinger finger, char *base_store) __get_path_to_print (const char *driver, const char * device_id,
FpFinger finger, char *base_store)
{ {
g_autofree char *dirpath = NULL; g_autofree char *dirpath = NULL;
char *path; char *path;
char fingername[2]; char fingername[2];
g_snprintf(fingername, 2, "%x", finger); g_snprintf (fingername, 2, "%x", finger);
dirpath = get_path_to_storedir(driver, device_id, base_store); dirpath = get_path_to_storedir (driver, device_id, base_store);
path = g_build_filename(dirpath, fingername, NULL); path = g_build_filename (dirpath, fingername, NULL);
return path; return path;
} }
static char *get_path_to_print(FpDevice *dev, FpFinger finger, char *base_store) static char *
get_path_to_print (FpDevice *dev, FpFinger finger, char *base_store)
{ {
return __get_path_to_print(fp_device_get_driver (dev), return __get_path_to_print (fp_device_get_driver (dev),
fp_device_get_device_id(dev), fp_device_get_device_id (dev),
finger, finger,
base_store); base_store);
} }
static char *get_path_to_print_dscv(FpDevice *dev, FpFinger finger, char *base_store) static char *
get_path_to_print_dscv (FpDevice *dev, FpFinger finger, char *base_store)
{ {
return __get_path_to_print(fp_device_get_driver (dev), return __get_path_to_print (fp_device_get_driver (dev),
fp_device_get_device_id(dev), fp_device_get_device_id (dev),
finger, finger,
base_store); base_store);
} }
static char *file_storage_get_basestore_for_username(const char *username) static char *
file_storage_get_basestore_for_username (const char *username)
{ {
return g_build_filename(get_storage_path(), username, NULL); return g_build_filename (get_storage_path (), username, NULL);
} }
int file_storage_print_data_save(FpPrint *print) int
file_storage_print_data_save (FpPrint *print)
{ {
g_autoptr(GError) err = NULL; g_autoptr(GError) err = NULL;
g_autofree char *path = NULL; g_autofree char *path = NULL;
g_autofree char *dirpath = NULL; g_autofree char *dirpath = NULL;
g_autofree char *base_store = NULL; g_autofree char *base_store = NULL;
g_autofree char *buf = NULL; g_autofree char *buf = NULL;
gsize len; gsize len;
int r; int r;
base_store = file_storage_get_basestore_for_username(fp_print_get_username (print)); base_store = file_storage_get_basestore_for_username (fp_print_get_username (print));
if (!fp_print_serialize (print, (guchar **) &buf, &len, &err)) { if (!fp_print_serialize (print, (guchar **) &buf, &len, &err))
g_warning ("Error serializing data: %s", err->message); {
return -ENOMEM; g_warning ("Error serializing data: %s", err->message);
} return -ENOMEM;
}
path = __get_path_to_print(fp_print_get_driver (print), path = __get_path_to_print (fp_print_get_driver (print),
fp_print_get_device_id (print), fp_print_get_device_id (print),
fp_print_get_finger (print), fp_print_get_finger (print),
base_store); base_store);
dirpath = g_path_get_dirname(path); dirpath = g_path_get_dirname (path);
r = g_mkdir_with_parents(dirpath, DIR_PERMS); r = g_mkdir_with_parents (dirpath, DIR_PERMS);
if (r < 0) { if (r < 0)
g_debug("file_storage_print_data_save(): could not mkdir(\"%s\"): %s", {
dirpath, g_strerror(r)); g_debug ("file_storage_print_data_save(): could not mkdir(\"%s\"): %s",
return r; dirpath, g_strerror (r));
} return r;
}
//fp_dbg("saving to %s", path); //fp_dbg("saving to %s", path);
g_file_set_contents(path, buf, len, &err); g_file_set_contents (path, buf, len, &err);
if (err) { if (err)
g_debug("file_storage_print_data_save(): could not save '%s': %s", {
path, err->message); g_debug ("file_storage_print_data_save(): could not save '%s': %s",
/* FIXME interpret error codes */ path, err->message);
return err->code; /* FIXME interpret error codes */
} return err->code;
}
return 0; return 0;
} }
static int load_from_file(char *path, FpPrint **print) static int
load_from_file (char *path, FpPrint **print)
{ {
g_autoptr(GError) err = NULL; g_autoptr(GError) err = NULL;
gsize length; gsize length;
g_autofree char *contents = NULL; g_autofree char *contents = NULL;
FpPrint *new; FpPrint *new;
//fp_dbg("from %s", path); //fp_dbg("from %s", path);
g_file_get_contents(path, &contents, &length, &err); g_file_get_contents (path, &contents, &length, &err);
if (err) { if (err)
int r = err->code; {
/* FIXME interpret more error codes */ int r = err->code;
if (r == G_FILE_ERROR_NOENT) /* FIXME interpret more error codes */
return -ENOENT; if (r == G_FILE_ERROR_NOENT)
else return -ENOENT;
return r; else
} return r;
}
new = fp_print_deserialize ((guchar *) contents, length, &err); new = fp_print_deserialize ((guchar *) contents, length, &err);
if (!new) { if (!new)
g_print ("Error deserializing data: %s", err->message); {
return -EIO; g_print ("Error deserializing data: %s", err->message);
} return -EIO;
}
*print = new; *print = new;
return 0; return 0;
} }
int file_storage_print_data_load(FpDevice *dev, int
FpFinger finger, file_storage_print_data_load (FpDevice *dev,
const char *username, FpFinger finger,
FpPrint **print) const char *username,
FpPrint **print)
{ {
g_autofree gchar *path = NULL; g_autofree gchar *path = NULL;
g_autofree gchar *base_store = NULL; g_autofree gchar *base_store = NULL;
g_autoptr(FpPrint) new = NULL;
int r;
base_store = file_storage_get_basestore_for_username(username); g_autoptr(FpPrint) new = NULL;
int r;
path = get_path_to_print(dev, finger, base_store); base_store = file_storage_get_basestore_for_username (username);
r = load_from_file(path, &new);
g_debug ("file_storage_print_data_load(): loaded '%s' %s",
path, g_strerror(r));
if (r)
return r;
if (!fp_print_compatible (new, dev)) { path = get_path_to_print (dev, finger, base_store);
return -EINVAL; r = load_from_file (path, &new);
} g_debug ("file_storage_print_data_load(): loaded '%s' %s",
path, g_strerror (r));
if (r)
return r;
*print = g_steal_pointer (&new); if (!fp_print_compatible (new, dev))
return 0; return -EINVAL;
*print = g_steal_pointer (&new);
return 0;
} }
int file_storage_print_data_delete(FpDevice *dev, FpFinger finger, const char *username) int
file_storage_print_data_delete (FpDevice *dev, FpFinger finger, const char *username)
{ {
g_autofree gchar *base_store = NULL; g_autofree gchar *base_store = NULL;
g_autofree gchar *path = NULL; g_autofree gchar *path = NULL;
int r; int r;
base_store = file_storage_get_basestore_for_username(username); base_store = file_storage_get_basestore_for_username (username);
path = get_path_to_print_dscv(dev, finger, base_store); path = get_path_to_print_dscv (dev, finger, base_store);
r = g_unlink(path); r = g_unlink (path);
g_debug("file_storage_print_data_delete(): unlink(\"%s\") %s", g_debug ("file_storage_print_data_delete(): unlink(\"%s\") %s",
path, g_strerror(r)); path, g_strerror (r));
/* FIXME: cleanup empty directory */ /* FIXME: cleanup empty directory */
return g_unlink(path); return g_unlink (path);
} }
static GSList *scan_dev_storedir(char *devpath, static GSList *
GSList *list) scan_dev_storedir (char *devpath,
GSList *list)
{ {
g_autoptr(GError) err = NULL; g_autoptr(GError) err = NULL;
const gchar *ent; const gchar *ent;
GDir *dir = g_dir_open(devpath, 0, &err); GDir *dir = g_dir_open (devpath, 0, &err);
if (!dir) {
g_debug("scan_dev_storedir(): opendir(\"%s\") failed: %s", devpath, err->message);
return list;
}
while ((ent = g_dir_read_name(dir))) { if (!dir)
/* ent is an 1 hex character fp_finger code */ {
guint64 val; g_debug ("scan_dev_storedir(): opendir(\"%s\") failed: %s", devpath, err->message);
gchar *endptr; return list;
}
if (*ent == 0 || strlen(ent) != 1) while ((ent = g_dir_read_name (dir)))
continue; {
/* ent is an 1 hex character fp_finger code */
guint64 val;
gchar *endptr;
val = g_ascii_strtoull(ent, &endptr, 16); if (*ent == 0 || strlen (ent) != 1)
if (endptr == ent || !FP_FINGER_IS_VALID(val)) { continue;
g_debug("scan_dev_storedir(): skipping print file '%s'", ent);
continue;
}
list = g_slist_prepend (list, GUINT_TO_POINTER (val)); val = g_ascii_strtoull (ent, &endptr, 16);
} if (endptr == ent || !FP_FINGER_IS_VALID (val))
{
g_debug ("scan_dev_storedir(): skipping print file '%s'", ent);
continue;
}
g_dir_close(dir); list = g_slist_prepend (list, GUINT_TO_POINTER (val));
return list; }
g_dir_close (dir);
return list;
} }
GSList *file_storage_discover_prints(FpDevice *dev, const char *username) GSList *
file_storage_discover_prints (FpDevice *dev, const char *username)
{ {
GSList *list = NULL; GSList *list = NULL;
g_autofree gchar *base_store = NULL; g_autofree gchar *base_store = NULL;
g_autofree gchar *storedir = NULL; g_autofree gchar *storedir = NULL;
base_store = file_storage_get_basestore_for_username(username); base_store = file_storage_get_basestore_for_username (username);
storedir = get_path_to_storedir(fp_device_get_driver (dev), storedir = get_path_to_storedir (fp_device_get_driver (dev),
fp_device_get_device_id (dev), fp_device_get_device_id (dev),
base_store); base_store);
g_debug ("file_storage_discover_prints() for user '%s' in '%s'", g_debug ("file_storage_discover_prints() for user '%s' in '%s'",
username, storedir); username, storedir);
list = scan_dev_storedir(storedir, list); list = scan_dev_storedir (storedir, list);
return list; return list;
} }
GSList *file_storage_discover_users(void) GSList *
file_storage_discover_users (void)
{ {
g_autoptr(GError) err = NULL; g_autoptr(GError) err = NULL;
GSList *list = NULL; GSList *list = NULL;
const gchar *ent; const gchar *ent;
GDir *dir = g_dir_open(get_storage_path(), 0, &err); GDir *dir = g_dir_open (get_storage_path (), 0, &err);
if (!dir) { if (!dir)
return list; return list;
}
while ((ent = g_dir_read_name(dir))) { while ((ent = g_dir_read_name (dir)))
/* ent is a username */ {
if (*ent == 0) /* ent is a username */
continue; if (*ent == 0)
continue;
list = g_slist_prepend(list, g_strdup (ent)); list = g_slist_prepend (list, g_strdup (ent));
} }
g_dir_close(dir); g_dir_close (dir);
return list; return list;
} }
int file_storage_init(void) int
file_storage_init (void)
{ {
/* Nothing to do */ /* Nothing to do */
return 0; return 0;
} }
int file_storage_deinit(void) int
file_storage_deinit (void)
{ {
g_clear_pointer (&storage_path, g_free); g_clear_pointer (&storage_path, g_free);
return 0; return 0;
} }

View File

@ -6,12 +6,12 @@
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * 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., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@ -20,20 +20,21 @@
#pragma once #pragma once
int file_storage_print_data_save(FpPrint *print); int file_storage_print_data_save (FpPrint *print);
int file_storage_print_data_load(FpDevice *dev, int file_storage_print_data_load (FpDevice *dev,
FpFinger finger, FpFinger finger,
const char *username, const char *username,
FpPrint **print); FpPrint **print);
int file_storage_print_data_delete(FpDevice *dev, int file_storage_print_data_delete (FpDevice *dev,
FpFinger finger, FpFinger finger,
const char *username); const char *username);
int file_storage_init(void); int file_storage_init (void);
int file_storage_deinit(void); int file_storage_deinit (void);
GSList *file_storage_discover_prints(FpDevice *dev, const char *username); GSList *file_storage_discover_prints (FpDevice *dev,
GSList *file_storage_discover_users(void); const char *username);
GSList *file_storage_discover_users (void);

View File

@ -6,12 +6,12 @@
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * 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., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@ -31,60 +31,63 @@
#define FPRINT_SERVICE_PATH "/net/reactivated/Fprint" #define FPRINT_SERVICE_PATH "/net/reactivated/Fprint"
/* Errors */ /* Errors */
GQuark fprint_error_quark(void); GQuark fprint_error_quark (void);
#define FPRINT_ERROR fprint_error_quark() #define FPRINT_ERROR fprint_error_quark ()
typedef enum { typedef enum {
/* developer didn't claim the device */ /* developer didn't claim the device */
FPRINT_ERROR_CLAIM_DEVICE, /*< nick=net.reactivated.Fprint.Error.ClaimDevice >*/ FPRINT_ERROR_CLAIM_DEVICE, /*< nick=net.reactivated.Fprint.Error.ClaimDevice >*/
/* device is already claimed by somebody else */ /* device is already claimed by somebody else */
FPRINT_ERROR_ALREADY_IN_USE, /*< nick=net.reactivated.Fprint.Error.AlreadyInUse >*/ FPRINT_ERROR_ALREADY_IN_USE, /*< nick=net.reactivated.Fprint.Error.AlreadyInUse >*/
/* internal error occurred */ /* internal error occurred */
FPRINT_ERROR_INTERNAL, /*< nick=net.reactivated.Fprint.Error.Internal >*/ FPRINT_ERROR_INTERNAL, /*< nick=net.reactivated.Fprint.Error.Internal >*/
/* PolicyKit refused the action */ /* PolicyKit refused the action */
FPRINT_ERROR_PERMISSION_DENIED, /*< nick=net.reactivated.Fprint.Error.PermissionDenied >*/ FPRINT_ERROR_PERMISSION_DENIED, /*< nick=net.reactivated.Fprint.Error.PermissionDenied >*/
/* No prints are enrolled */ /* No prints are enrolled */
FPRINT_ERROR_NO_ENROLLED_PRINTS, /*< nick=net.reactivated.Fprint.Error.NoEnrolledPrints >*/ FPRINT_ERROR_NO_ENROLLED_PRINTS, /*< nick=net.reactivated.Fprint.Error.NoEnrolledPrints >*/
/* No actions currently in progress */ /* No actions currently in progress */
FPRINT_ERROR_NO_ACTION_IN_PROGRESS, /*< nick=net.reactivated.Fprint.Error.NoActionInProgress >*/ FPRINT_ERROR_NO_ACTION_IN_PROGRESS, /*< nick=net.reactivated.Fprint.Error.NoActionInProgress >*/
/* the finger name passed was invalid */ /* the finger name passed was invalid */
FPRINT_ERROR_INVALID_FINGERNAME, /*< nick=net.reactivated.Fprint.Error.InvalidFingername >*/ FPRINT_ERROR_INVALID_FINGERNAME, /*< nick=net.reactivated.Fprint.Error.InvalidFingername >*/
/* device does not exist */ /* device does not exist */
FPRINT_ERROR_NO_SUCH_DEVICE, /*< nick=net.reactivated.Fprint.Error.NoSuchDevice >*/ FPRINT_ERROR_NO_SUCH_DEVICE, /*< nick=net.reactivated.Fprint.Error.NoSuchDevice >*/
} FprintError; } FprintError;
/* Enum of possible permissions, orders and nick matter here: /* Enum of possible permissions, orders and nick matter here:
- The order controls the priority of a required permission when various are - The order controls the priority of a required permission when various are
accepted: the lowest the value, the more priorty it has. accepted: the lowest the value, the more priorty it has.
- Nick must match the relative polkit rule. - Nick must match the relative polkit rule.
*/ */
typedef enum { typedef enum {
FPRINT_DEVICE_PERMISSION_NONE = 0, FPRINT_DEVICE_PERMISSION_NONE = 0,
FPRINT_DEVICE_PERMISSION_VERIFY = (1 << 0), /*< nick=net.reactivated.fprint.device.verify >*/ FPRINT_DEVICE_PERMISSION_VERIFY = (1 << 0), /*< nick=net.reactivated.fprint.device.verify >*/
FPRINT_DEVICE_PERMISSION_ENROLL = (1 << 1), /*< nick=net.reactivated.fprint.device.enroll >*/ FPRINT_DEVICE_PERMISSION_ENROLL = (1 << 1), /*< nick=net.reactivated.fprint.device.enroll >*/
FPRINT_DEVICE_PERMISSION_SETUSERNAME = (1 << 2), /*< nick=net.reactivated.fprint.device.setusername >*/ FPRINT_DEVICE_PERMISSION_SETUSERNAME = (1 << 2), /*< nick=net.reactivated.fprint.device.setusername >*/
} FprintDevicePermission; } FprintDevicePermission;
/* Manager */ /* Manager */
#define FPRINT_TYPE_MANAGER (fprint_manager_get_type()) #define FPRINT_TYPE_MANAGER (fprint_manager_get_type ())
G_DECLARE_FINAL_TYPE (FprintManager, fprint_manager, FPRINT, MANAGER, GObject) G_DECLARE_FINAL_TYPE (FprintManager, fprint_manager, FPRINT, MANAGER, GObject)
struct _FprintManager { struct _FprintManager
GObject parent; {
GObject parent;
}; };
FprintManager *fprint_manager_new (GDBusConnection *connection, gboolean no_timeout); FprintManager *fprint_manager_new (GDBusConnection *connection,
gboolean no_timeout);
/* Device */ /* Device */
#define FPRINT_TYPE_DEVICE (fprint_device_get_type()) #define FPRINT_TYPE_DEVICE (fprint_device_get_type ())
G_DECLARE_FINAL_TYPE (FprintDevice, fprint_device, FPRINT, DEVICE, G_DECLARE_FINAL_TYPE (FprintDevice, fprint_device, FPRINT, DEVICE,
FprintDBusDeviceSkeleton) FprintDBusDeviceSkeleton)
struct _FprintDevice { struct _FprintDevice
FprintDBusDeviceSkeleton parent; {
FprintDBusDeviceSkeleton parent;
}; };
FprintDevice *fprint_device_new(FpDevice *dev); FprintDevice *fprint_device_new (FpDevice *dev);
guint32 _fprint_device_get_id(FprintDevice *rdev); guint32 _fprint_device_get_id (FprintDevice *rdev);
/* Print */ /* Print */
/* TODO */ /* TODO */

View File

@ -7,12 +7,12 @@
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * 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., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@ -44,171 +44,179 @@ static gboolean g_fatal_warnings = FALSE;
static void static void
set_storage_file (void) set_storage_file (void)
{ {
store.init = &file_storage_init; store.init = &file_storage_init;
store.deinit = &file_storage_deinit; store.deinit = &file_storage_deinit;
store.print_data_save = &file_storage_print_data_save; store.print_data_save = &file_storage_print_data_save;
store.print_data_load = &file_storage_print_data_load; store.print_data_load = &file_storage_print_data_load;
store.print_data_delete = &file_storage_print_data_delete; store.print_data_delete = &file_storage_print_data_delete;
store.discover_prints = &file_storage_discover_prints; store.discover_prints = &file_storage_discover_prints;
store.discover_users = &file_storage_discover_users; store.discover_users = &file_storage_discover_users;
} }
static gboolean static gboolean
load_storage_module (const char *module_name) load_storage_module (const char *module_name)
{ {
GModule *module; GModule *module;
g_autofree char *filename = NULL; g_autofree char *filename = NULL;
filename = g_module_build_path (PLUGINDIR, module_name); filename = g_module_build_path (PLUGINDIR, module_name);
module = g_module_open (filename, 0); module = g_module_open (filename, 0);
if (module == NULL) if (module == NULL)
return FALSE; return FALSE;
if (!g_module_symbol (module, "init", (gpointer *) &store.init) || if (!g_module_symbol (module, "init", (gpointer *) &store.init) ||
!g_module_symbol (module, "deinit", (gpointer *) &store.deinit) || !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_save", (gpointer *) &store.print_data_save) ||
!g_module_symbol (module, "print_data_load", (gpointer *) &store.print_data_load) || !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, "print_data_delete", (gpointer *) &store.print_data_delete) ||
!g_module_symbol (module, "discover_prints", (gpointer *) &store.discover_prints)) { !g_module_symbol (module, "discover_prints", (gpointer *) &store.discover_prints))
g_module_close (module); {
return FALSE; g_module_close (module);
} return FALSE;
}
g_module_make_resident (module); g_module_make_resident (module);
return TRUE; return TRUE;
} }
static gboolean static gboolean
load_conf (void) load_conf (void)
{ {
g_autofree char *filename = NULL; g_autofree char *filename = NULL;
g_autofree char *module_name = NULL; g_autofree char *module_name = NULL;
g_autoptr(GKeyFile) file = NULL;
g_autoptr(GError) error = NULL;
filename = g_build_filename (SYSCONFDIR, "fprintd.conf", NULL); g_autoptr(GKeyFile) file = NULL;
file = g_key_file_new (); g_autoptr(GError) error = NULL;
g_debug("About to load configuration file '%s'", filename);
if (!g_key_file_load_from_file (file, filename, G_KEY_FILE_NONE, &error)) {
g_warning ("Could not open \"%s\": %s\n", filename, error->message);
return FALSE;
}
module_name = g_key_file_get_string (file, "storage", "type", &error); filename = g_build_filename (SYSCONFDIR, "fprintd.conf", NULL);
if (module_name == NULL) file = g_key_file_new ();
return FALSE; g_debug ("About to load configuration file '%s'", filename);
if (!g_key_file_load_from_file (file, filename, G_KEY_FILE_NONE, &error))
{
g_warning ("Could not open \"%s\": %s\n", filename, error->message);
return FALSE;
}
if (g_str_equal (module_name, "file")) { module_name = g_key_file_get_string (file, "storage", "type", &error);
set_storage_file (); if (module_name == NULL)
return TRUE; return FALSE;
}
return load_storage_module (module_name); if (g_str_equal (module_name, "file"))
{
set_storage_file ();
return TRUE;
}
return load_storage_module (module_name);
} }
static const GOptionEntry entries[] = { static const GOptionEntry entries[] = {
{"g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &g_fatal_warnings, "Make all warnings fatal", NULL}, {"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}, {"no-timeout", 't', 0, G_OPTION_ARG_NONE, &no_timeout, "Do not exit after unused for a while", NULL},
{ NULL } { NULL }
}; };
static gboolean sigterm_callback(gpointer data) static gboolean
sigterm_callback (gpointer data)
{ {
GMainLoop *loop = data; GMainLoop *loop = data;
g_main_loop_quit (loop); g_main_loop_quit (loop);
return FALSE; return FALSE;
} }
static void static void
on_name_acquired (GDBusConnection *connection, on_name_acquired (GDBusConnection *connection,
const char *name, const char *name,
gpointer user_data) gpointer user_data)
{ {
g_debug ("D-Bus service launched with name: %s", name); g_debug ("D-Bus service launched with name: %s", name);
} }
static void static void
on_name_lost (GDBusConnection *connection, on_name_lost (GDBusConnection *connection,
const char *name, const char *name,
gpointer user_data) gpointer user_data)
{ {
GMainLoop *loop = user_data; GMainLoop *loop = user_data;
g_warning ("Failed to get name: %s", name); g_warning ("Failed to get name: %s", name);
g_main_loop_quit (loop); g_main_loop_quit (loop);
} }
int main(int argc, char **argv) int
main (int argc, char **argv)
{ {
g_autoptr(GOptionContext) context = NULL; g_autoptr(GOptionContext) context = NULL;
g_autoptr(GMainLoop) loop = NULL; g_autoptr(GMainLoop) loop = NULL;
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
g_autoptr(FprintManager) manager = NULL; g_autoptr(FprintManager) manager = NULL;
g_autoptr(GDBusConnection) connection = NULL; g_autoptr(GDBusConnection) connection = NULL;
guint32 request_name_ret; guint32 request_name_ret;
setlocale (LC_ALL, ""); setlocale (LC_ALL, "");
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
textdomain (GETTEXT_PACKAGE); textdomain (GETTEXT_PACKAGE);
context = g_option_context_new ("Fingerprint handler daemon"); context = g_option_context_new ("Fingerprint handler daemon");
g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
if (g_option_context_parse (context, &argc, &argv, &error) == FALSE) { if (g_option_context_parse (context, &argc, &argv, &error) == FALSE)
g_warning ("couldn't parse command-line options: %s\n", error->message); {
return 1; g_warning ("couldn't parse command-line options: %s\n", error->message);
} return 1;
}
if (g_fatal_warnings) { if (g_fatal_warnings)
GLogLevelFlags fatal_mask; {
GLogLevelFlags fatal_mask;
fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
g_log_set_always_fatal (fatal_mask); g_log_set_always_fatal (fatal_mask);
} }
/* Obtain a connection to the system bus */ /* Obtain a connection to the system bus */
connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
if (!G_IS_DBUS_CONNECTION (connection)) { if (!G_IS_DBUS_CONNECTION (connection))
g_warning("Failed to open connection to bus: %s", error->message); {
return 1; g_warning ("Failed to open connection to bus: %s", error->message);
} return 1;
}
/* Load the configuration file, /* Load the configuration file,
* and the default storage plugin */ * and the default storage plugin */
if (!load_conf()) if (!load_conf ())
set_storage_file (); set_storage_file ();
store.init (); store.init ();
loop = g_main_loop_new(NULL, FALSE); loop = g_main_loop_new (NULL, FALSE);
g_unix_signal_add (SIGTERM, sigterm_callback, loop); g_unix_signal_add (SIGTERM, sigterm_callback, loop);
g_debug("Launching FprintObject"); g_debug ("Launching FprintObject");
/* create the one instance of the Manager object to be shared between /* create the one instance of the Manager object to be shared between
* all fprintd users. This blocks until all the devices are enumerated */ * all fprintd users. This blocks until all the devices are enumerated */
manager = fprint_manager_new (connection, no_timeout); manager = fprint_manager_new (connection, no_timeout);
/* Obtain the well-known name after the manager has been initialized. /* Obtain the well-known name after the manager has been initialized.
* Otherwise a client immediately enumerating the devices will not see * Otherwise a client immediately enumerating the devices will not see
* any. */ * any. */
request_name_ret = g_bus_own_name_on_connection (connection, request_name_ret = g_bus_own_name_on_connection (connection,
FPRINT_SERVICE_NAME, FPRINT_SERVICE_NAME,
G_BUS_NAME_OWNER_FLAGS_NONE, G_BUS_NAME_OWNER_FLAGS_NONE,
on_name_acquired, on_name_acquired,
on_name_lost, on_name_lost,
loop, NULL); loop, NULL);
g_debug("entering main loop"); g_debug ("entering main loop");
g_main_loop_run(loop); g_main_loop_run (loop);
g_bus_unown_name (request_name_ret); g_bus_unown_name (request_name_ret);
g_debug("main loop completed"); g_debug ("main loop completed");
return 0; return 0;
} }

View File

@ -7,12 +7,12 @@
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * 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., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@ -28,294 +28,316 @@
#include "fprintd.h" #include "fprintd.h"
static void fprint_manager_constructed (GObject *object); static void fprint_manager_constructed (GObject *object);
static gboolean fprint_manager_get_devices(FprintManager *manager, static gboolean fprint_manager_get_devices (FprintManager *manager,
GPtrArray **devices, GError **error); GPtrArray **devices,
static gboolean fprint_manager_get_default_device(FprintManager *manager, GError **error);
const char **device, GError **error); static gboolean fprint_manager_get_default_device (FprintManager *manager,
const char **device,
GError **error);
typedef struct typedef struct
{ {
GDBusConnection *connection; GDBusConnection *connection;
GDBusObjectManager *object_manager; GDBusObjectManager *object_manager;
FprintDBusManager *dbus_manager; FprintDBusManager *dbus_manager;
FpContext *context; FpContext *context;
gboolean no_timeout; gboolean no_timeout;
guint timeout_id; guint timeout_id;
} FprintManagerPrivate; } FprintManagerPrivate;
G_DEFINE_TYPE_WITH_CODE(FprintManager, fprint_manager, G_TYPE_OBJECT, G_ADD_PRIVATE (FprintManager)) G_DEFINE_TYPE_WITH_CODE (FprintManager, fprint_manager, G_TYPE_OBJECT, G_ADD_PRIVATE (FprintManager))
enum { enum {
PROP_0, PROP_0,
FPRINT_MANAGER_CONNECTION, FPRINT_MANAGER_CONNECTION,
N_PROPS N_PROPS
}; };
static GParamSpec *properties[N_PROPS]; static GParamSpec *properties[N_PROPS];
static void fprint_manager_finalize(GObject *object) static void
fprint_manager_finalize (GObject *object)
{ {
FprintManagerPrivate *priv = fprint_manager_get_instance_private (FPRINT_MANAGER (object)); FprintManagerPrivate *priv = fprint_manager_get_instance_private (FPRINT_MANAGER (object));
g_clear_object (&priv->object_manager); g_clear_object (&priv->object_manager);
g_clear_object (&priv->dbus_manager); g_clear_object (&priv->dbus_manager);
g_clear_object (&priv->connection); g_clear_object (&priv->connection);
g_clear_object (&priv->context); g_clear_object (&priv->context);
G_OBJECT_CLASS(fprint_manager_parent_class)->finalize(object); G_OBJECT_CLASS (fprint_manager_parent_class)->finalize (object);
} }
static FprintDevice * static FprintDevice *
fprint_dbus_object_skeleton_get_device (FprintDBusObjectSkeleton *object) { fprint_dbus_object_skeleton_get_device (FprintDBusObjectSkeleton *object)
FprintDevice *rdev; {
FprintDevice *rdev;
g_object_get (object, "device", &rdev, NULL); g_object_get (object, "device", &rdev, NULL);
return rdev; return rdev;
} }
static void fprint_manager_set_property (GObject *object, guint property_id, static void
const GValue *value, GParamSpec *pspec) fprint_manager_set_property (GObject *object, guint property_id,
const GValue *value, GParamSpec *pspec)
{ {
FprintManager *self = FPRINT_MANAGER (object); FprintManager *self = FPRINT_MANAGER (object);
FprintManagerPrivate *priv = fprint_manager_get_instance_private (self); FprintManagerPrivate *priv = fprint_manager_get_instance_private (self);
switch (property_id) { switch (property_id)
case FPRINT_MANAGER_CONNECTION: {
priv->connection = g_value_dup_object (value); case FPRINT_MANAGER_CONNECTION:
break; priv->connection = g_value_dup_object (value);
default: break;
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break; default:
} G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
} }
static void fprint_manager_get_property (GObject *object, guint property_id, static void
GValue *value, GParamSpec *pspec) fprint_manager_get_property (GObject *object, guint property_id,
GValue *value, GParamSpec *pspec)
{ {
FprintManager *self = FPRINT_MANAGER (object); FprintManager *self = FPRINT_MANAGER (object);
FprintManagerPrivate *priv = fprint_manager_get_instance_private (self); FprintManagerPrivate *priv = fprint_manager_get_instance_private (self);
switch (property_id) { switch (property_id)
case FPRINT_MANAGER_CONNECTION: {
g_value_set_object (value, priv->connection); case FPRINT_MANAGER_CONNECTION:
break; g_value_set_object (value, priv->connection);
default: break;
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break; default:
} G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
} }
static void fprint_manager_class_init(FprintManagerClass *klass) static void
fprint_manager_class_init (FprintManagerClass *klass)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = fprint_manager_constructed; object_class->constructed = fprint_manager_constructed;
object_class->set_property = fprint_manager_set_property; object_class->set_property = fprint_manager_set_property;
object_class->get_property = fprint_manager_get_property; object_class->get_property = fprint_manager_get_property;
object_class->finalize = fprint_manager_finalize; object_class->finalize = fprint_manager_finalize;
properties[FPRINT_MANAGER_CONNECTION] = properties[FPRINT_MANAGER_CONNECTION] =
g_param_spec_object ("connection", g_param_spec_object ("connection",
"Connection", "Connection",
"Set GDBus connection property", "Set GDBus connection property",
G_TYPE_DBUS_CONNECTION, G_TYPE_DBUS_CONNECTION,
G_PARAM_CONSTRUCT_ONLY | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_READWRITE); G_PARAM_READWRITE);
g_object_class_install_properties (object_class, N_PROPS, properties); g_object_class_install_properties (object_class, N_PROPS, properties);
} }
static gchar *get_device_path(FprintDevice *rdev) static gchar *
get_device_path (FprintDevice *rdev)
{ {
return g_strdup_printf (FPRINT_SERVICE_PATH "/Device/%d", return g_strdup_printf (FPRINT_SERVICE_PATH "/Device/%d",
_fprint_device_get_id(rdev)); _fprint_device_get_id (rdev));
} }
static gboolean static gboolean
fprint_manager_timeout_cb (FprintManager *manager) fprint_manager_timeout_cb (FprintManager *manager)
{ {
//FIXME kill all the devices //FIXME kill all the devices
exit(0); exit (0);
return FALSE; return FALSE;
} }
static void static void
fprint_manager_in_use_notified (FprintDevice *rdev, GParamSpec *spec, FprintManager *manager) fprint_manager_in_use_notified (FprintDevice *rdev, GParamSpec *spec, FprintManager *manager)
{ {
FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager); FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager);
guint num_devices_used = 0; guint num_devices_used = 0;
g_autolist(GDBusObject) devices = NULL;
GList *l;
gboolean in_use;
if (priv->timeout_id > 0) { g_autolist (GDBusObject) devices = NULL;
g_source_remove (priv->timeout_id); GList *l;
priv->timeout_id = 0; gboolean in_use;
}
if (priv->no_timeout)
return;
devices = g_dbus_object_manager_get_objects (priv->object_manager); if (priv->timeout_id > 0)
{
g_source_remove (priv->timeout_id);
priv->timeout_id = 0;
}
if (priv->no_timeout)
return;
for (l = devices; l != NULL; l = l->next) { devices = g_dbus_object_manager_get_objects (priv->object_manager);
g_autoptr(FprintDevice) dev = NULL;
FprintDBusObjectSkeleton *object = l->data;
dev = fprint_dbus_object_skeleton_get_device (object); for (l = devices; l != NULL; l = l->next)
g_object_get (G_OBJECT(dev), "in-use", &in_use, NULL); {
if (in_use != FALSE) g_autoptr(FprintDevice) dev = NULL;
num_devices_used++; FprintDBusObjectSkeleton *object = l->data;
}
if (num_devices_used == 0) dev = fprint_dbus_object_skeleton_get_device (object);
priv->timeout_id = g_timeout_add_seconds (TIMEOUT, (GSourceFunc) fprint_manager_timeout_cb, manager); g_object_get (G_OBJECT (dev), "in-use", &in_use, NULL);
if (in_use != FALSE)
num_devices_used++;
}
if (num_devices_used == 0)
priv->timeout_id = g_timeout_add_seconds (TIMEOUT, (GSourceFunc) fprint_manager_timeout_cb, manager);
} }
static gboolean static gboolean
handle_get_devices (FprintManager *manager, GDBusMethodInvocation *invocation, handle_get_devices (FprintManager *manager, GDBusMethodInvocation *invocation,
FprintDBusManager *skeleton) FprintDBusManager *skeleton)
{ {
g_autoptr(GPtrArray) devices = NULL; g_autoptr(GPtrArray) devices = NULL;
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
if (!fprint_manager_get_devices (manager, &devices, &error)) { if (!fprint_manager_get_devices (manager, &devices, &error))
g_dbus_method_invocation_return_gerror (invocation, error); {
return TRUE; g_dbus_method_invocation_return_gerror (invocation, error);
} return TRUE;
}
fprint_dbus_manager_complete_get_devices (skeleton, invocation, fprint_dbus_manager_complete_get_devices (skeleton, invocation,
(const gchar *const *) (const gchar *const *)
devices->pdata); devices->pdata);
return TRUE; return TRUE;
} }
static gboolean static gboolean
handle_get_default_device (FprintManager *manager, handle_get_default_device (FprintManager *manager,
GDBusMethodInvocation *invocation, GDBusMethodInvocation *invocation,
FprintDBusManager *skeleton) FprintDBusManager *skeleton)
{ {
const gchar *device; const gchar *device;
g_autoptr(GError) error = NULL;
if (!fprint_manager_get_default_device (manager, &device, &error)) { g_autoptr(GError) error = NULL;
g_dbus_method_invocation_return_gerror (invocation, error);
return TRUE;
}
fprint_dbus_manager_complete_get_default_device (skeleton, invocation, if (!fprint_manager_get_default_device (manager, &device, &error))
device); {
g_dbus_method_invocation_return_gerror (invocation, error);
return TRUE;
}
return TRUE; fprint_dbus_manager_complete_get_default_device (skeleton, invocation,
device);
return TRUE;
} }
static void static void
device_added_cb (FprintManager *manager, FpDevice *device, FpContext *context) device_added_cb (FprintManager *manager, FpDevice *device, FpContext *context)
{ {
FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager); FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager);
g_autoptr(FprintDBusObjectSkeleton) object = NULL;
g_autoptr(FprintDevice) rdev = NULL;
g_autofree gchar *path = NULL;
rdev = fprint_device_new(device); g_autoptr(FprintDBusObjectSkeleton) object = NULL;
g_autoptr(FprintDevice) rdev = NULL;
g_autofree gchar *path = NULL;
g_signal_connect (G_OBJECT(rdev), "notify::in-use", rdev = fprint_device_new (device);
G_CALLBACK (fprint_manager_in_use_notified), manager);
path = get_device_path (rdev); g_signal_connect (G_OBJECT (rdev), "notify::in-use",
G_CALLBACK (fprint_manager_in_use_notified), manager);
object = fprint_dbus_object_skeleton_new (path); path = get_device_path (rdev);
fprint_dbus_object_skeleton_set_device (object,
FPRINT_DBUS_DEVICE (rdev)); object = fprint_dbus_object_skeleton_new (path);
g_dbus_object_manager_server_export ( fprint_dbus_object_skeleton_set_device (object,
G_DBUS_OBJECT_MANAGER_SERVER (priv->object_manager), FPRINT_DBUS_DEVICE (rdev));
G_DBUS_OBJECT_SKELETON (object)); g_dbus_object_manager_server_export (
G_DBUS_OBJECT_MANAGER_SERVER (priv->object_manager),
G_DBUS_OBJECT_SKELETON (object));
} }
static void static void
device_removed_cb (FprintManager *manager, FpDevice *device, FpContext *context) device_removed_cb (FprintManager *manager, FpDevice *device, FpContext *context)
{ {
FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager); FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager);
g_autolist (FprintDBusObjectSkeleton) objects = NULL;
GList *item;
objects = g_dbus_object_manager_get_objects (priv->object_manager); g_autolist (FprintDBusObjectSkeleton) objects = NULL;
GList *item;
for (item = objects; item; item = item->next) { objects = g_dbus_object_manager_get_objects (priv->object_manager);
g_autoptr(FprintDevice) rdev = NULL;
g_autoptr(FpDevice) dev = NULL;
FprintDBusObjectSkeleton *object = item->data;
rdev = fprint_dbus_object_skeleton_get_device (object); for (item = objects; item; item = item->next)
g_object_get (rdev, "dev", &dev, NULL); {
if (dev != device) g_autoptr(FprintDevice) rdev = NULL;
continue; g_autoptr(FpDevice) dev = NULL;
FprintDBusObjectSkeleton *object = item->data;
g_dbus_object_manager_server_unexport ( rdev = fprint_dbus_object_skeleton_get_device (object);
G_DBUS_OBJECT_MANAGER_SERVER (priv->object_manager), g_object_get (rdev, "dev", &dev, NULL);
g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (rdev))); if (dev != device)
continue;
g_signal_handlers_disconnect_by_data (rdev, manager); g_dbus_object_manager_server_unexport (
G_DBUS_OBJECT_MANAGER_SERVER (priv->object_manager),
g_dbus_interface_skeleton_get_object_path (G_DBUS_INTERFACE_SKELETON (rdev)));
/* We cannot continue to iterate at this point, but we don't need to either */ g_signal_handlers_disconnect_by_data (rdev, manager);
break;
}
/* The device that disappeared might have been in-use. /* We cannot continue to iterate at this point, but we don't need to either */
* Do we need to do anything else in this case to clean up more gracefully? */ break;
fprint_manager_in_use_notified (NULL, NULL, manager); }
/* The device that disappeared might have been in-use.
* Do we need to do anything else in this case to clean up more gracefully? */
fprint_manager_in_use_notified (NULL, NULL, manager);
} }
static void fprint_manager_constructed (GObject *object) static void
fprint_manager_constructed (GObject *object)
{ {
FprintManager *manager = FPRINT_MANAGER (object); FprintManager *manager = FPRINT_MANAGER (object);
FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager); FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager);
GDBusObjectManagerServer *object_manager_server; GDBusObjectManagerServer *object_manager_server;
object_manager_server = object_manager_server =
g_dbus_object_manager_server_new (FPRINT_SERVICE_PATH "/Device"); g_dbus_object_manager_server_new (FPRINT_SERVICE_PATH "/Device");
priv->object_manager = G_DBUS_OBJECT_MANAGER (object_manager_server); priv->object_manager = G_DBUS_OBJECT_MANAGER (object_manager_server);
priv->dbus_manager = fprint_dbus_manager_skeleton_new (); priv->dbus_manager = fprint_dbus_manager_skeleton_new ();
priv->context = fp_context_new (); priv->context = fp_context_new ();
g_signal_connect_object (priv->dbus_manager, g_signal_connect_object (priv->dbus_manager,
"handle-get-devices", "handle-get-devices",
G_CALLBACK (handle_get_devices), G_CALLBACK (handle_get_devices),
manager, manager,
G_CONNECT_SWAPPED); G_CONNECT_SWAPPED);
g_signal_connect_object (priv->dbus_manager, g_signal_connect_object (priv->dbus_manager,
"handle-get-default-device", "handle-get-default-device",
G_CALLBACK (handle_get_default_device), G_CALLBACK (handle_get_default_device),
manager, manager,
G_CONNECT_SWAPPED); G_CONNECT_SWAPPED);
g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_manager), g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_manager),
priv->connection, priv->connection,
FPRINT_SERVICE_PATH "/Manager", NULL); FPRINT_SERVICE_PATH "/Manager", NULL);
g_dbus_object_manager_server_set_connection (object_manager_server, g_dbus_object_manager_server_set_connection (object_manager_server,
priv->connection); priv->connection);
/* And register the signals for initial enumeration and hotplug. */ /* And register the signals for initial enumeration and hotplug. */
g_signal_connect_object (priv->context, g_signal_connect_object (priv->context,
"device-added", "device-added",
(GCallback) device_added_cb, (GCallback) device_added_cb,
manager, manager,
G_CONNECT_SWAPPED); G_CONNECT_SWAPPED);
g_signal_connect_object (priv->context, g_signal_connect_object (priv->context,
"device-removed", "device-removed",
(GCallback) device_removed_cb, (GCallback) device_removed_cb,
manager, manager,
G_CONNECT_SWAPPED); G_CONNECT_SWAPPED);
/* Prepare everything by enumerating all devices. /* Prepare everything by enumerating all devices.
* This blocks the main loop until the existing devices are enumerated * This blocks the main loop until the existing devices are enumerated
*/ */
fp_context_enumerate (priv->context); fp_context_enumerate (priv->context);
G_OBJECT_CLASS (fprint_manager_parent_class)->constructed (object); G_OBJECT_CLASS (fprint_manager_parent_class)->constructed (object);
} }
static void static void
@ -323,99 +345,113 @@ fprint_manager_init (FprintManager *manager)
{ {
} }
FprintManager *fprint_manager_new (GDBusConnection *connection, gboolean no_timeout) FprintManager *
fprint_manager_new (GDBusConnection *connection, gboolean no_timeout)
{ {
FprintManagerPrivate *priv; FprintManagerPrivate *priv;
GObject *object; GObject *object;
object = g_object_new (FPRINT_TYPE_MANAGER, "connection", connection, NULL); object = g_object_new (FPRINT_TYPE_MANAGER, "connection", connection, NULL);
priv = fprint_manager_get_instance_private (FPRINT_MANAGER (object)); priv = fprint_manager_get_instance_private (FPRINT_MANAGER (object));
priv->no_timeout = no_timeout; priv->no_timeout = no_timeout;
if (!priv->no_timeout) if (!priv->no_timeout)
priv->timeout_id = g_timeout_add_seconds (TIMEOUT, (GSourceFunc) fprint_manager_timeout_cb, object); priv->timeout_id = g_timeout_add_seconds (TIMEOUT, (GSourceFunc) fprint_manager_timeout_cb, object);
return FPRINT_MANAGER (object); return FPRINT_MANAGER (object);
} }
static gboolean fprint_manager_get_devices(FprintManager *manager, static gboolean
GPtrArray **devices, GError **error) fprint_manager_get_devices (FprintManager *manager,
GPtrArray **devices, GError **error)
{ {
FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager); FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager);
g_autolist (FprintDBusObjectSkeleton) objects = NULL;
GList *l;
int num_open;
GPtrArray *devs;
objects = g_dbus_object_manager_get_objects (priv->object_manager); g_autolist (FprintDBusObjectSkeleton) objects = NULL;
objects = g_list_reverse (objects); GList *l;
int num_open;
GPtrArray *devs;
num_open = g_list_length (objects); objects = g_dbus_object_manager_get_objects (priv->object_manager);
devs = g_ptr_array_sized_new(num_open); objects = g_list_reverse (objects);
if (num_open > 0) { num_open = g_list_length (objects);
for (l = objects; l != NULL; l = l->next) { devs = g_ptr_array_sized_new (num_open);
g_autoptr(FprintDevice) rdev = NULL;
FprintDBusObjectSkeleton *object = l->data;
const char *path;
rdev = fprint_dbus_object_skeleton_get_device (object); if (num_open > 0)
path = g_dbus_interface_skeleton_get_object_path ( {
G_DBUS_INTERFACE_SKELETON (rdev)); for (l = objects; l != NULL; l = l->next)
g_ptr_array_add (devs, (char *) path); {
} g_autoptr(FprintDevice) rdev = NULL;
} FprintDBusObjectSkeleton *object = l->data;
g_ptr_array_add (devs, NULL); const char *path;
*devices = devs; rdev = fprint_dbus_object_skeleton_get_device (object);
return TRUE; path = g_dbus_interface_skeleton_get_object_path (
G_DBUS_INTERFACE_SKELETON (rdev));
g_ptr_array_add (devs, (char *) path);
}
}
g_ptr_array_add (devs, NULL);
*devices = devs;
return TRUE;
} }
static gboolean fprint_manager_get_default_device(FprintManager *manager, static gboolean
const char **device, GError **error) fprint_manager_get_default_device (FprintManager *manager,
const char **device, GError **error)
{ {
FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager); FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager);
g_autolist (FprintDBusObjectSkeleton) objects = NULL;
int num_open;
objects = g_dbus_object_manager_get_objects (priv->object_manager); g_autolist (FprintDBusObjectSkeleton) objects = NULL;
num_open = g_list_length (objects); int num_open;
if (num_open > 0) { objects = g_dbus_object_manager_get_objects (priv->object_manager);
g_autoptr(FprintDevice) rdev = NULL; num_open = g_list_length (objects);
FprintDBusObjectSkeleton *object = g_list_last (objects)->data;
rdev = fprint_dbus_object_skeleton_get_device (object); if (num_open > 0)
*device = g_dbus_interface_skeleton_get_object_path ( {
G_DBUS_INTERFACE_SKELETON (rdev)); g_autoptr(FprintDevice) rdev = NULL;
return TRUE; FprintDBusObjectSkeleton *object = g_list_last (objects)->data;
} else {
g_set_error (error, FPRINT_ERROR, FPRINT_ERROR_NO_SUCH_DEVICE, rdev = fprint_dbus_object_skeleton_get_device (object);
"No devices available"); *device = g_dbus_interface_skeleton_get_object_path (
*device = NULL; G_DBUS_INTERFACE_SKELETON (rdev));
return FALSE; return TRUE;
} }
else
{
g_set_error (error, FPRINT_ERROR, FPRINT_ERROR_NO_SUCH_DEVICE,
"No devices available");
*device = NULL;
return FALSE;
}
} }
GQuark fprint_error_quark (void) GQuark
fprint_error_quark (void)
{ {
static volatile gsize quark = 0; static volatile gsize quark = 0;
if (g_once_init_enter (&quark)) {
g_autoptr(GEnumClass) errors_enum = NULL;
GQuark domain;
unsigned i;
domain = g_quark_from_static_string ("fprintd-error-quark"); if (g_once_init_enter (&quark))
errors_enum = g_type_class_ref (FPRINT_TYPE_ERROR); {
g_autoptr(GEnumClass) errors_enum = NULL;
GQuark domain;
unsigned i;
for (i = 0; i < errors_enum->n_values; ++i) { domain = g_quark_from_static_string ("fprintd-error-quark");
GEnumValue *value = &errors_enum->values[i]; errors_enum = g_type_class_ref (FPRINT_TYPE_ERROR);
g_dbus_error_register_error (domain, value->value, for (i = 0; i < errors_enum->n_values; ++i)
value->value_nick); {
} GEnumValue *value = &errors_enum->values[i];
g_once_init_leave (&quark, domain); g_dbus_error_register_error (domain, value->value,
} value->value_nick);
return (GQuark) quark; }
g_once_init_leave (&quark, domain);
}
return (GQuark) quark;
} }

View File

@ -6,12 +6,12 @@
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * 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., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@ -28,19 +28,21 @@ typedef int (*storage_print_data_load)(FpDevice *dev,
typedef int (*storage_print_data_delete)(FpDevice *dev, typedef int (*storage_print_data_delete)(FpDevice *dev,
FpFinger finger, FpFinger finger,
const char *username); const char *username);
typedef GSList *(*storage_discover_prints)(FpDevice *dev, const char *username); typedef GSList *(*storage_discover_prints)(FpDevice *dev,
const char *username);
typedef GSList *(*storage_discover_users)(void); typedef GSList *(*storage_discover_users)(void);
typedef int (*storage_init)(void); typedef int (*storage_init)(void);
typedef int (*storage_deinit)(void); typedef int (*storage_deinit)(void);
struct storage { struct storage
storage_init init; {
storage_deinit deinit; storage_init init;
storage_print_data_save print_data_save; storage_deinit deinit;
storage_print_data_load print_data_load; storage_print_data_save print_data_save;
storage_print_data_delete print_data_delete; storage_print_data_load print_data_load;
storage_discover_prints discover_prints; storage_print_data_delete print_data_delete;
storage_discover_users discover_users; storage_discover_prints discover_prints;
storage_discover_users discover_users;
}; };
typedef struct storage fp_storage; typedef struct storage fp_storage;

View File

@ -7,12 +7,12 @@
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * 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., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@ -26,126 +26,146 @@
static FprintDBusManager *manager = NULL; static FprintDBusManager *manager = NULL;
static GDBusConnection *connection = NULL; static GDBusConnection *connection = NULL;
static void create_manager(void) static void
create_manager (void)
{ {
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
if (connection == NULL) { if (connection == NULL)
g_print("Failed to connect to session bus: %s\n", error->message); {
exit (1); g_print ("Failed to connect to session bus: %s\n", error->message);
} exit (1);
}
manager = fprint_dbus_manager_proxy_new_sync (connection, manager = fprint_dbus_manager_proxy_new_sync (connection,
G_DBUS_PROXY_FLAGS_NONE, G_DBUS_PROXY_FLAGS_NONE,
"net.reactivated.Fprint", "net.reactivated.Fprint",
"/net/reactivated/Fprint/Manager", "/net/reactivated/Fprint/Manager",
NULL, &error); NULL, &error);
if (manager == NULL) { if (manager == NULL)
g_print ("Failed to get Fprintd manager: %s\n", error->message); {
exit (1); g_print ("Failed to get Fprintd manager: %s\n", error->message);
} exit (1);
}
} }
static void delete_fingerprints (FprintDBusDevice *dev, const char *username) static void
delete_fingerprints (FprintDBusDevice *dev, const char *username)
{ {
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
if (!fprint_dbus_device_call_claim_sync (dev, username, NULL, &error)) { if (!fprint_dbus_device_call_claim_sync (dev, username, NULL, &error))
g_print("failed to claim device: %s\n", error->message); {
exit (1); g_print ("failed to claim device: %s\n", error->message);
} exit (1);
}
if (!fprint_dbus_device_call_delete_enrolled_fingers2_sync (dev, NULL, if (!fprint_dbus_device_call_delete_enrolled_fingers2_sync (dev, NULL,
&error)) { &error))
gboolean ignore_error = FALSE; {
if (g_dbus_error_is_remote_error (error)) { gboolean ignore_error = FALSE;
g_autofree char *dbus_error = if (g_dbus_error_is_remote_error (error))
g_dbus_error_get_remote_error (error); {
if (g_str_equal (dbus_error, g_autofree char *dbus_error =
"net.reactivated.Fprint.Error.NoEnrolledPrints")) { g_dbus_error_get_remote_error (error);
g_print ("No fingerprints to delete on %s\n", if (g_str_equal (dbus_error,
fprint_dbus_device_get_name (dev)); "net.reactivated.Fprint.Error.NoEnrolledPrints"))
ignore_error = TRUE; {
} g_print ("No fingerprints to delete on %s\n",
} fprint_dbus_device_get_name (dev));
if (!ignore_error) { ignore_error = TRUE;
g_print("ListEnrolledFingers failed: %s\n", }
error->message); }
exit (1); if (!ignore_error)
} else { {
g_print ("No fingerprints to delete on %s\n", g_print ("ListEnrolledFingers failed: %s\n",
fprint_dbus_device_get_name (dev)); error->message);
} exit (1);
} else { }
g_print ("Fingerprints deleted on %s\n", else
fprint_dbus_device_get_name (dev)); {
} g_print ("No fingerprints to delete on %s\n",
g_clear_error (&error); fprint_dbus_device_get_name (dev));
}
}
else
{
g_print ("Fingerprints deleted on %s\n",
fprint_dbus_device_get_name (dev));
}
g_clear_error (&error);
if (!fprint_dbus_device_call_release_sync (dev, NULL, &error)) { if (!fprint_dbus_device_call_release_sync (dev, NULL, &error))
g_print("ReleaseDevice failed: %s\n", error->message); {
exit (1); g_print ("ReleaseDevice failed: %s\n", error->message);
} exit (1);
}
} }
static void process_devices(char **argv) static void
process_devices (char **argv)
{ {
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
g_auto(GStrv) devices = NULL; g_auto(GStrv) devices = NULL;
char *path; char *path;
guint num_devices; guint num_devices;
guint i; guint i;
if (!fprint_dbus_manager_call_get_devices_sync (manager, &devices, if (!fprint_dbus_manager_call_get_devices_sync (manager, &devices,
NULL, &error)) { NULL, &error))
g_print("Impossible to get devices: %s\n", error->message); {
exit (1); g_print ("Impossible to get devices: %s\n", error->message);
} exit (1);
}
num_devices = g_strv_length (devices); num_devices = g_strv_length (devices);
if (num_devices == 0) { if (num_devices == 0)
g_print("No devices available\n"); {
exit(1); g_print ("No devices available\n");
} exit (1);
}
g_print ("found %u devices\n", num_devices); g_print ("found %u devices\n", num_devices);
for (i = 0; devices[i] != NULL; i++) { for (i = 0; devices[i] != NULL; i++)
path = devices[i]; {
g_print("Device at %s\n", path); path = devices[i];
} g_print ("Device at %s\n", path);
}
for (i = 0; devices[i] != NULL; i++) { for (i = 0; devices[i] != NULL; i++)
g_autoptr(FprintDBusDevice) dev = NULL; {
guint j; g_autoptr(FprintDBusDevice) dev = NULL;
guint j;
path = devices[i]; path = devices[i];
g_print("Using device %s\n", path); g_print ("Using device %s\n", path);
/* NOTE: We should handle error cases! */ /* NOTE: We should handle error cases! */
dev = fprint_dbus_device_proxy_new_sync (connection, dev = fprint_dbus_device_proxy_new_sync (connection,
G_DBUS_PROXY_FLAGS_NONE, G_DBUS_PROXY_FLAGS_NONE,
"net.reactivated.Fprint", "net.reactivated.Fprint",
path, NULL, NULL); path, NULL, NULL);
for (j = 1; argv[j] != NULL; j++) for (j = 1; argv[j] != NULL; j++)
delete_fingerprints (dev, argv[j]); delete_fingerprints (dev, argv[j]);
} }
} }
int main(int argc, char **argv) int
main (int argc, char **argv)
{ {
setlocale (LC_ALL, ""); setlocale (LC_ALL, "");
create_manager(); create_manager ();
if (argc < 2) { if (argc < 2)
g_print ("Usage: %s <username> [usernames...]\n", argv[0]); {
return 1; g_print ("Usage: %s <username> [usernames...]\n", argv[0]);
} return 1;
}
process_devices (argv); process_devices (argv);
return 0; return 0;
} }

View File

@ -7,12 +7,12 @@
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * 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., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@ -33,171 +33,193 @@ static GDBusConnection *connection = NULL;
static char *finger_name = NULL; static char *finger_name = NULL;
static char **usernames = NULL; static char **usernames = NULL;
static void create_manager(void) static void
create_manager (void)
{ {
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
if (connection == NULL) { if (connection == NULL)
g_print("Failed to connect to session bus: %s\n", error->message); {
exit (1); g_print ("Failed to connect to session bus: %s\n", error->message);
} exit (1);
}
manager = fprint_dbus_manager_proxy_new_sync (connection, manager = fprint_dbus_manager_proxy_new_sync (connection,
G_DBUS_PROXY_FLAGS_NONE, G_DBUS_PROXY_FLAGS_NONE,
"net.reactivated.Fprint", "net.reactivated.Fprint",
"/net/reactivated/Fprint/Manager", "/net/reactivated/Fprint/Manager",
NULL, &error); NULL, &error);
if (manager == NULL) { if (manager == NULL)
g_print ("Failed to get Fprintd manager: %s\n", error->message); {
exit (1); g_print ("Failed to get Fprintd manager: %s\n", error->message);
} exit (1);
}
} }
static FprintDBusDevice *open_device (const char *username) static FprintDBusDevice *
open_device (const char *username)
{ {
g_autoptr(FprintDBusDevice) dev = NULL; g_autoptr(FprintDBusDevice) dev = NULL;
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
g_autofree char *path = NULL; g_autofree char *path = NULL;
if (!fprint_dbus_manager_call_get_default_device_sync (manager, &path, if (!fprint_dbus_manager_call_get_default_device_sync (manager, &path,
NULL, &error)) { NULL, &error))
g_print("Impossible to enroll: %s\n", error->message); {
exit (1); g_print ("Impossible to enroll: %s\n", error->message);
} exit (1);
}
g_print("Using device %s\n", path); g_print ("Using device %s\n", path);
dev = fprint_dbus_device_proxy_new_sync (connection, dev = fprint_dbus_device_proxy_new_sync (connection,
G_DBUS_PROXY_FLAGS_NONE, G_DBUS_PROXY_FLAGS_NONE,
"net.reactivated.Fprint", "net.reactivated.Fprint",
path, NULL, &error); path, NULL, &error);
if (error) { if (error)
g_print ("failed to connect to device: %s\n", error->message); {
exit (1); g_print ("failed to connect to device: %s\n", error->message);
} exit (1);
}
if (!fprint_dbus_device_call_claim_sync (dev, username, NULL, &error)) { if (!fprint_dbus_device_call_claim_sync (dev, username, NULL, &error))
g_print("failed to claim device: %s\n", error->message); {
exit (1); g_print ("failed to claim device: %s\n", error->message);
} exit (1);
return g_steal_pointer (&dev); }
return g_steal_pointer (&dev);
} }
static void enroll_result(GObject *object, const char *result, gboolean done, void *user_data) static void
enroll_result (GObject *object, const char *result, gboolean done, void *user_data)
{ {
gboolean *enroll_completed = user_data; gboolean *enroll_completed = user_data;
g_print("Enroll result: %s\n", result);
if (done != FALSE) g_print ("Enroll result: %s\n", result);
*enroll_completed = TRUE; if (done != FALSE)
*enroll_completed = TRUE;
} }
static void proxy_signal_cb (GDBusProxy *proxy, static void
const gchar *sender_name, proxy_signal_cb (GDBusProxy *proxy,
const gchar *signal_name, const gchar *sender_name,
GVariant *parameters, const gchar *signal_name,
gpointer user_data) GVariant *parameters,
gpointer user_data)
{ {
if (g_str_equal (signal_name, "EnrollStatus")) { if (g_str_equal (signal_name, "EnrollStatus"))
const gchar *result; {
gboolean done; const gchar *result;
gboolean done;
g_variant_get (parameters, "(&sb)", &result, &done); g_variant_get (parameters, "(&sb)", &result, &done);
enroll_result (G_OBJECT (proxy), result, done, user_data); enroll_result (G_OBJECT (proxy), result, done, user_data);
} }
} }
static void do_enroll (FprintDBusDevice *dev) static void
do_enroll (FprintDBusDevice *dev)
{ {
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
gboolean enroll_completed = FALSE; gboolean enroll_completed = FALSE;
gboolean found; gboolean found;
guint i; guint i;
g_signal_connect (dev, "g-signal", G_CALLBACK (proxy_signal_cb), g_signal_connect (dev, "g-signal", G_CALLBACK (proxy_signal_cb),
&enroll_completed); &enroll_completed);
found = FALSE; found = FALSE;
for (i = 0; fingers[i].dbus_name != NULL; i++) { for (i = 0; fingers[i].dbus_name != NULL; i++)
if (g_strcmp0 (fingers[i].dbus_name, finger_name) == 0) { {
found = TRUE; if (g_strcmp0 (fingers[i].dbus_name, finger_name) == 0)
break; {
} found = TRUE;
} break;
if (!found) { }
g_autoptr(GString) s = NULL; }
if (!found)
{
g_autoptr(GString) s = NULL;
s = g_string_new (NULL); s = g_string_new (NULL);
g_string_append_printf (s, "Invalid finger name '%s'. Name must be one of ", finger_name); g_string_append_printf (s, "Invalid finger name '%s'. Name must be one of ", finger_name);
for (i = 0; fingers[i].dbus_name != NULL; i++) { for (i = 0; fingers[i].dbus_name != NULL; i++)
g_string_append_printf (s, "%s", fingers[i].dbus_name); {
if (fingers[i + 1].dbus_name != NULL) g_string_append_printf (s, "%s", fingers[i].dbus_name);
g_string_append (s, ", "); if (fingers[i + 1].dbus_name != NULL)
} g_string_append (s, ", ");
g_warning ("%s", s->str); }
exit (1); g_warning ("%s", s->str);
} exit (1);
}
g_print("Enrolling %s finger.\n", finger_name); g_print ("Enrolling %s finger.\n", finger_name);
if (!fprint_dbus_device_call_enroll_start_sync (dev, finger_name, NULL, if (!fprint_dbus_device_call_enroll_start_sync (dev, finger_name, NULL,
&error)) { &error))
g_print("EnrollStart failed: %s\n", error->message); {
exit (1); g_print ("EnrollStart failed: %s\n", error->message);
} exit (1);
}
while (!enroll_completed) while (!enroll_completed)
g_main_context_iteration(NULL, TRUE); g_main_context_iteration (NULL, TRUE);
g_signal_handlers_disconnect_by_func (dev, proxy_signal_cb, &enroll_result); g_signal_handlers_disconnect_by_func (dev, proxy_signal_cb, &enroll_result);
if (!fprint_dbus_device_call_enroll_stop_sync (dev, NULL, &error)) { if (!fprint_dbus_device_call_enroll_stop_sync (dev, NULL, &error))
g_print("VerifyStop failed: %s\n", error->message); {
exit(1); g_print ("VerifyStop failed: %s\n", error->message);
} exit (1);
}
} }
static void release_device (FprintDBusDevice *dev) static void
release_device (FprintDBusDevice *dev)
{ {
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
if (!fprint_dbus_device_call_release_sync (dev, NULL, &error)) { if (!fprint_dbus_device_call_release_sync (dev, NULL, &error))
g_print("ReleaseDevice failed: %s\n", error->message); {
exit (1); g_print ("ReleaseDevice failed: %s\n", error->message);
} exit (1);
}
} }
static const GOptionEntry entries[] = { static const GOptionEntry entries[] = {
{ "finger", 'f', 0, G_OPTION_ARG_STRING, &finger_name, "Finger selected to verify (default is automatic)", NULL }, { "finger", 'f', 0, G_OPTION_ARG_STRING, &finger_name, "Finger selected to verify (default is automatic)", NULL },
{ G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &usernames, NULL, "[username]" }, { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &usernames, NULL, "[username]" },
{ NULL } { NULL }
}; };
int main(int argc, char **argv) int
main (int argc, char **argv)
{ {
g_autoptr(FprintDBusDevice) dev = NULL; g_autoptr(FprintDBusDevice) dev = NULL;
GOptionContext *context; GOptionContext *context;
g_autoptr(GError) err = NULL;
setlocale (LC_ALL, ""); g_autoptr(GError) err = NULL;
context = g_option_context_new ("Enroll a fingerprint"); setlocale (LC_ALL, "");
g_option_context_add_main_entries (context, entries, NULL);
if (g_option_context_parse (context, &argc, &argv, &err) == FALSE) { context = g_option_context_new ("Enroll a fingerprint");
g_print ("couldn't parse command-line options: %s\n", err->message); g_option_context_add_main_entries (context, entries, NULL);
return 1;
}
if (finger_name == NULL) if (g_option_context_parse (context, &argc, &argv, &err) == FALSE)
finger_name = g_strdup("right-index-finger"); {
g_print ("couldn't parse command-line options: %s\n", err->message);
return 1;
}
create_manager(); if (finger_name == NULL)
finger_name = g_strdup ("right-index-finger");
dev = open_device (usernames ? usernames[0] : ""); create_manager ();
do_enroll(dev);
release_device(dev); dev = open_device (usernames ? usernames[0] : "");
g_free(finger_name); do_enroll (dev);
g_strfreev(usernames); release_device (dev);
return 0; g_free (finger_name);
g_strfreev (usernames);
return 0;
} }

View File

@ -7,12 +7,12 @@
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * 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., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@ -26,125 +26,137 @@
static FprintDBusManager *manager = NULL; static FprintDBusManager *manager = NULL;
static GDBusConnection *connection = NULL; static GDBusConnection *connection = NULL;
static void create_manager(void) static void
create_manager (void)
{ {
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
if (connection == NULL) { if (connection == NULL)
g_print("Failed to connect to session bus: %s\n", error->message); {
exit (1); g_print ("Failed to connect to session bus: %s\n", error->message);
} exit (1);
}
manager = fprint_dbus_manager_proxy_new_sync (connection, manager = fprint_dbus_manager_proxy_new_sync (connection,
G_DBUS_PROXY_FLAGS_NONE, G_DBUS_PROXY_FLAGS_NONE,
"net.reactivated.Fprint", "net.reactivated.Fprint",
"/net/reactivated/Fprint/Manager", "/net/reactivated/Fprint/Manager",
NULL, &error); NULL, &error);
if (manager == NULL) { if (manager == NULL)
g_print ("Failed to get Fprintd manager: %s\n", error->message); {
exit (1); g_print ("Failed to get Fprintd manager: %s\n", error->message);
} exit (1);
}
} }
static void list_fingerprints (FprintDBusDevice *dev, const char *username) static void
list_fingerprints (FprintDBusDevice *dev, const char *username)
{ {
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
g_auto(GStrv) fingers = NULL; g_auto(GStrv) fingers = NULL;
guint i; guint i;
if (!fprint_dbus_device_call_list_enrolled_fingers_sync (dev, username, if (!fprint_dbus_device_call_list_enrolled_fingers_sync (dev, username,
&fingers, NULL, &fingers, NULL,
&error)) { &error))
gboolean ignore_error = FALSE; {
if (g_dbus_error_is_remote_error (error)) { gboolean ignore_error = FALSE;
g_autofree char *dbus_error = if (g_dbus_error_is_remote_error (error))
g_dbus_error_get_remote_error (error); {
if (g_str_equal (dbus_error, g_autofree char *dbus_error =
"net.reactivated.Fprint.Error.NoEnrolledPrints")) { g_dbus_error_get_remote_error (error);
ignore_error = TRUE; if (g_str_equal (dbus_error,
} "net.reactivated.Fprint.Error.NoEnrolledPrints"))
} ignore_error = TRUE;
}
if (!ignore_error) { if (!ignore_error)
g_print("ListEnrolledFingers failed: %s\n", error->message); {
exit (1); g_print ("ListEnrolledFingers failed: %s\n", error->message);
} exit (1);
} }
}
if (fingers == NULL || g_strv_length (fingers) == 0) { if (fingers == NULL || g_strv_length (fingers) == 0)
g_print ("User %s has no fingers enrolled for %s.\n", username, {
fprint_dbus_device_get_name (dev)); g_print ("User %s has no fingers enrolled for %s.\n", username,
return; fprint_dbus_device_get_name (dev));
} return;
}
g_print("Fingerprints for user %s on %s (%s):\n", g_print ("Fingerprints for user %s on %s (%s):\n",
username, username,
fprint_dbus_device_get_name (dev), fprint_dbus_device_get_name (dev),
fprint_dbus_device_get_scan_type (dev)); fprint_dbus_device_get_scan_type (dev));
for (i = 0; fingers[i] != NULL; i++) { for (i = 0; fingers[i] != NULL; i++)
g_print(" - #%d: %s\n", i, fingers[i]); g_print (" - #%d: %s\n", i, fingers[i]);
}
} }
static void process_devices(char **argv) static void
process_devices (char **argv)
{ {
g_auto(GStrv) devices = NULL; g_auto(GStrv) devices = NULL;
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
char *path; char *path;
guint num_devices; guint num_devices;
guint i; guint i;
if (!fprint_dbus_manager_call_get_devices_sync (manager, &devices, NULL, if (!fprint_dbus_manager_call_get_devices_sync (manager, &devices, NULL,
&error)) { &error))
g_print("Impossible to get devices: %s\n", error->message); {
exit (1); g_print ("Impossible to get devices: %s\n", error->message);
} exit (1);
}
num_devices = g_strv_length (devices); num_devices = g_strv_length (devices);
if (num_devices == 0) { if (num_devices == 0)
g_print("No devices available\n"); {
exit(1); g_print ("No devices available\n");
} exit (1);
}
g_print ("found %u devices\n", num_devices); g_print ("found %u devices\n", num_devices);
for (i = 0; devices[i] != NULL; i++) { for (i = 0; devices[i] != NULL; i++)
path = devices[i]; {
g_print("Device at %s\n", path); path = devices[i];
} g_print ("Device at %s\n", path);
}
for (i = 0; devices[i] != NULL; i++) { for (i = 0; devices[i] != NULL; i++)
g_autoptr(FprintDBusDevice) dev = NULL; {
guint j; g_autoptr(FprintDBusDevice) dev = NULL;
guint j;
path = devices[i]; path = devices[i];
g_print("Using device %s\n", path); g_print ("Using device %s\n", path);
/* NOTE: We should handle error cases! */ /* NOTE: We should handle error cases! */
dev = fprint_dbus_device_proxy_new_sync (connection, dev = fprint_dbus_device_proxy_new_sync (connection,
G_DBUS_PROXY_FLAGS_NONE, G_DBUS_PROXY_FLAGS_NONE,
"net.reactivated.Fprint", "net.reactivated.Fprint",
path, NULL, NULL); path, NULL, NULL);
for (j = 1; argv[j] != NULL; j++) for (j = 1; argv[j] != NULL; j++)
list_fingerprints (dev, argv[j]); list_fingerprints (dev, argv[j]);
} }
} }
int main(int argc, char **argv) int
main (int argc, char **argv)
{ {
setlocale (LC_ALL, ""); setlocale (LC_ALL, "");
create_manager(); create_manager ();
if (argc < 2) { if (argc < 2)
g_print ("Usage: %s <username> [usernames...]\n", argv[0]); {
return 1; g_print ("Usage: %s <username> [usernames...]\n", argv[0]);
} return 1;
}
process_devices (argv); process_devices (argv);
return 0; return 0;
} }

View File

@ -7,12 +7,12 @@
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License along * 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., * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
@ -31,250 +31,274 @@ static char *finger_name = NULL;
static gboolean g_fatal_warnings = FALSE; static gboolean g_fatal_warnings = FALSE;
static char **usernames = NULL; static char **usernames = NULL;
static void create_manager(void) static void
create_manager (void)
{ {
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
if (connection == NULL) { if (connection == NULL)
g_print("Failed to connect to session bus: %s\n", error->message); {
exit (1); g_print ("Failed to connect to session bus: %s\n", error->message);
} exit (1);
}
manager = fprint_dbus_manager_proxy_new_sync (connection, manager = fprint_dbus_manager_proxy_new_sync (connection,
G_DBUS_PROXY_FLAGS_NONE, G_DBUS_PROXY_FLAGS_NONE,
"net.reactivated.Fprint", "net.reactivated.Fprint",
"/net/reactivated/Fprint/Manager", "/net/reactivated/Fprint/Manager",
NULL, &error); NULL, &error);
if (manager == NULL) { if (manager == NULL)
g_print ("Failed to get Fprintd manager: %s\n", error->message); {
exit (1); g_print ("Failed to get Fprintd manager: %s\n", error->message);
} exit (1);
}
} }
static FprintDBusDevice *open_device (const char *username) static FprintDBusDevice *
open_device (const char *username)
{ {
g_autoptr(FprintDBusDevice) dev = NULL; g_autoptr(FprintDBusDevice) dev = NULL;
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
g_autofree char *path = NULL; g_autofree char *path = NULL;
if (!fprint_dbus_manager_call_get_default_device_sync (manager, &path, if (!fprint_dbus_manager_call_get_default_device_sync (manager, &path,
NULL, &error)) { NULL, &error))
g_print("Impossible to verify: %s\n", error->message); {
exit (1); g_print ("Impossible to verify: %s\n", error->message);
} exit (1);
}
g_print("Using device %s\n", path); g_print ("Using device %s\n", path);
dev = fprint_dbus_device_proxy_new_sync (connection, dev = fprint_dbus_device_proxy_new_sync (connection,
G_DBUS_PROXY_FLAGS_NONE, G_DBUS_PROXY_FLAGS_NONE,
"net.reactivated.Fprint", "net.reactivated.Fprint",
path, NULL, &error); path, NULL, &error);
if (error) { if (error)
g_print ("failed to connect to device: %s\n", error->message); {
exit (1); g_print ("failed to connect to device: %s\n", error->message);
} exit (1);
}
if (!fprint_dbus_device_call_claim_sync (dev, username, NULL, &error)) { if (!fprint_dbus_device_call_claim_sync (dev, username, NULL, &error))
g_print("failed to claim device: %s\n", error->message); {
exit (1); g_print ("failed to claim device: %s\n", error->message);
} exit (1);
}
return g_steal_pointer (&dev); return g_steal_pointer (&dev);
} }
static void find_finger (FprintDBusDevice *dev, const char *username) static void
find_finger (FprintDBusDevice *dev, const char *username)
{ {
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
g_auto(GStrv) fingers = NULL; g_auto(GStrv) fingers = NULL;
guint i; guint i;
if (!fprint_dbus_device_call_list_enrolled_fingers_sync (dev, username, if (!fprint_dbus_device_call_list_enrolled_fingers_sync (dev, username,
&fingers, &fingers,
NULL, &error)) { NULL, &error))
g_print("ListEnrolledFingers failed: %s\n", error->message); {
exit (1); g_print ("ListEnrolledFingers failed: %s\n", error->message);
} exit (1);
}
if (fingers == NULL || g_strv_length (fingers) == 0) { if (fingers == NULL || g_strv_length (fingers) == 0)
g_print("No fingers enrolled for this device.\n"); {
exit(1); g_print ("No fingers enrolled for this device.\n");
} exit (1);
}
g_print("Listing enrolled fingers:\n"); g_print ("Listing enrolled fingers:\n");
for (i = 0; fingers[i] != NULL; i++) { for (i = 0; fingers[i] != NULL; i++)
g_print(" - #%d: %s\n", i, fingers[i]); g_print (" - #%d: %s\n", i, fingers[i]);
}
if (finger_name && !g_str_equal (finger_name, "any") && if (finger_name && !g_str_equal (finger_name, "any") &&
!g_strv_contains ((const char **) fingers, finger_name)) { !g_strv_contains ((const char **) fingers, finger_name))
g_print("Finger '%s' not enrolled for user %s.\n", finger_name, {
username); g_print ("Finger '%s' not enrolled for user %s.\n", finger_name,
g_free (finger_name); username);
exit(1); g_free (finger_name);
} exit (1);
}
if (finger_name == NULL) { if (finger_name == NULL)
finger_name = g_strdup (fingers[0]); finger_name = g_strdup (fingers[0]);
}
} }
struct VerifyState { struct VerifyState
GError *error; {
gboolean started; GError *error;
gboolean completed; gboolean started;
gboolean completed;
}; };
static void verify_result(GObject *object, const char *result, gboolean done, void *user_data) static void
verify_result (GObject *object, const char *result, gboolean done, void *user_data)
{ {
struct VerifyState *verify_state = user_data; struct VerifyState *verify_state = user_data;
g_print("Verify result: %s (%s)\n", result, done ? "done" : "not done");
if (done != FALSE) g_print ("Verify result: %s (%s)\n", result, done ? "done" : "not done");
verify_state->completed = TRUE; if (done != FALSE)
verify_state->completed = TRUE;
} }
static void verify_finger_selected(GObject *object, const char *name, void *user_data) static void
verify_finger_selected (GObject *object, const char *name, void *user_data)
{ {
g_print("Verifying: %s\n", name); g_print ("Verifying: %s\n", name);
} }
static void verify_started_cb (GObject *obj, static void
GAsyncResult *res, verify_started_cb (GObject *obj,
gpointer user_data) GAsyncResult *res,
gpointer user_data)
{ {
struct VerifyState *verify_state = user_data; struct VerifyState *verify_state = user_data;
if (fprint_dbus_device_call_verify_start_finish (FPRINT_DBUS_DEVICE (obj), res, &verify_state->error)) if (fprint_dbus_device_call_verify_start_finish (FPRINT_DBUS_DEVICE (obj), res, &verify_state->error))
verify_state->started = TRUE; verify_state->started = TRUE;
} }
static void proxy_signal_cb (GDBusProxy *proxy, static void
const gchar *sender_name, proxy_signal_cb (GDBusProxy *proxy,
const gchar *signal_name, const gchar *sender_name,
GVariant *parameters, const gchar *signal_name,
gpointer user_data) GVariant *parameters,
gpointer user_data)
{ {
struct VerifyState *verify_state = user_data; struct VerifyState *verify_state = user_data;
if (!verify_state->started) if (!verify_state->started)
return; return;
if (g_str_equal (signal_name, "VerifyStatus")) { if (g_str_equal (signal_name, "VerifyStatus"))
const gchar *result; {
gboolean done; const gchar *result;
gboolean done;
g_variant_get (parameters, "(&sb)", &result, &done); g_variant_get (parameters, "(&sb)", &result, &done);
verify_result (G_OBJECT (proxy), result, done, user_data); verify_result (G_OBJECT (proxy), result, done, user_data);
} else if (g_str_equal (signal_name, "VerifyFingerSelected")) { }
const gchar *name; else if (g_str_equal (signal_name, "VerifyFingerSelected"))
{
const gchar *name;
g_variant_get (parameters, "(&s)", &name); g_variant_get (parameters, "(&s)", &name);
verify_finger_selected (G_OBJECT (proxy), name, user_data); verify_finger_selected (G_OBJECT (proxy), name, user_data);
} }
} }
static void do_verify (FprintDBusDevice *dev) static void
do_verify (FprintDBusDevice *dev)
{ {
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
struct VerifyState verify_state = { 0 }; struct VerifyState verify_state = { 0 };
/* This one is funny. We connect to the signal immediately to avoid /* This one is funny. We connect to the signal immediately to avoid
* race conditions. However, we must ignore any authentication results * race conditions. However, we must ignore any authentication results
* that happen before our start call returns. * that happen before our start call returns.
* This is because the verify call itself may internally try to verify * This is because the verify call itself may internally try to verify
* against fprintd (possibly using a separate account). * against fprintd (possibly using a separate account).
* *
* To do so, we *must* use the async version of the verify call, as the * To do so, we *must* use the async version of the verify call, as the
* sync version would cause the signals to be queued and only processed * sync version would cause the signals to be queued and only processed
* after it returns. * after it returns.
*/ */
g_signal_connect (dev, "g-signal", G_CALLBACK (proxy_signal_cb), g_signal_connect (dev, "g-signal", G_CALLBACK (proxy_signal_cb),
&verify_state); &verify_state);
fprint_dbus_device_call_verify_start (dev, finger_name, NULL, fprint_dbus_device_call_verify_start (dev, finger_name, NULL,
verify_started_cb, verify_started_cb,
&verify_state); &verify_state);
/* Wait for verify start while discarding any VerifyStatus signals */ /* Wait for verify start while discarding any VerifyStatus signals */
while (!verify_state.started && !verify_state.error) while (!verify_state.started && !verify_state.error)
g_main_context_iteration(NULL, TRUE); g_main_context_iteration (NULL, TRUE);
if (verify_state.error) { if (verify_state.error)
g_print("VerifyStart failed: %s\n", verify_state.error->message); {
g_clear_error (&verify_state.error); g_print ("VerifyStart failed: %s\n", verify_state.error->message);
exit (1); g_clear_error (&verify_state.error);
} exit (1);
g_print("Verify started!\n"); }
g_print ("Verify started!\n");
/* VerifyStatus signals are processing, wait for completion. */ /* VerifyStatus signals are processing, wait for completion. */
while (!verify_state.completed) while (!verify_state.completed)
g_main_context_iteration(NULL, TRUE); g_main_context_iteration (NULL, TRUE);
g_signal_handlers_disconnect_by_func (dev, proxy_signal_cb, g_signal_handlers_disconnect_by_func (dev, proxy_signal_cb,
&verify_state); &verify_state);
if (!fprint_dbus_device_call_verify_stop_sync (dev, NULL, &error)) { if (!fprint_dbus_device_call_verify_stop_sync (dev, NULL, &error))
g_print("VerifyStop failed: %s\n", error->message); {
exit (1); g_print ("VerifyStop failed: %s\n", error->message);
} exit (1);
}
} }
static void release_device (FprintDBusDevice *dev) static void
release_device (FprintDBusDevice *dev)
{ {
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
if (!fprint_dbus_device_call_release_sync (dev, NULL, &error)) { if (!fprint_dbus_device_call_release_sync (dev, NULL, &error))
g_print("ReleaseDevice failed: %s\n", error->message); {
exit (1); g_print ("ReleaseDevice failed: %s\n", error->message);
} exit (1);
}
} }
static const GOptionEntry entries[] = { static const GOptionEntry entries[] = {
{ "finger", 'f', 0, G_OPTION_ARG_STRING, &finger_name, "Finger selected to verify (default is automatic)", NULL }, { "finger", 'f', 0, G_OPTION_ARG_STRING, &finger_name, "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-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]" }, { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_STRING_ARRAY, &usernames, NULL, "[username]" },
{ NULL } { NULL }
}; };
int main(int argc, char **argv) int
main (int argc, char **argv)
{ {
g_autoptr(FprintDBusDevice) dev = NULL; g_autoptr(FprintDBusDevice) dev = NULL;
g_autoptr(GError) err = NULL; g_autoptr(GError) err = NULL;
GOptionContext *context; GOptionContext *context;
const char *username = NULL; const char *username = NULL;
setlocale (LC_ALL, ""); setlocale (LC_ALL, "");
context = g_option_context_new ("Verify a fingerprint"); context = g_option_context_new ("Verify a fingerprint");
g_option_context_add_main_entries (context, entries, NULL); g_option_context_add_main_entries (context, entries, NULL);
if (g_option_context_parse (context, &argc, &argv, &err) == FALSE) { if (g_option_context_parse (context, &argc, &argv, &err) == FALSE)
g_print ("couldn't parse command-line options: %s\n", err->message); {
return 1; g_print ("couldn't parse command-line options: %s\n", err->message);
} return 1;
}
if (usernames == NULL) { if (usernames == NULL)
username = ""; username = "";
} else { else
username = usernames[0]; username = usernames[0];
}
if (g_fatal_warnings) { if (g_fatal_warnings)
GLogLevelFlags fatal_mask; {
GLogLevelFlags fatal_mask;
fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
g_log_set_always_fatal (fatal_mask); g_log_set_always_fatal (fatal_mask);
} }
create_manager(); create_manager ();
dev = open_device(username); dev = open_device (username);
find_finger(dev, username); find_finger (dev, username);
do_verify(dev); do_verify (dev);
release_device(dev); release_device (dev);
return 0; return 0;
} }