[dconf] engine, client: add list_locks() operation



commit 768ed4bbe040c53ee5010038c34aec7c69dba0a5
Author: Allison Ryan Lortie <desrt desrt ca>
Date:   Mon Nov 30 14:46:12 2015 -0500

    engine, client: add list_locks() operation
    
    Add an API to dconf-engine (and exposed via DConfClient) for getting a
    list of locks that are present in a given dconf profile.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=758864

 client/dconf-client.c   |   26 ++++++++++++++++++
 client/dconf-client.h   |    4 +++
 client/dconf.vapi       |    1 +
 engine/dconf-engine.c   |   65 +++++++++++++++++++++++++++++++++++++++++++++++
 engine/dconf-engine.h   |    5 +++
 tests/dconf-mock-gvdb.c |   10 +++++++
 6 files changed, 111 insertions(+), 0 deletions(-)
---
diff --git a/client/dconf-client.c b/client/dconf-client.c
index ea2e07c..7c04982 100644
--- a/client/dconf-client.c
+++ b/client/dconf-client.c
@@ -324,6 +324,32 @@ dconf_client_list (DConfClient *client,
 }
 
 /**
+ * dconf_client_list_locks:
+ * @client: a #DConfClient
+ * @dir: the dir to limit results to
+ * @length: the length of the returned list.
+ *
+ * Lists all locks under @dir in effect for @client.
+ *
+ * If no locks are in effect, an empty list is returned.  If no keys are
+ * writable at all then a list containing @dir is returned.
+ *
+ * The returned list will be %NULL-terminated.
+ *
+ * Returns: an array of strings, never %NULL.
+ */
+gchar **
+dconf_client_list_locks (DConfClient *client,
+                         const gchar *path,
+                         gint        *length)
+{
+  g_return_val_if_fail (DCONF_IS_CLIENT (client), NULL);
+  g_return_val_if_fail (dconf_is_path (path, NULL), NULL);
+
+  return dconf_engine_list_locks (client->engine, path, length);
+}
+
+/**
  * dconf_client_is_writable:
  * @client: a #DConfClient
  * @key: the key to check for writability
diff --git a/client/dconf-client.h b/client/dconf-client.h
index e50792b..d15d2ce 100644
--- a/client/dconf-client.h
+++ b/client/dconf-client.h
@@ -46,6 +46,10 @@ gchar **                dconf_client_list                               (DConfCl
                                                                          const gchar          *dir,
                                                                          gint                 *length);
 
+gchar **                dconf_client_list_locks                         (DConfClient          *client,
+                                                                         const gchar          *path,
+                                                                         gint                 *length);
+
 gboolean                dconf_client_is_writable                        (DConfClient          *client,
                                                                          const gchar          *key);
 
diff --git a/client/dconf.vapi b/client/dconf.vapi
index 7e5cdae..1067378 100644
--- a/client/dconf.vapi
+++ b/client/dconf.vapi
@@ -8,6 +8,7 @@ namespace DConf {
                public Client ();
                public GLib.Variant? read (string key);
                public string[] list (string dir);
+               public string[] list_locks (string dir);
                public bool is_writable (string key);
                public void write_fast (string path, GLib.Variant? value) throws GLib.Error;
                public void write_sync (string path, GLib.Variant? value, out string tag = null, 
GLib.Cancellable? cancellable = null) throws GLib.Error;
diff --git a/engine/dconf-engine.c b/engine/dconf-engine.c
index 57bce96..e51ec57 100644
--- a/engine/dconf-engine.c
+++ b/engine/dconf-engine.c
@@ -363,6 +363,71 @@ dconf_engine_is_writable (DConfEngine *engine,
   return writable;
 }
 
+gchar **
+dconf_engine_list_locks (DConfEngine *engine,
+                         const gchar *path,
+                         gint        *length)
+{
+  gchar **strv;
+
+  if (dconf_is_dir (path, NULL))
+    {
+      GHashTable *set;
+
+      set = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+      dconf_engine_acquire_sources (engine);
+
+      if (engine->n_sources > 0 && engine->sources[0]->writable)
+        {
+          gint i, j;
+
+          for (i = 1; i < engine->n_sources; i++)
+            {
+              if (engine->sources[i]->locks)
+                {
+                  strv = gvdb_table_get_names (engine->sources[i]->locks, NULL);
+
+                  for (j = 0; strv[j]; j++)
+                    {
+                      /* It is not currently possible to lock dirs, so we
+                       * don't (yet) have to check the other direction.
+                       */
+                      if (g_str_has_prefix (strv[j], path))
+                        g_hash_table_add (set, strv[j]);
+                      else
+                        g_free (strv[j]);
+                    }
+
+                  g_free (strv);
+                }
+            }
+        }
+      else
+        g_hash_table_add (set, g_strdup (path));
+
+      dconf_engine_release_sources (engine);
+
+      strv = (gchar **) g_hash_table_get_keys_as_array (set, (guint *) length);
+      g_hash_table_steal_all (set);
+      g_hash_table_unref (set);
+    }
+  else
+    {
+      if (dconf_engine_is_writable (engine, path))
+        {
+          strv = g_new0 (gchar *, 0 + 1);
+        }
+      else
+        {
+          strv = g_new0 (gchar *, 1 + 1);
+          strv[0] = g_strdup (path);
+        }
+    }
+
+  return strv;
+}
+
 static gboolean
 dconf_engine_find_key_in_queue (GQueue       *queue,
                                 const gchar  *key,
diff --git a/engine/dconf-engine.h b/engine/dconf-engine.h
index 9ea118c..5c34bbd 100644
--- a/engine/dconf-engine.h
+++ b/engine/dconf-engine.h
@@ -112,6 +112,11 @@ gboolean                dconf_engine_is_writable                        (DConfEn
                                                                          const gchar             *key);
 
 G_GNUC_INTERNAL
+gchar **                dconf_engine_list_locks                         (DConfEngine             *engine,
+                                                                         const gchar             *path,
+                                                                         gint                    *length);
+
+G_GNUC_INTERNAL
 GVariant *              dconf_engine_read                               (DConfEngine             *engine,
                                                                          GQueue                  
*read_through,
                                                                          const gchar             *key);
diff --git a/tests/dconf-mock-gvdb.c b/tests/dconf-mock-gvdb.c
index a922a49..4f58de1 100644
--- a/tests/dconf-mock-gvdb.c
+++ b/tests/dconf-mock-gvdb.c
@@ -168,6 +168,16 @@ gvdb_table_list (GvdbTable   *table,
   return g_strdupv ((gchar **) result);
 }
 
+gchar **
+gvdb_table_get_names (GvdbTable *table,
+                      gint      *length)
+{
+  if (length)
+    *length = 0;
+
+  return g_new0 (gchar *, 0 + 1);
+}
+
 GvdbTable *
 gvdb_table_new (const gchar  *filename,
                 gboolean      trusted,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]