[dconf] cli: add keyfile-based "dump" and "load" commands



commit 5a8b222f297546105350e734bb79bd8373bdd1a2
Author: Ryan Lortie <desrt desrt ca>
Date:   Thu Jul 21 18:10:07 2011 +0200

    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.

 bin/Makefile.am              |    2 +-
 bin/dconf-bash-completion.sh |    6 +-
 bin/dconf-dump.vala          |   94 ++++++++++++++++++++++++++++++++++++++++++
 bin/dconf.vala               |   12 +++++
 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)
 	};
 



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