summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Lortie <desrt@desrt.ca>2011-07-21 18:10:07 +0200
committerRyan Lortie <desrt@desrt.ca>2011-07-21 18:10:07 +0200
commit5a8b222f297546105350e734bb79bd8373bdd1a2 (patch)
tree4f6b5c4a230a142cbf2f1e9ea18bfaf4d0e4dc22
parent2289e020500951f65d7b4c35927d43c8af34a9c6 (diff)
downloaddconf-5a8b222f297546105350e734bb79bd8373bdd1a2.tar.gz
cli: add keyfile-based "dump" and "load" commands
These should be in the same format as the system database keyfiles and fairly similar to the GSettings keyfile backend format.
-rw-r--r--bin/Makefile.am2
-rw-r--r--bin/dconf-bash-completion.sh6
-rw-r--r--bin/dconf-dump.vala94
-rw-r--r--bin/dconf.vala12
4 files changed, 110 insertions, 4 deletions
diff --git a/bin/Makefile.am b/bin/Makefile.am
index 8f24bb0..d3252cc 100644
--- a/bin/Makefile.am
+++ b/bin/Makefile.am
@@ -6,7 +6,7 @@ bin_PROGRAMS = dconf
dconf_VALAFLAGS = --vapidir ../client --pkg=gio-2.0 --pkg=posix --pkg=dconf
dconf_LDADD = $(gio_LIBS) ../client/libdconf.so.0
-dconf_SOURCES = dconf.vala dconf-update.vala ../gvdb/gvdb-builder.c gvdb.vapi fixes.vapi
+dconf_SOURCES = dconf.vala dconf-update.vala dconf-dump.vala ../gvdb/gvdb-builder.c gvdb.vapi fixes.vapi
completiondir = $(sysconfdir)/bash_completion.d
completion_DATA = dconf-bash-completion.sh
diff --git a/bin/dconf-bash-completion.sh b/bin/dconf-bash-completion.sh
index 46d732d..37ab477 100644
--- a/bin/dconf-bash-completion.sh
+++ b/bin/dconf-bash-completion.sh
@@ -9,15 +9,15 @@ __dconf() {
case "${COMP_CWORD}" in
1)
- choices=$'help \nread \nlist \nwrite \nreset\n update \nlock \nunlock \nwatch '
+ choices=$'help \nread \nlist \nwrite \nreset\n update \nlock \nunlock \nwatch \ndump \nload '
;;
2)
case "${COMP_WORDS[1]}" in
help)
- choices=$'help \nread \nlist \nwrite \nreset\n update \nlock \nunlock \nwatch '
+ choices=$'help \nread \nlist \nwrite \nreset\n update \nlock \nunlock \nwatch \ndump \nload '
;;
- list)
+ list|dump|load)
choices="$(dconf _complete / "${COMP_WORDS[2]}")"
;;
read|list|write|lock|unlock|watch|reset)
diff --git a/bin/dconf-dump.vala b/bin/dconf-dump.vala
new file mode 100644
index 0000000..85b60e8
--- /dev/null
+++ b/bin/dconf-dump.vala
@@ -0,0 +1,94 @@
+void add_to_keyfile (KeyFile kf, DConf.Client client, string topdir, string? rel = "") {
+ var this_dir = topdir + rel;
+ string this_group;
+
+ if (rel != "") {
+ this_group = rel.slice (0, -1);
+ } else {
+ this_group = "/";
+ }
+
+ foreach (var item in client.list (this_dir)) {
+ if (item.has_suffix ("/")) {
+ add_to_keyfile (kf, client, topdir, rel + item);
+ } else {
+ var val = client.read (this_dir + item);
+
+ if (val != null) {
+ kf.set_value (this_group, item, val.print (true));
+ }
+ }
+ }
+}
+
+void dconf_dump (string[] args) throws Error {
+ var client = new DConf.Client ();
+ var kf = new KeyFile ();
+ var dir = args[2];
+
+ DConf.verify_dir (dir);
+
+ add_to_keyfile (kf, client, dir);
+ print ("%s", kf.to_data ());
+}
+
+KeyFile keyfile_from_stdin () throws Error {
+ unowned string? tmp;
+ char buffer[1024];
+
+ var s = new StringBuilder ();
+ while ((tmp = stdin.gets (buffer)) != null) {
+ s.append (tmp);
+ }
+
+ var kf = new KeyFile ();
+ kf.load_from_data (s.str, s.len, 0);
+
+ return kf;
+}
+
+class DConfLoadState {
+ public string[] keys;
+ public Variant[] vals;
+ int n_keys;
+ int i;
+
+ public DConfLoadState (int n) {
+ keys = new string[n + 1];
+ vals = new Variant[n];
+ n_keys = n;
+ i = 0;
+ }
+
+ public int add (void *key, void *value) {
+ assert (i < n_keys);
+
+ keys[i] = (string) key;
+ vals[i] = (Variant) value;
+ i++;
+
+ return (int) false;
+ }
+}
+
+void dconf_load (string[] args) throws Error {
+ var dir = args[2];
+ DConf.verify_dir (dir);
+
+ var tree = new Tree<string, Variant> (strcmp);
+ var kf = keyfile_from_stdin ();
+
+ foreach (var group in kf.get_groups ()) {
+ foreach (var key in kf.get_keys (group)) {
+ var rel = (group == "/" ? "" : group + "/") + key;
+ DConf.verify_rel_key (rel);
+ tree.insert (rel, Variant.parse (null, kf.get_value (group, key)));
+ }
+ }
+
+ DConfLoadState list = new DConfLoadState (tree.nnodes ());
+ tree.foreach (list.add);
+
+ var client = new DConf.Client ();
+ client.write_many (dir, list.keys, list.vals);
+}
diff --git a/bin/dconf.vala b/bin/dconf.vala
index 071d39e..6c63bd1 100644
--- a/bin/dconf.vala
+++ b/bin/dconf.vala
@@ -74,6 +74,16 @@ void show_help (bool requested, string? command) {
synopsis = "PATH";
break;
+ case "dump":
+ description = "Dump an entire subpath to stdout";
+ synopsis = "DIR";
+ break;
+
+ case "load":
+ description = "Populate a subpath from stdin";
+ synopsis = "DIR";
+ break;
+
default:
str.append_printf ("Unknown command '%s'\n\n", command);
command = null;
@@ -304,6 +314,8 @@ int main (string[] args) {
CommandMapping ("lock", dconf_lock),
CommandMapping ("unlock", dconf_unlock),
CommandMapping ("watch", dconf_watch),
+ CommandMapping ("dump", dconf_dump),
+ CommandMapping ("load", dconf_load),
CommandMapping ("_complete", dconf_complete)
};