summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllison Ryan Lortie <desrt@desrt.ca>2015-11-30 14:46:12 -0500
committerAllison Ryan Lortie <desrt@desrt.ca>2015-11-30 14:59:10 -0500
commit768ed4bbe040c53ee5010038c34aec7c69dba0a5 (patch)
treeba0de89dbcc757b9f3c85cf301ae2f1e2dacf197
parent014d634529f2a88ff638834dbbe827f6bb82aa16 (diff)
downloaddconf-768ed4bbe040c53ee5010038c34aec7c69dba0a5.tar.gz
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
-rw-r--r--client/dconf-client.c26
-rw-r--r--client/dconf-client.h4
-rw-r--r--client/dconf.vapi1
-rw-r--r--engine/dconf-engine.c65
-rw-r--r--engine/dconf-engine.h5
-rw-r--r--tests/dconf-mock-gvdb.c10
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,