diff options
-rw-r--r-- | client/dconf-client.c | 26 | ||||
-rw-r--r-- | client/dconf-client.h | 4 | ||||
-rw-r--r-- | client/dconf.vapi | 1 | ||||
-rw-r--r-- | engine/dconf-engine.c | 65 | ||||
-rw-r--r-- | engine/dconf-engine.h | 5 | ||||
-rw-r--r-- | 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, |