summaryrefslogtreecommitdiff
path: root/bin/dconf-update.vala
diff options
context:
space:
mode:
Diffstat (limited to 'bin/dconf-update.vala')
-rw-r--r--bin/dconf-update.vala292
1 files changed, 0 insertions, 292 deletions
diff --git a/bin/dconf-update.vala b/bin/dconf-update.vala
deleted file mode 100644
index 9492adb..0000000
--- a/bin/dconf-update.vala
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright © 2010 Codethink Limited
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the licence, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- *
- * Author: Ryan Lortie <desrt@desrt.ca>
- */
-
-unowned Gvdb.Item get_parent (Gvdb.HashTable table, string name) {
- unowned Gvdb.Item parent;
-
- int end = 0;
-
- for (int i = 1; name[i] != '\0'; i++) {
- if (name[i - 1] == '/') {
- end = i;
- }
- }
-
- assert (end != 0);
-
- var parent_name = name.substring (0, end);
- parent = table.lookup (parent_name);
-
- if (parent == null) {
- parent = table.insert (parent_name);
- parent.set_parent (get_parent (table, parent_name));
- }
-
- return parent;
-}
-
-SList<string>? list_directory (string dirname, Posix.mode_t mode) throws GLib.Error {
- var list = new SList<string> ();
- var dir = Dir.open (dirname);
- unowned string? name;
-
- while ((name = dir.read_name ()) != null) {
- if (name.has_prefix (".")) {
- continue;
- }
-
- var filename = Path.build_filename (dirname, name);
- Posix.Stat buf;
-
- // only files of the requested type
- if (Posix.stat (filename, out buf) < 0 || (buf.st_mode & Posix.S_IFMT) != mode) {
- continue;
- }
-
- list.prepend (filename);
- }
-
- return list;
-}
-
-Gvdb.HashTable? read_locks_directory (string dirname) throws GLib.Error {
- SList<string>? files;
-
- try {
- files = list_directory (dirname, Posix.S_IFREG);
- } catch (FileError.NOENT e) {
- /* If locks directory is missing, there are just no locks... */
- return null;
- }
-
- var table = new Gvdb.HashTable ();
-
- foreach (var filename in files) {
- string contents;
- FileUtils.get_contents (filename, out contents, null);
-
- foreach (var line in contents.split ("\n")) {
- if (line.has_prefix ("/")) {
- table.insert_string (line, "");
- }
- }
- }
-
- return table;
-}
-
-Gvdb.HashTable read_directory (string dirname) throws GLib.Error {
- var table = new Gvdb.HashTable ();
- table.insert ("/");
-
- var files = list_directory (dirname, Posix.S_IFREG);
- files.sort (strcmp);
- files.reverse ();
-
- foreach (var filename in files) {
- var kf = new KeyFile ();
-
- try {
- kf.load_from_file (filename, KeyFileFlags.NONE);
- } catch (GLib.Error e) {
- e.message = "warning: Failed to read keyfile '%s': %s".printf (filename, e.message);
- throw e;
- }
-
- foreach (var group in kf.get_groups ()) {
- if (group.has_prefix ("/") || group.has_suffix ("/") || "//" in group) {
- throw new KeyFileError.PARSE ("%s: invalid group name: %s".printf (filename, group));
- }
-
- foreach (var key in kf.get_keys (group)) {
- if ("/" in key) {
- throw new KeyFileError.INVALID_VALUE ("%s: [%s]: invalid key name: %s",
- filename, group, key);
- }
-
- var path = "/" + group + "/" + key;
-
- if (table.lookup (path) != null) {
- /* We process the files in reverse alphabetical order. If the key is already set then
- * it must have been set from a file with higher precedence so we should ignore this
- * one.
- */
- continue;
- }
-
- var text = kf.get_value (group, key);
-
- try {
- var value = Variant.parse (null, text);
- unowned Gvdb.Item item = table.insert (path);
- item.set_parent (get_parent (table, path));
- item.set_value (value);
- } catch (VariantParseError e) {
- e.message = "%s: [%s]: %s: invalid value: %s (%s)".printf (filename, group, key, text, e.message);
- throw e;
- }
- }
- }
- }
-
- var locks = read_locks_directory (dirname + "/locks");
-
- if (locks != null) {
- unowned Gvdb.Item item = table.insert (".locks");
- item.set_hash_table (locks);
- }
-
- return table;
-}
-
-time_t get_directory_mtime (string dirname, Posix.Stat dir_buf) throws GLib.Error {
- Posix.Stat lockdir_buf;
- Posix.Stat file_buf;
- time_t latest_mtime = dir_buf.st_mtime;
-
- var files = list_directory (dirname, Posix.S_IFREG);
-
- foreach (var filename in files) {
- if (Posix.stat (filename, out file_buf) == 0 && file_buf.st_mtime > latest_mtime)
- latest_mtime = file_buf.st_mtime;
- }
-
- if (Posix.stat (dirname + "/locks", out lockdir_buf) == 0 && Posix.S_ISDIR (lockdir_buf.st_mode)) {
- if (lockdir_buf.st_mtime > latest_mtime) {
- // if the lock directory has been updated more recently then consider its timestamp instead
- latest_mtime = lockdir_buf.st_mtime;
- }
-
- files = list_directory (dirname + "/locks", Posix.S_IFREG);
-
- foreach (var filename in files) {
- if (Posix.stat (filename, out file_buf) == 0 && file_buf.st_mtime > latest_mtime)
- latest_mtime = file_buf.st_mtime;
- }
- }
-
- return latest_mtime;
-}
-
-void maybe_update_from_directory (string dirname) throws GLib.Error {
- Posix.Stat dir_buf;
-
- if (Posix.stat (dirname, out dir_buf) == 0 && Posix.S_ISDIR (dir_buf.st_mode)) {
- Posix.Stat file_buf;
-
- var filename = dirname.substring (0, dirname.length - 2);
-
- if (Posix.stat (filename, out file_buf) == 0 && file_buf.st_mtime > get_directory_mtime (dirname, dir_buf)) {
- return;
- }
-
- var table = read_directory (dirname);
-
- var fd = Posix.open (filename, Posix.O_WRONLY);
-
- if (fd < 0 && errno != Posix.ENOENT) {
- var saved_error = errno;
- printerr ("warning: Failed to open '%s' for replacement: %s\n", filename, strerror (saved_error));
- return;
- }
-
- // We expect that fd < 0 here if ENOENT (ie: the db merely didn't exist yet)
-
- try {
- table.write_contents (filename);
-
- if (fd >= 0) {
- Posix.write (fd, "\0\0\0\0\0\0\0\0", 8);
- }
- } catch (Error e) {
- printerr ("warning: %s\n", e.message);
- return;
- } finally {
- if (fd >= 0) {
- Posix.close (fd);
- }
- }
-
- try {
- var system_bus = Bus.get_sync (BusType.SYSTEM);
- system_bus.emit_signal (null, "/ca/desrt/dconf/Writer/" + Path.get_basename (filename),
- "ca.desrt.dconf.Writer", "WritabilityNotify", new Variant ("(s)", "/"));
- system_bus.flush_sync ();
- } catch {
- /* if we can't, ... don't. */
- }
- }
-}
-
-void update_all (string dirname) throws GLib.Error {
- var failed = false;
-
- foreach (var name in list_directory (dirname, Posix.S_IFDIR)) {
- if (name.has_suffix (".d")) {
- try {
- maybe_update_from_directory (name);
- } catch (Error e) {
- failed = true;
- printerr ("unable to compile %s: %s\n", name, e.message);
- }
- }
- }
-
- if (failed) {
- Process.exit (2);
- }
-}
-
-void dconf_compile (string[] args) throws GLib.Error {
- if (args[2] == null || args[3] == null || args[4] != null) {
- throw new OptionError.FAILED ("must give output file and .d dir");
- }
-
- try {
- // We always write the result of "dconf compile" as little endian
- // so that it can be installed in /usr/share
- var table = read_directory (args[3]);
- var should_byteswap = (BYTE_ORDER == ByteOrder.BIG_ENDIAN);
- table.write_contents (args[2], should_byteswap);
- } catch (Error e) {
- printerr ("%s\n", e.message);
- Process.exit (1);
- }
-}
-
-[CCode (cname = "SYSCONFDIR")]
-extern const string CONFIG_SYSCONFDIR;
-
-void dconf_update (string[] args) throws GLib.Error {
- var index = 2;
- var dbpath = CONFIG_SYSCONFDIR + "/dconf/db";
-
- if (args[index] != null) {
- dbpath = args[index];
- index ++;
- }
-
- if (args[index] != null) {
- throw new OptionError.FAILED ("too many arguments");
- }
-
- update_all (dbpath);
-}
-
-// vim:noet ts=4 sw=4