Index: backends/xml-backend.c =================================================================== RCS file: /cvs/gnome/gconf/backends/xml-backend.c,v retrieving revision 1.81 diff -u -p -u -r1.81 xml-backend.c --- GConf-1.2.1/backends/xml-backend.c 21 Mar 2002 23:55:06 -0000 1.81 +++ GConf-1.2.1/backends/xml-backend.c 21 Aug 2002 12:47:17 -0000 @@ -206,6 +206,8 @@ static void destroy_source (GC static void clear_cache (GConfSource* source); +static void blow_away_locks (const char *address); + static GConfBackendVTable xml_vtable = { x_shutdown, resolve_address, @@ -224,7 +226,8 @@ static GConfBackendVTable xml_vtable = { set_schema, sync_all, destroy_source, - clear_cache + clear_cache, + blow_away_locks }; static void @@ -267,13 +270,48 @@ writable (GConfSource* source, return TRUE; } +static char* +get_dir_from_address (const char *address, + GError **err) +{ + char *root_dir; + int len; + + root_dir = gconf_address_resource (address); + + if (root_dir == NULL) + { + gconf_set_error (err, GCONF_ERROR_BAD_ADDRESS, + _("Couldn't find the XML root directory in the address `%s'"), + address); + return NULL; + } + + /* Chop trailing '/' to canonicalize */ + len = strlen (root_dir); + + if (root_dir[len-1] == '/') + root_dir[len-1] = '\0'; + + return root_dir; +} + +static char* +get_lock_dir_from_root_dir (const char *root_dir) +{ + gchar* lockdir; + + lockdir = gconf_concat_dir_and_key (root_dir, "%gconf-xml-backend.lock"); + + return lockdir; +} + static GConfSource* resolve_address (const gchar* address, GError** err) { gchar* root_dir; XMLSource* xsource; GConfSource* source; - guint len; gint flags = 0; GConfLock* lock = NULL; guint dir_mode = 0700; @@ -281,20 +319,10 @@ resolve_address (const gchar* address, G gchar** address_flags; gchar** iter; gboolean force_readonly; - - root_dir = gconf_address_resource(address); + root_dir = get_dir_from_address (address, err); if (root_dir == NULL) - { - gconf_set_error(err, GCONF_ERROR_BAD_ADDRESS, _("Couldn't find the XML root directory in the address `%s'"), address); - return NULL; - } - - /* Chop trailing '/' to canonicalize */ - len = strlen(root_dir); - - if (root_dir[len-1] == '/') - root_dir[len-1] = '\0'; + return NULL; if (mkdir(root_dir, dir_mode) < 0) { @@ -374,7 +402,7 @@ resolve_address (const gchar* address, G { gchar* lockdir; - lockdir = gconf_concat_dir_and_key(root_dir, "%gconf-xml-backend.lock"); + lockdir = get_lock_dir_from_root_dir (root_dir); lock = gconf_get_lock(lockdir, err); @@ -712,6 +740,58 @@ clear_cache (GConfSource* source) /* clean all entries older than 0 seconds */ cache_clean(xs->cache, 0); +} + +static void +blow_away_locks (const char *address) +{ + char *root_dir; + char *lock_dir; + DIR *dp; + struct dirent *dent; + + root_dir = get_dir_from_address (address, NULL); + if (root_dir == NULL) + return; + + lock_dir = get_lock_dir_from_root_dir (root_dir); + + dp = opendir (lock_dir); + + if (dp == NULL) + { + g_printerr (_("Could not open lock directory for %s to remove locks: %s\n"), + address, g_strerror (errno)); + goto out; + } + + while ((dent = readdir (dp)) != NULL) + { + char *path; + + /* ignore ., .. (and any ..foo as an intentional who-cares bug) */ + if (dent->d_name[0] == '.' && + (dent->d_name[1] == '\0' || dent->d_name[1] == '.')) + continue; + + path = g_build_filename (lock_dir, dent->d_name, NULL); + + if (unlink (path) < 0) + { + g_printerr (_("Could not remove file %s: %s\n"), + path, g_strerror (errno)); + } + + g_free (path); + } + + out: + + if (dp) + closedir (dp); + + g_free (root_dir); + g_free (lock_dir); } /* Initializer */ Index: gconf/gconf-backend.c =================================================================== RCS file: /cvs/gnome/gconf/gconf/gconf-backend.c,v retrieving revision 1.21 diff -u -p -u -r1.21 gconf-backend.c --- GConf-1.2.1/gconf/gconf-backend.c 4 Dec 2001 22:17:09 -0000 1.21 +++ GConf-1.2.1/gconf/gconf-backend.c 21 Aug 2002 12:47:17 -0000 @@ -353,5 +353,15 @@ gconf_backend_resolve_address (GConfBack return retval; } +void +gconf_blow_away_locks (const gchar* address) +{ + GConfBackend* backend; + backend = gconf_get_backend (address, NULL); + if (backend != NULL) + { + (*backend->vtable->blow_away_locks) (address); + } +} Index: gconf/gconf-backend.h =================================================================== RCS file: /cvs/gnome/gconf/gconf/gconf-backend.h,v retrieving revision 1.29 diff -u -p -u -r1.29 gconf-backend.h --- GConf-1.2.1/gconf/gconf-backend.h 13 Jul 2001 22:07:37 -0000 1.29 +++ GConf-1.2.1/gconf/gconf-backend.h 21 Aug 2002 12:47:17 -0000 @@ -127,6 +127,9 @@ struct _GConfBackendVTable { /* This is basically used by the test suite */ void (* clear_cache) (GConfSource* source); + + /* used by gconf-sanity-check */ + void (* blow_away_locks) (const char *address); }; struct _GConfBackend { @@ -161,6 +164,8 @@ void gconf_backend_unref(GConfB GConfSource* gconf_backend_resolve_address (GConfBackend* backend, const gchar* address, GError** err); + +void gconf_blow_away_locks (const gchar* address); #endif Index: gconf/gconf-internals.c =================================================================== RCS file: /cvs/gnome/gconf/gconf/gconf-internals.c,v retrieving revision 1.114 diff -u -p -u -r1.114 gconf-internals.c --- GConf-1.2.1/gconf/gconf-internals.c 4 Aug 2002 17:44:16 -0000 1.114 +++ GConf-1.2.1/gconf/gconf-internals.c 21 Aug 2002 12:47:18 -0000 @@ -2701,6 +2701,24 @@ gconf_get_current_lock_holder (const gc return server; } +void +gconf_daemon_blow_away_locks (void) +{ + char *lock_directory; + char *iorfile; + + lock_directory = gconf_get_lock_dir (); + + iorfile = g_strconcat (lock_directory, "/ior", NULL); + + if (unlink (iorfile) < 0) + g_printerr (_("Failed to unlink lock file %s: %s\n"), + iorfile, g_strerror (errno)); + + g_free (iorfile); + g_free (lock_directory); +} + static CORBA_ORB gconf_orb = CORBA_OBJECT_NIL; CORBA_ORB Index: gconf/gconf-internals.h =================================================================== RCS file: /cvs/gnome/gconf/gconf/gconf-internals.h,v retrieving revision 1.74 diff -u -p -u -r1.74 gconf-internals.h --- GConf-1.2.1/gconf/gconf-internals.h 3 Jun 2002 02:36:26 -0000 1.74 +++ GConf-1.2.1/gconf/gconf-internals.h 21 Aug 2002 12:47:18 -0000 @@ -190,6 +190,8 @@ GConfLock* gconf_get_lock_or_current_hol ConfigServer gconf_get_current_lock_holder (const gchar *lock_directory, GString *failure_log); +void gconf_daemon_blow_away_locks (void); + GError* gconf_error_new (GConfError en, const gchar* format, ...) G_GNUC_PRINTF (2, 3); Index: gconf/gconf-sanity-check.c =================================================================== RCS file: /cvs/gnome/gconf/gconf/gconf-sanity-check.c,v retrieving revision 1.4 diff -u -p -u -r1.4 gconf-sanity-check.c --- GConf-1.2.1/gconf/gconf-sanity-check.c 21 Mar 2002 23:55:09 -0000 1.4 +++ GConf-1.2.1/gconf/gconf-sanity-check.c 21 Aug 2002 12:47:18 -0000 @@ -53,8 +53,9 @@ struct poptOption options[] = { static gboolean ensure_gtk (void); static void show_fatal_error_dialog (const char *format, ...) G_GNUC_PRINTF (1, 2); +static gboolean offer_delete_locks (void); static gboolean check_file_locking (void); -static gboolean check_gconf (void); +static gboolean check_gconf (gboolean display_errors); int main (int argc, char** argv) @@ -83,8 +84,14 @@ main (int argc, char** argv) if (!check_file_locking ()) return 1; - if (!check_gconf ()) - return 1; + if (!check_gconf (FALSE)) + { + if (!offer_delete_locks ()) + return 1; + + if (!check_gconf (TRUE)) + return 1; + } return 0; } @@ -164,7 +171,7 @@ check_file_locking (void) } static gboolean -check_gconf (void) +check_gconf (gboolean display_errors) { GSList* addresses; GSList* tmp; @@ -192,11 +199,12 @@ check_gconf (void) if (addresses == NULL) { - show_fatal_error_dialog (_("Please contact your system administrator to resolve the following problem:\n" - "No configuration sources in the configuration file \"%s\"; this means that preferences and other settings can't be saved. %s%s"), - conffile, - error ? _("Error reading the file: ") : "", - error ? error->message : ""); + if (display_errors) + show_fatal_error_dialog (_("Please contact your system administrator to resolve the following problem:\n" + "No configuration sources in the configuration file \"%s\"; this means that preferences and other settings can't be saved. %s%s"), + conffile, + error ? _("Error reading the file: ") : "", + error ? error->message : ""); if (error) g_error_free (error); @@ -217,9 +225,10 @@ check_gconf (void) if (error) { - show_fatal_error_dialog (_("Please contact your system administrator to resolve the following problem:\n" - "Could not resolve the address \"%s\" in the configuration file \"%s\": %s"), - address, conffile, error->message); + if (display_errors) + show_fatal_error_dialog (_("Please contact your system administrator to resolve the following problem:\n" + "Could not resolve the address \"%s\" in the configuration file \"%s\": %s"), + address, conffile, error->message); g_error_free (error); goto out; } @@ -269,6 +278,97 @@ show_fatal_error_dialog (const char *for gtk_dialog_run (GTK_DIALOG (d)); gtk_widget_destroy (d); +} + +static gboolean +offer_delete_locks (void) +{ + gboolean delete_locks; + const char *question; + + delete_locks = FALSE; + question = _("Your preferences files are currently in use. " + "(If you are logged in to this same account from " + "another computer, the other login session is probably using " + "your preferences files.) " + "You can choose to continue, but be aware that other login " + "sessions may become temporarily confused. " + "If you are not logged in elsewhere, it should be harmless to " + "continue."); + + if (ensure_gtk ()) + { + GtkDialog *d; + int response; + + d = gtk_message_dialog_new (NULL, 0, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_NONE, + "%s", question); + + gtk_dialog_add_buttons (GTK_DIALOG (d), + GTK_STOCK_CANCEL, + GTK_RESPONSE_REJECT, + _("Continue"), + GTK_RESPONSE_ACCEPT, + NULL); + + response = gtk_dialog_run (GTK_DIALOG (d)); + + gtk_widget_destroy (d); + + if (response == GTK_RESPONSE_ACCEPT) + delete_locks = TRUE; + } + else + { + g_print (_("%s Continue (y/n)?"), question); + switch (getchar ()) + { + case 'y': + case 'Y': + delete_locks = TRUE; + break; + } + } + + if (delete_locks) + { + GSList* addresses; + GSList* tmp; + char *conffile; + + conffile = g_strconcat (GCONF_CONFDIR, "/path", NULL); + + addresses = gconf_load_source_path (conffile, NULL); + + g_free (conffile); + + if (addresses == NULL) + g_printerr ("Failed to load addresses to delete locks\n"); + + tmp = addresses; + while (tmp != NULL) + { + const char *address; + + address = tmp->data; + + gconf_blow_away_locks (address); + + g_free (tmp->data); + + tmp = tmp->next; + } + + g_slist_free (addresses); + + gconf_daemon_blow_away_locks (); + + return TRUE; + } + + return FALSE; } /* this is because setting up gtk is kind of slow, no point doing it