summaryrefslogtreecommitdiff
path: root/daemon/errorgui.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/errorgui.c')
-rw-r--r--daemon/errorgui.c868
1 files changed, 0 insertions, 868 deletions
diff --git a/daemon/errorgui.c b/daemon/errorgui.c
deleted file mode 100644
index 51fe035c..00000000
--- a/daemon/errorgui.c
+++ /dev/null
@@ -1,868 +0,0 @@
-/* GDM - The GNOME Display Manager
- * Copyright (C) 1998, 1999, 2000 Martin K. Petersen <mkp@mkp.net>
- *
- * 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 2 of the License, 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* This is the gdm slave process. gdmslave runs the chooser, greeter
- * and the user's session scripts. */
-
-#include "config.h"
-
-#include <unistd.h>
-#include <syslog.h>
-#include <grp.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <pwd.h>
-#include <sys/types.h>
-#include <signal.h>
-
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkx.h>
-
-#include "gdm.h"
-#include "misc.h"
-#include "auth.h"
-#include "gdmconfig.h"
-#include "errorgui.h"
-
-/* set in the main function */
-extern char **stored_argv;
-extern int stored_argc;
-extern char *stored_path;
-
-static int screenx = 0;
-static int screeny = 0;
-static int screenwidth = 0;
-static int screenheight = 0;
-
-static gboolean inhibit_gtk_modules = FALSE;
-static gboolean inhibit_gtk_themes = FALSE;
-
-static void
-setup_cursor (GdkCursorType type)
-{
- GdkCursor *cursor = gdk_cursor_new (type);
- gdk_window_set_cursor (gdk_get_default_root_window (), cursor);
- gdk_cursor_unref (cursor);
-}
-
-static gboolean
-gdm_event (GSignalInvocationHint *ihint,
- guint n_param_values,
- const GValue *param_values,
- gpointer data)
-{
- GdkEvent *event;
-
- /* HAAAAAAAAAAAAAAAAACK */
- /* Since the user has not logged in yet and may have left/right
- * mouse buttons switched, we just translate every right mouse click
- * to a left mouse click */
- if (n_param_values != 2 ||
- !G_VALUE_HOLDS (&param_values[1], GDK_TYPE_EVENT))
- return FALSE;
-
- event = g_value_get_boxed (&param_values[1]);
- if ((event->type == GDK_BUTTON_PRESS ||
- event->type == GDK_2BUTTON_PRESS ||
- event->type == GDK_3BUTTON_PRESS ||
- event->type == GDK_BUTTON_RELEASE)
- && event->button.button == 3)
- event->button.button = 1;
-
- return TRUE;
-}
-
-static void
-get_screen_size (GdmDisplay *d)
-{
- if (d != NULL) {
- screenx = d->screenx;
- screeny = d->screeny;
- screenwidth = d->screenwidth;
- screenheight = d->screenheight;
- }
-
- if (screenwidth <= 0)
- screenwidth = gdk_screen_width ();
- if (screenheight <= 0)
- screenheight = gdk_screen_height ();
-}
-
-static void
-center_window (GtkWidget *window)
-{
- int w, h;
-
- /* sanity, should never happen */
- if (window == NULL)
- return;
-
- gtk_window_get_size (GTK_WINDOW (window), &w, &h);
-
- gtk_window_move (GTK_WINDOW (window),
- screenx +
- (screenwidth / 2) -
- (w / 2),
- screeny +
- (screenheight / 2) -
- (h / 2));
-}
-
-static void
-show_errors (GtkWidget *button, gpointer data)
-{
- GtkRequisition req;
- GtkWidget *textsw = data;
- GtkWidget *dlg = g_object_get_data (G_OBJECT (button), "dlg");
-
- if (GTK_TOGGLE_BUTTON (button)->active) {
- gtk_widget_show (textsw);
- } else {
- gtk_widget_hide (textsw);
- }
-
- /* keep window at the size request size */
- gtk_widget_size_request (dlg, &req);
- gtk_window_resize (GTK_WINDOW (dlg), req.width, req.height);
-}
-
-static GtkWidget *
-get_error_text_view (const char *details)
-{
- GtkWidget *sw;
- GtkWidget *tv;
- GtkTextBuffer *buf;
- GtkTextIter iter;
-
- tv = gtk_text_view_new ();
- buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
- gtk_text_view_set_editable (GTK_TEXT_VIEW (tv), FALSE);
- gtk_text_buffer_create_tag (buf, "foo",
- "editable", FALSE,
- "family", "monospace",
- NULL);
- gtk_text_buffer_get_iter_at_offset (buf, &iter, 0);
-
- gtk_text_buffer_insert_with_tags_by_name
- (buf, &iter,
- ve_sure_string (details), -1,
- "foo", NULL);
-
- sw = gtk_scrolled_window_new (NULL, NULL);
- if (gdk_screen_width () >= 800)
- gtk_widget_set_size_request (sw, 500, 150);
- else
- gtk_widget_set_size_request (sw, 200, 150);
-
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_ALWAYS);
-
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
- GTK_SHADOW_IN);
-
- gtk_container_add (GTK_CONTAINER (sw), tv);
- gtk_widget_show (tv);
-
- return sw;
-}
-
-static void
-setup_dialog (GdmDisplay *d, const char *name, int closefdexcept, gboolean set_gdm_ids, uid_t uid)
-{
- int argc = 1;
- char **argv;
- struct passwd *pw;
-
- closelog ();
-
- gdm_close_all_descriptors (0 /* from */, closefdexcept /* except */, -1 /* except2 */);
-
- /* No error checking here - if it's messed the best response
- * is to ignore & try to continue */
- gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */
- gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
- gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
-
- if (set_gdm_ids) {
- setgid (gdm_get_gdmgid ());
- initgroups (gdm_get_value_string (GDM_KEY_USER), gdm_get_gdmgid ());
- setuid (gdm_get_gdmuid ());
- pw = NULL;
- } else {
- pw = getpwuid (uid);
- }
-
- gdm_desetuid ();
-
- /* restore initial environment */
- gdm_restoreenv ();
-
- openlog ("gdm", LOG_PID, LOG_DAEMON);
-
- g_setenv ("LOGNAME", gdm_get_value_string (GDM_KEY_USER), TRUE);
- g_setenv ("USER", gdm_get_value_string (GDM_KEY_USER), TRUE);
- g_setenv ("USERNAME", gdm_get_value_string (GDM_KEY_USER), TRUE);
-
- g_setenv ("DISPLAY", d->name, TRUE);
- g_unsetenv ("XAUTHORITY");
-
- gdm_auth_set_local_auth (d);
-
- /* sanity env stuff */
- g_setenv ("SHELL", "/bin/sh", TRUE);
- /* set HOME to /, we don't need no stinking HOME anyway */
- if (pw == NULL ||
- ve_string_empty (pw->pw_dir))
- g_setenv ("HOME", ve_sure_string (gdm_get_value_string (GDM_KEY_SERV_AUTHDIR)), TRUE);
- else
- g_setenv ("HOME", pw->pw_dir, TRUE);
-
- argv = g_new0 (char *, 3);
- argv[0] = (char *)name;
- argc = 1;
-
- if ( ! inhibit_gtk_modules &&
- gdm_get_value_bool (GDM_KEY_ADD_GTK_MODULES) &&
- ! ve_string_empty (gdm_get_value_string (GDM_KEY_GTK_MODULES_LIST))) {
- argv[1] = g_strdup_printf ("--gtk-module=%s", gdm_get_value_string (GDM_KEY_GTK_MODULES_LIST));
- argc = 2;
- }
-
- if (inhibit_gtk_modules) {
- g_unsetenv ("GTK_MODULES");
- }
-
- gtk_init (&argc, &argv);
-
- if ( ! inhibit_gtk_themes) {
- const char *theme_name;
- gchar *gtkrc = gdm_get_value_string (GDM_KEY_GTKRC);
-
- if ( ! ve_string_empty (gtkrc) &&
- g_access (gtkrc, R_OK) == 0)
- gtk_rc_parse (gtkrc);
-
- theme_name = d->theme_name;
- if (ve_string_empty (theme_name))
- theme_name = gdm_get_value_string (GDM_KEY_GTK_THEME);
- if ( ! ve_string_empty (theme_name)) {
- gchar *theme_dir = gtk_rc_get_theme_dir ();
- char *theme = g_strdup_printf ("%s/%s/gtk-2.0/gtkrc", theme_dir, theme_name);
- g_free (theme_dir);
-
- if ( ! ve_string_empty (theme) &&
- g_access (theme, R_OK) == 0)
- gtk_rc_parse (theme);
-
- g_free (theme);
- }
- }
-
- get_screen_size (d);
-}
-
-static gboolean
-dialog_failed (int status)
-{
- if (WIFSIGNALED (status) &&
- (WTERMSIG (status) == SIGTERM ||
- WTERMSIG (status) == SIGINT ||
- WTERMSIG (status) == SIGQUIT ||
- WTERMSIG (status) == SIGHUP)) {
- return FALSE;
- } else if (WIFEXITED (status) &&
- WEXITSTATUS (status) == 0) {
- return FALSE;
- } else {
- gdm_error ("failsafe dialog failed (inhibitions: %d %d)",
- inhibit_gtk_modules, inhibit_gtk_themes);
- return TRUE;
- }
-}
-
-void
-gdm_error_box_full (GdmDisplay *d, GtkMessageType type, const char *error,
- const char *details_label, const char *details_file,
- uid_t uid, gid_t gid)
-{
- GdkDisplay *gdk_display;
- pid_t pid;
-
- pid = gdm_fork_extra ();
-
- if (pid == 0) {
- guint sid;
- GtkWidget *dlg;
- GtkWidget *button;
- char *loc;
- char *details;
-
- if (uid != 0) {
- gid_t groups[1] = { gid };
-
- /* if we for some reason fail here
- don't allow the file */
- if G_UNLIKELY (setgid (gid) != 0)
- details_file = NULL;
- if G_UNLIKELY (setgroups (1, groups) != 0)
- details_file = NULL;
- if G_UNLIKELY (setuid (uid) != 0)
- details_file = NULL;
-
- gdm_desetuid ();
- }
-
- /* First read the details if they exist */
- if (details_label != NULL && details_file != NULL) {
- FILE *fp;
- struct stat s;
- int r;
- gboolean valid_utf8 = TRUE;
- GString *gs = g_string_new (NULL);
-
- fp = NULL;
- VE_IGNORE_EINTR (r = g_lstat (details_file, &s));
- if (r == 0) {
- if (S_ISREG (s.st_mode)) {
- VE_IGNORE_EINTR (fp = fopen (details_file, "r"));
- } else {
- loc = gdm_locale_to_utf8 (_("%s not a regular file!\n"));
- g_string_printf (gs, loc, details_file);
- g_free (loc);
- }
- }
- if (fp != NULL) {
- char buf[256];
- int lines = 0;
- char *getsret;
- VE_IGNORE_EINTR (getsret = fgets (buf, sizeof (buf), fp));
- while (getsret != NULL) {
- if ( ! g_utf8_validate (buf, -1, NULL))
- valid_utf8 = FALSE;
- g_string_append (gs, buf);
- /* cap the lines at 500, that's already
- a possibility of 128k of data */
- if (lines++ > 500) {
- loc = gdm_locale_to_utf8 (_("\n... File too long to display ...\n"));
- g_string_append (gs, loc);
- g_free (loc);
- break;
- }
- VE_IGNORE_EINTR (getsret = fgets (buf, sizeof (buf), fp));
- }
- VE_IGNORE_EINTR (fclose (fp));
- } else {
- loc = gdm_locale_to_utf8 (_("%s could not be opened"));
- g_string_append_printf (gs, loc, details_file);
- g_free (loc);
- }
-
- details = g_string_free (gs, FALSE);
-
- if ( ! valid_utf8) {
- char *tmp = gdm_locale_to_utf8 (details);
- g_free (details);
- details = tmp;
- }
- } else {
- details = NULL;
- }
-
- setup_dialog (d, "gtk-error-box", -1, TRUE, uid);
-
- loc = gdm_locale_to_utf8 (error);
-
- dlg = gtk_message_dialog_new (NULL /* parent */,
- 0 /* flags */,
- type,
- GTK_BUTTONS_NONE,
- "%s",
- loc);
- g_free (loc);
- gtk_widget_set_events (dlg, GDK_ALL_EVENTS_MASK);
- gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE);
-
- if (details_label != NULL) {
- GtkWidget *text = get_error_text_view (details);
-
- loc = gdm_locale_to_utf8 (details_label);
- button = gtk_check_button_new_with_label (loc);
- g_free (loc);
-
- gtk_widget_show (button);
- g_object_set_data (G_OBJECT (button), "dlg", dlg);
- g_signal_connect (button, "toggled",
- G_CALLBACK (show_errors),
- text);
-
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
- button, FALSE, FALSE, 6);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
- text, FALSE, FALSE, 6);
-
- g_signal_connect_after (dlg, "size_allocate",
- G_CALLBACK (center_window),
- NULL);
- }
-
- button = gtk_dialog_add_button (GTK_DIALOG (dlg),
- GTK_STOCK_OK,
- GTK_RESPONSE_OK);
- sid = g_signal_lookup ("event",
- GTK_TYPE_WIDGET);
- g_signal_add_emission_hook (sid,
- 0 /* detail */,
- gdm_event,
- NULL /* data */,
- NULL /* destroy_notify */);
-
- center_window (dlg);
-
- gtk_widget_grab_focus (button);
-
- gtk_widget_show_now (dlg);
-
- gdk_display = gdk_display_get_default ();
-
- if (dlg->window != NULL) {
- gdk_error_trap_push ();
- XSetInputFocus (GDK_DISPLAY_XDISPLAY (gdk_display),
- GDK_WINDOW_XWINDOW (dlg->window),
- RevertToPointerRoot,
- CurrentTime);
- gdk_flush ();
- gdk_error_trap_pop ();
- }
-
- setup_cursor (GDK_LEFT_PTR);
-
- gtk_dialog_run (GTK_DIALOG (dlg));
-
- XSetInputFocus (GDK_DISPLAY_XDISPLAY (gdk_display),
- PointerRoot,
- RevertToPointerRoot,
- CurrentTime);
-
- _exit (0);
- } else if (pid > 0) {
- int status;
- gdm_wait_for_extra (&status);
-
- if (dialog_failed (status)) {
- if ( ! inhibit_gtk_themes) {
- /* on failure try again, this time without any themes
- which may be causing a crash */
- inhibit_gtk_themes = TRUE;
- gdm_error_box_full (d, type, error, details_label, details_file, uid, gid);
- inhibit_gtk_themes = FALSE;
- } else if ( ! inhibit_gtk_modules) {
- /* on failure try again, this time without any modules
- which may be causing a crash */
- inhibit_gtk_modules = TRUE;
- gdm_error_box_full (d, type, error, details_label, details_file, uid, gid);
- inhibit_gtk_modules = FALSE;
- }
- }
- } else {
- gdm_error (_("%s: Cannot fork to display error/info box"),
- "gdm_error_box");
- }
-}
-
-static void
-press_ok (GtkWidget *entry, gpointer data)
-{
- GtkWidget *dlg = data;
- gtk_dialog_response (GTK_DIALOG (dlg), GTK_RESPONSE_OK);
-}
-
-void
-gdm_error_box (GdmDisplay *d, GtkMessageType type, const char *error)
-{
- gdm_error_box_full (d, type, error, NULL, NULL,
- /* zero for uid/gid doesn't mean root, but
- it means to use the gdm user/group */
- 0, 0);
-}
-
-char *
-gdm_failsafe_question (GdmDisplay *d,
- const char *question,
- gboolean echo)
-{
- GdkDisplay *gdk_display;
- pid_t pid;
- int p[2];
-
- if G_UNLIKELY (pipe (p) < 0)
- return NULL;
-
- pid = gdm_fork_extra ();
- if (pid == 0) {
- guint sid;
- GtkWidget *dlg, *label, *entry;
- char *loc;
-
- setup_dialog (d, "gtk-failsafe-question", p[1], TRUE /* set_gdm_ids */, 0);
-
- loc = gdm_locale_to_utf8 (question);
-
- dlg = gtk_dialog_new_with_buttons (loc,
- NULL /* parent */,
- 0 /* flags */,
- GTK_STOCK_OK,
- GTK_RESPONSE_OK,
- NULL);
- gtk_widget_set_events (dlg, GDK_ALL_EVENTS_MASK);
- gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE);
- g_signal_connect (G_OBJECT (dlg), "delete_event",
- G_CALLBACK (gtk_true), NULL);
-
- label = gtk_label_new (loc);
- gtk_widget_show_all (label);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
- label, FALSE, FALSE, 0);
- entry = gtk_entry_new ();
- gtk_widget_show_all (entry);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox),
- entry, FALSE, FALSE, 0);
- if ( ! echo)
- gtk_entry_set_visibility (GTK_ENTRY (entry),
- FALSE /* visible */);
- g_signal_connect (G_OBJECT (entry), "activate",
- G_CALLBACK (press_ok), dlg);
-
- sid = g_signal_lookup ("event",
- GTK_TYPE_WIDGET);
- g_signal_add_emission_hook (sid,
- 0 /* detail */,
- gdm_event,
- NULL /* data */,
- NULL /* destroy_notify */);
-
- center_window (dlg);
-
- gtk_widget_show_now (dlg);
-
- gdk_display = gdk_display_get_default ();
-
- if (dlg->window != NULL) {
- gdk_error_trap_push ();
- XSetInputFocus (GDK_DISPLAY_XDISPLAY (gdk_display),
- GDK_WINDOW_XWINDOW (dlg->window),
- RevertToPointerRoot,
- CurrentTime);
- gdk_flush ();
- gdk_error_trap_pop ();
- }
-
- gtk_widget_grab_focus (entry);
-
- setup_cursor (GDK_LEFT_PTR);
-
- gtk_dialog_run (GTK_DIALOG (dlg));
-
- loc = gdm_locale_from_utf8 (ve_sure_string (gtk_entry_get_text (GTK_ENTRY (entry))));
-
- gdm_fdprintf (p[1], "%s", ve_sure_string (loc));
-
- XSetInputFocus (GDK_DISPLAY_XDISPLAY (gdk_display),
- PointerRoot,
- RevertToPointerRoot,
- CurrentTime);
-
- _exit (0);
- } else if (pid > 0) {
- int status;
- char buf[BUFSIZ];
- int bytes;
-
- VE_IGNORE_EINTR (close (p[1]));
-
- gdm_wait_for_extra (&status);
-
- if (dialog_failed (status)) {
- char *ret = NULL;
- VE_IGNORE_EINTR (close (p[0]));
- if ( ! inhibit_gtk_themes) {
- /* on failure try again, this time without any themes
- which may be causing a crash */
- inhibit_gtk_themes = TRUE;
- ret = gdm_failsafe_question (d, question, echo);
- inhibit_gtk_themes = FALSE;
- } else if ( ! inhibit_gtk_modules) {
- /* on failure try again, this time without any modules
- which may be causing a crash */
- inhibit_gtk_modules = TRUE;
- ret = gdm_failsafe_question (d, question, echo);
- inhibit_gtk_modules = FALSE;
- }
- return ret;
- }
-
- VE_IGNORE_EINTR (bytes = read (p[0], buf, BUFSIZ-1));
- if (bytes > 0) {
- VE_IGNORE_EINTR (close (p[0]));
- buf[bytes] = '\0';
- return g_strdup (buf);
- }
- VE_IGNORE_EINTR (close (p[0]));
- } else {
- gdm_error (_("%s: Cannot fork to display error/info box"),
- "gdm_failsafe_question");
- }
- return NULL;
-}
-
-gboolean
-gdm_failsafe_yesno (GdmDisplay *d,
- const char *question)
-{
- GdkDisplay *gdk_display;
- pid_t pid;
- int p[2];
-
- if G_UNLIKELY (pipe (p) < 0)
- return FALSE;
-
- pid = gdm_fork_extra ();
- if (pid == 0) {
- guint sid;
- GtkWidget *dlg;
- char *loc;
-
- setup_dialog (d, "gtk-failsafe-yesno", p[1], TRUE /* set_gdm_ids */, 0);
-
- loc = gdm_locale_to_utf8 (question);
-
- dlg = gtk_message_dialog_new (NULL /* parent */,
- 0 /* flags */,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_YES_NO,
- "%s",
- loc);
- gtk_widget_set_events (dlg, GDK_ALL_EVENTS_MASK);
- gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE);
-
- sid = g_signal_lookup ("event",
- GTK_TYPE_WIDGET);
- g_signal_add_emission_hook (sid,
- 0 /* detail */,
- gdm_event,
- NULL /* data */,
- NULL /* destroy_notify */);
-
- center_window (dlg);
-
- gtk_widget_show_now (dlg);
-
- gdk_display = gdk_display_get_default ();
-
- if (dlg->window != NULL) {
- gdk_error_trap_push ();
- XSetInputFocus (GDK_DISPLAY_XDISPLAY (gdk_display),
- GDK_WINDOW_XWINDOW (dlg->window),
- RevertToPointerRoot,
- CurrentTime);
- gdk_flush ();
- gdk_error_trap_pop ();
- }
-
- setup_cursor (GDK_LEFT_PTR);
-
- if (gtk_dialog_run (GTK_DIALOG (dlg)) == GTK_RESPONSE_YES)
- gdm_fdprintf (p[1], "yes\n");
- else
- gdm_fdprintf (p[1], "no\n");
-
- XSetInputFocus (GDK_DISPLAY_XDISPLAY (gdk_display),
- PointerRoot,
- RevertToPointerRoot,
- CurrentTime);
-
- _exit (0);
- } else if (pid > 0) {
- int status;
- char buf[BUFSIZ];
- int bytes;
-
- VE_IGNORE_EINTR (close (p[1]));
-
- gdm_wait_for_extra (&status);
-
- if (dialog_failed (status)) {
- gboolean ret = FALSE;
- VE_IGNORE_EINTR (close (p[0]));
- if ( ! inhibit_gtk_themes) {
- /* on failure try again, this time without any themes
- which may be causing a crash */
- inhibit_gtk_themes = TRUE;
- ret = gdm_failsafe_yesno (d, question);
- inhibit_gtk_themes = FALSE;
- } else if ( ! inhibit_gtk_modules) {
- /* on failure try again, this time without any modules
- which may be causing a crash */
- inhibit_gtk_modules = TRUE;
- ret = gdm_failsafe_yesno (d, question);
- inhibit_gtk_modules = FALSE;
- }
- return ret;
- }
-
- VE_IGNORE_EINTR (bytes = read (p[0], buf, BUFSIZ-1));
- if (bytes > 0) {
- VE_IGNORE_EINTR (close (p[0]));
- if (buf[0] == 'y')
- return TRUE;
- else
- return FALSE;
- }
- VE_IGNORE_EINTR (close (p[0]));
- } else {
- gdm_error (_("%s: Cannot fork to display error/info box"),
- "gdm_failsafe_yesno");
- }
- return FALSE;
-}
-
-int
-gdm_failsafe_ask_buttons (GdmDisplay *d,
- const char *question,
- char **but)
-{
- GdkDisplay *gdk_display;
- pid_t pid;
- int p[2];
-
- if G_UNLIKELY (pipe (p) < 0)
- return -1;
-
- pid = gdm_fork_extra ();
- if (pid == 0) {
- int i;
- guint sid;
- GtkWidget *dlg;
- char *loc;
-
- setup_dialog (d, "gtk-failsafe-ask-buttons", p[1], TRUE /* set_gdm_ids */, 0);
-
- loc = gdm_locale_to_utf8 (question);
-
- dlg = gtk_message_dialog_new (NULL /* parent */,
- 0 /* flags */,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_NONE,
- "%s",
- loc);
- g_free (loc);
- gtk_widget_set_events (dlg, GDK_ALL_EVENTS_MASK);
- for (i = 0; but[i] != NULL; i++) {
- loc = gdm_locale_to_utf8 (but[i]);
- gtk_dialog_add_button (GTK_DIALOG (dlg),
- loc, i);
- g_free (loc);
-
- }
- gtk_dialog_set_has_separator (GTK_DIALOG (dlg), FALSE);
-
- sid = g_signal_lookup ("event",
- GTK_TYPE_WIDGET);
- g_signal_add_emission_hook (sid,
- 0 /* detail */,
- gdm_event,
- NULL /* data */,
- NULL /* destroy_notify */);
-
- center_window (dlg);
-
- gtk_widget_show_now (dlg);
-
- gdk_display = gdk_display_get_default ();
-
- if (dlg->window != NULL) {
- gdk_error_trap_push ();
- XSetInputFocus (GDK_DISPLAY_XDISPLAY (gdk_display),
- GDK_WINDOW_XWINDOW (dlg->window),
- RevertToPointerRoot,
- CurrentTime);
- gdk_flush ();
- gdk_error_trap_pop ();
- }
-
- setup_cursor (GDK_LEFT_PTR);
-
- i = gtk_dialog_run (GTK_DIALOG (dlg));
- gdm_fdprintf (p[1], "%d\n", i);
-
- XSetInputFocus (GDK_DISPLAY_XDISPLAY (gdk_display),
- PointerRoot,
- RevertToPointerRoot,
- CurrentTime);
-
- _exit (0);
- } else if (pid > 0) {
- int status;
- char buf[BUFSIZ];
- int bytes;
-
- VE_IGNORE_EINTR (close (p[1]));
-
- gdm_wait_for_extra (&status);
-
- if (dialog_failed (status)) {
- int ret = -1;
- VE_IGNORE_EINTR (close (p[0]));
- if ( ! inhibit_gtk_themes) {
- /* on failure try again, this time without any themes
- which may be causing a crash */
- inhibit_gtk_themes = TRUE;
- ret = gdm_failsafe_ask_buttons (d, question, but);
- inhibit_gtk_themes = FALSE;
- } else if ( ! inhibit_gtk_modules) {
- /* on failure try again, this time without any modules
- which may be causing a crash */
- inhibit_gtk_modules = TRUE;
- ret = gdm_failsafe_ask_buttons (d, question, but);
- inhibit_gtk_modules = FALSE;
- }
- return ret;
- }
-
- VE_IGNORE_EINTR (bytes = read (p[0], buf, BUFSIZ-1));
- if (bytes > 0) {
- int i;
- VE_IGNORE_EINTR (close (p[0]));
- buf[bytes] = '\0';
- if (sscanf (buf, "%d", &i) == 1)
- return i;
- else
- return -1;
- }
- VE_IGNORE_EINTR (close (p[0]));
- } else {
- gdm_error (_("%s: Cannot fork to display error/info box"),
- "gdm_failsafe_ask_buttons");
- }
- return -1;
-}
-
-/* EOF */