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