diff options
Diffstat (limited to 'bin/dconf-update.vala')
-rw-r--r-- | bin/dconf-update.vala | 292 |
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 |