diff --git a/.dconf.metadata b/.dconf.metadata
new file mode 100644
index 0000000..0fda437
--- /dev/null
+++ b/.dconf.metadata
@@ -0,0 +1 @@
+e6b10da51df002a1661ce938941770c549cd5b87 SOURCES/dconf-0.28.0.tar.xz
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..7125557
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+SOURCES/dconf-0.28.0.tar.xz
diff --git a/SOURCES/dconf-0.26.0-permissions.patch b/SOURCES/dconf-0.26.0-permissions.patch
new file mode 100644
index 0000000..151b790
--- /dev/null
+++ b/SOURCES/dconf-0.26.0-permissions.patch
@@ -0,0 +1,31 @@
+--- a/gvdb/gvdb-builder.c
++++ b/gvdb/gvdb-builder.c
+@@ -21,6 +21,7 @@
+ #include "gvdb-format.h"
+ 
+ #include <glib.h>
++#include <glib/gstdio.h>
+ #include <fcntl.h>
+ #if !defined(G_OS_WIN32) || !defined(_MSC_VER)
+ #include <unistd.h>
+@@ -509,13 +510,20 @@ gvdb_table_write_contents (GHashTable   *table,
+   gboolean status;
+   FileBuilder *fb;
+   GString *str;
++  GStatBuf buf;
++  gint stat_ret;
+ 
+   fb = file_builder_new (byteswap);
+   file_builder_add_hash (fb, table, &root);
+   str = file_builder_serialise (fb, root);
+ 
++  stat_ret = g_stat (filename, &buf);
++
+   status = g_file_set_contents (filename, str->str, str->len, error);
+   g_string_free (str, TRUE);
+ 
++  if (stat_ret == 0)
++    g_chmod (filename, buf.st_mode);
++
+   return status;
+ }
diff --git a/SOURCES/dconf-0.28.0-db-mtime.patch b/SOURCES/dconf-0.28.0-db-mtime.patch
new file mode 100644
index 0000000..69fe241
--- /dev/null
+++ b/SOURCES/dconf-0.28.0-db-mtime.patch
@@ -0,0 +1,77 @@
+From 6a6797446f13378035a2700253546b524d629c8a Mon Sep 17 00:00:00 2001
+From: Marek Kasik <mkasik@redhat.com>
+Date: Tue, 10 Jul 2018 18:29:16 +0200
+Subject: [PATCH] Check mtimes of files when updating databases
+
+Do not check just mtimes of directories in /etc/dconf/db/
+but also mtimes of the files in those directories
+to catch all modifications in them.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=708258
+---
+ bin/dconf-update.vala | 41 ++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 34 insertions(+), 7 deletions(-)
+
+diff --git a/bin/dconf-update.vala b/bin/dconf-update.vala
+index d452092..5aac6c7 100644
+--- a/bin/dconf-update.vala
++++ b/bin/dconf-update.vala
+@@ -162,21 +162,48 @@ Gvdb.HashTable read_directory (string dirname) throws GLib.Error {
+ 	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 dir_mtime = dir_buf.st_mtime;
++
++	var files = list_directory (dirname, Posix.S_IFREG);
++	files.sort (strcmp);
++	files.reverse ();
++
++	foreach (var filename in files) {
++		if (Posix.stat (filename, out file_buf) == 0 && file_buf.st_mtime > dir_mtime)
++			dir_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 > dir_mtime) {
++			// if the lock directory has been updated more recently then consider its timestamp instead
++			dir_mtime = lockdir_buf.st_mtime;
++		}
++
++		files = list_directory (dirname + "/locks", Posix.S_IFREG);
++		files.sort (strcmp);
++		files.reverse ();
++
++		foreach (var filename in files) {
++			if (Posix.stat (filename, out file_buf) == 0 && file_buf.st_mtime > dir_mtime)
++				dir_mtime = file_buf.st_mtime;
++		}
++	}
++
++	return dir_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 lockdir_buf;
+ 		Posix.Stat file_buf;
+ 
+ 		var filename = dirname.substring (0, dirname.length - 2);
+ 
+-		if (Posix.stat (dirname + "/locks", out lockdir_buf) == 0 && lockdir_buf.st_mtime > dir_buf.st_mtime) {
+-			// if the lock directory has been updated more recently then consider its timestamp instead
+-			dir_buf.st_mtime = lockdir_buf.st_mtime;
+-		}
+-
+-		if (Posix.stat (filename, out file_buf) == 0 && file_buf.st_mtime > dir_buf.st_mtime) {
++		if (Posix.stat (filename, out file_buf) == 0 && file_buf.st_mtime > get_directory_mtime (dirname, dir_buf)) {
+ 			return;
+ 		}
+ 
+-- 
+2.17.1
+
diff --git a/SOURCES/dconf-0.28.0-dbus-1.patch b/SOURCES/dconf-0.28.0-dbus-1.patch
new file mode 100644
index 0000000..a895f92
--- /dev/null
+++ b/SOURCES/dconf-0.28.0-dbus-1.patch
@@ -0,0 +1,706 @@
+--- a/meson.build
++++ b/meson.build
+@@ -75,6 +75,7 @@ gio_unix_req_version = '>= 2.25.7'
+ 
+ glib_dep = dependency('glib-2.0', version: '>= 2.44.0')
+ gio_unix_dep = dependency('gio-unix-2.0', version: gio_unix_req_version)
++dbus_1_dep = dependency('dbus-1')
+ 
+ gio_querymodules = find_program('gio-querymodules', required: false)
+ if gio_querymodules.found()
+@@ -101,6 +102,7 @@ subdir('gvdb')
+ subdir('common')
+ subdir('engine')
+ subdir('service')
++subdir('dbus-1')
+ subdir('gdbus')
+ subdir('gsettings')
+ subdir('client')
+--- /dev/null
++++ b/dbus-1/meson.build
+@@ -0,0 +1,43 @@
++client_inc = include_directories('.')
++
++libdbus_1_sources = files('dconf-libdbus-1.c', 'dconf-libdbus-1.h')
++
++cflags = '-DG_LOG_DOMAIN="@0@"'.format(meson.project_name())
++
++libdconf_libdbus_1_shared = static_library(
++  meson.project_name() + '-libdbus-1-shared',
++  sources: libdbus_1_sources,
++  include_directories: top_inc,
++  dependencies: [gio_unix_dep, dbus_1_dep],
++  c_args: cflags,
++  pic: true
++)
++
++libdconf_libdbus_1 = static_library(
++  meson.project_name() + '-libdbus-1',
++  sources: libdbus_1_sources,
++  include_directories: top_inc,
++  dependencies: [gio_unix_dep, dbus_1_dep],
++  c_args: cflags,
++)
++
++dbus_1_sources = files('dconf-dbus-1.c')
++
++libdconf_dbus_1 = shared_library(
++  meson.project_name() + '-dbus-1',
++  sources: dbus_1_sources,
++  version: '0.0.0',
++  soversion: '0',
++  include_directories: top_inc,
++  dependencies: [gio_unix_dep, dbus_1_dep],
++  c_args: cflags,
++  link_with: [
++    libdconf_common_hidden,
++    libdconf_engine_shared,
++    libdconf_libdbus_1_shared,
++    libdconf_shm_shared,
++    libgvdb_shared
++  ],
++  install: true,
++  install_dir: dconf_libdir
++)
+--- /dev/null
++++ b/dbus-1/dconf-dbus-1.c
+@@ -0,0 +1,188 @@
++/**
++ * Copyright © 2010 Canonical Limited
++ *
++ * This program is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation, either version 3 of the licence, or (at
++ * your option) any later version.
++ *
++ * This program 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
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
++ *
++ * Author: Ryan Lortie <desrt@desrt.ca>
++ **/
++
++#include "config.h"
++
++#include "dconf-dbus-1.h"
++
++#include "../engine/dconf-engine.h"
++#include "dconf-libdbus-1.h"
++
++#include <string.h>
++
++struct _DConfDBusClient
++{
++  DConfEngine *engine;
++  GSList *watches;
++  gint ref_count;
++};
++
++typedef struct
++{
++  gchar           *path;
++  DConfDBusNotify  notify;
++  gpointer         user_data;
++} Watch;
++
++void
++dconf_engine_change_notify (DConfEngine         *engine,
++                            const gchar         *prefix,
++                            const gchar * const *changes,
++                            const gchar         *tag,
++                            gboolean             is_writability,
++                            gpointer             origin_tag,
++                            gpointer             user_data)
++{
++  DConfDBusClient *dcdbc = user_data;
++  gchar **my_changes;
++  gint n_changes;
++  GSList *iter;
++  gint i;
++
++  n_changes = g_strv_length ((gchar **) changes);
++  my_changes = g_new (gchar *, n_changes + 1);
++
++  for (i = 0; i < n_changes; i++)
++    my_changes[i] = g_strconcat (prefix, changes[i], NULL);
++  my_changes[i] = NULL;
++
++  for (iter = dcdbc->watches; iter; iter = iter->next)
++    {
++      Watch *watch = iter->data;
++
++      for (i = 0; i < n_changes; i++)
++        if (g_str_has_prefix (my_changes[i], watch->path))
++          watch->notify (dcdbc, my_changes[i], watch->user_data);
++    }
++
++  g_strfreev (my_changes);
++}
++
++GVariant *
++dconf_dbus_client_read (DConfDBusClient *dcdbc,
++                        const gchar     *key)
++{
++  return dconf_engine_read (dcdbc->engine, DCONF_READ_FLAGS_NONE, NULL, key);
++}
++
++gboolean
++dconf_dbus_client_write (DConfDBusClient *dcdbc,
++                         const gchar     *key,
++                         GVariant        *value)
++{
++  DConfChangeset *changeset;
++  gboolean success;
++
++  changeset = dconf_changeset_new_write (key, value);
++  success = dconf_engine_change_fast (dcdbc->engine, changeset, NULL, NULL);
++  dconf_changeset_unref (changeset);
++
++  return success;
++}
++
++void
++dconf_dbus_client_subscribe (DConfDBusClient *dcdbc,
++                             const gchar     *path,
++                             DConfDBusNotify  notify,
++                             gpointer         user_data)
++{
++  Watch *watch;
++
++  watch = g_slice_new (Watch);
++  watch->path = g_strdup (path);
++  watch->notify = notify;
++  watch->user_data = user_data;
++
++  dcdbc->watches = g_slist_prepend (dcdbc->watches, watch);
++
++  dconf_engine_watch_fast (dcdbc->engine, path);
++}
++
++void
++dconf_dbus_client_unsubscribe (DConfDBusClient *dcdbc,
++                               DConfDBusNotify  notify,
++                               gpointer         user_data)
++{
++  GSList **ptr;
++
++  for (ptr = &dcdbc->watches; *ptr; ptr = &(*ptr)->next)
++    {
++      Watch *watch = (*ptr)->data;
++
++      if (watch->notify == notify && watch->user_data == user_data)
++        {
++          *ptr = g_slist_remove_link (*ptr, *ptr);
++          dconf_engine_unwatch_fast (dcdbc->engine, watch->path);
++          g_free (watch->path);
++          g_slice_free (Watch, watch);
++          return;
++        }
++    }
++
++  g_warning ("No matching watch found to unsubscribe");
++}
++
++gboolean
++dconf_dbus_client_has_pending (DConfDBusClient *dcdbc)
++{
++  return dconf_engine_has_outstanding (dcdbc->engine);
++}
++
++DConfDBusClient *
++dconf_dbus_client_new (const gchar    *profile,
++                       DBusConnection *session,
++                       DBusConnection *system)
++{
++  DConfDBusClient *dcdbc;
++
++  if (session == NULL)
++    session = dbus_bus_get (DBUS_BUS_SESSION, NULL);
++
++  if (system == NULL)
++    system = dbus_bus_get (DBUS_BUS_SYSTEM, NULL);
++
++  dconf_libdbus_1_provide_bus (G_BUS_TYPE_SESSION, session);
++  dconf_libdbus_1_provide_bus (G_BUS_TYPE_SYSTEM, system);
++
++  dcdbc = g_slice_new (DConfDBusClient);
++  dcdbc->engine = dconf_engine_new (NULL, dcdbc, NULL);
++  dcdbc->watches = NULL;
++  dcdbc->ref_count = 1;
++
++  return dcdbc;
++}
++
++void
++dconf_dbus_client_unref (DConfDBusClient *dcdbc)
++{
++  if (--dcdbc->ref_count == 0)
++    {
++      g_return_if_fail (dcdbc->watches == NULL);
++
++      g_slice_free (DConfDBusClient, dcdbc);
++    }
++}
++
++DConfDBusClient *
++dconf_dbus_client_ref (DConfDBusClient *dcdbc)
++{
++  dcdbc->ref_count++;
++
++  return dcdbc;
++}
+--- /dev/null
++++ b/dbus-1/dconf-dbus-1.h
+@@ -0,0 +1,56 @@
++/**
++ * Copyright © 2010 Canonical Limited
++ *
++ * This program is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation, either version 3 of the licence, or (at
++ * your option) any later version.
++ *
++ * This program 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
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
++ *
++ * Author: Ryan Lortie <desrt@desrt.ca>
++ **/
++
++#ifndef _dconf_dbus_1_h_
++#define _dconf_dbus_1_h_
++
++#include <dbus/dbus.h>
++#include <glib.h>
++
++G_BEGIN_DECLS
++
++typedef struct _DConfDBusClient DConfDBusClient;
++
++typedef void         (* DConfDBusNotify)                                (DConfDBusClient *dcdbc,
++                                                                         const gchar     *key,
++                                                                         gpointer         user_data);
++
++DConfDBusClient *       dconf_dbus_client_new                           (const gchar     *profile,
++                                                                         DBusConnection  *session,
++                                                                         DBusConnection  *system);
++void                    dconf_dbus_client_unref                         (DConfDBusClient *dcdbc);
++DConfDBusClient *       dconf_dbus_client_ref                           (DConfDBusClient *dcdbc);
++
++GVariant *              dconf_dbus_client_read                          (DConfDBusClient *dcdbc,
++                                                                         const gchar     *key);
++gboolean                dconf_dbus_client_write                         (DConfDBusClient *dcdbc,
++                                                                         const gchar     *key,
++                                                                         GVariant        *value);
++void                    dconf_dbus_client_subscribe                     (DConfDBusClient *dcdbc,
++                                                                         const gchar     *name,
++                                                                         DConfDBusNotify  notify,
++                                                                         gpointer         user_data);
++void                    dconf_dbus_client_unsubscribe                   (DConfDBusClient *dcdbc,
++                                                                         DConfDBusNotify  notify,
++                                                                         gpointer         user_data);
++gboolean                dconf_dbus_client_has_pending                   (DConfDBusClient *dcdbc);
++
++G_END_DECLS
++
++#endif /* _dconf_dbus_1_h_ */
+--- /dev/null
++++ b/dbus-1/dconf-libdbus-1.c
+@@ -0,0 +1,365 @@
++/**
++ * Copyright © 2010 Canonical Limited
++ *
++ * This program is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation, either version 3 of the licence, or (at
++ * your option) any later version.
++ *
++ * This program 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
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
++ *
++ * Author: Ryan Lortie <desrt@desrt.ca>
++ **/
++
++#include "config.h"
++
++#include "dconf-libdbus-1.h"
++
++#include "../engine/dconf-engine.h"
++
++#include <string.h>
++
++static DBusConnection *dconf_libdbus_1_buses[5];
++
++struct _DConfDBusClient
++{
++  DConfEngine *engine;
++  GSList *watches;
++  gint ref_count;
++};
++
++#define DCONF_LIBDBUS_1_ERROR (g_quark_from_static_string("DCONF_LIBDBUS_1_ERROR"))
++#define DCONF_LIBDBUS_1_ERROR_FAILED 0
++
++static DBusMessage *
++dconf_libdbus_1_new_method_call (const gchar *bus_name,
++                                 const gchar *object_path,
++                                 const gchar *interface_name,
++                                 const gchar *method_name,
++                                 GVariant    *parameters)
++{
++  DBusMessageIter dbus_iter;
++  DBusMessage *message;
++  GVariantIter iter;
++  GVariant *child;
++
++  g_variant_ref_sink (parameters);
++
++  message = dbus_message_new_method_call (bus_name, object_path, interface_name, method_name);
++  dbus_message_iter_init_append (message, &dbus_iter);
++  g_variant_iter_init (&iter, parameters);
++
++  while ((child = g_variant_iter_next_value (&iter)))
++    {
++      if (g_variant_is_of_type (child, G_VARIANT_TYPE_STRING))
++        {
++          const gchar *str;
++
++          str = g_variant_get_string (child, NULL);
++          dbus_message_iter_append_basic (&dbus_iter, DBUS_TYPE_STRING, &str);
++        }
++
++      else if (g_variant_is_of_type (child, G_VARIANT_TYPE_UINT32))
++        {
++          guint32 uint;
++
++          uint = g_variant_get_uint32 (child);
++          dbus_message_iter_append_basic (&dbus_iter, DBUS_TYPE_UINT32, &uint);
++        }
++
++      else
++        {
++          DBusMessageIter subiter;
++          const guint8 *bytes;
++          gsize n_elements;
++
++          g_assert (g_variant_is_of_type (child, G_VARIANT_TYPE_BYTESTRING));
++
++          bytes = g_variant_get_fixed_array (child, &n_elements, sizeof (guint8));
++          dbus_message_iter_open_container (&dbus_iter, DBUS_TYPE_ARRAY, "y", &subiter);
++          dbus_message_iter_append_fixed_array (&subiter, DBUS_TYPE_BYTE, &bytes, n_elements);
++          dbus_message_iter_close_container (&dbus_iter, &subiter);
++        }
++
++      g_variant_unref (child);
++    }
++
++  g_variant_unref (parameters);
++
++  return message;
++}
++
++static GVariant *
++dconf_libdbus_1_get_message_body (DBusMessage  *message,
++                                  GError      **error)
++{
++  GVariantBuilder builder;
++  const gchar *signature;
++  DBusMessageIter iter;
++
++  /* We support two types: strings and arrays of strings.
++   *
++   * It's very simple to detect if the message contains only these
++   * types: check that the signature contains only the letters "a" and
++   * "s" and that it does not contain "aa".
++   */
++  signature = dbus_message_get_signature (message);
++  if (signature[strspn(signature, "as")] != '\0' || strstr (signature, "aa"))
++    {
++      g_set_error (error, DCONF_LIBDBUS_1_ERROR, DCONF_LIBDBUS_1_ERROR_FAILED,
++                   "unable to handle message type '(%s)'", signature);
++      return NULL;
++    }
++
++  g_variant_builder_init (&builder, G_VARIANT_TYPE_TUPLE);
++  dbus_message_iter_init (message, &iter);
++  while (dbus_message_iter_get_arg_type (&iter))
++    {
++      const gchar *string;
++
++      if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_STRING)
++        {
++          dbus_message_iter_get_basic (&iter, &string);
++          g_variant_builder_add (&builder, "s", string);
++        }
++      else
++        {
++          DBusMessageIter sub;
++
++          g_assert (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_ARRAY &&
++                    dbus_message_iter_get_element_type (&iter) == DBUS_TYPE_STRING);
++
++          g_variant_builder_open (&builder, G_VARIANT_TYPE_STRING_ARRAY);
++          dbus_message_iter_recurse (&iter, &sub);
++
++          while (dbus_message_iter_get_arg_type (&sub))
++            {
++              const gchar *string;
++              dbus_message_iter_get_basic (&sub, &string);
++              g_variant_builder_add (&builder, "s", string);
++              dbus_message_iter_next (&sub);
++            }
++
++          g_variant_builder_close (&builder);
++        }
++      dbus_message_iter_next (&iter);
++    }
++
++  return g_variant_ref_sink (g_variant_builder_end (&builder));
++}
++
++static GVariant *
++dconf_libdbus_1_interpret_result (DBusMessage         *result,
++                                  const GVariantType  *expected_type,
++                                  GError             **error)
++{
++  GVariant *reply;
++
++  if (dbus_message_get_type (result) == DBUS_MESSAGE_TYPE_ERROR)
++    {
++      const gchar *errstr = "(no message)";
++
++      dbus_message_get_args (result, NULL, DBUS_TYPE_STRING, &errstr, DBUS_TYPE_INVALID);
++      g_set_error (error, DCONF_LIBDBUS_1_ERROR, DCONF_LIBDBUS_1_ERROR_FAILED,
++                   "%s: %s", dbus_message_get_error_name (result), errstr);
++      return NULL;
++    }
++
++  reply = dconf_libdbus_1_get_message_body (result, error);
++
++  if (reply && expected_type && !g_variant_is_of_type (reply, expected_type))
++    {
++      gchar *expected_string;
++
++      expected_string = g_variant_type_dup_string (expected_type);
++      g_set_error (error, DCONF_LIBDBUS_1_ERROR, DCONF_LIBDBUS_1_ERROR_FAILED,
++                   "received reply '%s' is not of the expected type %s",
++                   g_variant_get_type_string (reply), expected_string);
++      g_free (expected_string);
++
++      g_variant_unref (reply);
++      reply = NULL;
++    }
++
++  return reply;
++}
++
++static void
++dconf_libdbus_1_method_call_done (DBusPendingCall *pending,
++                                  gpointer         user_data)
++{
++  DConfEngineCallHandle *handle = user_data;
++  const GVariantType *expected_type;
++  DBusMessage *message;
++  GError *error = NULL;
++  GVariant *reply;
++
++  if (pending == NULL)
++    return;
++
++  message = dbus_pending_call_steal_reply (pending);
++  dbus_pending_call_unref (pending);
++
++  expected_type = dconf_engine_call_handle_get_expected_type (handle);
++  reply = dconf_libdbus_1_interpret_result (message, expected_type, &error);
++  dbus_message_unref (message);
++
++  dconf_engine_call_handle_reply (handle, reply, error);
++
++  if (reply)
++    g_variant_unref (reply);
++  if (error)
++    g_error_free (error);
++}
++
++gboolean
++dconf_engine_dbus_call_async_func (GBusType                bus_type,
++                                   const gchar            *bus_name,
++                                   const gchar            *object_path,
++                                   const gchar            *interface_name,
++                                   const gchar            *method_name,
++                                   GVariant               *parameters,
++                                   DConfEngineCallHandle  *handle,
++                                   GError                **error)
++{
++  DBusConnection *connection;
++  DBusPendingCall *pending;
++  DBusMessage *message;
++
++  g_assert_cmpint (bus_type, <, G_N_ELEMENTS (dconf_libdbus_1_buses));
++  connection = dconf_libdbus_1_buses[bus_type];
++  g_assert (connection != NULL);
++
++  message = dconf_libdbus_1_new_method_call (bus_name, object_path, interface_name, method_name, parameters);
++  dbus_connection_send_with_reply (connection, message, &pending, -1);
++  dbus_pending_call_set_notify (pending, dconf_libdbus_1_method_call_done, handle, NULL);
++  dbus_message_unref (message);
++
++  return TRUE;
++}
++
++static void
++dconf_libdbus_1_convert_error (DBusError  *dbus_error,
++                               GError    **error)
++{
++  g_set_error (error, DCONF_LIBDBUS_1_ERROR, DCONF_LIBDBUS_1_ERROR_FAILED,
++               "%s: %s", dbus_error->name, dbus_error->message);
++}
++
++GVariant *
++dconf_engine_dbus_call_sync_func (GBusType             bus_type,
++                                  const gchar         *bus_name,
++                                  const gchar         *object_path,
++                                  const gchar         *interface_name,
++                                  const gchar         *method_name,
++                                  GVariant            *parameters,
++                                  const GVariantType  *expected_type,
++                                  GError             **error)
++{
++  DBusConnection *connection;
++  DBusMessage *message;
++  DBusError dbus_error;
++  DBusMessage *result;
++  GVariant *reply;
++
++  g_assert_cmpint (bus_type, <, G_N_ELEMENTS (dconf_libdbus_1_buses));
++  connection = dconf_libdbus_1_buses[bus_type];
++  g_assert (connection != NULL);
++
++  dbus_error_init (&dbus_error);
++  message = dconf_libdbus_1_new_method_call (bus_name, object_path, interface_name, method_name, parameters);
++  result = dbus_connection_send_with_reply_and_block (connection, message, -1, &dbus_error);
++  dbus_message_unref (message);
++
++  if (result == NULL)
++    {
++      dconf_libdbus_1_convert_error (&dbus_error, error);
++      dbus_error_free (&dbus_error);
++      return NULL;
++    }
++
++  reply = dconf_libdbus_1_interpret_result (result, expected_type, error);
++  dbus_message_unref (result);
++
++  return reply;
++}
++
++static DBusHandlerResult
++dconf_libdbus_1_filter (DBusConnection *connection,
++                        DBusMessage    *message,
++                        gpointer        user_data)
++{
++  GBusType bus_type = GPOINTER_TO_INT (user_data);
++
++  if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL)
++    {
++      const gchar *interface;
++
++      interface = dbus_message_get_interface (message);
++
++      if (interface && g_str_equal (interface, "ca.desrt.dconf.Writer"))
++        {
++          GVariant *parameters;
++
++          parameters = dconf_libdbus_1_get_message_body (message, NULL);
++
++          if (parameters != NULL)
++            {
++              dconf_engine_handle_dbus_signal (bus_type,
++                                               dbus_message_get_sender (message),
++                                               dbus_message_get_path (message),
++                                               dbus_message_get_member (message),
++                                               parameters);
++              g_variant_unref (parameters);
++            }
++        }
++    }
++
++  return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
++}
++
++void
++dconf_libdbus_1_provide_bus (GBusType        bus_type,
++                             DBusConnection *connection)
++{
++  g_assert_cmpint (bus_type, <, G_N_ELEMENTS (dconf_libdbus_1_buses));
++
++  if (!dconf_libdbus_1_buses[bus_type])
++    {
++      dconf_libdbus_1_buses[bus_type] = dbus_connection_ref (connection);
++      dbus_connection_add_filter (connection, dconf_libdbus_1_filter, GINT_TO_POINTER (bus_type), NULL);
++    }
++}
++
++#ifndef PIC
++static gboolean
++dconf_libdbus_1_check_connection (gpointer user_data)
++{
++  DBusConnection *connection = user_data;
++
++  dbus_connection_read_write (connection, 0);
++  dbus_connection_dispatch (connection);
++
++  return G_SOURCE_CONTINUE;
++}
++
++void
++dconf_engine_dbus_init_for_testing (void)
++{
++  DBusConnection *session;
++  DBusConnection *system;
++
++  dconf_libdbus_1_provide_bus (G_BUS_TYPE_SESSION, session = dbus_bus_get (DBUS_BUS_SESSION, NULL));
++  dconf_libdbus_1_provide_bus (G_BUS_TYPE_SYSTEM, system = dbus_bus_get (DBUS_BUS_SYSTEM, NULL));
++
++  /* "mainloop integration" */
++  g_timeout_add (1, dconf_libdbus_1_check_connection, session);
++  g_timeout_add (1, dconf_libdbus_1_check_connection, system);
++}
++#endif
+--- /dev/null
++++ b/dbus-1/dconf-libdbus-1.h
+@@ -0,0 +1,11 @@
++#ifndef __dconf_libdbus_1_h__
++#define __dconf_libdbus_1_h__
++
++#include <dbus/dbus.h>
++#include <gio/gio.h>
++
++G_GNUC_INTERNAL
++void                    dconf_libdbus_1_provide_bus                     (GBusType        bus_type,
++                                                                         DBusConnection *connection);
++
++#endif /* __dconf_libdbus_1_h__ */
+--- a/tests/meson.build
++++ b/tests/meson.build
+@@ -23,6 +23,7 @@ unit_tests = [
+   ['gvdb', 'gvdb.c', '-DSRCDIR="@0@"'.format(test_dir), glib_dep, libgvdb],
+   ['gdbus-thread', 'dbus.c', '-DDBUS_BACKEND="/gdbus/thread"', gio_unix_dep, libdconf_gdbus_thread],
+   ['gdbus-filter', 'dbus.c', '-DDBUS_BACKEND="/gdbus/filter"', gio_unix_dep, libdconf_gdbus_filter],
++  ['libdbus-1', 'dbus.c', '-DDBUS_BACKEND="/libdbus-1"', gio_unix_dep, libdconf_libdbus_1],
+   ['engine', 'engine.c', '-DSRCDIR="@0@"'.format(test_dir), [glib_dep, dl_dep, m_dep], [libdconf_engine, libdconf_common, libdconf_mock]],
+   ['client', 'client.c', '-DSRCDIR="@0@"'.format(test_dir), gio_unix_dep, [libdconf_client, libdconf_engine, libdconf_common, libdconf_mock]]
+ ]
diff --git a/SPECS/dconf.spec b/SPECS/dconf.spec
new file mode 100644
index 0000000..d280279
--- /dev/null
+++ b/SPECS/dconf.spec
@@ -0,0 +1,328 @@
+%define glib2_version 2.44.0
+
+Name:           dconf
+Version:        0.28.0
+Release:        4%{?dist}
+Summary:        A configuration system
+
+License:        LGPLv2+ and GPLv2+ and GPLv3+
+URL:            http://live.gnome.org/dconf
+Source0:        http://download.gnome.org/sources/dconf/0.28/dconf-%{version}.tar.xz
+
+# https://bugzilla.redhat.com/show_bug.cgi?id=1567184
+Patch1:         dconf-0.28.0-dbus-1.patch
+
+# https://bugzilla.redhat.com/show_bug.cgi?id=1281253
+Patch2:         dconf-0.26.0-permissions.patch
+
+# https://bugzilla.redhat.com/show_bug.cgi?id=1570569
+Patch3:         dconf-0.28.0-db-mtime.patch
+
+BuildRequires:  glib2-devel >= %{glib2_version}
+BuildRequires:  dbus-devel
+BuildRequires:  gtk-doc
+BuildRequires:  meson
+BuildRequires:  vala
+
+Requires:       dbus
+Requires:       glib2%{?_isa} >= %{glib2_version}
+
+%description
+dconf is a low-level configuration system. Its main purpose is to provide a
+backend to the GSettings API in GLib.
+
+%package devel
+Summary: Header files and libraries for dconf development
+Requires: %{name}%{?_isa} = %{version}-%{release}
+
+%description devel
+dconf development package. Contains files needed for doing software
+development using dconf.
+
+%prep
+%autosetup -p1
+
+%build
+%meson -Denable-gtk-doc=true
+%meson_build
+
+%install
+%meson_install
+
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/dconf/profile
+
+cat << EOF > $RPM_BUILD_ROOT%{_sysconfdir}/dconf/profile/user
+user-db:user
+system-db:local
+system-db:site
+system-db:distro
+EOF
+
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/dconf/db/local.d/locks
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/dconf/db/site.d/locks
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/dconf/db/distro.d/locks
+
+# dconf-dbus-1 was removed in dconf 0.24,
+# we keep just the library for compatibility
+rm -fv $RPM_BUILD_ROOT%{_libdir}/libdconf-dbus-1.so
+
+%post
+/sbin/ldconfig
+gio-querymodules-%{__isa_bits} %{_libdir}/gio/modules
+
+%postun
+/sbin/ldconfig
+if [ $1 -eq 0 ] ; then
+  gio-querymodules-%{__isa_bits} %{_libdir}/gio/modules
+  glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
+fi
+
+%posttrans
+glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || :
+dconf update
+
+%files
+%license COPYING
+%dir %{_sysconfdir}/dconf
+%dir %{_sysconfdir}/dconf/db
+%dir %{_sysconfdir}/dconf/db/local.d
+%dir %{_sysconfdir}/dconf/db/local.d/locks
+%dir %{_sysconfdir}/dconf/db/site.d
+%dir %{_sysconfdir}/dconf/db/site.d/locks
+%dir %{_sysconfdir}/dconf/db/distro.d
+%dir %{_sysconfdir}/dconf/db/distro.d/locks
+%dir %{_sysconfdir}/dconf/profile
+%{_libdir}/gio/modules/libdconfsettings.so
+%{_libexecdir}/dconf-service
+%{_datadir}/dbus-1/services/ca.desrt.dconf.service
+%{_bindir}/dconf
+%{_libdir}/libdconf.so.1*
+%{_libdir}/libdconf-dbus-1.so.0*
+%{_datadir}/bash-completion/completions/dconf
+%{_mandir}/man1/dconf-service.1.gz
+%{_mandir}/man1/dconf.1.gz
+%{_mandir}/man7/dconf.7.gz
+%config(noreplace) %{_sysconfdir}/dconf/profile/user
+
+%files devel
+%{_includedir}/dconf
+%{_libdir}/libdconf.so
+%{_libdir}/pkgconfig/dconf.pc
+%dir %{_datadir}/gtk-doc
+%dir %{_datadir}/gtk-doc/html
+%{_datadir}/gtk-doc/html/dconf
+%{_datadir}/vala
+
+%changelog
+* Wed Jul 25 2018 Marek Kasik <mkasik@redhat.com> - 0.28.0-3
+- Check mtimes of files in /etc/dconf/db/*.d/ directories
+- when running "dconf update"
+- Resolves: #1570569
+
+* Wed May 23 2018 Marek Kasik <mkasik@redhat.com> - 0.28.0-2
+- Return dconf-dbus-1 library (without devel files)
+- Related: #1567184
+
+* Tue Mar 13 2018 Kalev Lember <klember@redhat.com> - 0.28.0-1
+- Update to 0.28.0
+- Resolves: #1567184
+
+* Mon Mar  6 2017 Marek Kasik <mkasik@redhat.com> - 0.26.0-2
+- Restore permissions on updated database
+- Resolves: #1281253
+
+* Fri Feb 10 2017 Marek Kasik <mkasik@redhat.com> - 0.26.0-1
+- Update to 0.26.0
+- Remove editor subpackage
+- Return libdbus-1 library (not header or pkgconfig files)
+- Resolves: #1386841
+
+* Tue Mar 24 2015 Marek Kasik <mkasik@redhat.com> - 0.22.0-2
+- Remove unused patches
+- Resolves: #1174448
+
+* Fri Sep 19 2014 Kalev Lember <kalevlember@gmail.com> - 0.22.0-1
+- Update to 0.22.0
+- Resolves: #1174448
+
+* Fri Apr  4 2014 Marek Kasik <mkasik@redhat.com> - 0.16.0-6
+- Don't hang shutdown
+- Resolves: #1082994
+
+* Fri Jan 24 2014 Daniel Mach <dmach@redhat.com> - 0.16.0-5
+- Mass rebuild 2014-01-24
+
+* Fri Dec 27 2013 Daniel Mach <dmach@redhat.com> - 0.16.0-4
+- Mass rebuild 2013-12-27
+
+* Wed Jul 31 2013 Ray Strode <rstrode@redhat.com> 0.16.0-3
+- Add system dbs for distro, site, and machine local dconf databases
+  Resolves: #990630
+
+* Tue Jun 25 2013 Matthias Clasen <mclasen@redhat.com> - 0.16.0-2
+- Fix a frequent crash (#975687)
+
+* Mon Mar 25 2013 Kalev Lember <kalevlember@gmail.com> - 0.16.0-1
+- Update to 0.16.0
+
+* Mon Feb 11 2013 Kalev Lember <kalevlember@gmail.com> - 0.15.3-1
+- Update to 0.15.3
+- Install the HighContrast icons and update the icon cache scriptlets to take
+  this into account
+
+* Sat Dec 22 2012 Rex Dieter <rdieter@fedoraproject.org> - 0.15.2-2
+- -devel: drop Requires: glib2-devel, already gets pulled in via pkgconfig deps
+- -editor: add icon scriptlets
+- tighten subpkg deps via %%{_isa}
+
+* Tue Nov 20 2012 Richard Hughes <hughsient@gmail.com> - 0.15.2-1
+- Update to 0.15.2
+
+* Fri Nov 09 2012 Kalev Lember <kalevlember@gmail.com> - 0.15.0-3
+- Move some of the rpm scriptlets back to %%posttrans
+  (glib-compile-schemas, icon cache)
+
+* Thu Nov  8 2012 Marek Kasik <mkasik@redhat.com> - 0.15.0-2
+- Move dconf-editor's man page to the dconf-editor sub-package
+
+* Wed Nov  7 2012 Marek Kasik <mkasik@redhat.com> - 0.15.0-1
+- Update to 0.15.0
+- Remove upstreamed patch
+
+* Wed Nov  7 2012 Marek Kasik <mkasik@redhat.com> - 0.14.0-4
+- Move %%posttrans commands to %%post (rpmlint related)
+
+* Wed Nov  7 2012 Marek Kasik <mkasik@redhat.com> - 0.14.0-3
+- Update License field
+- Update Source URL
+- Add link of corresponding bug for the memory leak patch
+
+* Wed Nov  7 2012 Marek Kasik <mkasik@redhat.com> - 0.14.0-2.1
+- Merge spec-file fixes from f18 branch
+
+* Sun Oct 21 2012 Matthias Clasen <mclasen@redhat.com> - 0.14.0-2
+- Fix a memory leak
+- Update to 0.14.0
+
+* Wed Jul 18 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.13.4-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Tue Jul 17 2012 Richard Hughes <hughsient@gmail.com> - 0.13.4-1
+- Update to 0.13.4
+
+* Thu Jun 07 2012 Richard Hughes <hughsient@gmail.com> - 0.13.0-2
+- Add missing file to file list.
+
+* Thu Jun 07 2012 Richard Hughes <hughsient@gmail.com> - 0.13.0-1
+- Update to 0.13.0
+
+* Sat May 05 2012 Kalev Lember <kalevlember@gmail.com> - 0.12.1-1
+- Update to 0.12.1
+
+* Tue Mar 27 2012 Kalev Lember <kalevlember@gmail.com> - 0.12.0-1
+- Update to 0.12.0
+
+* Tue Mar 20 2012 Kalev Lember <kalevlember@gmail.com> - 0.11.7-1
+- Update to 0.11.7
+
+* Fri Mar  9 2012 Matthias Clasen <mclasen@redhat.com> - 0.11.6-1
+- Update to 0.11.6
+
+* Mon Feb  6 2012 Matthias Clasen <mclasen@redhat.com> - 0.11.5-1
+- Update to 0.11.5
+
+* Fri Jan 13 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.11.2-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
+
+* Mon Nov 21 2011 Matthias Clasen <mclasen@redhat.com> - 0.11.2-1
+- Update to 0.11.2
+
+* Fri Nov  4 2011 Matthias Clasen <mclasen@redhat.com> - 0.11.0-2
+- Fix a typo (#710700)
+
+* Wed Nov  2 2011 Matthias Clasen <mclasen@redhat.com> - 0.11.0-1
+- Update to 0.11.0
+
+* Mon Sep 26 2011 Ray <rstrode@redhat.com> - 0.10.0-1
+- Update to 0.10.0
+
+* Mon Sep 19 2011 Matthias Clasen <mclasen@redhat.com> - 0.9.1-1
+- Update to 0.9.1
+
+* Tue Jul 26 2011 Matthias Clasen <mclasen@redhat.com> - 0.9.0-1
+- Update to 0.9.0
+
+* Wed May 11 2011 Tomas Bzatek <tbzatek@redhat.com> - 0.7.5-1
+- Update to 0.7.5
+
+* Fri May  6 2011 Matthias Clasen <mclasen@redhat.com> - 0.7.4-1
+- Update to 0.7.4
+
+* Wed Apr  6 2011 Matthias Clasen <mclasen@redhat.com> - 0.7.3-2
+- Fix a crash in dconf-editor
+
+* Tue Mar 22 2011 Tomas Bzatek <tbzatek@redhat.com> - 0.7.3-1
+- Update to 0.7.3
+
+* Thu Feb 10 2011 Matthias Clasen <mclasen@redhat.com> - 0.7.2-3
+- Rebuild for newer gtk
+
+* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.7.2-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Sat Feb  5 2011 Matthias Clasen <mclasen@redhat.com> - 0.7.2-1
+- Update to 0.7.2
+
+* Wed Feb  2 2011 Matthias Clasen <mclasen@redhat.com> - 0.7.1-1
+- Update to 0.7.1
+
+* Mon Jan 17 2011 Matthias Clasen <mclasen@redhat.com> - 0.7-1
+- Update to 0.7
+
+* Wed Sep 29 2010 jkeating - 0.5.1-2
+- Rebuilt for gcc bug 634757
+
+* Tue Sep 21 2010 Matthias Clasen <mclasen@redhat.com> - 0.5.1-1
+- Update to 0.5.1
+
+* Thu Aug  5 2010 Matthias Clasen <mclasen@redhat.com> - 0.5-2
+- Fix up shared library symlinks (#621733)
+
+* Tue Aug  3 2010 Matthias Clasen <mclasen@redhat.com> - 0.5-1
+- Update to 0.5
+
+* Mon Jul 12 2010 Matthias Clasen <mclasen@redhat.com> - 0.4.2-1
+- Update to 0.4.2
+
+* Wed Jun 30 2010 Colin Walters <walters@verbum.org> - 0.4.1-2
+- Changes to support snapshot builds
+
+* Sat Jun 26 2010 Matthias Clasen <mclasen@redhat.com> 0.4.1-1
+- Update to 0.4.1
+- Include dconf-editor (in a subpackage)
+
+* Wed Jun 23 2010 Matthias Clasen <mclasen@redhat.com> 0.4-2
+- Rebuild against glib 2.25.9
+
+* Sat Jun 12 2010 Matthias Clasen <mclasen@redhat.com> 0.4-1
+- Update to 0.4
+
+* Tue Jun 08 2010 Richard Hughes <rhughes@redhat.com> 0.3.2-0.1.20100608
+- Update to a git snapshot so that users do not get a segfault in every
+  application using GSettings.
+
+* Wed Jun 02 2010 Bastien Nocera <bnocera@redhat.com> 0.3.1-2
+- Rebuild against latest glib2
+
+* Mon May 24 2010 Matthias Clasen <mclasen@redhat.com> 0.3.1-1
+- Update to 0.3.1
+- Add a -devel subpackage
+
+* Fri May 21 2010 Matthias Clasen <mclasen@redhat.com> 0.3-3
+- Make batched writes (e.g. with delayed settings) work
+
+* Thu May 20 2010 Matthias Clasen <mclasen@redhat.com> 0.3-2
+- Make the registration of the backend work
+
+* Wed May 19 2010 Matthias Clasen <mclasen@redhat.com> 0.3-1
+- Initial packaging