[gcr/tintou/no-file-tracker] ssh-agent-preload: Remove usage of EggFileTracker
- From: Corentin Noël <corentinnoel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gcr/tintou/no-file-tracker] ssh-agent-preload: Remove usage of EggFileTracker
- Date: Mon, 8 Aug 2022 07:33:39 +0000 (UTC)
commit 8914cb454abb1070cd2823bfa89ae7940784320c
Author: Corentin Noël <corentin noel collabora com>
Date: Mon Aug 8 09:32:35 2022 +0200
ssh-agent-preload: Remove usage of EggFileTracker
We can have the same features with a GFileMonitor and a GFileEnumerator.
egg/egg-file-tracker.c | 303 --------------------------------------------
egg/egg-file-tracker.h | 59 ---------
egg/meson.build | 1 -
gcr/gcr-ssh-agent-preload.c | 171 +++++++++++++++++--------
gcr/gcr-ssh-agent-preload.h | 6 +-
5 files changed, 123 insertions(+), 417 deletions(-)
---
diff --git a/egg/meson.build b/egg/meson.build
index b577fd34..d475b0e0 100644
--- a/egg/meson.build
+++ b/egg/meson.build
@@ -6,7 +6,6 @@ libegg_sources = [
'egg-dh.c',
'egg-dn.c',
'egg-decimal.c',
- 'egg-file-tracker.c',
'egg-hex.c',
'egg-hkdf.c',
'egg-libgcrypt.c',
diff --git a/gcr/gcr-ssh-agent-preload.c b/gcr/gcr-ssh-agent-preload.c
index 4e5bc66e..5bd1b5b5 100644
--- a/gcr/gcr-ssh-agent-preload.c
+++ b/gcr/gcr-ssh-agent-preload.c
@@ -41,11 +41,12 @@ struct _GcrSshAgentPreload
gchar *path;
GHashTable *keys_by_public_filename;
GHashTable *keys_by_public_key;
- EggFileTracker *file_tracker;
+ GFileMonitor *file_monitor;
GMutex lock;
};
G_DEFINE_TYPE (GcrSshAgentPreload, gcr_ssh_agent_preload, G_TYPE_OBJECT);
+G_DEFINE_BOXED_TYPE(GcrSshAgentKeyInfo, gcr_ssh_agent_key_info, gcr_ssh_agent_key_info_copy,
gcr_ssh_agent_key_info_free)
void
gcr_ssh_agent_key_info_free (gpointer boxed)
@@ -53,9 +54,9 @@ gcr_ssh_agent_key_info_free (gpointer boxed)
GcrSshAgentKeyInfo *info = boxed;
if (!info)
return;
- g_bytes_unref (info->public_key);
- g_free (info->comment);
- g_free (info->filename);
+ g_clear_pointer (&info->public_key, g_bytes_unref);
+ g_clear_pointer (&info->comment, g_free);
+ g_clear_pointer (&info->filename, g_free);
g_free (info);
}
@@ -70,12 +71,11 @@ gcr_ssh_agent_key_info_copy (gpointer boxed)
return copy;
}
-static void file_load_inlock (EggFileTracker *tracker,
- const gchar *path,
- gpointer user_data);
-static void file_remove_inlock (EggFileTracker *tracker,
- const gchar *path,
- gpointer user_data);
+static void changed_inlock (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
static void
gcr_ssh_agent_preload_init (GcrSshAgentPreload *self)
@@ -88,11 +88,17 @@ static void
gcr_ssh_agent_preload_constructed (GObject *object)
{
GcrSshAgentPreload *self = GCR_SSH_AGENT_PRELOAD (object);
+ GError *error = NULL;
+ GFile *file;
- self->file_tracker = egg_file_tracker_new (self->path, "*.pub", NULL);
- g_signal_connect (self->file_tracker, "file-added", G_CALLBACK (file_load_inlock), self);
- g_signal_connect (self->file_tracker, "file-removed", G_CALLBACK (file_remove_inlock), self);
- g_signal_connect (self->file_tracker, "file-changed", G_CALLBACK (file_load_inlock), self);
+ file = g_file_new_for_path (self->path);
+ self->file_monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, &error);
+ if (!self->file_monitor) {
+ g_critical ("Unable to listen to directory %s: %s", self->path, error->message);
+ g_clear_error (&error);
+ } else
+ g_signal_connect (self->file_monitor, "changed", G_CALLBACK (changed_inlock), self);
+ g_object_unref (file);
G_OBJECT_CLASS (gcr_ssh_agent_preload_parent_class)->constructed (object);
}
@@ -120,10 +126,11 @@ gcr_ssh_agent_preload_finalize (GObject *object)
{
GcrSshAgentPreload *self = GCR_SSH_AGENT_PRELOAD (object);
- g_free (self->path);
+ g_clear_pointer (&self->path, g_free);
g_clear_pointer (&self->keys_by_public_key, g_hash_table_unref);
g_clear_pointer (&self->keys_by_public_filename, g_hash_table_unref);
- g_clear_object (&self->file_tracker);
+ g_signal_handlers_disconnect_by_func (self->file_monitor, changed_inlock, self);
+ g_clear_object (&self->file_monitor);
g_mutex_clear (&self->lock);
@@ -143,15 +150,6 @@ gcr_ssh_agent_preload_class_init (GcrSshAgentPreloadClass *klass)
G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
}
-static gchar *
-private_path_for_public (const gchar *public_path)
-{
- if (g_str_has_suffix (public_path, ".pub"))
- return g_strndup (public_path, strlen (public_path) - 4);
-
- return NULL;
-}
-
static GBytes *
file_get_contents (const gchar *path,
gboolean must_be_present)
@@ -171,11 +169,8 @@ file_get_contents (const gchar *path,
}
static void
-file_remove_inlock (EggFileTracker *tracker,
- const gchar *path,
- gpointer user_data)
+file_remove_inlock (GcrSshAgentPreload *self, const gchar *path)
{
- GcrSshAgentPreload *self = GCR_SSH_AGENT_PRELOAD (user_data);
GcrSshAgentKeyInfo *info;
info = g_hash_table_lookup (self->keys_by_public_filename, path);
@@ -186,38 +181,40 @@ file_remove_inlock (EggFileTracker *tracker,
}
static void
-file_load_inlock (EggFileTracker *tracker,
- const gchar *path,
- gpointer user_data)
+file_load_inlock (GcrSshAgentPreload *self, const gchar *path)
{
- GcrSshAgentPreload *self = GCR_SSH_AGENT_PRELOAD (user_data);
- gchar *private_path;
- GBytes *private_bytes;
+ gchar *private_path = NULL;
GBytes *public_bytes;
- GBytes *public_key;
- GcrSshAgentKeyInfo *info;
- gchar *comment;
- file_remove_inlock (tracker, path, user_data);
+ file_remove_inlock (self, path);
- private_path = private_path_for_public (path);
+ if (g_str_has_suffix (path, ".pub")) {
+ GBytes *private_bytes;
- private_bytes = file_get_contents (private_path, FALSE);
- if (!private_bytes) {
- g_debug ("no private key present for public key: %s", path);
- g_free (private_path);
- return;
+ private_path = g_strndup (path, strlen (path) - 4);
+ private_bytes = file_get_contents (private_path, FALSE);
+ if (!private_bytes) {
+ g_debug ("no private key present for public key: %s", path);
+ g_free (private_path);
+ return;
+ }
+
+ g_bytes_unref (private_bytes);
}
public_bytes = file_get_contents (path, TRUE);
if (public_bytes) {
+ gchar *comment = NULL;
+ GBytes *public_key;
+
public_key = _gcr_ssh_agent_parse_public_key (public_bytes, &comment);
if (public_key) {
+ GcrSshAgentKeyInfo *info;
+
info = g_new0 (GcrSshAgentKeyInfo, 1);
- info->filename = private_path;
- private_path = NULL;
- info->public_key = public_key;
- info->comment = comment;
+ info->filename = g_steal_pointer (&private_path);
+ info->public_key = g_steal_pointer (&public_key);
+ info->comment = g_steal_pointer (&comment);
g_hash_table_replace (self->keys_by_public_filename, g_strdup (path), info);
g_hash_table_replace (self->keys_by_public_key, info->public_key, info);
} else {
@@ -227,10 +224,80 @@ file_load_inlock (EggFileTracker *tracker,
g_bytes_unref (public_bytes);
}
- g_bytes_unref (private_bytes);
g_free (private_path);
}
+static void
+changed_inlock (GFileMonitor *monitor,
+ GFile *file,
+ GFile *other_file,
+ GFileMonitorEvent event_type,
+ gpointer user_data)
+{
+ GcrSshAgentPreload *self = GCR_SSH_AGENT_PRELOAD (user_data);
+ char *path;
+
+ switch (event_type) {
+ case G_FILE_MONITOR_EVENT_CHANGED:
+ case G_FILE_MONITOR_EVENT_CREATED:
+ path = g_file_get_path (file);
+ if (g_str_has_suffix (path, ".pub"))
+ file_load_inlock (self, path);
+ g_free (path);
+ break;
+ case G_FILE_MONITOR_EVENT_DELETED:
+ path = g_file_get_path (file);
+ if (g_str_has_suffix (path, ".pub"))
+ file_remove_inlock (self, path);
+ g_free (path);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+refresh_listened_directory (GcrSshAgentPreload *self)
+{
+ GFile *file;
+ GFileEnumerator *direnum;
+ GError *error = NULL;
+
+ file = g_file_new_for_path (self->path);
+ direnum = g_file_enumerate_children (file,
+ G_FILE_ATTRIBUTE_STANDARD_TYPE G_FILE_ATTRIBUTE_STANDARD_NAME
G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN,
+ G_FILE_QUERY_INFO_NONE,
+ NULL,
+ &error);
+ g_object_unref (file);
+
+ while (TRUE) {
+ GFileInfo *info;
+ const char *name;
+ if (!g_file_enumerator_iterate (direnum, &info, NULL, NULL, &error)) {
+ g_critical ("Error while iterating files in %s: %s", self->path, error->message);
+ g_clear_error (&error);
+ break;
+ }
+
+ if (!info)
+ break;
+
+ if (g_file_info_get_is_hidden (info) ||
+ g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
+ continue;
+
+ name = g_file_info_get_name (info);
+ if (g_str_has_suffix (name, ".pub")) {
+ char *path = g_build_filename (self->path, name, NULL);
+ file_load_inlock (self, path);
+ g_free (path);
+ }
+ }
+
+ g_object_unref (direnum);
+}
+
GcrSshAgentPreload *
gcr_ssh_agent_preload_new (const gchar *path)
{
@@ -248,7 +315,7 @@ gcr_ssh_agent_preload_get_keys (GcrSshAgentPreload *self)
g_mutex_lock (&self->lock);
- egg_file_tracker_refresh (self->file_tracker, FALSE);
+ refresh_listened_directory (self);
g_hash_table_iter_init (&iter, self->keys_by_public_key);
while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&info))
@@ -267,7 +334,7 @@ gcr_ssh_agent_preload_lookup_by_public_key (GcrSshAgentPreload *self,
g_mutex_lock (&self->lock);
- egg_file_tracker_refresh (self->file_tracker, FALSE);
+ refresh_listened_directory (self);
info = g_hash_table_lookup (self->keys_by_public_key, public_key);
if (info)
diff --git a/gcr/gcr-ssh-agent-preload.h b/gcr/gcr-ssh-agent-preload.h
index 1ea52586..98de032d 100644
--- a/gcr/gcr-ssh-agent-preload.h
+++ b/gcr/gcr-ssh-agent-preload.h
@@ -32,8 +32,10 @@ typedef struct {
gchar *comment;
} GcrSshAgentKeyInfo;
-void gcr_ssh_agent_key_info_free (gpointer boxed);
-gpointer gcr_ssh_agent_key_info_copy (gpointer boxed);
+#define GCR_TYPE_SSH_AGENT_KEY_INFO gcr_ssh_agent_key_info_get_type ()
+GType gcr_ssh_agent_key_info_get_type (void) G_GNUC_CONST;
+void gcr_ssh_agent_key_info_free (gpointer boxed);
+gpointer gcr_ssh_agent_key_info_copy (gpointer boxed);
#define GCR_TYPE_SSH_AGENT_PRELOAD gcr_ssh_agent_preload_get_type ()
G_DECLARE_FINAL_TYPE (GcrSshAgentPreload, gcr_ssh_agent_preload, GCR, SSH_AGENT_PRELOAD, GObject)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]