[dconf] prevent sets from succeeding on locked keys
- From: Ryan Lortie <ryanl src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [dconf] prevent sets from succeeding on locked keys
- Date: Thu, 1 Oct 2009 15:05:50 +0000 (UTC)
commit 3aef08011ab8048d98adcd6b8ed1df81aa897675
Author: Ryan Lortie <desrt desrt ca>
Date: Thu Oct 1 11:05:03 2009 -0400
prevent sets from succeeding on locked keys
partially implemented.
dconf/dconf-core.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++
dconf/dconf-reader.c | 38 ++++++++++++++++++++---
dconf/dconf-reader.h | 38 ++++++++++++-----------
3 files changed, 136 insertions(+), 23 deletions(-)
---
diff --git a/dconf/dconf-core.c b/dconf/dconf-core.c
index 30cb9c9..660fcb8 100644
--- a/dconf/dconf-core.c
+++ b/dconf/dconf-core.c
@@ -295,6 +295,63 @@ dconf_get_writable (const gchar *path)
return writable;
}
+static gboolean
+dconf_check_writable (DConfMount *mount,
+ const gchar *key,
+ GError **error)
+{
+ gboolean writable = TRUE;
+ gint i;
+
+ for (i = 0; writable && i < mount->n_dbs; i++)
+ writable = dconf_reader_get_writable (mount->dbs[i]->reader, key);
+
+ if (!writable)
+ {
+ g_set_error (error, 0, 0,
+ "this key is locked");
+ }
+
+ return writable;
+}
+
+
+static gboolean
+dconf_check_tree_writable (DConfMount *mount,
+ const gchar *prefix,
+ GTree *tree,
+ GError **error)
+{
+ const gchar * const *const_items;
+ gboolean writable = TRUE;
+ gchar **items;
+ gint length;
+ gint i;
+
+ length = g_tree_nnodes (tree);
+ items = g_new (gchar *, length + 1);
+ const_items = (const gchar * const *) items;
+
+ {
+ gchar **ptr;
+ g_tree_foreach (tree, append_to_array, &ptr);
+ *ptr = NULL;
+ }
+
+ for (i = 0; writable && i < mount->n_dbs; i++)
+ writable = dconf_reader_get_several_writable (mount->dbs[i]->reader,
+ prefix, const_items);
+ g_strfreev (items);
+
+ if (!writable)
+ {
+ g_set_error (error, 0, 0,
+ "one or more keys are locked");
+ }
+
+ return writable;
+}
+
/**
* dconf_watch:
* @match: a key or path to watch
@@ -466,6 +523,9 @@ dconf_merge (const gchar *prefix,
mount = dconf_demux_path (&prefix, TRUE, NULL);
g_assert (mount);
+ if (!dconf_check_tree_writable (mount, prefix, tree, error))
+ return FALSE;
+
return dconf_dbus_merge (mount->dbs[0]->bus, prefix, tree, event_id, error);
}
@@ -500,6 +560,16 @@ dconf_merge_async (const gchar *prefix,
mount = dconf_demux_path (&prefix, TRUE, NULL);
g_assert (mount);
+ {
+ GError *error = NULL;
+
+ if (!dconf_check_tree_writable (mount, prefix, tree, &error))
+ {
+ g_assert_not_reached ();
+ // XXX dispatch in idle...
+ }
+ }
+
dconf_dbus_merge_async (mount->dbs[0]->bus, prefix, tree,
(DConfDBusAsyncReadyCallback) callback,
user_data);
@@ -539,6 +609,9 @@ dconf_set (const gchar *key,
if ((mount = dconf_demux_path (&key, TRUE, error)) == NULL)
return FALSE;
+ if (!dconf_check_writable (mount, key, error))
+ return FALSE;
+
return dconf_dbus_set (mount->dbs[0]->bus, key, value, event_id, error);
}
@@ -556,6 +629,16 @@ dconf_set_async (const gchar *key,
mount = dconf_demux_path (&key, TRUE, NULL);
g_assert (mount);
+ {
+ GError *error = NULL;
+
+ if (!dconf_check_writable (mount, key, &error))
+ {
+ g_assert_not_reached ();
+ // XXX dispatch in idle...
+ }
+ }
+
dconf_dbus_set_async (mount->dbs[0]->bus, key, value,
(DConfDBusAsyncReadyCallback) callback,
user_data);
diff --git a/dconf/dconf-reader.c b/dconf/dconf-reader.c
index a6d26ab..395d981 100644
--- a/dconf/dconf-reader.c
+++ b/dconf/dconf-reader.c
@@ -389,19 +389,18 @@ gboolean
dconf_reader_get_writable (DConfReader *reader,
const gchar *name)
{
- const volatile struct dir_entry *entry;
gboolean locked = FALSE;
if (!dconf_reader_ensure_valid (reader))
return FALSE;
if (reader->data.super->flags & DCONF_FLAG_LOCKED)
- locked = TRUE;
+ return FALSE;
if (*name)
- entry = dconf_reader_get_entry (reader, name,
- reader->data.super->root_index,
- &locked);
+ dconf_reader_get_entry (reader, name,
+ reader->data.super->root_index,
+ &locked);
return !locked;
}
@@ -428,3 +427,32 @@ dconf_reader_get_locked (DConfReader *reader,
else
return (reader->data.super->flags & DCONF_FLAG_LOCKED) != 0;
}
+
+gboolean
+dconf_reader_get_several_writable (DConfReader *reader,
+ const gchar *name,
+ const gchar * const *items)
+{
+ const volatile struct dir_entry *entry;
+ gboolean locked = FALSE;
+
+ if (!dconf_reader_ensure_valid (reader))
+ return FALSE;
+
+ entry = dconf_reader_get_entry (reader, name,
+ reader->data.super->root_index,
+ &locked);
+
+ if (items[0][0] == '\0')
+ {
+ g_assert (items[1] == NULL);
+
+ return !locked;
+ }
+
+ /* not *the* most efficient way possible, but simple. */
+ while (!locked && *items != NULL)
+ dconf_reader_get_entry (reader, *items++, entry->data.index, &locked);
+
+ return !locked;
+}
diff --git a/dconf/dconf-reader.h b/dconf/dconf-reader.h
index c691368..098e1a5 100644
--- a/dconf/dconf-reader.h
+++ b/dconf/dconf-reader.h
@@ -18,23 +18,25 @@
#include <glib.h>
-DConfReader * dconf_reader_new (const gchar *filename);
-
-void dconf_reader_get (DConfReader *reader,
- const gchar *key,
- GVariant **value,
- gboolean *locked);
-
-void dconf_reader_list (DConfReader *reader,
- const gchar *path,
- GTree *builder,
- gboolean *locked);
-
-gboolean dconf_reader_get_locked (DConfReader *reader,
- const gchar *name);
-
-gboolean dconf_reader_get_writable (DConfReader *reader,
- const gchar *name);
-
+DConfReader * dconf_reader_new (const gchar *filename);
+
+void dconf_reader_get (DConfReader *reader,
+ const gchar *key,
+ GVariant **value,
+ gboolean *locked);
+
+void dconf_reader_list (DConfReader *reader,
+ const gchar *path,
+ GTree *builder,
+ gboolean *locked);
+
+gboolean dconf_reader_get_locked (DConfReader *reader,
+ const gchar *name);
+
+gboolean dconf_reader_get_writable (DConfReader *reader,
+ const gchar *name);
+gboolean dconf_reader_get_several_writable (DConfReader *reader,
+ const gchar *prefix,
+ const gchar * const *items);
#endif /* _dconf_reader_h_ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]