Index: backends/xml-backend.c
===================================================================
RCS file: /cvs/gnome/gconf/backends/xml-backend.c,v
retrieving revision 1.81
diff -u -p -r1.81 xml-backend.c
--- backends/xml-backend.c	21 Mar 2002 23:55:06 -0000	1.81
+++ backends/xml-backend.c	10 Jun 2002 03:40:16 -0000
@@ -267,6 +267,141 @@ writable (GConfSource* source,
   return TRUE;
 }
 
+static char *
+get_local_mirror_dir (const char *root_dir)
+{
+  char hostname [NI_MAXHOST];
+
+  if (gethostname (hostname, NI_MAXHOST) < 0)
+    {
+      gconf_log (GCL_DEBUG, "couldn't gethostname: %s\n", g_strerror (errno));
+      return NULL;
+    }
+ 
+  return g_strconcat (root_dir, "/%gconf-local-mirror-", hostname, NULL);
+}
+
+static gboolean
+check_mirror_dir (const char *mirror_dir)
+{
+  char        *check_file;
+  struct stat  s;
+  gboolean     retval = FALSE;
+
+  if (!mirror_dir)
+    return FALSE;
+
+  check_file = g_build_filename (
+                   mirror_dir, "%gconf.xml", NULL);
+  if (stat (check_file, &s) == 0 && S_ISREG (s.st_mode))
+      retval = TRUE;
+  g_free (check_file);
+
+  return retval;
+}
+
+static void
+mirror_file (const char *src,
+             const char *dest)
+{
+  char *buffer [BUFSIZ];
+  int srcfd;
+  int destfd;
+  ssize_t num_bytes;
+
+  srcfd = open (src, O_RDONLY);
+  if (srcfd < 0)
+    {
+      g_warning ("Unable to open %s : %s\n",
+                 src, strerror (errno));
+      return;
+    }
+
+  destfd = open (dest, O_WRONLY|O_CREAT, 0600);
+  if (destfd < 0)
+    {
+      g_warning ("Unable to open %s : %s\n",
+                 dest, strerror (errno));
+      close (srcfd);
+      return;
+    }
+
+  while ((num_bytes = read (srcfd, buffer, BUFSIZ)) > 0)
+    if (write (destfd, buffer, num_bytes) < 0)
+      {
+        g_warning ("Error writing to %s : %s\n",
+                   dest, strerror (errno));
+        break;
+      }
+
+  if (num_bytes < 0)
+    g_warning ("Error reading from %s : %s\n",
+               src, strerror (errno));
+
+  close (srcfd);
+  close (destfd);
+}
+
+static void
+mirror_dir (const char *src,
+            const char *dest)
+{
+  struct dirent *entry;
+  DIR *dir;
+
+  if (mkdir (dest, 0700) < 0)
+    {
+      g_warning ("Error making directory %s : %s\n",
+                 dest, strerror (errno));
+      return;
+    }
+
+  if (!(dir = opendir (src)))
+    {
+      g_warning ("Error opening directory %s : %s\n",
+                 src, strerror (errno));
+      return;
+    }
+
+  while ((entry = readdir (dir)))
+    if (!strcmp (entry->d_name, ".") ||
+        !strcmp (entry->d_name, ".."))
+      continue;
+
+    else if (!strcmp (entry->d_name, "%gconf.xml"))
+      {
+        char *srcfile;
+        char *destfile;
+
+        srcfile  = g_build_filename (src, entry->d_name, NULL);
+        destfile = g_build_filename (dest, entry->d_name, NULL);
+
+        mirror_file (srcfile, destfile);
+
+        g_free (srcfile);
+        g_free (destfile);
+      }
+    else if (entry->d_name [0] != '%')
+      {
+        char *srcdir;
+        struct stat s;
+
+        srcdir = g_build_filename (src, entry->d_name, NULL);
+        if (stat (srcdir, &s) == 0 && S_ISDIR (s.st_mode))
+          {
+            char *destdir;
+
+            destdir = g_build_filename (
+                            dest, entry->d_name, NULL);
+            mirror_dir (srcdir, destdir);
+            g_free (destdir);
+          }
+        g_free (srcdir);
+      }
+
+  closedir (dir);
+}
+
 static GConfSource*  
 resolve_address (const gchar* address, GError** err)
 {
@@ -344,6 +479,8 @@ resolve_address (const gchar* address, G
     gboolean writable;
     int fd;
     gchar* testfile;
+    gboolean use_local_mirror = FALSE;
+    char *local_mirror_dir;
 
     writable = FALSE;
     
@@ -367,6 +504,10 @@ resolve_address (const gchar* address, G
     if (writable)
       flags |= GCONF_SOURCE_ALL_WRITEABLE;
 
+    local_mirror_dir = get_local_mirror_dir (root_dir);
+    if (check_mirror_dir (local_mirror_dir))
+      use_local_mirror = TRUE;
+
     /* We only do locking if it's writable,
        which is sort of broken but close enough
     */
@@ -374,9 +515,36 @@ resolve_address (const gchar* address, G
       {
         gchar* lockdir;
 
-        lockdir = gconf_concat_dir_and_key(root_dir, "%gconf-xml-backend.lock");
-        
-        lock = gconf_get_lock(lockdir, err);
+        if (use_local_mirror)
+          {
+            lockdir = gconf_concat_dir_and_key (
+				local_mirror_dir, "%gconf-xml-backend.lock");
+	    lock = gconf_get_lock (lockdir, err);
+          }
+        else
+          {
+            lockdir = gconf_concat_dir_and_key (
+				root_dir, "%gconf-xml-backend.lock");
+            lock = gconf_get_lock (lockdir, err);
+            if (!lock && local_mirror_dir)
+              {
+                g_clear_error (err);
+                g_free (lockdir);
+                mirror_dir (root_dir, local_mirror_dir);
+                lockdir = gconf_concat_dir_and_key (
+				local_mirror_dir, "%gconf-xml-backend.lock");
+	        lock = gconf_get_lock (lockdir, err);
+		use_local_mirror = TRUE;
+              }
+          }
+
+        if (use_local_mirror)
+          {
+            g_free (root_dir);
+            root_dir = local_mirror_dir;
+          }
+        else
+          g_free (local_mirror_dir);
 
         if (lock != NULL)
           gconf_log(GCL_DEBUG, "Acquired lock directory `%s'", lockdir);
Index: gconf/Makefile.am
===================================================================
RCS file: /cvs/gnome/gconf/gconf/Makefile.am,v
retrieving revision 1.75
diff -u -p -r1.75 Makefile.am
--- gconf/Makefile.am	7 Feb 2002 21:13:57 -0000	1.75
+++ gconf/Makefile.am	10 Jun 2002 03:40:16 -0000
@@ -29,7 +29,7 @@ endif
 
 lib_LTLIBRARIES = libgconf-2.la
 
-bin_PROGRAMS = gconfd-2 gconftool-2 $(SANITY_CHECK)
+bin_PROGRAMS = gconfd-2 gconftool-2 $(SANITY_CHECK) gconf-test-lock-2
 
 CORBA_SOURCECODE = GConf-common.c GConf-skels.c GConf-stubs.c GConf.h
 
@@ -91,6 +91,12 @@ gconf_sanity_check_2_SOURCES = \
 	gconf-sanity-check.c
 
 gconf_sanity_check_2_LDADD = $(EFENCE) $(INTLLIBS) $(DEPENDENT_WITH_XML_AND_GTK_LIBS) $(POPT_LIBS) libgconf-$(MAJOR_VERSION).la
+
+gconf_test_lock_2_SOURCES = \
+	gconf-test-lock.c
+
+gconf_test_lock_2_LDADD = $(EFENCE) $(INTLLIBS) $(DEPENDENT_WITH_XML_AND_GTK_LIBS) $(POPT_LIBS) libgconf-$(MAJOR_VERSION).la
+
 
 $(CORBA_SOURCECODE): $(srcdir)/GConf.idl $(ORBIT_IDL)
 	$(ORBIT_IDL) $(srcdir)/GConf.idl
Index: gconf/gconf-internals.c
===================================================================
RCS file: /cvs/gnome/gconf/gconf/gconf-internals.c,v
retrieving revision 1.112
diff -u -p -r1.112 gconf-internals.c
--- gconf/gconf-internals.c	3 Jun 2002 02:36:25 -0000	1.112
+++ gconf/gconf-internals.c	10 Jun 2002 03:40:17 -0000
@@ -36,7 +36,7 @@
 #include <time.h>
 #include <math.h>
 
-gboolean gconf_log_debug_messages = FALSE;
+gboolean gconf_log_debug_messages = TRUE;
 
 static gboolean gconf_daemon_mode = FALSE;
 static gchar* daemon_ior = NULL;
@@ -2700,6 +2700,61 @@ gconf_get_current_lock_holder  (const gc
   return server;
 }
 
+ConfigServer
+gconf_get_daemon (const char *lock_dir,
+		  gboolean   *ping_failed,
+		  GString    *failure_log)
+{
+  ConfigServer retval;
+
+  retval = gconf_get_current_lock_holder (lock_dir, failure_log);
+
+  if (retval != CORBA_OBJECT_NIL)
+    {
+      CORBA_Environment env;
+
+      CORBA_exception_init (&env);
+
+      ConfigServer_ping (retval, &env);
+      
+      if (env._major != CORBA_NO_EXCEPTION)
+        {
+          if (ping_failed)
+            {
+              char *iorfile;
+              int   fd;
+
+              /* Only set ping_failed if someone actually
+               * has a lock on the file
+               */
+              iorfile = g_strconcat (lock_dir, "/ior", NULL);
+              fd = open_empty_locked_file (lock_dir, iorfile, NULL);
+              if (fd < 0)
+                *ping_failed = TRUE;
+              g_free (iorfile);
+              close (fd);
+            }
+
+          CORBA_Object_release ((CORBA_Object) retval, NULL);
+          retval = CORBA_OBJECT_NIL;
+
+          g_string_append_printf (failure_log,
+                                  _("Server ping error: %s"),
+                                  CORBA_exception_id (&env));
+        }
+      else if (ping_failed && getenv ("GCONF_FAKE_PING_FAILURE"))
+        {
+          *ping_failed = TRUE;
+          CORBA_Object_release ((CORBA_Object) retval, NULL);
+          retval = CORBA_OBJECT_NIL;
+        }
+
+      CORBA_exception_free (&env);
+    }
+
+  return retval;
+}
+
 static CORBA_ORB gconf_orb = CORBA_OBJECT_NIL;      
 
 CORBA_ORB
@@ -2770,6 +2825,26 @@ gconf_get_lock_dir (void)
   return lock_dir;
 }
 
+char*
+gconf_get_local_lock_dir (void)
+{
+  char *gconfd_dir;
+  char *lock_dir;
+  char  hostname [NI_MAXHOST];
+
+  if (gethostname (hostname, NI_MAXHOST) < 0)
+    {
+      gconf_log (GCL_DEBUG, "couldn't gethostname: %s\n", g_strerror (errno));
+      return NULL;
+    }
+  
+  gconfd_dir = gconf_get_daemon_dir ();
+  lock_dir = g_strconcat (gconfd_dir, "/lock-", hostname, NULL);
+  g_free (gconfd_dir);
+
+  return lock_dir;
+}
+
 static void
 set_cloexec (gint fd)
 {
@@ -2801,11 +2876,11 @@ gconf_activate_server (gboolean  start_i
   int p[2] = { -1, -1 };
   char buf[1];
   GError *tmp_err;
-  char *argv[3];
+  char *argv[4];
   char *gconfd_dir;
   char *lock_dir;
   GString *failure_log;
-  CORBA_Environment ev;
+  gboolean use_local_lock = FALSE;
 
   failure_log = g_string_new (NULL);
   
@@ -2818,29 +2893,21 @@ gconf_activate_server (gboolean  start_i
   g_free (gconfd_dir);
 
   g_string_append (failure_log, " 1: ");
-  lock_dir = gconf_get_lock_dir ();
-  server = gconf_get_current_lock_holder (lock_dir, failure_log);
-  g_free (lock_dir);
 
   /* Confirm server exists */
-  CORBA_exception_init (&ev);
+  lock_dir = gconf_get_lock_dir ();
+  server = gconf_get_daemon (lock_dir, &use_local_lock, failure_log);
+  g_free (lock_dir);
 
-  if (!CORBA_Object_is_nil (server, &ev))
+  if (server == CORBA_OBJECT_NIL)
     {
-      ConfigServer_ping (server, &ev);
-      
-      if (ev._major != CORBA_NO_EXCEPTION)
-        {
-          server = CORBA_OBJECT_NIL;
-
-          g_string_append_printf (failure_log,
-                                  _("Server ping error: %s"),
-                                  CORBA_exception_id (&ev));
-        }
+      lock_dir = gconf_get_local_lock_dir ();
+      if (lock_dir)
+	server = gconf_get_daemon (lock_dir, NULL, failure_log);
+      g_free (lock_dir);
     }
+  lock_dir = NULL;
 
-  CORBA_exception_free (&ev);
-  
   if (server != CORBA_OBJECT_NIL)
     {
       g_string_free (failure_log, TRUE);
@@ -2862,8 +2929,9 @@ gconf_activate_server (gboolean  start_i
 
       argv[0] = g_strconcat (GCONF_BINDIR, "/" GCONFD, NULL);
       argv[1] = g_strdup_printf ("%d", p[1]);
-      argv[2] = NULL;
-  
+      argv[2] = use_local_lock ? "--use-local-lock" : NULL;
+      argv[3] = NULL;
+
       tmp_err = NULL;
       if (!g_spawn_async (NULL,
                           argv,
@@ -2892,7 +2960,11 @@ gconf_activate_server (gboolean  start_i
       read (p[0], buf, 1);
 
       g_string_append (failure_log, " 2: ");
-      lock_dir = gconf_get_lock_dir ();
+
+      if (use_local_lock)
+	lock_dir = gconf_get_local_lock_dir ();
+      if (!lock_dir)
+	lock_dir = gconf_get_lock_dir ();
       server = gconf_get_current_lock_holder (lock_dir, failure_log);
       g_free (lock_dir);
     }
Index: gconf/gconf-internals.h
===================================================================
RCS file: /cvs/gnome/gconf/gconf/gconf-internals.h,v
retrieving revision 1.74
diff -u -p -r1.74 gconf-internals.h
--- gconf/gconf-internals.h	3 Jun 2002 02:36:26 -0000	1.74
+++ gconf/gconf-internals.h	10 Jun 2002 03:40:17 -0000
@@ -205,8 +205,9 @@ CORBA_ORB gconf_orb_get (void);
 ConfigServer gconf_activate_server (gboolean  start_if_not_found,
                                     GError  **error);
 
-char*     gconf_get_lock_dir (void);
-char*     gconf_get_daemon_dir (void);
+char*     gconf_get_lock_dir       (void);
+char*     gconf_get_local_lock_dir (void);
+char*     gconf_get_daemon_dir     (void);
 
 gboolean gconf_schema_validate (const GConfSchema  *sc,
                                 GError            **err);
Index: gconf/gconf-sanity-check.c
===================================================================
RCS file: /cvs/gnome/gconf/gconf/gconf-sanity-check.c,v
retrieving revision 1.4
diff -u -p -r1.4 gconf-sanity-check.c
--- gconf/gconf-sanity-check.c	21 Mar 2002 23:55:09 -0000	1.4
+++ gconf/gconf-sanity-check.c	10 Jun 2002 03:40:17 -0000
@@ -20,9 +20,14 @@
 #include "gconf.h"
 #include "gconf-internals.h"
 #include "gconf-sources.h"
+#include "gconf-backend.h"
 #include <gtk/gtk.h>
+#include <libxml/parser.h>
 #include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 #include <unistd.h>
+#include <dirent.h>
 #include <string.h>
 #include <popt.h>
 #include <stdlib.h>
@@ -55,6 +60,9 @@ static void     show_fatal_error_dialog 
                                          ...) G_GNUC_PRINTF (1, 2);
 static gboolean check_file_locking (void);
 static gboolean check_gconf (void);
+static void     merge_xml_backend_copies (void);
+
+#define GCONF_XML_MIRROR_PREFIX "%gconf-local-mirror-"
 
 int 
 main (int argc, char** argv)
@@ -85,6 +93,8 @@ main (int argc, char** argv)
 
   if (!check_gconf ())
     return 1;
+
+  merge_xml_backend_copies ();
   
   return 0;
 }
@@ -287,4 +297,394 @@ ensure_gtk (void)
     }
   
   return ok;
+}
+
+/* XML backend merging
+ *    a.k.a. crack laden goodness
+ */
+
+static xmlDocPtr
+my_xmlParseDoc (const char *file)
+{
+  xmlDocPtr  retval;
+  GError    *error = NULL;
+  char      *contents = NULL;
+  gsize      length = 0;
+
+  g_file_get_contents (file, &contents, &length, &error);
+  if (!contents)
+    {
+      g_warning ("Unable to open %s : %s\n", file, error->message);
+      return NULL;
+    }
+
+  retval = xmlParseMemory (contents, length);
+  g_free (contents);
+  if (!retval)
+    {
+      g_warning ("Unable to parse xml file\n");
+      return NULL;
+    }
+
+  if (!retval->xmlRootNode || !retval->xmlRootNode->xmlChildrenNode)
+    {
+      xmlFreeDoc (retval);
+      g_warning ("Empty xml file\n");
+      return NULL;
+    }
+
+  return retval;
+}
+
+static char *
+my_xmlGetProp (xmlNodePtr  node,
+               const char *name)
+{
+  char *prop;
+
+  prop = xmlGetProp(node, name);
+
+  if (prop && prop [0] == '\0')
+    {
+      xmlFree (prop);
+      return NULL;
+    }
+
+  return prop;
+}
+
+static xmlNodePtr
+lookup_entry (xmlDocPtr   doc,
+              const char *name)
+{
+  xmlNodePtr node;
+
+  for (node = doc->xmlRootNode->xmlChildrenNode;
+       node; node = node->next)
+    {
+      char *prop_name;
+
+      if (node->type != XML_ELEMENT_NODE ||
+          strcmp (node->name, "entry"))
+        continue;
+
+      prop_name = my_xmlGetProp (node, "name");
+      if (!strcmp (name, prop_name))
+        {
+          xmlFree (prop_name);
+          break;
+        }
+      xmlFree (prop_name);
+    }
+
+  return node;
+}
+
+static gulong
+get_node_mtime (xmlNodePtr node)
+{
+  gulong  retval = G_MAXULONG;
+  char   *mtime;
+
+  mtime = my_xmlGetProp (node, "mtime");
+  if (mtime)
+    {
+      retval = gconf_string_to_gulong (mtime);
+      xmlFree (mtime);
+    }
+
+  return retval;
+}
+
+static void
+merge (xmlDocPtr new,
+       xmlDocPtr doc,
+       xmlDocPtr compare)
+{
+  xmlNodePtr node;
+
+  for (node = doc->xmlRootNode->xmlChildrenNode;
+       node; node = node->next)
+    {
+      xmlNodePtr  comp_node;
+      char       *name;
+
+      if (node->type != XML_ELEMENT_NODE ||
+          strcmp (node->name, "entry"))
+        continue;
+
+      name = my_xmlGetProp (node, "name");
+      comp_node = lookup_entry (compare, name);
+
+      if (!comp_node ||
+          get_node_mtime (node) > get_node_mtime (comp_node))
+        xmlAddChild (new->xmlRootNode, xmlCopyNode (node, TRUE));
+      else
+        xmlAddChild (new->xmlRootNode, xmlCopyNode (comp_node, TRUE));
+
+      xmlFree (name);
+    }
+}
+
+static void
+merge_file (const char *orig_file,
+            const char *copy_file)
+{
+  FILE      *outfile;
+  xmlDocPtr  orig;
+  xmlDocPtr  copy;
+  xmlDocPtr  new;
+
+  orig = my_xmlParseDoc (orig_file);
+  if (!orig)
+    {
+      unlink (copy_file);
+      return;
+    }
+
+  copy = my_xmlParseDoc (copy_file);
+  if (!copy)
+    {
+      xmlFreeDoc (orig);
+      unlink (copy_file);
+      return;
+    }
+
+  unlink (copy_file);
+
+  new = xmlNewDoc ("1.0");
+  new->xmlRootNode = xmlNewDocNode (new, NULL, "gconf", NULL);
+
+  merge (new, orig, copy);
+  merge (new, copy, orig);
+
+  outfile = fopen (orig_file, "w");
+  if (outfile)
+    {
+      xmlDocDump (outfile, new);
+      fclose (outfile);
+    }
+
+  xmlFreeDoc (new);
+  xmlFreeDoc (orig);
+  xmlFreeDoc (copy);
+}
+
+static void
+merge_dir_recurse (const char *orig,
+                   const char *copy)
+{
+  GSList        *merged_dirs = NULL;
+  GSList        *l;
+  struct dirent *entry;
+  struct stat    s;
+  DIR           *dir;
+
+  if (!(dir = opendir (orig)))
+    return;
+
+  while ((entry = readdir (dir)))
+    if (!strcmp (entry->d_name, ".") ||
+        !strcmp (entry->d_name, ".."))
+      continue;
+
+    else if (!strcmp (entry->d_name, "%gconf.xml"))
+      {
+        char *origfile;
+        char *copyfile;
+
+        origfile = g_build_filename (orig, entry->d_name, NULL);
+        copyfile = g_build_filename (copy, entry->d_name, NULL);
+        if (stat (copyfile, &s) == 0 && S_ISREG (s.st_mode) && s.st_size > 0)
+          merge_file (origfile, copyfile);
+        else
+          unlink (copyfile);
+
+        g_free (origfile);
+        g_free (copyfile);
+      }
+    else if (entry->d_name [0] != '%')
+      {
+        char *origdir;
+        char *copydir;
+
+        origdir = g_build_filename (orig, entry->d_name, NULL);
+        copydir = g_build_filename (copy, entry->d_name, NULL);
+
+        if (stat (origdir, &s) == 0 && S_ISDIR (s.st_mode) &&
+            stat (copydir, &s) == 0 && S_ISDIR (s.st_mode))
+          {
+            merge_dir_recurse (origdir, copydir);
+            merged_dirs = g_slist_prepend (
+                             merged_dirs, g_strdup (entry->d_name));
+          }
+
+        g_free (origdir);
+        g_free (copydir);
+      }
+
+  closedir (dir);
+
+  if (!(dir = opendir (copy)))
+    return;
+
+  while ((entry = readdir (dir)))
+    if (!strcmp (entry->d_name, ".") ||
+        !strcmp (entry->d_name, ".."))
+      continue;
+
+    else if (entry->d_name [0] != '%')
+      {
+        for (l = merged_dirs; l; l = l->next)
+          if (!strcmp (entry->d_name, l->data))
+		break;
+
+	if (!l)
+          {
+            char *copydir;
+            char *newdir;
+
+            copydir = g_build_filename (copy, entry->d_name, NULL);
+            newdir  = g_build_filename (orig, entry->d_name, NULL);
+
+            if (stat (copydir, &s) == 0 && S_ISDIR (s.st_mode))
+	      rename (copydir, newdir);
+
+            g_free (copydir);
+            g_free (newdir);
+          }
+      }
+
+  for (l = merged_dirs; l; l = l->next)
+    g_free (l->data);
+  g_slist_free (l);
+
+  closedir (dir);
+
+  rmdir (copy);
+}
+
+static void
+merge_source (const char *root_dir)
+{
+  struct dirent *entry;
+  DIR           *dir;
+
+  if (!(dir = opendir (root_dir)))
+    return;
+
+  while ((entry = readdir (dir)))
+    if (!strcmp (entry->d_name, ".") ||
+        !strcmp (entry->d_name, ".."))
+      continue;
+
+    else if (!strncmp (entry->d_name,
+                       GCONF_XML_MIRROR_PREFIX,
+                       strlen (GCONF_XML_MIRROR_PREFIX)))
+      {
+        char        *mirror_dir;
+        struct stat  s;
+
+        mirror_dir = g_build_filename (
+                        root_dir, entry->d_name, NULL);
+	if (stat (mirror_dir, &s) == 0 && S_ISDIR (s.st_mode))
+          {
+            GConfLock *lock;
+
+            if ((lock = gconf_get_lock (mirror_dir, NULL)))
+              {
+                merge_dir_recurse (root_dir, mirror_dir);
+                gconf_release_lock (lock, NULL);
+              }
+          }
+
+        g_free (mirror_dir);
+      }
+
+  closedir (dir);
+}
+
+static void
+merge_address (const char *address)
+{
+  GConfLock *lock;
+  char      *root_dir;
+  char      *lockdir;
+  char      *backend;
+  char     **address_flags;
+  gboolean   readonly = FALSE;
+  int        len;
+  int        i;
+
+  backend = gconf_address_backend (address);
+  if (!backend || strcmp (backend, "xml"))
+    {
+      g_free (backend);
+      return;
+    }
+  g_free (backend);
+
+  root_dir = gconf_address_resource (address);
+  len = strlen (root_dir);
+  if (root_dir [len - 1] == '/')
+    root_dir [len - 1] = '\0';
+
+  address_flags = gconf_address_flags (address);
+  for (i = 0; address_flags && address_flags [i]; i++)
+    if (!strcmp (address_flags [i], "readonly"))
+      {
+        readonly = TRUE;
+        break;
+      }
+  g_strfreev (address_flags);
+
+  if (readonly)
+    {
+      g_free (root_dir);
+      return;
+    }
+
+  lockdir = gconf_concat_dir_and_key (
+		root_dir, "%gconf-xml-backend.lock");
+  lock = gconf_get_lock (lockdir, NULL);
+  g_free (lockdir);
+  if (!lock)
+    {
+      g_free (root_dir);
+      return;
+    }
+
+  merge_source (root_dir);
+
+  g_free (root_dir);
+  gconf_release_lock (lock, NULL);
+}
+
+/* If this blows up, we don't care.
+ * The last thing we want is this
+ * crack preventing people logging
+ * in.
+ */
+static void
+merge_xml_backend_copies (void)
+{
+  GSList *l;
+  GSList *addresses;
+  char   *conffile;
+
+  conffile = g_strconcat (GCONF_CONFDIR, "/path", NULL);
+  addresses = gconf_load_source_path (conffile, NULL);
+  g_free (conffile);
+
+  if (!addresses)
+    /* FIXME: just do the homedir one */
+    return;
+
+  for (l = addresses; l; l = l->next)
+    {
+      merge_address (l->data);
+      g_free (l->data);
+    }
+
+  g_slist_free (addresses);
 }
Index: gconf/gconfd.c
===================================================================
RCS file: /cvs/gnome/gconf/gconf/gconfd.c,v
retrieving revision 1.126
diff -u -p -r1.126 gconfd.c
--- gconf/gconfd.c	3 Jun 2002 02:36:26 -0000	1.126
+++ gconf/gconfd.c	10 Jun 2002 03:40:19 -0000
@@ -475,21 +475,25 @@ main(int argc, char** argv)
   gchar* ior;
   int exit_code = 0;
   GError *err;
-  char *lock_dir;
+  char *lock_dir = NULL;
   char *gconfd_dir;
   int dev_null_fd;
   int write_byte_fd;
+  gboolean use_local_lock = FALSE;
 
   _gconf_init_i18n ();
   setlocale (LC_ALL, "");
   textdomain (GETTEXT_PACKAGE);
-  
+
   /* Now this is an argument parser */
   if (argc > 1)
     write_byte_fd = atoi (argv[1]);
   else
     write_byte_fd = -1;
-  
+
+  if (argc > 2 && !strcmp (argv [2], "--use-local-lock"))
+    use_local_lock = TRUE;
+
   /* This is so we don't prevent unmounting of devices. We divert
    * all messages to syslog
    */
@@ -514,6 +518,8 @@ main(int argc, char** argv)
     {
       gconf_log_debug_messages = TRUE;
     }
+
+  gconf_log (GCL_DEBUG, "argc %d argv %s %s %s\n", argc, argv [0], argv [1], argv [2]);
   
   umask (022);
   
@@ -589,7 +595,10 @@ main(int argc, char** argv)
   CORBA_free (ior);
 
   gconfd_dir = gconf_get_daemon_dir ();
-  lock_dir = gconf_get_lock_dir ();
+  if (use_local_lock)
+    lock_dir = gconf_get_local_lock_dir ();
+  if (!lock_dir)
+    lock_dir = gconf_get_lock_dir ();
   
   if (mkdir (gconfd_dir, 0700) < 0 && errno != EEXIST)
     gconf_log (GCL_WARNING, _("Failed to create %s: %s"),
@@ -597,6 +606,7 @@ main(int argc, char** argv)
   
   err = NULL;
 
+  gconf_log (GCL_DEBUG, "use_local_lock=%s lock_dir=%s\n", use_local_lock ? "(true)" : "(false)", lock_dir);
   daemon_lock = gconf_get_lock (lock_dir, &err);
 
   if (daemon_lock != NULL)
