Index: gui/gdmuser.c
===================================================================
--- gui/gdmuser.c	(revision 4731)
+++ gui/gdmuser.c	(working copy)
@@ -35,6 +35,7 @@
 #include "gdmconfig.h"
 
 #include "gdm-common.h"
+#include "gdm-socket-protocol.h"
 #include "gdm-daemon-config-keys.h"
 
 static time_t time_started;
Index: gui/gdmwm.c
===================================================================
--- gui/gdmwm.c	(revision 4731)
+++ gui/gdmwm.c	(working copy)
@@ -20,6 +20,11 @@
 
 #include "config.h"
 
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pwd.h>
+
 #include <X11/X.h>
 #include <X11/Xlib.h>
 #include <X11/Xatom.h>
@@ -28,8 +33,6 @@
 #elif HAVE_SOLARIS_XINERAMA
 #include <X11/extensions/xinerama.h>
 #endif
-#include <pwd.h>
-#include <unistd.h>
 
 #include "gdmwm.h"
 #include "gdm.h"
Index: gui/gdmdynamic.c
===================================================================
--- gui/gdmdynamic.c	(revision 4731)
+++ gui/gdmdynamic.c	(working copy)
@@ -42,6 +42,8 @@
 #include "gdmconfig.h"
 
 #include "gdm-common.h"
+#include "gdm-log.h"
+#include "gdm-socket-protocol.h"
 #include "gdm-daemon-config-keys.h"
 
 static char *myname = NULL;  /* name of this program */
@@ -172,7 +174,9 @@ main (int argc, char *argv[])
         }
     }
 
-    gdmcomm_set_debug (verbose);
+    gdm_log_init ();
+    gdm_log_set_debug (verbose);
+
     /*
      * If verbose is not on, then set quiet errors to TRUE since
      * errors are expected and managed by gdmdynamic, so we want
Index: gui/gdmlogin.c
===================================================================
--- gui/gdmlogin.c	(revision 4731)
+++ gui/gdmlogin.c	(working copy)
@@ -24,7 +24,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <syslog.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <ctype.h>
@@ -62,6 +61,7 @@
 #include "misc.h"
 
 #include "gdm-common.h"
+#include "gdm-socket-protocol.h"
 #include "gdm-daemon-config-keys.h"
 
 /* set the DOING_GDM_DEVELOPMENT env variable if you aren't running
@@ -692,8 +692,6 @@ gdm_login_restart_handler (void)
 	    _("Are you sure you want to restart the computer?"), "",
 	    _("_Restart"), NULL, TRUE) == GTK_RESPONSE_YES) {
 
-		closelog ();
-
 		gdm_kill_thingies ();
 		_exit (DISPLAY_REBOOT);
 	}
@@ -723,8 +721,6 @@ gdm_login_halt_handler (void)
 	    _("Are you sure you want to Shut Down the computer?"), "",
 	    _("Shut _Down"), NULL, TRUE) == GTK_RESPONSE_YES) {
 
-		closelog ();
-
 		gdm_kill_thingies ();
 		_exit (DISPLAY_HALT);
 	}
@@ -733,8 +729,6 @@ gdm_login_halt_handler (void)
 static void
 gdm_login_use_chooser_handler (void)
 {
-	closelog ();
-
 	gdm_kill_thingies ();
 	_exit (DISPLAY_RUN_CHOOSER);
 }
@@ -3091,8 +3085,6 @@ gdm_read_config (void)
 	/* Read config data in bulk */
 	gdmcomm_comm_bulk_start ();
 
-	gdmcomm_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG));
-
 	/*
 	 * Read all the keys at once and close sockets connection so we do
 	 * not have to keep the socket open. 
@@ -3199,9 +3191,6 @@ gdm_reread_config (int sig, gpointer dat
 	/* Read config data in bulk */
 	gdmcomm_comm_bulk_start ();
 
-	if (gdm_config_reload_bool (GDM_KEY_DEBUG))
-		gdmcomm_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG));
-
 	/* reparse config stuff here.  At least the ones we care about */
 	/*
 	 * We don't want to reload GDM_KEY_POSITION_X, GDM_KEY_POSITION_Y
@@ -3404,8 +3393,6 @@ main (int argc, char *argv[])
     if (g_getenv ("DOING_GDM_DEVELOPMENT") != NULL)
 	    DOING_GDM_DEVELOPMENT = TRUE;
 
-    gdm_common_openlog ("gdmlogin", LOG_PID, LOG_DAEMON);
-
     bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
     bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
     textdomain (GETTEXT_PACKAGE);
@@ -3425,6 +3412,9 @@ main (int argc, char *argv[])
     if (ve_string_empty (g_getenv ("GDM_IS_LOCAL")))
 	disable_sys_config_chooser_buttons = TRUE;
 
+    gdm_common_log_init ();
+    gdm_common_log_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG));
+
     /* Read all configuration at once, so the values get cached */
     gdm_read_config ();
 
Index: gui/gdmsession.c
===================================================================
--- gui/gdmsession.c	(revision 4731)
+++ gui/gdmsession.c	(working copy)
@@ -23,7 +23,9 @@
 
 #include "config.h"
 
+#include <stdlib.h>
 #include <unistd.h>
+#include <string.h>
 #include <dirent.h>
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
Index: gui/gdmXnestchooser.c
===================================================================
--- gui/gdmXnestchooser.c	(revision 4731)
+++ gui/gdmXnestchooser.c	(working copy)
@@ -35,6 +35,8 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <errno.h>
+
+#include <X11/Xlib.h>
 #include <X11/Xauth.h>
 
 #include "gdm.h"
Index: gui/greeter/greeter_item_customlist.c
===================================================================
--- gui/greeter/greeter_item_customlist.c	(revision 4731)
+++ gui/greeter/greeter_item_customlist.c	(working copy)
@@ -18,6 +18,8 @@
 
 #include "config.h"
 
+#include <stdlib.h>
+#include <string.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 
Index: gui/greeter/greeter_parser.c
===================================================================
--- gui/greeter/greeter_parser.c	(revision 4731)
+++ gui/greeter/greeter_parser.c	(working copy)
@@ -25,7 +25,6 @@
 #include <librsvg/rsvg.h>
 #include <math.h>
 #include <locale.h>
-#include <syslog.h>
 
 #include <glib/gi18n.h>
 #include <gdk/gdkx.h>
@@ -607,7 +606,7 @@ parse_show (xmlNodePtr       node,
   prop = xmlGetProp (node,(const xmlChar *) "min-screen-width");
   if (prop != NULL)
     {
-          syslog (LOG_ERR, "minimum width is %d", info->minimum_required_screen_height);
+          g_warning ("minimum width is %d", info->minimum_required_screen_height);
 	  info->minimum_required_screen_width = atoi ((char *) prop);
 	  xmlFree (prop);
     }
@@ -616,7 +615,7 @@ parse_show (xmlNodePtr       node,
   if (prop != NULL)
     {
 	  info->minimum_required_screen_height = atoi ((char *) prop);
-          syslog (LOG_ERR, "minimum height is %d", info->minimum_required_screen_height);
+          g_warning ("minimum height is %d", info->minimum_required_screen_height);
 	  xmlFree (prop);
     }
 
Index: gui/greeter/greeter_item_ulist.c
===================================================================
--- gui/greeter/greeter_item_ulist.c	(revision 4731)
+++ gui/greeter/greeter_item_ulist.c	(working copy)
@@ -40,6 +40,7 @@
 #include "gdmuser.h"
 
 #include "gdm-common.h"
+#include "gdm-socket-protocol.h"
 #include "gdm-daemon-config-keys.h"
 
 #include "greeter.h"
Index: gui/greeter/greeter_item_timed.c
===================================================================
--- gui/greeter/greeter_item_timed.c	(revision 4731)
+++ gui/greeter/greeter_item_timed.c	(working copy)
@@ -25,6 +25,7 @@
 #include "gdmconfig.h"
 
 #include "gdm-common.h"
+#include "gdm-socket-protocol.h"
 #include "gdm-daemon-config-keys.h"
 
 #include "greeter_parser.h"
Index: gui/greeter/greeter_system.c
===================================================================
--- gui/greeter/greeter_system.c	(revision 4731)
+++ gui/greeter/greeter_system.c	(working copy)
@@ -19,7 +19,6 @@
 #include "config.h"
 
 #include <unistd.h>
-#include <syslog.h>
 
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
@@ -31,6 +30,7 @@
 #include "misc.h"
 
 #include "gdm-common.h"
+#include "gdm-socket-protocol.h"
 #include "gdm-daemon-config-keys.h"
 
 #include "greeter.h"
@@ -78,8 +78,6 @@ query_greeter_restart_handler (void)
 {
 	if (gdm_wm_warn_dialog (_("Are you sure you want to restart the computer?"), "",
 			     _("_Restart"), NULL, TRUE) == GTK_RESPONSE_YES) {
-		closelog ();
-		
 		_exit (DISPLAY_REBOOT);
 	}
 }
@@ -104,8 +102,6 @@ query_greeter_halt_handler (void)
 {
 	if (gdm_wm_warn_dialog (_("Are you sure you want to Shut Down the computer?"), "",
 			     _("Shut _Down"), NULL, TRUE) == GTK_RESPONSE_YES) {
-		closelog ();
-
 		_exit (DISPLAY_HALT);
 	}
 }
@@ -124,7 +120,6 @@ query_greeter_suspend_handler (void)
 static void
 greeter_restart_handler (void)
 {
-	closelog ();
 	_exit (DISPLAY_REBOOT);
 }
 
@@ -138,7 +133,6 @@ greeter_custom_cmd_handler (gint cmd_id)
 static void
 greeter_halt_handler (void)
 {
-	closelog ();
 	_exit (DISPLAY_HALT);
 }
 
@@ -168,7 +162,6 @@ greeter_config_handler (void)
 static void
 greeter_chooser_handler (void)
 {
-	closelog ();
 	_exit (DISPLAY_RUN_CHOOSER);
 }
 
Index: gui/greeter/greeter_item_pam.c
===================================================================
--- gui/greeter/greeter_item_pam.c	(revision 4731)
+++ gui/greeter/greeter_item_pam.c	(working copy)
@@ -24,6 +24,7 @@
 #include <gdk/gdkkeysyms.h>
 
 #include "gdm-common.h"
+#include "gdm-socket-protocol.h"
 
 #include "greeter.h"
 #include "greeter_item.h"
Index: gui/greeter/greeter.c
===================================================================
--- gui/greeter/greeter.c	(revision 4731)
+++ gui/greeter/greeter.c	(working copy)
@@ -23,7 +23,6 @@
 #include <string.h>
 #include <unistd.h>
 #include <signal.h>
-#include <syslog.h>
 #include <errno.h>
 
 #if HAVE_PAM
@@ -39,6 +38,7 @@
 #include <libgnomecanvas/libgnomecanvas.h>
 
 #include "gdm-common.h"
+#include "gdm-socket-protocol.h"
 #include "gdm-daemon-config-keys.h"
 
 #include "gdm.h"
@@ -823,8 +823,6 @@ gdm_read_config (void)
 	/* Read config data in bulk */
 	gdmcomm_comm_bulk_start ();
 
-	gdmcomm_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG));
-
 	/*
 	 * Read all the keys at once and close sockets connection so we do
 	 * not have to keep the socket open.
@@ -916,9 +914,6 @@ greeter_reread_config (int sig, gpointer
 	/* Read config data in bulk */
 	gdmcomm_comm_bulk_start ();
 
-	if (gdm_config_reload_bool (GDM_KEY_DEBUG))
-		gdmcomm_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG));
-
 	/* FIXME: The following is evil, we should update on the fly rather
 	 * then just restarting */
 	/* Also we may not need to check ALL those keys but just a few */
@@ -1195,8 +1190,6 @@ main (int argc, char *argv[])
   if (g_getenv ("DOING_GDM_DEVELOPMENT") != NULL)
     DOING_GDM_DEVELOPMENT = TRUE;
 
-  gdm_common_openlog ("gdmgreeter", LOG_PID, LOG_DAEMON);
-
   bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
   bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
   textdomain (GETTEXT_PACKAGE);
@@ -1217,11 +1210,14 @@ main (int argc, char *argv[])
   if (! DOING_GDM_DEVELOPMENT) {
        gdm_common_atspi_launch ();
   }
-  
+
   gtk_init (&argc, &argv);
 
   gdm_common_setup_cursor (GDK_WATCH);
 
+  gdm_common_log_init ();
+  gdm_common_log_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG));
+
   /* Read all configuration at once, so the values get cached */
   gdm_read_config ();
 
Index: gui/gdmcommon.c
===================================================================
--- gui/gdmcommon.c	(revision 4731)
+++ gui/gdmcommon.c	(working copy)
@@ -27,7 +27,6 @@
 #include <unistd.h>
 #include <locale.h>
 #include <string.h>
-#include <syslog.h>
 #include <time.h>
 #include <sys/utsname.h>
 #include <sys/types.h>
@@ -43,149 +42,157 @@
 #include "gdmconfig.h"
 
 #include "gdm-common.h"
+#include "gdm-log.h"
+#include "gdm-socket-protocol.h"
 #include "gdm-daemon-config-keys.h"
 
 gint gdm_timed_delay = 0;
 static Atom AT_SPI_IOR;
 
 /*
- * Some slaves want to send output to syslog and others (such as 
- * gdmflexiserver and gdmdynamic send error messages to stdout.  
+ * Some slaves want to send output to syslog and others (such as
+ * gdmflexiserver and gdmdynamic send error messages to stdout.
  * Calling gdm_common_openlog to open the syslog sets the
- * using_syslog flag so that calls to gdm_common_fail, 
- * gdm_common_info, gdm_common_error, and gdm_common_debug sends 
+ * using_syslog flag so that calls to gdm_common_fail,
+ * gdm_common_info, gdm_common_error, and gdm_common_debug sends
  * output to the syslog if the syslog has been opened, otherwise
  * send to stdout.
  */
 static gboolean using_syslog = FALSE;
 
 void
-gdm_common_openlog (const char *ident, int logopt, int facility)
+gdm_common_log_init (void)
 {
-   openlog (ident, logopt, facility);
-   using_syslog = TRUE;
+	gdm_log_init ();
+
+	using_syslog = TRUE;
+}
+
+void
+gdm_common_log_set_debug (gboolean enable)
+{
+	gdm_log_set_debug (enable);
 }
 
 void
 gdm_common_fail_exit (const gchar *format, ...)
 {
-    va_list args;
-    gchar *s;
+	va_list args;
+	gchar *s;
 
-    if (!format) {
-	_exit (EXIT_FAILURE);
-    }
+	if (!format) {
+		_exit (EXIT_FAILURE);
+	}
 
-    va_start (args, format);
-    s = g_strdup_vprintf (format, args);
-    va_end (args);
-    
-    if (using_syslog) {
-        syslog (LOG_ERR, "%s", s);
-        closelog ();
-    } else
-        g_printf ("%s\n", s);
+	va_start (args, format);
+	s = g_strdup_vprintf (format, args);
+	va_end (args);
 
-    g_free (s);
+	if (using_syslog) {
+		g_critical ("%s", s);
+	} else {
+		g_printf ("%s\n", s);
+	}
+
+	g_free (s);
 
-    _exit (EXIT_FAILURE);
+	_exit (EXIT_FAILURE);
 }
 
 void
 gdm_common_fail_greeter (const gchar *format, ...)
 {
-    va_list args;
-    gchar *s;
+	va_list args;
+	gchar *s;
 
-    if (!format) {
-	_exit (DISPLAY_GREETERFAILED);
-    }
+	if (!format) {
+		_exit (DISPLAY_GREETERFAILED);
+	}
 
-    va_start (args, format);
-    s = g_strdup_vprintf (format, args);
-    va_end (args);
-    
-    if (using_syslog) {
-        syslog (LOG_ERR, "%s", s);
-        closelog ();
-    } else
-        g_printf ("%s\n", s);
+	va_start (args, format);
+	s = g_strdup_vprintf (format, args);
+	va_end (args);
 
-    g_free (s);
+	if (using_syslog) {
+		g_critical ("%s", s);
+	} else
+		g_printf ("%s\n", s);
+
+	g_free (s);
 
-    _exit (DISPLAY_GREETERFAILED);
+	_exit (DISPLAY_GREETERFAILED);
 }
 
 void
 gdm_common_info (const gchar *format, ...)
 {
-    va_list args;
-    gchar *s;
+	va_list args;
+	gchar *s;
+
+	va_start (args, format);
+	s = g_strdup_vprintf (format, args);
+	va_end (args);
+
+	if (using_syslog) {
+		g_message ("%s", s);
+	} else {
+		g_printf ("%s\n", s);
+	}
 
-    va_start (args, format);
-    s = g_strdup_vprintf (format, args);
-    va_end (args);
-
-    if (using_syslog)
-        syslog (LOG_INFO, "%s", s);
-    else
-        g_printf ("%s\n", s);
- 
-    g_free (s);
+	g_free (s);
 }
 
 void
 gdm_common_error (const gchar *format, ...)
 {
-    va_list args;
-    gchar *s;
+	va_list args;
+	gchar *s;
+
+	va_start (args, format);
+	s = g_strdup_vprintf (format, args);
+	va_end (args);
+
+	if (using_syslog) {
+		g_critical ("%s", s);
+	} else {
+		g_printf ("%s\n", s);
+	}
 
-    va_start (args, format);
-    s = g_strdup_vprintf (format, args);
-    va_end (args);
-
-    if (using_syslog)
-        syslog (LOG_ERR, "%s", s);
-    else
-        g_printf ("%s\n", s);
-    
-    g_free (s);
+	g_free (s);
 }
 
 void
 gdm_common_warning (const gchar *format, ...)
 {
-    va_list args;
-    gchar *s;
+	va_list args;
+	gchar *s;
+
+	va_start (args, format);
+	s = g_strdup_vprintf (format, args);
+	va_end (args);
 
-    va_start (args, format);
-    s = g_strdup_vprintf (format, args);
-    va_end (args);
-
-    if (using_syslog)
-        syslog (LOG_WARNING, "%s", s);
-    else
-        g_printf ("%s\n", s);
-    
-    g_free (s);
+	if (using_syslog) {
+		g_warning ("%s", s);
+	} else {
+		g_printf ("%s\n", s);
+	}
+
+	g_free (s);
 }
 
 void
 gdm_common_debug (const gchar *format, ...)
 {
-    va_list args;
-    gchar *s;
+	va_list args;
+	gchar *s;
+
+	va_start (args, format);
+	s = g_strdup_vprintf (format, args);
+	va_end (args);
 
-    if G_LIKELY (! gdm_config_get_bool (GDM_KEY_DEBUG))
-        return;
+	g_debug ("%s", s);
 
-    va_start (args, format);
-    s = g_strdup_vprintf (format, args);
-    va_end (args);
-
-    syslog (LOG_ERR, "%s", s);
-    closelog ();
-    g_free (s);
+	g_free (s);
 }
 
 void
@@ -263,8 +270,7 @@ delay_noblink (GSignalInvocationHint *ih
 	noblink_timeout
 		= g_timeout_add (NOBLINK_TIMEOUT, no_blink, NULL);
 	return TRUE;
-}      
-
+}
 
 void
 gdm_common_setup_blinking (void)
@@ -272,37 +278,37 @@ gdm_common_setup_blinking (void)
 	guint sid;
 
 	if ( ! ve_string_empty (g_getenv ("GDM_IS_LOCAL")) &&
-	    strncmp (ve_sure_string (g_getenv ("DISPLAY")), ":0", 2) == 0)
+	     strncmp (ve_sure_string (g_getenv ("DISPLAY")), ":0", 2) == 0)
 		return;
 
 	sid = g_signal_lookup ("activate",
 			       GTK_TYPE_MENU_ITEM);
 	if (sid != 0) {
-	   g_signal_add_emission_hook (sid,
-				       0 /* detail */,
-				       delay_noblink,
-				       NULL /* data */,
-				       NULL /* destroy_notify */);
+		g_signal_add_emission_hook (sid,
+					    0 /* detail */,
+					    delay_noblink,
+					    NULL /* data */,
+					    NULL /* destroy_notify */);
 	}
 
 	sid = g_signal_lookup ("key_press_event",
 			       GTK_TYPE_WIDGET);
 	if (sid != 0) {
-	   g_signal_add_emission_hook (sid,
-				       0 /* detail */,
-				       delay_noblink,
-				       NULL /* data */,
-				       NULL /* destroy_notify */);
+		g_signal_add_emission_hook (sid,
+					    0 /* detail */,
+					    delay_noblink,
+					    NULL /* data */,
+					    NULL /* destroy_notify */);
 	}
 
 	sid = g_signal_lookup ("button_press_event",
 			       GTK_TYPE_WIDGET);
 	if (sid != 0) {
-	   g_signal_add_emission_hook (sid,
-				       0 /* detail */,
-				       delay_noblink,
-				       NULL /* data */,
-				       NULL /* destroy_notify */);
+		g_signal_add_emission_hook (sid,
+					    0 /* detail */,
+					    delay_noblink,
+					    NULL /* data */,
+					    NULL /* destroy_notify */);
 	}
 
 	noblink_timeout = g_timeout_add (NOBLINK_TIMEOUT, no_blink, NULL);
@@ -315,7 +321,7 @@ gdm_common_setup_blinking_entry (GtkWidg
 	GtkSettings *settings;
 
 	if ( ! ve_string_empty (g_getenv ("GDM_IS_LOCAL")) &&
-	    strncmp (ve_sure_string (g_getenv ("DISPLAY")), ":0", 2) == 0)
+	     strncmp (ve_sure_string (g_getenv ("DISPLAY")), ":0", 2) == 0)
 		return;
 
 	eb = g_new0 (EntryBlink, 1);
@@ -355,7 +361,7 @@ gdm_common_get_face (const char *filenam
 
 	if (pixbuf) {
 		guint w, h;
-	
+
 		w = gdk_pixbuf_get_width (pixbuf);
 		h = gdk_pixbuf_get_height (pixbuf);
 
@@ -380,7 +386,7 @@ gdm_common_get_face (const char *filenam
 	return pixbuf;
 }
 
-gchar * 
+gchar *
 gdm_common_get_config_file (void)
 {
 	gchar *result;
@@ -392,7 +398,7 @@ gdm_common_get_config_file (void)
 		return NULL;
 
 	if (ve_string_empty (result) ||
-		strncmp (result, "OK ", 3) != 0) {
+	    strncmp (result, "OK ", 3) != 0) {
 		g_free (result);
 		return NULL;
 	}
@@ -405,7 +411,7 @@ gdm_common_get_config_file (void)
 	return config_file;
 }
 
-gchar * 
+gchar *
 gdm_common_get_custom_config_file (void)
 {
 	gchar *result;
@@ -417,7 +423,7 @@ gdm_common_get_custom_config_file (void)
 		return NULL;
 
 	if (ve_string_empty (result) ||
-		strncmp (result, "OK ", 3) != 0) {
+	    strncmp (result, "OK ", 3) != 0) {
 		g_free (result);
 		return NULL;
 	}
@@ -443,10 +449,10 @@ gdm_common_select_time_format (void)
 	     atoi (val) != 0)) {
 		return TRUE;
 	} else if (val != NULL &&
-	    (val[0] == 'F' ||
-	     val[0] == 'f' ||
-	     val[0] == 'N' ||
-	     val[0] == 'n')) {
+		   (val[0] == 'F' ||
+		    val[0] == 'f' ||
+		    val[0] == 'N' ||
+		    val[0] == 'n')) {
 		return FALSE;
 	} else {
 		/* Value is "auto" (default), thus select according to
@@ -469,34 +475,34 @@ gdm_common_select_time_format (void)
 void
 gdm_common_setup_background_color (gchar *bg_color)
 {
-  GdkColormap *colormap;
-  GdkColor color;
+	GdkColormap *colormap;
+	GdkColor color;
+
+	if (bg_color == NULL ||
+	    bg_color[0] == '\0' ||
+	    ! gdk_color_parse (bg_color, &color))
+		{
+			gdk_color_parse ("#007777", &color);
+		}
+
+	g_free (bg_color);
+
+	colormap = gdk_drawable_get_colormap
+		(gdk_get_default_root_window ());
+	/* paranoia */
+	if (colormap != NULL)
+		{
+			gboolean success;
+			gdk_error_trap_push ();
+
+			gdk_colormap_alloc_colors (colormap, &color, 1,
+						   FALSE, TRUE, &success);
+			gdk_window_set_background (gdk_get_default_root_window (), &color);
+			gdk_window_clear (gdk_get_default_root_window ());
 
-  if (bg_color == NULL ||
-      bg_color[0] == '\0' ||
-      ! gdk_color_parse (bg_color, &color))
-    {
-      gdk_color_parse ("#007777", &color);
-    }
-
-  g_free (bg_color);
-
-  colormap = gdk_drawable_get_colormap
-          (gdk_get_default_root_window ());
-  /* paranoia */
-  if (colormap != NULL)
-    {
-      gboolean success;
-      gdk_error_trap_push ();
-
-      gdk_colormap_alloc_colors (colormap, &color, 1,
-                                 FALSE, TRUE, &success);
-      gdk_window_set_background (gdk_get_default_root_window (), &color);
-      gdk_window_clear (gdk_get_default_root_window ());
-
-      gdk_flush ();
-      gdk_error_trap_pop ();
-    }
+			gdk_flush ();
+			gdk_error_trap_pop ();
+		}
 }
 
 gchar *
@@ -615,19 +621,18 @@ pre_atspi_launch (void){
 
 }
 
-
-static GdkFilterReturn 
+static GdkFilterReturn
 filter_watch (GdkXEvent *xevent, GdkEvent *event, gpointer data){
-     XEvent *xev = (XEvent *)xevent;
+	XEvent *xev = (XEvent *)xevent;
+
+	if (xev->xany.type == PropertyNotify &&
+	    xev->xproperty.atom == AT_SPI_IOR){
+		gtk_main_quit ();
 
-     if (xev->xany.type == PropertyNotify &&
-	 xev->xproperty.atom == AT_SPI_IOR){
-	     gtk_main_quit ();
-	  
-	  return GDK_FILTER_REMOVE;
-     }
+		return GDK_FILTER_REMOVE;
+	}
 
-     return GDK_FILTER_CONTINUE;
+	return GDK_FILTER_CONTINUE;
 }
 
 static gboolean
@@ -643,21 +648,21 @@ filter_timeout (gpointer data)
 void
 gdm_common_atspi_launch (void)
 {
-	GdkWindow *w = gdk_get_default_root_window (); 
+	GdkWindow *w = gdk_get_default_root_window ();
 	gboolean a11y = gdm_config_get_bool (GDM_KEY_ADD_GTK_MODULES);
 	guint tid;
 
 	if (! a11y)
 		return;
- 
+
 	if ( ! AT_SPI_IOR)
 		AT_SPI_IOR = XInternAtom (GDK_DISPLAY (), "AT_SPI_IOR", False);
 
-	gdk_window_set_events (w,  GDK_PROPERTY_CHANGE_MASK); 
-	
+	gdk_window_set_events (w,  GDK_PROPERTY_CHANGE_MASK);
+
 	if ( ! pre_atspi_launch ()) {
 		gdm_common_info (_("The accessibility registry could not be started."));
-		
+
 		return;
 	}
 	gdk_window_add_filter (w, filter_watch, NULL);
@@ -733,145 +738,134 @@ gdm_common_get_clock (struct tm **the_tm
 char *
 gdm_common_expand_text (const gchar *text)
 {
-  GString *str;
-  const char *p;
-  gchar *clock, *display;
-  int r, i, n_chars;
-  gboolean underline = FALSE;
-  gchar buf[256];
-  struct utsname name;
-  struct tm *the_tm;
-
-  str = g_string_sized_new (strlen (text));
-
-  p = text;
-  n_chars = g_utf8_strlen (text, -1);
-  i = 0;
-  
-  while (i < n_chars)
-    {
-      gunichar ch;
-
-      ch = g_utf8_get_char (p);
-
-      /* Backslash commands */
-      if (ch == '\\')
-        {
-	  p = g_utf8_next_char (p);
-	  i++;
-	  ch = g_utf8_get_char (p);
-
-	  if (i >= n_chars || ch == '\0')
-	    {
-	      g_warning ("Unescaped \\ at end of text\n");
-	      goto bail;
-	    }
-	  else if (ch == 'n')
-	    g_string_append_unichar (str, '\n');
-	  else
-	    g_string_append_unichar (str, ch);
-	}
-      else if (ch == '%')
-	{
-	  p = g_utf8_next_char (p);
-	  i++;
-	  ch = g_utf8_get_char (p);
-
-	  if (i >= n_chars || ch == '\0')
-	    {
-	      g_warning ("Unescaped %% at end of text\n");
-	      goto bail;
-	    }
-
-	  switch (ch)
-	    {
-	    case '%':
-	      g_string_append (str, "%");
-	      break;
-	    case 'c':
-	      clock = gdm_common_get_clock (&the_tm);
-	      g_string_append (str, clock);
-	      g_free (clock);
-	      break;
-	    case 'd':
-	      display = g_strdup (g_getenv ("DISPLAY"));
-	      g_string_append (str, display);
-	      break;
-	    case 'h':
-	      buf[sizeof (buf) - 1] = '\0';
-	      r = gethostname (buf, sizeof (buf) - 1);
-	      if (r)
-		g_string_append (str, "localhost");
-	      else
-		g_string_append (str, buf);
-	      break;
-	    case 'm':
-	      uname (&name);
-	      g_string_append (str, name.machine);
-	      break;
-	    case 'n':
-	      uname (&name);
-	      g_string_append (str, name.nodename);
-	      break;
-	    case 'o':
-	      buf[sizeof (buf) - 1] = '\0';
-	      r = getdomainname (buf, sizeof (buf) - 1);
-	      if (r)
-		g_string_append (str, "localdomain");
-	      else
-		g_string_append (str, buf);
-	      break;
-	    case 'r':
-	      uname (&name);
-	      g_string_append (str, name.release);
-	      break;
-	    case 's':
-	      uname (&name);
-	      g_string_append (str, name.sysname);
-	      break;
-	    case 't':
-	      g_string_append_printf (str, ngettext("%d second", "%d seconds", gdm_timed_delay),
-				      gdm_timed_delay);
-	      break;
-	    case 'u':
-	      g_string_append (str, ve_sure_string (g_getenv("GDM_TIMED_LOGIN_OK")));
-	      break;
-	    default:
-	      if (ch < 127)
-	        g_warning ("unknown escape code %%%c in text\n", (char)ch);
-	      else
-		g_warning ("unknown escape code %%(U%x) in text\n", (int)ch);
-	    }
-	}
-      else if (ch == '_')
-        {
-          /*
-           * Could be true if an underscore was put right before a special
-           * character like % or /
-           */
-          if (underline == FALSE) {
-            underline = TRUE;
-	    g_string_append (str, "<u>");
-	  }
-	}
-      else
-	{
-	  g_string_append_unichar (str, ch);
-	  if (underline)
-	    {
-	      underline = FALSE;
-	      g_string_append (str, "</u>");
-	    }
-	}
-      p = g_utf8_next_char (p);
-      i++;
-    }
-  
+	GString *str;
+	const char *p;
+	gchar *clock, *display;
+	int r, i, n_chars;
+	gboolean underline = FALSE;
+	gchar buf[256];
+	struct utsname name;
+	struct tm *the_tm;
+
+	str = g_string_sized_new (strlen (text));
+
+	p = text;
+	n_chars = g_utf8_strlen (text, -1);
+	i = 0;
+
+	while (i < n_chars) {
+		gunichar ch;
+
+		ch = g_utf8_get_char (p);
+
+		/* Backslash commands */
+		if (ch == '\\') {
+			p = g_utf8_next_char (p);
+			i++;
+			ch = g_utf8_get_char (p);
+
+			if (i >= n_chars || ch == '\0') {
+				g_warning ("Unescaped \\ at end of text\n");
+				goto bail;
+			}
+			else if (ch == 'n')
+				g_string_append_unichar (str, '\n');
+			else
+				g_string_append_unichar (str, ch);
+		}
+		else if (ch == '%') {
+			p = g_utf8_next_char (p);
+			i++;
+			ch = g_utf8_get_char (p);
+
+			if (i >= n_chars || ch == '\0') {
+				g_warning ("Unescaped %% at end of text\n");
+				goto bail;
+			}
+
+			switch (ch) {
+			case '%':
+				g_string_append (str, "%");
+				break;
+			case 'c':
+				clock = gdm_common_get_clock (&the_tm);
+				g_string_append (str, clock);
+				g_free (clock);
+				break;
+			case 'd':
+				display = g_strdup (g_getenv ("DISPLAY"));
+				g_string_append (str, display);
+				break;
+			case 'h':
+				buf[sizeof (buf) - 1] = '\0';
+				r = gethostname (buf, sizeof (buf) - 1);
+				if (r)
+					g_string_append (str, "localhost");
+				else
+					g_string_append (str, buf);
+				break;
+			case 'm':
+				uname (&name);
+				g_string_append (str, name.machine);
+				break;
+			case 'n':
+				uname (&name);
+				g_string_append (str, name.nodename);
+				break;
+			case 'o':
+				buf[sizeof (buf) - 1] = '\0';
+				r = getdomainname (buf, sizeof (buf) - 1);
+				if (r)
+					g_string_append (str, "localdomain");
+				else
+					g_string_append (str, buf);
+				break;
+			case 'r':
+				uname (&name);
+				g_string_append (str, name.release);
+				break;
+			case 's':
+				uname (&name);
+				g_string_append (str, name.sysname);
+				break;
+			case 't':
+				g_string_append_printf (str, ngettext("%d second", "%d seconds", gdm_timed_delay),
+							gdm_timed_delay);
+				break;
+			case 'u':
+				g_string_append (str, ve_sure_string (g_getenv("GDM_TIMED_LOGIN_OK")));
+				break;
+			default:
+				if (ch < 127)
+					g_warning ("unknown escape code %%%c in text\n", (char)ch);
+				else
+					g_warning ("unknown escape code %%(U%x) in text\n", (int)ch);
+			}
+		} else if (ch == '_') {
+			/*
+			 * Could be true if an underscore was put right before a special
+			 * character like % or /
+			 */
+			if (underline == FALSE) {
+				underline = TRUE;
+				g_string_append (str, "<u>");
+			}
+		} else {
+			g_string_append_unichar (str, ch);
+			if (underline) {
+				underline = FALSE;
+				g_string_append (str, "</u>");
+			}
+		}
+		p = g_utf8_next_char (p);
+		i++;
+	}
+
  bail:
 
-  if (underline)
-    g_string_append (str, "</u>");
+	if (underline)
+		g_string_append (str, "</u>");
 
-  return g_string_free (str, FALSE);
+	return g_string_free (str, FALSE);
 }
 
Index: gui/gdmcomm.c
===================================================================
--- gui/gdmcomm.c	(revision 4731)
+++ gui/gdmcomm.c	(working copy)
@@ -1,21 +1,22 @@
-/*
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
  *    GDMcommunication routines
  *    (c)2001 Queen of England, (c)2002,2003 George Lebl
- *    
+ *
  *    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., 675 Mass Ave, Cambridge, MA 02139, USA.
- * 
+ *
  */
 
 #include "config.h"
@@ -41,28 +42,14 @@
 #include "gdmconfig.h"
 
 #include "gdm-common.h"
+#include "gdm-socket-protocol.h"
 #include "gdm-daemon-config-keys.h"
 
 static gboolean bulk_acs = FALSE;
-static gboolean debug    = FALSE;
 static gboolean quiet    = FALSE;
 static int      num_cmds = 0;
 
 /*
- * Note, in this function we have to call gdm_common_error instead
- * of gdm_common_debug, since gdm_common_debug accesses the
- * GDM_KEY_DEBUG which can cause a sockets connection to get the
- * config data, causing an infinite loop.  This is why clients must
- * call the gdmcomm_set_debug function to turn on debug for these
- * functions.  
- */
-void
-gdmcomm_set_debug (gboolean enable)
-{
-	debug = enable;
-}
-
-/*
  * Normally errors are printed.  Setting quiet to TRUE turns off
  * display of error messages.
  */
@@ -83,9 +70,7 @@ do_command (int fd, const char *command,
 	void (*old_handler)(int);
 #endif
 
-	if (debug) {
-		gdm_common_error ("Sending command: '%s'", command);
-	}
+        gdm_common_debug ("Sending command: '%s'", command);
 
 	cstr = g_strdup_printf ("%s\n", command);
 
@@ -102,7 +87,7 @@ do_command (int fd, const char *command,
 
 	if (ret < 0) {
 		if ( !quiet)
-			gdm_common_error ("Command failed, no data returned");
+			gdm_common_debug ("Command failed, no data returned");
 		return NULL;
 	}
 
@@ -116,8 +101,7 @@ do_command (int fd, const char *command,
 		g_string_append_c (str, buf[0]);
 	}
 
-	if (debug)
-		gdm_common_error ("  Got response: '%s'", str->str);
+        gdm_common_debug ("  Got response: '%s'", str->str);
 
 	cstr = str->str;
 	g_string_free (str, FALSE);
@@ -135,7 +119,7 @@ do_command (int fd, const char *command,
 	if (ve_string_empty (cstr) ||
 	    strcmp (ve_sure_string (cstr), "ERROR 200 Too many messages") == 0) {
 		if ( !quiet)
-			gdm_common_error ("Command failed, daemon busy.");
+			gdm_common_debug ("Command failed, daemon busy.");
 		g_free (cstr);
 		return NULL;
 	}
@@ -181,23 +165,22 @@ gdmcomm_call_gdm_real (const char *comma
          * and reopen.  Subtract 1 to allow the "CLOSE" to get through.
          */
 	if (num_cmds == (GDM_SUP_MAX_MESSAGES - 1)) {
-	   if (debug)
-		gdm_common_error ("  Closing and reopening connection.");
-	   do_command (comm_fd, GDM_SUP_CLOSE, FALSE);
-	   VE_IGNORE_EINTR (close (comm_fd));
-	   comm_fd  = 0;
-	   num_cmds = 0;
+		gdm_common_debug ("  Closing and reopening connection.");
+		do_command (comm_fd, GDM_SUP_CLOSE, FALSE);
+		VE_IGNORE_EINTR (close (comm_fd));
+		comm_fd  = 0;
+		num_cmds = 0;
 	}
 
 	if (tries <= 0) {
 		if ( !quiet)
-			gdm_common_error ("  Command failed %d times, aborting.", try_start);
+			gdm_common_debug ("  Command failed %d times, aborting.", try_start);
 		return NULL;
 	}
 
 	if (!quiet && tries != try_start) {
-		gdm_common_error ("  Trying failed command again.  Try %d of %d.",
-			(try_start - tries + 1), try_start);
+		gdm_common_debug ("  Trying failed command again.  Try %d of %d.",
+				  (try_start - tries + 1), try_start);
 	}
 
 	if (comm_fd <= 0) {
@@ -207,7 +190,7 @@ gdmcomm_call_gdm_real (const char *comma
 		comm_fd = socket (AF_UNIX, SOCK_STREAM, 0);
 		if (comm_fd < 0) {
 			if ( !quiet)
-				gdm_common_error ("  Failed to open socket");
+				gdm_common_debug ("  Failed to open socket");
 
 			return gdmcomm_call_gdm_real (command, auth_cookie, min_version, tries - 1, try_start);
 		}
@@ -235,17 +218,17 @@ gdmcomm_call_gdm_real (const char *comma
 				 */
 				if (tries > 1) {
 					if ( !quiet)
-						gdm_common_error ("  Failed to connect to socket, sleep 1 second and retry");
+						gdm_common_debug ("  Failed to connect to socket, sleep 1 second and retry");
 					sleep (1);
 				}
 			} else {
 				if ( !quiet)
-					gdm_common_error ("  Failed to connect to socket, not sleeping");
+					gdm_common_debug ("  Failed to connect to socket, not sleeping");
 			}
 			VE_IGNORE_EINTR (close (comm_fd));
 			comm_fd = 0;
 			return gdmcomm_call_gdm_real (command, auth_cookie,
-				min_version, tries - 1, try_start);
+						      min_version, tries - 1, try_start);
 		}
 
 		/*
@@ -260,15 +243,15 @@ gdmcomm_call_gdm_real (const char *comma
 		ret = do_command (comm_fd, GDM_SUP_VERSION, TRUE);
 		if (ret == NULL) {
 			if ( !quiet)
-				gdm_common_error ("  Version check failed");
+				gdm_common_debug ("  Version check failed");
 			VE_IGNORE_EINTR (close (comm_fd));
 			comm_fd = 0;
 			return gdmcomm_call_gdm_real (command, auth_cookie,
-				min_version, tries - 1, try_start);
+						      min_version, tries - 1, try_start);
 		}
 		if (strncmp (ret, "GDM ", strlen ("GDM ")) != 0) {
 			if ( !quiet)
-				gdm_common_error ("  Version check failed, bad name");
+				gdm_common_debug ("  Version check failed, bad name");
 
 			g_free (ret);
 			do_command (comm_fd, GDM_SUP_CLOSE, FALSE);
@@ -278,7 +261,7 @@ gdmcomm_call_gdm_real (const char *comma
 		}
 		if ( ! version_ok_p (&ret[4], min_version)) {
 			if ( !quiet)
-				gdm_common_error ("  Version check failed, bad version");
+				gdm_common_debug ("  Version check failed, bad version");
 			g_free (ret);
 			do_command (comm_fd, GDM_SUP_CLOSE, FALSE);
 			VE_IGNORE_EINTR (close (comm_fd));
@@ -298,12 +281,12 @@ gdmcomm_call_gdm_real (const char *comma
 			VE_IGNORE_EINTR (close (comm_fd));
 			comm_fd = 0;
 			return gdmcomm_call_gdm_real (command, auth_cookie,
-				min_version, tries - 1, try_start);
+						      min_version, tries - 1, try_start);
 		}
 		/* not auth'ed */
 		if (strcmp (ve_sure_string (ret), "OK") != 0) {
 			if ( !quiet)
-				gdm_common_error ("  Error, auth check failed");
+				gdm_common_debug ("  Error, auth check failed");
 			do_command (comm_fd, GDM_SUP_CLOSE, FALSE);
 			VE_IGNORE_EINTR (close (comm_fd));
 			comm_fd = 0;
@@ -318,7 +301,7 @@ gdmcomm_call_gdm_real (const char *comma
 		VE_IGNORE_EINTR (close (comm_fd));
 		comm_fd = 0;
 		return gdmcomm_call_gdm_real (command, auth_cookie,
-			min_version, tries - 1, try_start);
+					      min_version, tries - 1, try_start);
 	}
 
 	/*
@@ -343,13 +326,13 @@ gdmcomm_call_gdm_real (const char *comma
 
 char *
 gdmcomm_call_gdm (const char *command, const char * auth_cookie,
-	const char *min_version, int tries)
+		  const char *min_version, int tries)
 {
 
 	char *retstr;
 
 	retstr = gdmcomm_call_gdm_real (command, auth_cookie, min_version,
-		tries, tries);
+					tries, tries);
 
 	/*
 	 * Disallow sleeping on future calls if it failed to connect.
Index: gui/gdmcommon.h
===================================================================
--- gui/gdmcommon.h	(revision 4731)
+++ gui/gdmcommon.h	(working copy)
@@ -24,14 +24,13 @@
 #ifndef GDM_COMMON_H
 #define GDM_COMMON_H
 
-#include <gtk/gtk.h> 
+#include <gtk/gtk.h>
 
 #include "misc.h"
 
 /* Handle error messages */
-void      gdm_common_openlog                (const char *ident,
-                                             int logopt,
-                                             int facility);
+void      gdm_common_log_init               (void);
+void      gdm_common_log_set_debug          (gboolean enable);
 void	  gdm_common_fail_exit		    (const gchar *format, ...)
 					     G_GNUC_PRINTF (1, 2);
 void	  gdm_common_fail_greeter	    (const gchar *format, ...)
Index: gui/gdmflexiserver.c
===================================================================
--- gui/gdmflexiserver.c	(revision 4731)
+++ gui/gdmflexiserver.c	(working copy)
@@ -37,13 +37,18 @@
 #include <gdk/gdkx.h>
 #include <gtk/gtk.h>
 
+#include <X11/Xauth.h>
+
 #include "gdm.h"
 #include "gdmcomm.h"
 #include "gdmcommon.h"
 #include "gdmconfig.h"
 
 #include "gdm-common.h"
+#include "gdm-log.h"
+#include "gdm-socket-protocol.h"
 #include "gdm-daemon-config-keys.h"
+#include "server.h"
 
 static GSList *xservers          = NULL;
 static const char *send_command  = NULL;
@@ -756,7 +761,8 @@ main (int argc, char *argv[])
 		return 0;
 	}
 
-	gdmcomm_set_debug (debug_in);
+	gdm_log_init ();
+	gdm_log_set_debug (debug_in);
 
 	if (args_remaining != NULL && args_remaining[0] != NULL)
 		server = args_remaining[0];
Index: gui/Makefile.am
===================================================================
--- gui/Makefile.am	(revision 4731)
+++ gui/Makefile.am	(working copy)
@@ -81,12 +81,14 @@ libgdmcommon_a_SOURCES = \
 	gdmconfig.c		\
 	gdmconfig.h		\
 	gdmcommon.c		\
-	gdmcommon.h
+	gdmcommon.h		\
+	$(NULL)
 
 gdmchooser_SOURCES = \
 	gdmchooser.c		\
 	misc.c			\
-	misc.h			
+	misc.h			\
+	$(NULL)
 
 gdmlogin_SOURCES = \
 	gdmlogin.c
@@ -112,7 +114,7 @@ gdmchooser_LDADD = \
 	$(X_LIBS)		\
 	$(XDMCP_LIBS)		\
 	-lX11			\
-	-lpopt
+	$(NULL)
 
 gdmlogin_LDADD = \
 	libgdmwm.a		\
@@ -128,7 +130,8 @@ gdmlogin_LDADD = \
 	$(X_EXTRA_LIBS)		\
 	$(XINERAMA_LIBS)	\
 	$(X_LIBS)		\
-	-lX11
+	-lX11			\
+	$(NULL)
 
 # LIBGNOMEUI should be removed from gdmsetup at some point.
 # It is needed because it uses gnome_help_display_uri(), which
@@ -150,7 +153,8 @@ gdmsetup_LDADD = \
 	$(top_builddir)/common/libgdmcommon.a \
 	$(X_LIBS)		\
 	-lXau			\
-	-lX11
+	-lX11			\
+	$(NULL)
 
 gdmphotosetup_LDADD = \
 	libgdmcommon.a		\
@@ -177,7 +181,7 @@ gdmXnestchooser_LDADD = \
 	$(X_LIBS)		\
 	-lXau			\
 	-lX11			\
-	-lpopt
+	$(NULL)
 
 gdmflexiserver_LDADD = \
 	libgdmcommon.a		\
@@ -191,7 +195,7 @@ gdmflexiserver_LDADD = \
 	$(X_LIBS)		\
 	-lX11			\
 	-lXau			\
-	-lpopt
+	$(NULL)
 
 gdmdynamic_LDADD = 		\
 	libgdmcommon.a		\
@@ -204,7 +208,8 @@ gdmdynamic_LDADD = 		\
 	$(EXTRA_DYNAMIC_LIBS)	\
 	$(X_LIBS)		\
 	-lX11			\
-	-lXau
+	-lXau			\
+	$(NULL)
 
 Settingsdir = $(datadir)/applications
 Settings_files = gdmphotosetup.desktop
Index: gui/gdmsetup.c
===================================================================
--- gui/gdmsetup.c	(revision 4731)
+++ gui/gdmsetup.c	(working copy)
@@ -50,8 +50,11 @@
 #include "gdmconfig.h"
 
 #include "gdm-common.h"
+#include "gdm-socket-protocol.h"
 #include "gdm-daemon-config-keys.h"
 
+#include "server.h"
+
 static char     *GdmSoundProgram = NULL;
 static gchar    *GdmExclude      = NULL;
 static gchar    *GdmInclude      = NULL;
Index: gui/gdmchooser.c
===================================================================
--- gui/gdmchooser.c	(revision 4731)
+++ gui/gdmchooser.c	(working copy)
@@ -29,7 +29,6 @@
 #include <dirent.h>
 #include <string.h>
 #include <unistd.h>
-#include <syslog.h>
 #include <ctype.h>
 #include <fcntl.h>
 #include <signal.h>
@@ -1567,7 +1566,6 @@ gdm_chooser_cancel (int sig)
 	    scan_time_handler = 0;
     }
 
-    closelog ();
     /* exit rather gtk_main_quit, it's just safer this way we don't
        have to worry about random whackiness happening */
     exit (EXIT_SUCCESS);
@@ -1584,8 +1582,6 @@ gdm_chooser_manage (GtkButton *button, g
 
     if (curhost)
       gdm_chooser_choose_host (curhost->name);
-   
-    closelog ();
 
     /* exit rather gtk_main_quit, it's just safer this way we don't
        have to worry about random whackiness happening */
@@ -1782,8 +1778,6 @@ gdm_read_config (void)
 	/* Read config data in bulk */
 	gdmcomm_comm_bulk_start ();
 
-	gdmcomm_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG));
-
 	/*
 	 * Read all the keys at once and close sockets connection so we do
 	 * not have to keep the socket open.  
@@ -1817,9 +1811,6 @@ gdm_reread_config (int sig, gpointer dat
 	/* Read config data in bulk */
 	gdmcomm_comm_bulk_start ();
 
-	if (gdm_config_reload_bool (GDM_KEY_DEBUG))
-		gdmcomm_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG));
-
 	/* FIXME: The following is evil, we should update on the fly rather
 	 * then just restarting */
 	/* Also we may not need to check ALL those keys but just a few */
@@ -1965,8 +1956,6 @@ main (int argc, char *argv[])
     if (g_getenv ("RUNNING_UNDER_GDM") != NULL)
 	    RUNNING_UNDER_GDM = TRUE;
 
-    gdm_common_openlog ("gdmchooser", LOG_PID, LOG_DAEMON);
-
     bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
     bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
     textdomain (GETTEXT_PACKAGE);
@@ -1980,6 +1969,9 @@ main (int argc, char *argv[])
 
     glade_init ();
 
+    gdm_common_log_init ();
+    gdm_common_log_set_debug (gdm_config_get_bool (GDM_KEY_DEBUG));
+
     /* Read all configuration at once, so the values get cached */
     gdm_read_config ();
 
Index: gui/gdmconfig.c
===================================================================
--- gui/gdmconfig.c	(revision 4731)
+++ gui/gdmconfig.c	(working copy)
@@ -22,6 +22,7 @@
  */
 
 #include <stdlib.h>
+#include <string.h>
 #include <gtk/gtk.h>
 
 #include "config.h"
@@ -33,6 +34,8 @@
 
 #include "gdm-common.h"
 
+#include "server.h"
+
 static GHashTable *int_hash       = NULL;
 static GHashTable *bool_hash      = NULL;
 static GHashTable *string_hash    = NULL;
Index: common/gdm-config.h
===================================================================
--- common/gdm-config.h	(revision 4731)
+++ common/gdm-config.h	(working copy)
@@ -125,7 +125,10 @@ char **                gdm_config_get_ke
 							  gsize           *length,
 							  GError         **error);
 
-
+gboolean               gdm_config_peek_value             (GdmConfig             *config,
+							  const char            *group,
+							  const char            *key,
+							  const GdmConfigValue **value);
 gboolean               gdm_config_get_value              (GdmConfig       *config,
 							  const char      *group,
 							  const char      *key,
@@ -135,6 +138,7 @@ gboolean               gdm_config_set_va
 							  const char      *key,
 							  GdmConfigValue  *value);
 
+/* convenience functions */
 gboolean               gdm_config_get_value_for_id       (GdmConfig       *config,
 							  int              id,
 							  GdmConfigValue **value);
@@ -142,18 +146,27 @@ gboolean               gdm_config_set_va
 							  int              id,
 							  GdmConfigValue  *value);
 
+gboolean               gdm_config_peek_string_for_id     (GdmConfig       *config,
+							  int              id,
+							  const char     **str);
 gboolean               gdm_config_get_string_for_id      (GdmConfig       *config,
 							  int              id,
 							  char           **str);
 gboolean               gdm_config_get_bool_for_id        (GdmConfig       *config,
 							  int              id,
 							  gboolean        *bool);
+gboolean               gdm_config_get_int_for_id         (GdmConfig       *config,
+							  int              id,
+							  int             *integer);
 gboolean               gdm_config_set_string_for_id      (GdmConfig       *config,
 							  int              id,
 							  char            *str);
 gboolean               gdm_config_set_bool_for_id        (GdmConfig       *config,
 							  int              id,
 							  gboolean         bool);
+gboolean               gdm_config_set_int_for_id         (GdmConfig       *config,
+							  int              id,
+							  int              integer);
 
 /* Config Values */
 
Index: common/gdm-log.c
===================================================================
--- common/gdm-log.c	(revision 0)
+++ common/gdm-log.c	(revision 0)
@@ -0,0 +1,185 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
+ *
+ * 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.
+ *
+ * Authors: William Jon McCann <mccann@jhu.edu>
+ *
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <signal.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <syslog.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include "gdm-log.h"
+
+static gboolean initialized = FALSE;
+static int      syslog_levels = (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
+
+static void
+log_level_to_priority_and_prefix (GLogLevelFlags log_level,
+				  int           *priorityp,
+				  const char   **prefixp)
+{
+	int         priority;
+	const char *prefix;
+
+	/* Process the message prefix and priority */
+	switch (log_level & G_LOG_LEVEL_MASK) {
+	case G_LOG_FLAG_FATAL:
+		priority = LOG_EMERG;
+		prefix = "FATAL";
+		break;
+	case G_LOG_LEVEL_ERROR:
+		priority = LOG_ERR;
+		prefix = "ERROR";
+		break;
+	case G_LOG_LEVEL_CRITICAL:
+		priority = LOG_CRIT;
+		prefix = "CRITICAL";
+		break;
+	case G_LOG_LEVEL_WARNING:
+		priority = LOG_WARNING;
+		prefix = "WARNING";
+		break;
+	case G_LOG_LEVEL_MESSAGE:
+		priority = LOG_NOTICE;
+		prefix = "MESSAGE";
+		break;
+	case G_LOG_LEVEL_INFO:
+		priority = LOG_INFO;
+		prefix = "INFO";
+		break;
+	case G_LOG_LEVEL_DEBUG:
+		/* if debug was requested then bump this up to ERROR
+		 * to ensure it is seen in a log */
+		if (syslog_levels & G_LOG_LEVEL_DEBUG) {
+			priority = LOG_WARNING;
+		} else {
+			priority = LOG_DEBUG;
+		}
+		prefix = "DEBUG";
+		break;
+	default:
+		priority = LOG_DEBUG;
+		prefix = "UNKNOWN";
+		break;
+	}
+
+	if (priorityp != NULL) {
+		*priorityp = priority;
+	}
+	if (prefixp != NULL) {
+		*prefixp = prefix;
+	}
+}
+
+void
+gdm_log_default_handler (const gchar   *log_domain,
+			 GLogLevelFlags log_level,
+			 const gchar   *message,
+			 gpointer	unused_data)
+{
+	GString     *gstring;
+	int          priority;
+	const char  *level_prefix;
+	char        *string;
+	gboolean     do_log;
+	gboolean     is_fatal;
+
+	is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
+
+	do_log = (log_level & syslog_levels);
+	if (! do_log) {
+		return;
+	}
+
+	if (! initialized) {
+		gdm_log_init ();
+	}
+
+	log_level_to_priority_and_prefix (log_level,
+					  &priority,
+					  &level_prefix);
+
+	gstring = g_string_new (NULL);
+
+	if (log_domain != NULL) {
+		g_string_append (gstring, log_domain);
+		g_string_append_c (gstring, '-');
+	}
+	g_string_append (gstring, level_prefix);
+
+	g_string_append (gstring, ": ");
+	if (message == NULL) {
+		g_string_append (gstring, "(NULL) message");
+	} else {
+		g_string_append (gstring, message);
+	}
+	if (is_fatal) {
+		g_string_append (gstring, "\naborting...\n");
+	} else {
+		g_string_append (gstring, "\n");
+	}
+
+	string = g_string_free (gstring, FALSE);
+
+	syslog (priority, "%s", string);
+
+	g_free (string);
+}
+
+void
+gdm_log_set_debug (gboolean debug)
+{
+	if (debug) {
+		syslog_levels |= G_LOG_LEVEL_DEBUG;
+	} else {
+		syslog_levels &= ~G_LOG_LEVEL_DEBUG;
+    	}
+}
+
+void
+gdm_log_init (void)
+{
+	const char *prg_name;
+
+	g_log_set_default_handler (gdm_log_default_handler, NULL);
+
+	prg_name = g_get_prgname ();
+
+	openlog (prg_name, LOG_PERROR|LOG_PID, LOG_DAEMON);
+
+	initialized = TRUE;
+}
+
+void
+gdm_log_shutdown (void)
+{
+	closelog ();
+	initialized = FALSE;
+}
+
Index: common/Makefile.am
===================================================================
--- common/Makefile.am	(revision 4731)
+++ common/Makefile.am	(working copy)
@@ -34,12 +34,15 @@ libgdmcommon_a_SOURCES =	\
 	gdm-common-config.c	\
 	gdm-config.h		\
 	gdm-config.c		\
+	gdm-log.h		\
+	gdm-log.c		\
 	ve-signal.h		\
 	ve-signal.c		\
 	$(NULL)
 
 noinst_PROGRAMS = 		\
 	test-config		\
+	test-log		\
 	$(NULL)
 
 test_config_SOURCES = 		\
@@ -51,3 +54,12 @@ test_config_LDADD =		\
 	$(top_builddir)/common/libgdmcommon.a	\
 	$(GLIB_LIBS)		\
 	$(NULL)
+
+test_log_SOURCES = 		\
+	test-log.c	 	\
+	$(NULL)
+
+test_log_LDADD =		\
+	$(top_builddir)/common/libgdmcommon.a	\
+	$(GLIB_LIBS)		\
+	$(NULL)
Index: common/gdm-config.c
===================================================================
--- common/gdm-config.c	(revision 4731)
+++ common/gdm-config.c	(working copy)
@@ -1107,14 +1107,14 @@ gdm_config_process_all (GdmConfig *confi
 }
 
 gboolean
-gdm_config_get_value (GdmConfig       *config,
-		      const char      *group,
-		      const char      *key,
-		      GdmConfigValue **valuep)
+gdm_config_peek_value (GdmConfig             *config,
+		       const char            *group,
+		       const char            *key,
+		       const GdmConfigValue **valuep)
 {
-	gboolean        ret;
-	char           *key_path;
-	GdmConfigValue *value;
+	gboolean              ret;
+	char                 *key_path;
+	const GdmConfigValue *value;
 
 	g_return_val_if_fail (config != NULL, FALSE);
 
@@ -1128,7 +1128,7 @@ gdm_config_get_value (GdmConfig       *c
 
 	if (valuep != NULL) {
 		if (ret) {
-			*valuep = gdm_config_value_copy (value);
+			*valuep = value;
 		} else {
 			*valuep = NULL;
 		}
@@ -1138,6 +1138,23 @@ gdm_config_get_value (GdmConfig       *c
 }
 
 gboolean
+gdm_config_get_value (GdmConfig       *config,
+		      const char      *group,
+		      const char      *key,
+		      GdmConfigValue **valuep)
+{
+	gboolean              res;
+	const GdmConfigValue *value;
+
+	res = gdm_config_peek_value (config, group, key, &value);
+	if (valuep != NULL) {
+		*valuep = (value == NULL) ? NULL : gdm_config_value_copy (value);
+	}
+
+	return res;
+}
+
+gboolean
 gdm_config_set_value (GdmConfig       *config,
 		      const char      *group,
 		      const char      *key,
@@ -1153,6 +1170,23 @@ gdm_config_set_value (GdmConfig       *c
 	return TRUE;
 }
 
+static gboolean
+gdm_config_peek_value_for_id (GdmConfig             *config,
+			      int                    id,
+			      const GdmConfigValue **valuep)
+{
+	const GdmConfigEntry *entry;
+
+	g_return_val_if_fail (config != NULL, FALSE);
+
+	entry = gdm_config_lookup_entry_for_id (config, id);
+	if (entry == NULL) {
+		return FALSE;
+	}
+
+	return gdm_config_peek_value (config, entry->group, entry->key, valuep);
+}
+
 gboolean
 gdm_config_get_value_for_id (GdmConfig       *config,
 			     int              id,
@@ -1188,27 +1222,41 @@ gdm_config_set_value_for_id (GdmConfig  
 }
 
 gboolean
-gdm_config_get_string_for_id (GdmConfig       *config,
-			      int              id,
-			      char           **strp)
+gdm_config_peek_string_for_id (GdmConfig       *config,
+			       int              id,
+			       const char     **strp)
 {
-	GdmConfigValue *value;
-	const char     *str;
-	gboolean        res;
+	const GdmConfigValue *value;
+	const char           *str;
+	gboolean              res;
 
 	g_return_val_if_fail (config != NULL, FALSE);
 
-	res = gdm_config_get_value_for_id (config, id, &value);
+	res = gdm_config_peek_value_for_id (config, id, &value);
 	if (! res) {
 		return FALSE;
 	}
 
 	str = gdm_config_value_get_string (value);
 	if (strp != NULL) {
-		*strp = g_strdup (str);
+		*strp = str;
 	}
 
-	gdm_config_value_free (value);
+	return res;
+}
+
+gboolean
+gdm_config_get_string_for_id (GdmConfig       *config,
+			      int              id,
+			      char           **strp)
+{
+	gboolean    res;
+	const char *str;
+
+	res = gdm_config_peek_string_for_id (config, id, &str);
+	if (strp != NULL) {
+		*strp = g_strdup (str);
+	}
 
 	return res;
 }
@@ -1240,6 +1288,32 @@ gdm_config_get_bool_for_id (GdmConfig   
 }
 
 gboolean
+gdm_config_get_int_for_id (GdmConfig       *config,
+			   int              id,
+			   int             *integerp)
+{
+	GdmConfigValue *value;
+	gboolean        integer;
+	gboolean        res;
+
+	g_return_val_if_fail (config != NULL, FALSE);
+
+	res = gdm_config_get_value_for_id (config, id, &value);
+	if (! res) {
+		return FALSE;
+	}
+
+	integer = gdm_config_value_get_int (value);
+	if (integerp != NULL) {
+		*integerp = integer;
+	}
+
+	gdm_config_value_free (value);
+
+	return res;
+}
+
+gboolean
 gdm_config_set_string_for_id (GdmConfig      *config,
 			      int             id,
 			      char           *str)
@@ -1276,3 +1350,22 @@ gdm_config_set_bool_for_id (GdmConfig   
 
 	return res;
 }
+
+gboolean
+gdm_config_set_int_for_id (GdmConfig      *config,
+			   int             id,
+			   int             integer)
+{
+	GdmConfigValue *value;
+	gboolean        res;
+
+	g_return_val_if_fail (config != NULL, FALSE);
+
+	value = gdm_config_value_new (GDM_CONFIG_VALUE_INT);
+	gdm_config_value_set_int (value, integer);
+
+	res = gdm_config_set_value_for_id (config, id, value);
+	gdm_config_value_free (value);
+
+	return res;
+}
Index: common/gdm-log.h
===================================================================
--- common/gdm-log.h	(revision 0)
+++ common/gdm-log.h	(revision 0)
@@ -0,0 +1,50 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
+ *
+ * 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.
+ *
+ * Authors: William Jon McCann <mccann@jhu.edu>
+ *
+ */
+
+#ifndef __GDM_LOG_H
+#define __GDM_LOG_H
+
+#include <stdarg.h>
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+void      gdm_log_default_handler (const gchar   *log_domain,
+                                   GLogLevelFlags log_level,
+                                   const gchar   *message,
+                                   gpointer	 unused_data);
+void      gdm_log_set_debug       (gboolean       debug);
+void      gdm_log_init            (void);
+void      gdm_log_shutdown        (void);
+
+/* compatibility */
+#define   gdm_fail               g_critical
+#define   gdm_error              g_warning
+#define   gdm_info               g_message
+#define   gdm_debug              g_debug
+
+#define   gdm_assert             g_assert
+#define   gdm_assert_not_reached g_assert_not_reached
+
+G_END_DECLS
+
+#endif /* __GDM_LOG_H */
Index: daemon/errorgui.c
===================================================================
--- daemon/errorgui.c	(revision 4731)
+++ daemon/errorgui.c	(working copy)
@@ -21,8 +21,9 @@
 
 #include "config.h"
 
+#include <stdlib.h>
 #include <unistd.h>
-#include <syslog.h>
+#include <string.h>
 #include <grp.h>
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -43,8 +44,11 @@
 #include "slave.h"
 
 #include "gdm-common.h"
+#include "gdm-log.h"
 #include "gdm-daemon-config.h"
 
+#include "gdm-socket-protocol.h"
+
 /* set in the main function */
 extern char **stored_argv;
 extern int stored_argc;
@@ -195,7 +199,7 @@ setup_dialog (GdmDisplay *d, const char 
 	char **argv;
 	struct passwd *pw;
 
-	closelog ();
+        gdm_log_shutdown ();
 
 	/* No error checking here - if it's messed the best response
 	 * is to ignore & try to continue */
@@ -217,7 +221,7 @@ setup_dialog (GdmDisplay *d, const char 
 	/* restore initial environment */
 	gdm_restoreenv ();
 
-	openlog ("gdm", LOG_PID, LOG_DAEMON);
+        gdm_log_init ();
 
 	g_setenv ("LOGNAME", gdm_daemon_config_get_value_string (GDM_KEY_USER), TRUE);
 	g_setenv ("USER", gdm_daemon_config_get_value_string (GDM_KEY_USER), TRUE);
Index: daemon/misc.h
===================================================================
--- daemon/misc.h	(revision 4731)
+++ daemon/misc.h	(working copy)
@@ -19,32 +19,11 @@
 #ifndef GDM_MISC_H
 #define GDM_MISC_H
 
-#ifndef __PRETTY_FUNCTION__
-#define __PRETTY_FUNCTION__ "N/A"
-#endif
-
+#include <stdio.h>
 #include <sys/types.h>
 
 #include "gdm.h"
-
-void gdm_fail   (const gchar *format, ...) G_GNUC_PRINTF (1, 2);
-void gdm_info   (const gchar *format, ...) G_GNUC_PRINTF (1, 2);
-void gdm_error  (const gchar *format, ...) G_GNUC_PRINTF (1, 2);
-void gdm_debug  (const gchar *format, ...) G_GNUC_PRINTF (1, 2);
-
-#define gdm_assert(expr)		G_STMT_START{			\
-     if G_LIKELY(expr) { } else 					\
-        gdm_fail ("GDM file %s: line %d (%s): assertion failed: (%s)",	\
-		  __FILE__,						\
-		  __LINE__,						\
-		  __PRETTY_FUNCTION__,					\
-                  #expr);			}G_STMT_END
-
-#define gdm_assert_not_reached()	G_STMT_START{			\
-     gdm_fail ("GDM file %s: line %d (%s): should not be reached",	\
-	       __FILE__,						\
-	       __LINE__,						\
-	       __PRETTY_FUNCTION__);	}G_STMT_END
+#include "display.h"
 
 void gdm_fdprintf  (int fd, const gchar *format, ...) G_GNUC_PRINTF (2, 3);
 int gdm_fdgetc     (int fd);
@@ -182,6 +161,36 @@ const char * gdm_console_translate (cons
 
 gchar * gdm_read_default (gchar *key);
 
+#define NEVER_FAILS_seteuid(uid) \
+	{ int r = 0; \
+	  if (geteuid () != uid) \
+	    r = seteuid (uid); \
+	  if G_UNLIKELY (r != 0) \
+        gdm_fail ("GDM file %s: line %d (%s): Cannot run seteuid to %d: %s", \
+		  __FILE__,						\
+		  __LINE__,						\
+		  __PRETTY_FUNCTION__,					\
+                  (int)uid,						\
+		  strerror (errno));			}
+#define NEVER_FAILS_setegid(gid) \
+	{ int r = 0; \
+	  if (getegid () != gid) \
+	    r = setegid (gid); \
+	  if G_UNLIKELY (r != 0) \
+        gdm_fail ("GDM file %s: line %d (%s): Cannot run setegid to %d: %s", \
+		  __FILE__,						\
+		  __LINE__,						\
+		  __PRETTY_FUNCTION__,					\
+                  (int)gid,						\
+		  strerror (errno));			}
+
+/* first goes to euid-root and then sets the egid and euid, to make sure
+ * this succeeds */
+#define NEVER_FAILS_root_set_euid_egid(uid,gid) \
+	{ NEVER_FAILS_seteuid (0); \
+	  NEVER_FAILS_setegid (gid); \
+	  if (uid != 0) { NEVER_FAILS_seteuid (uid); } }
+
 #endif /* GDM_MISC_H */
 
 /* EOF */
Index: daemon/gdm-net.h
===================================================================
--- daemon/gdm-net.h	(revision 4731)
+++ daemon/gdm-net.h	(working copy)
@@ -21,15 +21,18 @@
 
 #include <glib.h>
 
-#ifndef TYPEDEF_GDM_CONNECTION
-#define TYPEDEF_GDM_CONNECTION
 typedef struct _GdmConnection GdmConnection;
-#endif  /* TYPEDEF_GDM_CONNECTION */
 
-#ifndef TYPEDEF_GDM_DISPLAY
-#define TYPEDEF_GDM_DISPLAY
-typedef struct _GdmDisplay GdmDisplay;
-#endif /* TYPEDEF_GDM_DISPLAY */
+#include "display.h"
+
+/* Macros to check authentication level */
+#define GDM_CONN_AUTHENTICATED(conn) \
+	((gdm_connection_get_user_flags (conn) & GDM_SUP_FLAG_AUTHENTICATED) || \
+	 (gdm_connection_get_user_flags (conn) & GDM_SUP_FLAG_AUTH_GLOBAL))
+
+#define GDM_CONN_AUTH_GLOBAL(conn) \
+	 (gdm_connection_get_user_flags (conn) & GDM_SUP_FLAG_AUTH_GLOBAL)
+
 
 /* Something that will get stuff line by line */
 typedef void (* GdmConnectionHandler) (GdmConnection *conn,
Index: daemon/gdmconsolekit.c
===================================================================
--- daemon/gdmconsolekit.c	(revision 4731)
+++ daemon/gdmconsolekit.c	(working copy)
@@ -21,13 +21,16 @@
 #include "config.h"
 
 #include <stdlib.h>
+#include <string.h>
 #include <pwd.h>
 
+#include <glib.h>
+
 #define DBUS_API_SUBJECT_TO_CHANGE
 #include <dbus/dbus.h>
 #include <dbus/dbus-glib-lowlevel.h>
 
-#include "misc.h" /* for gdm_debug */
+#include "gdm-log.h" /* for gdm_debug */
 #include "gdmconsolekit.h"
 
 
@@ -268,7 +271,7 @@ get_path_array_from_iter (DBusMessageIte
 	return buffer;
 
 oom:
-	fprintf (stderr, "%s %d : error allocating memory\n", __FILE__, __LINE__);
+	g_warning ("%s %d : error allocating memory\n", __FILE__, __LINE__);
 	return NULL;
 
 }
Index: daemon/display.c
===================================================================
--- daemon/display.c	(revision 4731)
+++ daemon/display.c	(working copy)
@@ -21,7 +21,6 @@
 #include "config.h"
 
 #include <glib/gi18n.h>
-#include <syslog.h>
 #include <signal.h>
 #include <sys/wait.h>
 #include <sys/types.h>
@@ -41,18 +40,16 @@
 #include "gdm-net.h"
 
 #include "gdm-common.h"
+#include "gdm-log.h"
 #include "gdm-daemon-config.h"
 
 /* External vars */
-extern gint xdmcp_sessions;
-extern gint flexi_servers;
-extern gint xdmcp_pending;
 extern gboolean gdm_in_final_cleanup;
-extern GSList *displays;
 extern GdmConnection *fifoconn;
 extern GdmConnection *pipeconn;
 extern GdmConnection *unixconn;
 extern int slave_fifo_pipe_fd; /* the slavepipe (like fifo) connection, this is the write end */
+extern gint flexi_servers;
 
 static gboolean
 gdm_display_check_loop (GdmDisplay *disp)
@@ -306,7 +303,7 @@ gdm_display_manage (GdmDisplay *d)
 	gdm_connection_close (unixconn);
 	unixconn = NULL;
 
-	closelog ();
+	gdm_log_shutdown ();
 
 	/* Close everything */
 	gdm_close_all_descriptors (0 /* from */, fds[0] /* except */, slave_fifo_pipe_fd /* except2 */);
@@ -317,7 +314,7 @@ gdm_display_manage (GdmDisplay *d)
 	gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
 	gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
 
-	openlog ("gdm", LOG_PID, LOG_DAEMON);
+	gdm_log_init ();
 
 	d->slave_notify_fd = fds[0];
 
@@ -405,19 +402,17 @@ static void
 count_session_limits (void)
 {
 	GSList *li;
+	GSList *displays;
+
+	displays = gdm_daemon_config_get_display_list ();
+
+	gdm_xdmcp_recount_sessions ();
 
-	xdmcp_sessions = 0;
-	xdmcp_pending = 0;
 	flexi_servers = 0;
 
 	for (li = displays; li != NULL; li = li->next) {
 		GdmDisplay *d = li->data;
-		if (SERVER_IS_XDMCP (d)) {
-			if (d->dispstat == XDMCP_MANAGED)
-				xdmcp_sessions++;
-			else if (d->dispstat == XDMCP_PENDING)
-				xdmcp_pending++;
-		}
+
 		if (SERVER_IS_FLEXI (d)) {
 			flexi_servers++;
 		}
@@ -434,6 +429,7 @@ count_session_limits (void)
 void
 gdm_display_dispose (GdmDisplay *d)
 {
+
     if (d == NULL)
 	return;
 
@@ -457,7 +453,7 @@ gdm_display_dispose (GdmDisplay *d)
 	    d->master_notify_fd = -1;
     }
 
-    displays = g_slist_remove (displays, d);
+    gdm_daemon_config_display_list_remove (d);
 
     d->dispstat = DISPLAY_DEAD;
     d->type = -1;
@@ -577,6 +573,9 @@ GdmDisplay *
 gdm_display_lookup (pid_t pid)
 {
     GSList *li;
+    GSList *displays;
+
+    displays = gdm_daemon_config_get_display_list ();
 
     /* Find slave in display list */
     for (li = displays; li != NULL; li = li->next) {
Index: daemon/gdmconsolekit.h
===================================================================
--- daemon/gdmconsolekit.h	(revision 4731)
+++ daemon/gdmconsolekit.h	(working copy)
@@ -22,6 +22,10 @@
 #ifndef __GDM_CONSOLE_KIT_H
 #define __GDM_CONSOLE_KIT_H
 
+#include <pwd.h>
+
+#include "display.h" /* for GdmDisplay */
+
 G_BEGIN_DECLS
 
 char *      open_ck_session       (struct passwd *pwent,
Index: daemon/gdm.c
===================================================================
--- daemon/gdm.c	(revision 4731)
+++ daemon/gdm.c	(working copy)
@@ -40,7 +40,6 @@
 #include <grp.h>
 #include <fcntl.h>
 #include <errno.h>
-#include <syslog.h>
 #include <locale.h>
 #include <dirent.h>
 #include <gtk/gtk.h>
@@ -68,7 +67,9 @@
 #include "filecheck.h"
 #include "errorgui.h"
 
+#include "gdm-socket-protocol.h"
 #include "gdm-daemon-config.h"
+#include "gdm-log.h"
 
 #define DYNAMIC_ADD     0
 #define DYNAMIC_RELEASE 1
@@ -78,8 +79,6 @@
 #include <libdevinfo.h>
 #endif  /* HAVE_LOGINDEVPERM */
 
-extern GSList *displays;
-
 /* Local functions */
 static void gdm_handle_message (GdmConnection *conn,
 				const gchar *msg,
@@ -105,8 +104,6 @@ static void custom_cmd_restart (long cmd
 static void custom_cmd_no_restart (long cmd_id);
 
 /* Global vars */
-gint xdmcp_sessions = 0;	/* Number of remote sessions */
-gint xdmcp_pending = 0;		/* Number of pending remote sessions */
 gint flexi_servers = 0;		/* Number of flexi servers */
 pid_t extra_process = 0;	/* An extra process.  Used for quickie 
 				   processes, so that they also get whacked */
@@ -162,7 +159,6 @@ static GMainLoop *main_loop = NULL;
 
 static gboolean monte_carlo_sqrt2 = FALSE;
 
-
 /*
  * lookup display number if the display number is
  * exists then clear the remove flag and return TRUE
@@ -171,7 +167,10 @@ static gboolean monte_carlo_sqrt2 = FALS
 static gboolean
 mark_display_exists (int num)
 {
-    GSList *li;
+	GSList *li;
+	GSList *displays;
+
+	displays = gdm_daemon_config_get_display_list ();
 
 	for (li = displays; li != NULL; li = li->next) {
 		GdmDisplay *disp = li->data;
@@ -248,6 +247,9 @@ static void 
 gdm_start_first_unborn_local (int delay)
 {
 	GSList *li;
+	GSList *displays;
+
+	displays = gdm_daemon_config_get_display_list ();
 
 	/* tickle the random stuff */
 	gdm_random_tick ();
@@ -302,6 +304,9 @@ gdm_final_cleanup (void)
 	GSList *list, *li;
 	const char *pidfile;
 	gboolean first;
+	GSList *displays;
+
+	displays = gdm_daemon_config_get_display_list ();
 
 	gdm_debug ("gdm_final_cleanup");
 
@@ -395,8 +400,6 @@ gdm_final_cleanup (void)
 		unixconn = NULL;
 	}
 
-	closelog ();
-
 	pidfile = GDM_PID_FILE;
 	if (pidfile != NULL) {
 		VE_IGNORE_EINTR (g_unlink (pidfile));
@@ -497,8 +500,6 @@ deal_with_x_crashes (GdmDisplay *d)
 		    if (gdm_daemon_config_get_value_bool (GDM_KEY_XDMCP))
 			    gdm_xdmcp_close ();
 
-		    closelog ();
-
 		    gdm_close_all_descriptors (0 /* from */, -1 /* except */, -1 /* except2 */);
 
 		    /* No error checking here - if it's messed the best response
@@ -1187,6 +1188,9 @@ static void
 gdm_safe_restart (void)
 {
 	GSList *li;
+	GSList *displays;
+
+	displays = gdm_daemon_config_get_display_list ();
 
 	if ( ! gdm_restart_mode)
 		return;
@@ -1231,6 +1235,9 @@ static void
 gdm_try_logout_action (GdmDisplay *disp)
 {
 	GSList *li;
+	GSList *displays;
+
+	displays = gdm_daemon_config_get_display_list ();
 
 	if (disp != NULL &&
 	    disp->logout_action != GDM_LOGOUT_ACTION_NONE &&
@@ -1610,6 +1617,11 @@ main (int argc, char *argv[])
 	    exit (0);
     }
 
+    gdm_log_init ();
+    /* Parse configuration file */
+    gdm_daemon_config_parse (config_file);
+    gdm_log_set_debug (gdm_daemon_config_get_bool_for_id (GDM_ID_DEBUG));
+
     /* XDM compliant error message */
     if G_UNLIKELY (getuid () != 0) {
 	    /* make sure the pid file doesn't get wiped */
@@ -1618,7 +1630,6 @@ main (int argc, char *argv[])
     }
 
     main_loop = g_main_loop_new (NULL, FALSE);
-    openlog ("gdm", LOG_PID, LOG_DAEMON);
 
     if ( ! g_get_charset (&charset)) {
 	    gdm_charset = g_strdup (charset);
@@ -1633,9 +1644,6 @@ main (int argc, char *argv[])
     sig.sa_flags = SA_RESTART;
     sigemptyset (&sig.sa_mask);
 
-    /* Parse configuration file */
-    gdm_daemon_config_parse (config_file);
-
     /*
      * Do not call gdm_fail before calling gdm_config_parse ()
      * since the gdm_fail function uses config data
@@ -1846,6 +1854,9 @@ static gboolean
 order_exists (int order)
 {
 	GSList *li;
+	GSList *displays;
+
+	displays = gdm_daemon_config_get_display_list ();
 	for (li = displays; li != NULL; li = li->next) {
 		GdmDisplay *d = li->data;
 		if (d->x_servers_order == order)
@@ -1859,6 +1870,9 @@ get_new_order (GdmDisplay *d)
 {
 	int order;
 	GSList *li;
+	GSList *displays;
+
+	displays = gdm_daemon_config_get_display_list ();
 	/* first try the position in the 'displays' list as
 	 * our order */
 	for (order = 0, li = displays; li != NULL; order++, li = li->next) {
@@ -2269,6 +2283,9 @@ gdm_handle_message (GdmConnection *conn,
 		if (d != NULL) {
 			GString *resp = NULL;
 			GSList *li;
+			GSList *displays;
+
+			displays = gdm_daemon_config_get_display_list ();
 			gdm_debug ("Got QUERYLOGIN %s", p);
 			for (li = displays; li != NULL; li = li->next) {
 				GdmDisplay *di = li->data;
@@ -2309,6 +2326,9 @@ gdm_handle_message (GdmConnection *conn,
 		long slave_pid;
 		char *p;
 		GSList *li;
+		GSList *displays;
+
+		displays = gdm_daemon_config_get_display_list ();
 
 		if (sscanf (msg, GDM_SOP_MIGRATE " %ld", &slave_pid) != 1)
 			return;
@@ -2459,12 +2479,18 @@ gdm_handle_message (GdmConnection *conn,
 		gdm_safe_restart ();
 	} else if (strcmp (msg, GDM_SOP_DIRTY_SERVERS) == 0) {
 		GSList *li;
+		GSList *displays;
+
+		displays = gdm_daemon_config_get_display_list ();
 		for (li = displays; li != NULL; li = li->next) {
 			GdmDisplay *d = li->data;
 			send_slave_command (d, GDM_NOTIFY_DIRTY_SERVERS);
 		}
 	} else if (strcmp (msg, GDM_SOP_SOFT_RESTART_SERVERS) == 0) {
 		GSList *li;
+		GSList *displays;
+
+		displays = gdm_daemon_config_get_display_list ();
 		for (li = displays; li != NULL; li = li->next) {
 			GdmDisplay *d = li->data;
 			send_slave_command (d, GDM_NOTIFY_SOFT_RESTART_SERVERS);
@@ -2492,12 +2518,16 @@ gdm_handle_message (GdmConnection *conn,
 			return;
 		p++;
 
-		syslog (type, "(child %ld) %s", pid, p);
+		/* FIXME: use g_critical or g_debug when required */
+		g_warning ("(child %ld) %s", pid, p);
 	} else if (strcmp (msg, GDM_SOP_START_NEXT_LOCAL) == 0) {
 		gdm_start_first_unborn_local (3 /* delay */);
 	} else if (strcmp (msg, GDM_SOP_HUP_ALL_GREETERS) == 0) {
 		/* probably shouldn't be done too often */
 		GSList *li;
+		GSList *displays;
+
+		displays = gdm_daemon_config_get_display_list ();
 		for (li = displays; li != NULL; li = li->next) {
 			GdmDisplay *d = li->data;
 			if (d->greetpid > 1)
@@ -2508,6 +2538,9 @@ gdm_handle_message (GdmConnection *conn,
 	} else if (strcmp (msg, GDM_SOP_GO) == 0) {
 		GSList *li;
 		gboolean old_wait = gdm_wait_for_go;
+		GSList *displays;
+
+		displays = gdm_daemon_config_get_display_list ();
 		gdm_wait_for_go = FALSE;
 		for (li = displays; li != NULL; li = li->next) {
 			GdmDisplay *d = li->data;
@@ -2887,6 +2920,9 @@ static GdmDisplay *
 find_display (const char *name)
 {
 	GSList *li;
+	GSList *displays;
+
+	displays = gdm_daemon_config_get_display_list ();
 
 	for (li = displays; li != NULL; li = li->next) {
 		GdmDisplay *disp = li->data;
@@ -3141,7 +3177,8 @@ handle_flexi_server (GdmConnection *conn
 	display->parent_auth_file = g_strdup (xnest_auth_file);
 	if (conn != NULL)
 		gdm_connection_set_close_notify (conn, display, close_conn);
-	displays = g_slist_append (displays, display);
+	gdm_daemon_config_display_list_append (display);
+
 	if ( ! gdm_display_manage (display)) {
 		gdm_display_unmanage (display);
 		if (conn != NULL)
@@ -3205,9 +3242,8 @@ handle_dynamic_server (GdmConnection *co
             gdm_connection_write (conn, "ERROR 4 Display startup failure\n");
             return;
         }
-        displays = g_slist_insert_sorted (displays,
-                                          disp,
-                                          gdm_daemon_config_compare_displays);
+
+	gdm_daemon_config_display_list_insert (disp);
 
         disp->dispstat = DISPLAY_CONFIG;
         disp->removeconf = FALSE;
@@ -3222,6 +3258,10 @@ handle_dynamic_server (GdmConnection *co
     if (type == DYNAMIC_REMOVE) {
         GSList *li;
         GSList *nli;
+	GSList *displays;
+
+	displays = gdm_daemon_config_get_display_list ();
+
         /* shutdown a dynamic X server */
 
         for (li = displays; li != NULL; li = nli) {
@@ -3245,6 +3285,9 @@ handle_dynamic_server (GdmConnection *co
         GSList *li;
         GSList *nli;
 	gboolean found = FALSE;
+	GSList *displays;
+
+	displays = gdm_daemon_config_get_display_list ();
 
         for (li = displays; li != NULL; li = nli) {
             GdmDisplay *disp = li->data;
@@ -3292,6 +3335,10 @@ gdm_handle_user_message (GdmConnection *
 		GSList *li;
 		gchar *cookie = g_strdup
 			(&msg[strlen (GDM_SUP_AUTH_LOCAL " ")]);
+		GSList *displays;
+
+		displays = gdm_daemon_config_get_display_list ();
+
 		g_strstrip (cookie);
 		if (strlen (cookie) != 16*2) /* 16 bytes in hex form */ {
 			/* evil, just whack the connection in this case */
@@ -3467,6 +3514,9 @@ gdm_handle_user_message (GdmConnection *
 		const gchar *sep = " ";
 		char    *key;
 		int     msgLen=0;
+		GSList *displays;
+
+		displays = gdm_daemon_config_get_display_list ();
 
 		if (strncmp (msg, GDM_SUP_ATTACHED_SERVERS,
 		             strlen (GDM_SUP_ATTACHED_SERVERS)) == 0)
@@ -3505,6 +3555,9 @@ gdm_handle_user_message (GdmConnection *
 		GString *msg;
 		GSList *li;
 		const gchar *sep = " ";
+		GSList *displays;
+
+		displays = gdm_daemon_config_get_display_list ();
 
 		msg = g_string_new ("OK");
 		for (li = displays; li != NULL; li = li->next) {
@@ -3578,6 +3631,9 @@ gdm_handle_user_message (GdmConnection *
 		GString *msg;
 		GSList *li;
 		const gchar *sep = " ";
+		GSList *displays;
+
+		displays = gdm_daemon_config_get_display_list ();
 
 		msg = g_string_new ("OK");
 		for (li = displays; li != NULL; li = li->next) {
@@ -3961,6 +4017,9 @@ gdm_handle_user_message (GdmConnection *
 			    strlen (GDM_SUP_SET_VT " ")) == 0) {
 		int vt;
 		GSList *li;
+		GSList *displays;
+
+		displays = gdm_daemon_config_get_display_list ();
 
 		if (sscanf (msg, GDM_SUP_SET_VT " %d", &vt) != 1 ||
 		    vt < 0) {
Index: daemon/display.h
===================================================================
--- daemon/display.h	(revision 4731)
+++ daemon/display.h	(working copy)
@@ -1,4 +1,6 @@
-/* GDM - The GNOME Display Manager
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * 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
@@ -16,16 +18,176 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#ifndef GDM_DISPLAY_H
-#define GDM_DISPLAY_H
+#ifndef _GDM_DISPLAY_H
+#define _GDM_DISPLAY_H
+
+#include <X11/Xlib.h> /* for Display */
+#include <X11/Xmd.h> /* for CARD32 */
+#include <netinet/in.h> /* for in_addr */
+
+typedef struct _GdmDisplay GdmDisplay;
+
+#include "gdm-net.h" /* for GdmConnection */
+
+#define TYPE_STATIC 1		/* X server defined in GDM configuration */
+#define TYPE_XDMCP 2		/* Remote display/Xserver */
+#define TYPE_FLEXI 3		/* Local Flexi X server */
+#define TYPE_FLEXI_XNEST 4	/* Local Flexi Nested server */
+#define TYPE_XDMCP_PROXY 5	/* Proxy X server for XDMCP */
+
+#define SERVER_IS_LOCAL(d) ((d)->type == TYPE_STATIC || \
+			    (d)->type == TYPE_FLEXI || \
+			    (d)->type == TYPE_FLEXI_XNEST || \
+			    (d)->type == TYPE_XDMCP_PROXY)
+#define SERVER_IS_FLEXI(d) ((d)->type == TYPE_FLEXI || \
+			    (d)->type == TYPE_FLEXI_XNEST || \
+			    (d)->type == TYPE_XDMCP_PROXY)
+#define SERVER_IS_PROXY(d) ((d)->type == TYPE_FLEXI_XNEST || \
+			    (d)->type == TYPE_XDMCP_PROXY)
+#define SERVER_IS_XDMCP(d) ((d)->type == TYPE_XDMCP || \
+			    (d)->type == TYPE_XDMCP_PROXY)
+
+/* Use this to get the right authfile name */
+#define GDM_AUTHFILE(display) \
+	(display->authfile_gdm != NULL ? display->authfile_gdm : display->authfile)
+
+/* Values between GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST and
+   GDM_LOGOUT_ACTION_CUSTOM_CMD_LAST are reserved and should not be used */
+typedef enum {
+	GDM_LOGOUT_ACTION_NONE = 0,
+	GDM_LOGOUT_ACTION_HALT,
+	GDM_LOGOUT_ACTION_REBOOT,
+	GDM_LOGOUT_ACTION_SUSPEND,
+	GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST,
+	GDM_LOGOUT_ACTION_CUSTOM_CMD_LAST,
+	GDM_LOGOUT_ACTION_LAST
+} GdmLogoutAction;
+
+struct _GdmDisplay
+{
+	CARD32 sessionid;
+	Display *dsp;
+	gchar *authfile; /* authfile for the server */
+	gchar *authfile_gdm; /* authfile readable by gdm user
+				if necessary */
+	GSList *auths; 
+	GSList *local_auths; 
+	gchar *userauth;
+	gboolean authfb;
+	time_t last_auth_touch;
+	gchar *command;
+	gboolean failsafe_xserver;
+	gboolean use_chooser; /* run chooser instead of greeter */
+	gchar *chosen_hostname; /* locally chosen hostname if not NULL,
+				   "-query chosen_hostname" is appened to server command line */
+	guint indirect_id;
+	gchar *cookie;
+	gchar *bcookie;
+	gchar *name;
+	gchar *hostname;
+	struct in_addr addr;
+#ifdef ENABLE_IPV6
+	struct in6_addr addr6;
+	struct sockaddr_storage *addrs; /* array of addresses */
+#else
+	struct in_addr *addrs; /* array of addresses */
+#endif
+	int addrtype;        /* Specifying the variable used, addr or addr6  */
+	int addr_count; /* number of addresses in array */
+	/* Note that the above may in fact be empty even though
+	   addr is set, these are just extra addresses
+	   (it could also contain addr for all we know) */
+
+	guint8 dispstat;
+	guint16 dispnum;
+	gboolean removeconf;
+	guint8 servstat;
+	time_t starttime;
+	time_t managetime;
+	guint8 type;
+	pid_t greetpid;
+	pid_t servpid;
+	pid_t sesspid;
+	int last_sess_status; /* status returned by last session */
+	pid_t slavepid;
+	pid_t chooserpid;
+	time_t acctime;
+
+	gboolean handled;
+	gboolean tcp_disallowed;
+
+	int priority;
+	int vt;
+
+	gboolean busy_display;
+
+	gboolean attached;  /* Display is physically attached to the machine. */
+	/* TYPE_XDMCP would have this FALSE, eg. */
+
+	time_t last_start_time;
+	time_t last_loop_start_time;
+	gint retry_count;
+
+	int sleep_before_run;
+
+	time_t last_x_failed;
+	int x_faileds;
+
+	gboolean try_different_greeter;
+
+	gboolean logged_in; /* TRUE if someone is logged in */
+	char *login;
+
+	char *preset_user;
+
+	gboolean timed_login_ok;
+
+	int screenx;
+	int screeny;
+	int screenwidth; /* Note 0 means use the gdk size */
+	int screenheight;
+	int lrh_offsetx; /* lower right hand corner x offset */
+	int lrh_offsety; /* lower right hand corner y offset */
+
+	/* Flexi stuff */
+	char *parent_disp;
+	Display *parent_dsp;
+	char *parent_auth_file;
+	char *parent_temp_auth_file;
+	uid_t server_uid;
+	GdmConnection *socket_conn;
+
+	int xdmcp_dispnum;
+
+	/* Notification connection */
+	int master_notify_fd;  /* write part of the connection */
+	int slave_notify_fd; /* read part of the connection */
+
+	/* order in the Xservers file for sessreg, -1 if unset yet */
+	int x_servers_order;
+
+	/* The xsession-errors connection */
+	int xsession_errors_fd; /* write to the file */
+	int session_output_fd; /* read from the session */
+	int xsession_errors_bytes;
+#define MAX_XSESSION_ERRORS_BYTES (80*2500)  /* maximum number of bytes in
+						the ~/.xsession-errors file */
+	char *xsession_errors_filename; /* if NULL then there is no .xsession-errors
+					   file */
+
+	int chooser_output_fd; /* from the chooser */
+	char *chooser_last_line;
+
+	/* Only set in the main daemon as that's the only place that cares */
+	GdmLogoutAction logout_action;
 
-#include "gdm.h"
+	char *theme_name;
+};
 
 gboolean    gdm_display_manage   (GdmDisplay *d);
 void        gdm_display_dispose  (GdmDisplay *d);
 void        gdm_display_unmanage (GdmDisplay *d);
 GdmDisplay *gdm_display_lookup   (pid_t pid);
 
-#endif /* GDM_DISPLAY_H */
+#endif /* _GDM_DISPLAY_H */
 
-/* EOF */
Index: daemon/xdmcp.c
===================================================================
--- daemon/xdmcp.c	(revision 4731)
+++ daemon/xdmcp.c	(working copy)
@@ -1,4 +1,6 @@
-/* GDM - The GNOME Display Manager
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * 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
@@ -61,7 +63,6 @@
 #include <unistd.h>
 #include <time.h>
 #include <stdlib.h>
-#include <syslog.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -103,6 +104,7 @@
 #include "cookie.h"
 
 #include "gdm-common.h"
+#include "gdm-log.h"
 #include "gdm-daemon-config.h"
 
 /*This is to be changed when the Xdmcp Multicast address is decided */
@@ -110,11 +112,10 @@
 
 int gdm_xdmcpfd = -1;
 
-#ifdef HAVE_LIBXDMCP
+static gint xdmcp_sessions = 0;	/* Number of remote sessions */
+static gint xdmcp_pending = 0;  /* Number of pending remote sessions */
 
-/* TCP Wrapper syslog control */
-gint allow_severity = LOG_INFO;
-gint deny_severity = LOG_WARNING;
+#ifdef HAVE_LIBXDMCP
 
 static guint xdmcp_source = 0;
 static CARD32 globsessid;
@@ -123,10 +124,6 @@ static ARRAY8 servhost;
 static XdmcpBuffer buf;
 static gboolean initted = FALSE;
 
-extern GSList *displays;
-extern gint xdmcp_pending;
-extern gint xdmcp_sessions;
-
 /* Local prototypes */
 static gboolean gdm_xdmcp_decode_packet (GIOChannel *source,
 					 GIOCondition cond,
@@ -311,6 +308,9 @@ gdm_xdmcp_displays_from_host (struct soc
 {
 	GSList *li;
 	int count = 0;
+        GSList *displays;
+
+        displays = gdm_daemon_config_get_display_list ();
 
 	for (li = displays; li != NULL; li = li->next) {
 		GdmDisplay *disp = li->data;
@@ -341,6 +341,9 @@ gdm_xdmcp_display_lookup_by_host (struct
 #endif
 {
 	GSList *li;
+        GSList *displays;
+
+        displays = gdm_daemon_config_get_display_list ();
 
 	for (li = displays; li != NULL; li = li->next) {
 		GdmDisplay *disp = li->data;
@@ -366,7 +369,6 @@ gdm_xdmcp_display_lookup_by_host (struct
 	return NULL;
 }
 
-
 gboolean
 gdm_xdmcp_init (void)
 {
@@ -2826,8 +2828,8 @@ gdm_xdmcp_display_alloc (
 	    d->authfile         = NULL;
     }
 
-    displays = g_slist_append (displays, d);
-    
+    gdm_daemon_config_display_list_append (d);
+
     xdmcp_pending++;
     
     gdm_debug ("gdm_xdmcp_display_alloc: display=%s, session id=%ld, xdmcp_pending=%d",
@@ -2840,7 +2842,7 @@ gdm_xdmcp_display_alloc (
 static GdmDisplay *
 gdm_xdmcp_display_lookup (CARD32 sessid)
 {
-    GSList *dlist = displays;
+    GSList *dlist = gdm_daemon_config_get_display_list ();
     GdmDisplay *d;
     
     if (!sessid)
@@ -2863,6 +2865,9 @@ static void
 gdm_xdmcp_display_dispose_check (const gchar *hostname, int dspnum)
 {
 	GSList *dlist;
+        GSList *displays;
+
+        displays = gdm_daemon_config_get_display_list ();
 
 	if (hostname == NULL)
 		return;
@@ -2896,6 +2901,9 @@ gdm_xdmcp_displays_check (void)
 {
 	GSList *dlist;
 	time_t curtime = time (NULL);
+        GSList *displays;
+
+        displays = gdm_daemon_config_get_display_list ();
 
 	dlist = displays;
 	while (dlist != NULL) {
@@ -3003,4 +3011,26 @@ gdm_xdmcp_migrate (GdmDisplay *from, Gdm
 
 #endif /* HAVE_LIBXDMCP */
 
+void
+gdm_xdmcp_recount_sessions (void)
+{
+	GSList *li;
+	GSList *displays;
+
+	displays = gdm_daemon_config_get_display_list ();
+
+	xdmcp_sessions = 0;
+	xdmcp_pending = 0;
+
+	for (li = displays; li != NULL; li = li->next) {
+		GdmDisplay *d = li->data;
+		if (SERVER_IS_XDMCP (d)) {
+			if (d->dispstat == XDMCP_MANAGED)
+				xdmcp_sessions++;
+			else if (d->dispstat == XDMCP_PENDING)
+				xdmcp_pending++;
+		}
+	}
+}
+
 /* EOF */
Index: daemon/gdm.h
===================================================================
--- daemon/gdm.h	(revision 4731)
+++ daemon/gdm.h	(working copy)
@@ -21,47 +21,9 @@
 #ifndef GDM_H
 #define GDM_H
 
-#include <glib.h>
-#include <glib/gstdio.h>
-#include <X11/Xlib.h>
-#include <X11/Xmd.h>
-#include <X11/Xauth.h>
-#include <netinet/in.h>
-#include <time.h>
-
 #define GDM_MAX_PASS 256	/* Define a value for password length. Glibc
 				 * leaves MAX_PASS undefined. */
 
-#define STX 0x2			/* Start of txt */
-#define BEL 0x7			/* Bell, used to interrupt login for
-				 * say timed login or something similar */
-
-#define TYPE_STATIC 1		/* X server defined in GDM configuration */
-#define TYPE_XDMCP 2		/* Remote display/Xserver */
-#define TYPE_FLEXI 3		/* Local Flexi X server */
-#define TYPE_FLEXI_XNEST 4	/* Local Flexi Nested server */
-#define TYPE_XDMCP_PROXY 5	/* Proxy X server for XDMCP */
-
-#define SERVER_IS_LOCAL(d) ((d)->type == TYPE_STATIC || \
-			    (d)->type == TYPE_FLEXI || \
-			    (d)->type == TYPE_FLEXI_XNEST || \
-			    (d)->type == TYPE_XDMCP_PROXY)
-#define SERVER_IS_FLEXI(d) ((d)->type == TYPE_FLEXI || \
-			    (d)->type == TYPE_FLEXI_XNEST || \
-			    (d)->type == TYPE_XDMCP_PROXY)
-#define SERVER_IS_PROXY(d) ((d)->type == TYPE_FLEXI_XNEST || \
-			    (d)->type == TYPE_XDMCP_PROXY)
-#define SERVER_IS_XDMCP(d) ((d)->type == TYPE_XDMCP || \
-			    (d)->type == TYPE_XDMCP_PROXY)
-
-/* These are the servstat values, also used as server
- * process exit codes */
-#define SERVER_TIMEOUT 2	/* Server didn't start */
-#define SERVER_DEAD 250		/* Server stopped */
-#define SERVER_PENDING 251	/* Server started but not ready for connections yet */
-#define SERVER_RUNNING 252	/* Server running and ready for connections */
-#define SERVER_ABORT 253	/* Server failed badly. Suspending display. */
-
 /* DO NOTE USE 1, that's used as error if x connection fails usually */
 /* Note that there is no reason why these were a power of two, and note
  * that they have to fit in 256 */
@@ -88,56 +50,7 @@ enum {
 	DISPLAY_CONFIG /* in process of being configured */
 };
 
-/* Opcodes for the highly sophisticated protocol used for
- * daemon<->greeter communications */
-
-/* This will change if there are incompatible
- * protocol changes */
-#define GDM_GREETER_PROTOCOL_VERSION "3"
-
-#define GDM_MSG        'D'
-#define GDM_NOECHO     'U'
-#define GDM_PROMPT     'N'
-#define GDM_SESS       'G'
-#define GDM_LANG       '&'
-#define GDM_SSESS      'C'
-#define GDM_SLANG      'R'
-#define GDM_RESET      'A'
-#define GDM_QUIT       'P'
-/* Well these aren't as nice as above, oh well */
-#define GDM_STARTTIMER 's'
-#define GDM_STOPTIMER  'S'
-#define GDM_SETLOGIN   'l' /* this just sets the login to be this, just for
-			      the greeters knowledge */
-#define GDM_DISABLE    '-' /* disable the login screen */
-#define GDM_ENABLE     '+' /* enable the login screen */
-#define GDM_RESETOK    'r' /* reset but don't shake */
-#define GDM_NEEDPIC    '#' /* need a user picture?, sent after greeter
-			    *  is started */
-#define GDM_READPIC    '%' /* Send a user picture in a temp file */
-#define GDM_ERRBOX     'e' /* Puts string in the error box */
-#define GDM_ERRDLG     'E' /* Puts string up in an error dialog */
-#define GDM_NOFOCUS    'f' /* Don't focus the login window (optional) */
-#define GDM_FOCUS      'F' /* Allow focus on the login window again (optional) */
-#define GDM_SAVEDIE    '!' /* Save wm order and die (and set busy cursor) */
-#define GDM_QUERY_CAPSLOCK 'Q' /* Is capslock on? */
-
-/* Different login interruptions */
-#define GDM_INTERRUPT_TIMED_LOGIN 'T'
-#define GDM_INTERRUPT_CONFIGURE   'C'
-#define GDM_INTERRUPT_SUSPEND     'S'
-#define GDM_INTERRUPT_SELECT_USER 'U'
-#define GDM_INTERRUPT_LOGIN_SOUND 'L'
-#define GDM_INTERRUPT_THEME       'H'
-#define GDM_INTERRUPT_CUSTOM_CMD  'M'
-#define GDM_INTERRUPT_CANCEL      'X'
-
-/* List delimiter for config file lists */
-#define GDM_DELIMITER_MODULES ":"
-#define GDM_DELIMITER_THEMES "/:"
-
 /* The dreaded miscellaneous category */
-#define FIELD_SIZE 256
 #define PIPE_SIZE 4096
 
 /*
@@ -167,977 +80,15 @@ enum {
 
 #define GDM_RESPONSE_CANCEL "GDM_RESPONSE_CANCEL"
 
-#ifndef TYPEDEF_GDM_CONNECTION
-#define TYPEDEF_GDM_CONNECTION
-typedef struct _GdmConnection GdmConnection;
-#endif  /* TYPEDEF_GDM_CONNECTION */
-
-#ifndef TYPEDEF_GDM_CUSTOM_CMD
-#define TYPEDEF_GDM_CUSTOM_CMD
-typedef struct _GdmCustomCmd GdmCustomCmd;
-#endif /* TYPEDEF_GDM_CUSTOM_CMD */
-struct _GdmCustomCmd {
-    gchar *command; /* command(s) to execute */
-    gchar *command_label; /* button/menu item label */
-    gchar *command_lr_label; /* radio button/list item label */
-    gchar *command_text; /* warning dialog text */
-    gchar *command_tooltip; /* tooltip string */
-    gboolean command_no_restart; /* no restart flag */
-    gboolean command_is_persistent; /* persistence flag */
-};
-
 #define GDM_CUSTOM_COMMAND_MAX 10 /* maximum number of supported custom commands */
 
-/* Values between GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST and 
-   GDM_LOGOUT_ACTION_CUSTOM_CMD_LAST are reserved and should not be used */
-typedef enum {
-	GDM_LOGOUT_ACTION_NONE = 0,
-	GDM_LOGOUT_ACTION_HALT,
-	GDM_LOGOUT_ACTION_REBOOT,
-	GDM_LOGOUT_ACTION_SUSPEND,
-	GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST,
-	GDM_LOGOUT_ACTION_CUSTOM_CMD_LAST = GDM_LOGOUT_ACTION_CUSTOM_CMD_FIRST + GDM_CUSTOM_COMMAND_MAX - 1,
-	GDM_LOGOUT_ACTION_LAST
-} GdmLogoutAction;
-
-#ifndef TYPEDEF_GDM_DISPLAY
-#define TYPEDEF_GDM_DISPLAY
-typedef struct _GdmDisplay GdmDisplay;
-#endif /* TYPEDEF_GDM_DISPLAY */
-
-/* Use this to get the right authfile name */
-#define GDM_AUTHFILE(display) \
-	(display->authfile_gdm != NULL ? display->authfile_gdm : display->authfile)
-
 #ifdef sun
 #define SDTLOGIN_DIR "/var/dt/sdtlogin"
 #endif
 
-struct _GdmDisplay {
-    CARD32 sessionid;
-    Display *dsp;
-    gchar *authfile; /* authfile for the server */
-    gchar *authfile_gdm; /* authfile readable by gdm user
-			    if necessary */
-    GSList *auths; 
-    GSList *local_auths; 
-    gchar *userauth;
-    gboolean authfb;
-    time_t last_auth_touch;
-    gchar *command;
-    gboolean failsafe_xserver;
-    gboolean use_chooser; /* run chooser instead of greeter */
-    gchar *chosen_hostname; /* locally chosen hostname if not NULL,
-			       "-query chosen_hostname" is appened to server command line */
-    guint indirect_id;
-    gchar *cookie;
-    gchar *bcookie;
-    gchar *name;
-    gchar *hostname;
-    struct in_addr addr;
-#ifdef ENABLE_IPV6
-    struct in6_addr addr6;
-    struct sockaddr_storage *addrs; /* array of addresses */
-#else
-    struct in_addr *addrs; /* array of addresses */
-#endif
-    int addrtype;        /* Specifying the variable used, addr or addr6  */
-    int addr_count; /* number of addresses in array */
-    /* Note that the above may in fact be empty even though
-       addr is set, these are just extra addresses
-       (it could also contain addr for all we know) */
-
-    guint8 dispstat;
-    guint16 dispnum;
-	gboolean removeconf;
-    guint8 servstat;
-    time_t starttime;
-    time_t managetime;
-    guint8 type;
-    pid_t greetpid;
-    pid_t servpid;
-    pid_t sesspid;
-    int last_sess_status; /* status returned by last session */
-    pid_t slavepid;
-    pid_t chooserpid;
-    time_t acctime;
-
-    gboolean handled;
-    gboolean tcp_disallowed;
-
-    int priority;
-    int vt;
-
-    gboolean busy_display;
-
-    gboolean attached;  /* Display is physically attached to the machine. */
-                        /* TYPE_XDMCP would have this FALSE, eg. */
-
-    time_t last_start_time;
-    time_t last_loop_start_time;
-    gint retry_count;
-
-    int sleep_before_run;
-
-    time_t last_x_failed;
-    int x_faileds;
-
-    gboolean try_different_greeter;
-
-    gboolean logged_in; /* TRUE if someone is logged in */
-    char *login;
-
-    char *preset_user;
-
-    gboolean timed_login_ok;
-
-    int screenx;
-    int screeny;
-    int screenwidth; /* Note 0 means use the gdk size */
-    int screenheight;
-    int lrh_offsetx; /* lower right hand corner x offset */
-    int lrh_offsety; /* lower right hand corner y offset */
-
-    /* Flexi stuff */
-    char *parent_disp;
-    Display *parent_dsp;
-    char *parent_auth_file;
-    char *parent_temp_auth_file;
-    uid_t server_uid;
-    GdmConnection *socket_conn;
-
-    int xdmcp_dispnum;
-
-    /* Notification connection */
-    int master_notify_fd;  /* write part of the connection */
-    int slave_notify_fd; /* read part of the connection */
-
-    /* order in the Xservers file for sessreg, -1 if unset yet */
-    int x_servers_order;
-
-    /* The xsession-errors connection */
-    int xsession_errors_fd; /* write to the file */
-    int session_output_fd; /* read from the session */
-    int xsession_errors_bytes;
-#define MAX_XSESSION_ERRORS_BYTES (80*2500)  /* maximum number of bytes in
-						the ~/.xsession-errors file */
-    char *xsession_errors_filename; /* if NULL then there is no .xsession-errors
-				       file */
-
-    int chooser_output_fd; /* from the chooser */
-    char *chooser_last_line;
-
-    /* Only set in the main daemon as that's the only place that cares */
-    GdmLogoutAction logout_action;
-    
-    char *theme_name;
-};
-
-typedef struct _GdmXserver GdmXserver;
-struct _GdmXserver {
-	char *id;
-	char *name;
-	char *command;
-	gboolean flexible;
-	gboolean choosable; /* not implemented yet */
-	gboolean chooser; /* instead of greeter, run chooser */
-	gboolean handled;
-	int number;
-	int priority;
-};
-
-typedef struct _GdmIndirectDisplay GdmIndirectDisplay;
-struct _GdmIndirectDisplay {
-	int id;
-#ifdef ENABLE_IPV6
-       struct sockaddr_storage* dsp_sa;
-       struct in6_addr* chosen_host6;
-#else
-	struct sockaddr_in* dsp_sa;
-#endif
-	time_t acctime;
-	struct in_addr *chosen_host;
-};
-
-/* NOTE: Timeout and max are hardcoded */
-typedef struct _GdmForwardQuery GdmForwardQuery;
-struct _GdmForwardQuery {
-	time_t acctime;
-#ifdef ENABLE_IPV6
-       struct sockaddr_storage* dsp_sa;
-       struct sockaddr_storage* from_sa;
-#else
-	struct sockaddr_in* dsp_sa;
-	struct sockaddr_in* from_sa;
-#endif
-};
-#define GDM_MAX_FORWARD_QUERIES 10
-#define GDM_FORWARD_QUERY_TIMEOUT 30
-
-/* some extra XDMCP opcodes that xdm will happily ignore since they'll be
- * the wrong XDMCP version anyway */
-#define GDM_XDMCP_PROTOCOL_VERSION 1001
-enum {
-	GDM_XDMCP_FIRST_OPCODE = 1000, /*just a marker, not an opcode */
-
-	GDM_XDMCP_MANAGED_FORWARD = 1000,
-		/* manager (master) -> manager
-		 * A packet with MANAGED_FORWARD is sent to the
-		 * manager that sent the forward query from the manager to
-		 * which forward query was sent.  It indicates that the forward
-		 * was fully processed and that the client now has either
-		 * a managed session, or has been sent denial, refuse or failed.
-		 * (if the denial gets lost then client gets dumped into the
-		 * chooser again).  This should be resent a few times
-		 * until some (short) timeout or until GOT_MANAGED_FORWARD
-		 * is sent.  GDM sends at most 3 packates with 1.5 seconds
-		 * between each.
-		 *
-		 * Argument is ARRAY8 with the address of the originating host */
-	GDM_XDMCP_GOT_MANAGED_FORWARD,
-		/* manager -> manager (master)
-		 * A single packet with GOT_MANAGED_FORWARD is sent to indicate
-		 * that we did receive the MANAGED_FORWARD packet.  The argument
-		 * must match the MANAGED_FORWARD one or it will just be ignored.
-		 *
-		 * Argument is ARRAY8 with the address of the originating host */
-	GDM_XDMCP_LAST_OPCODE /*just a marker, not an opcode */
-};
-
 /* If id == NULL, then get the first X server */
 void		gdm_final_cleanup	(void);
 
-
-/* primitive protocol for controlling the daemon from slave
- * or gdmconfig or whatnot */
-
-/* The ones that pass a <slave pid> must be from a valid slave, and
- * the slave will be sent a SIGUSR2.  Nowdays there is a pipe that is
- * used from inside slaves, so those messages may stop being processed
- * by the fifo at some point perhaps.  */
-/* The fifo protocol, used only by gdm internally */
-#define GDM_SOP_CHOSEN       "CHOSEN" /* <indirect id> <ip addr> */
-#define GDM_SOP_CHOSEN_LOCAL "CHOSEN_LOCAL" /* <slave pid> <hostname> */
-#define GDM_SOP_XPID         "XPID" /* <slave pid> <xpid> */
-#define GDM_SOP_SESSPID      "SESSPID" /* <slave pid> <sesspid> */
-#define GDM_SOP_GREETPID     "GREETPID" /* <slave pid> <greetpid> */
-#define GDM_SOP_CHOOSERPID   "CHOOSERPID" /* <slave pid> <chooserpid> */
-#define GDM_SOP_LOGGED_IN    "LOGGED_IN" /* <slave pid> <logged_in as int> */
-#define GDM_SOP_LOGIN        "LOGIN" /* <slave pid> <username> */
-#define GDM_SOP_COOKIE       "COOKIE" /* <slave pid> <cookie> */
-#define GDM_SOP_AUTHFILE     "AUTHFILE" /* <slave pid> <authfile> */
-#define GDM_SOP_QUERYLOGIN   "QUERYLOGIN" /* <slave pid> <username> */
-/* if user already logged in somewhere, the ack response will be
-   <display>,<migratable>,<display>,<migratable>,... */
-#define GDM_SOP_MIGRATE      "MIGRATE" /* <slave pid> <display> */
-#define GDM_SOP_DISP_NUM     "DISP_NUM" /* <slave pid> <display as int> */
-/* For Linux only currently */
-#define GDM_SOP_VT_NUM       "VT_NUM" /* <slave pid> <vt as int> */
-#define GDM_SOP_FLEXI_ERR    "FLEXI_ERR" /* <slave pid> <error num> */
-	/* 3 = X failed */
-	/* 4 = X too busy */
-	/* 5 = Nest display can't connect */
-#define GDM_SOP_FLEXI_OK     "FLEXI_OK" /* <slave pid> */
-#define GDM_SOP_SOFT_RESTART "SOFT_RESTART" /* no arguments */
-#define GDM_SOP_START_NEXT_LOCAL "START_NEXT_LOCAL" /* no arguments */
-#define GDM_SOP_HUP_ALL_GREETERS "HUP_ALL_GREETERS" /* no arguments */
-
-/* stop waiting for this and go on with your life, useful with
-   the --wait-for-go command line option */
-#define GDM_SOP_GO "GO" /* no arguments */
-
-/* sometimes we can't do a syslog so we tell the main daemon */
-#define GDM_SOP_SYSLOG "SYSLOG" /* <pid> <type> <message> */
-
-/* write out a sessreg (xdm) compatible Xservers file
- * in the ServAuthDir as <name>.Xservers */
-#define GDM_SOP_WRITE_X_SERVERS "WRITE_X_SERVERS" /* <slave pid> */
-
-/* All X servers should be restarted rather then regenerated.  Useful
- * if you have updated the X configuration.  Note that this happens
- * only when the user logs out or when we otherwise would have restarted
- * a server, nothing is done by this command. */
-#define GDM_SOP_DIRTY_SERVERS "DIRTY_SERVERS"  /* no arguments */
-
-/* restart all servers that people aren't logged in on.  Maybe you may not
- * want to do this on every change of X server config since this may cause
- * flicker on screen and jumping around on the vt.  Perhaps useful to do
- * by asking the user if they want to do that.  Note that this will not
- * kill any logged in sessions. */
-#define GDM_SOP_SOFT_RESTART_SERVERS "SOFT_RESTART_SERVERS"  /* no arguments */
-/* Suspend the machine if it is even allowed */
-#define GDM_SOP_SUSPEND_MACHINE "SUSPEND_MACHINE"  /* no arguments */
-#define GDM_SOP_CHOSEN_THEME "CHOSEN_THEME"  /* <slave pid> <theme name> */
-
-/*Execute custom cmd*/
-#define GDM_SOP_CUSTOM_CMD "CUSTOM_CMD"  /* <slave pid> <cmd id> */
-
-/* Start a new standard X flexible server */
-#define GDM_SOP_FLEXI_XSERVER "FLEXI_XSERVER" /* no arguments */
-
-#define GDM_SOP_SHOW_ERROR_DIALOG "SHOW_ERROR_DIALOG"  /* show the error dialog from daemon */
-#define GDM_SOP_SHOW_YESNO_DIALOG "SHOW_YESNO_DIALOG"  /* show the yesno dialog from daemon */
-#define GDM_SOP_SHOW_QUESTION_DIALOG "SHOW_QUESTION_DIALOG"  /* show the question dialog from daemon */
-#define GDM_SOP_SHOW_ASKBUTTONS_DIALOG "SHOW_ASKBUTTON_DIALOG"  /* show the askbutton dialog from daemon */
-
-
-/* Ack for a slave message */
-/* Note that an extra response can follow an 'ack' */
-#define GDM_SLAVE_NOTIFY_ACK 'A'
-/* Update this key */
-#define GDM_SLAVE_NOTIFY_KEY '!'
-/* notify a command */
-#define GDM_SLAVE_NOTIFY_COMMAND '#'
-/* send the response */
-#define GDM_SLAVE_NOTIFY_RESPONSE 'R'
-/* send the error dialog response */
-#define GDM_SLAVE_NOTIFY_ERROR_RESPONSE 'E'
-/* send the yesno dialog response */
-#define GDM_SLAVE_NOTIFY_YESNO_RESPONSE 'Y'
-/* send the askbuttons dialog response */
-#define GDM_SLAVE_NOTIFY_ASKBUTTONS_RESPONSE 'B'
-/* send the question dialog response */
-#define GDM_SLAVE_NOTIFY_QUESTION_RESPONSE 'Q'
-
-/*
- * Maximum number of messages allowed over the sockets protocol.  This
- * is set to 80 since the gdmlogin/gdmgreeter programs have ~60 config
- * values that are pulled over the socket connection so it allows them
- * all to be grabbed in one pull.
- */
-#define GDM_SUP_MAX_MESSAGES 80
-#define GDM_SUP_SOCKET "/tmp/.gdm_socket"
-
-/*
- * The user socket protocol.  Each command is given on a separate line
- *
- * A user should first send a VERSION\n after connecting and only do
- * anything else if gdm responds with the correct response.  The version
- * is the gdm version and not a "protocol" revision, so you can't check
- * against a single version but check if the version is higher then some
- * value.
- *
- * You can only send a few commands at a time, so if you keep getting error
- * 200 try opening a new socket for every command you send.
- */
-/* The user protocol, using /tmp/.gdm_socket */
-
-#define GDM_SUP_VERSION "VERSION" /* no arguments */
-/* VERSION: Query GDM version
- * Supported since: 2.2.4.0
- * Arguments: None
- * Answers:
- *   GDM <gdm version>
- *   ERROR <err number> <english error description>
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_AUTH_LOCAL "AUTH_LOCAL" /* <xauth cookie> */
-/* AUTH_LOCAL: Setup this connection as authenticated for FLEXI_SERVER.
- *             Because all full blown (non-nested) displays can be started
- *             only from users logged in locally, and here gdm assumes
- *             only users logged in from gdm.  They must pass the xauth
- *             MIT-MAGIC-COOKIE-1 that they were passed before the
- *             connection is authenticated.
- * Note:       The AUTH LOCAL command requires the --authenticate option,
- *             although only FLEXI XSERVER uses this currently.
- * Note:       Since 2.6.0.6 you can also use a global
- *             <ServAuthDir>/.cookie, which works for all authentication
- *             except for SET_LOGOUT_ACTION and QUERY_LOGOUT_ACTION
- *             and SET_SAFE_LOGOUT_ACTION which require a logged in
- *             display.
- * Supported since: 2.2.4.0
- * Arguments: <xauth cookie>
- *   <xauth cookie> is in hex form with no 0x prefix
- * Answers:
- *   OK
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      100 = Not authenticated
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_FLEXI_XSERVER "FLEXI_XSERVER" /* <xserver type> */
-/* FLEXI_XSERVER: Start a new X flexible display.  Only supported on
- *                connection that passed AUTH_LOCAL
- * Supported since: 2.2.4.0
- * Arguments: <xserver type>
- *   If no arguments, starts the standard X server
- * Answers:
- *   OK <display>
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      1 = No more flexi servers
- *      2 = Startup errors
- *      3 = X failed
- *      4 = X too busy
- *      6 = No server binary
- *      100 = Not authenticated
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_FLEXI_XSERVER_USER  "FLEXI_XSERVER_USER" /* <username> <xserver type> */
-/* FLEXI_XSERVER_USER: Start a new X flexible display and initialize the 
- *                greeter with the given username. Only supported on 
- *                connection that passed AUTH_LOCAL
- * Supported since: 2.17.7
- * Arguments: <username> <xserver type>
- *   If no server type specified, starts the standard X server
- * Answers:
- *   OK <display>
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      1 = No more flexi servers
- *      2 = Startup errors
- *      3 = X failed
- *      4 = X too busy
- *      6 = No server binary
- *      100 = Not authenticated
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_FLEXI_XNEST  "FLEXI_XNEST" /* <display> <uid> <xauth cookie> <xauth file> */
-/* FLEXI_XNEXT: Start a new flexible nested display.
- * Note:        Supported on older versions from 2.2.4.0, later
- *              2.2.4.2, but since 2.3.90.4 you must supply 4 
- *              arguments or ERROR 100 will be returned.  This
- *              will start the nested Xserver command using the
- *              XAUTHORITY file supplied and as the uid same as
- *              the owner of that file (and same as you supply).
- *              You must also supply the cookie as the third
- *              argument for this display, to prove that you
- *              indeed are this user.  Also this file must be
- *              readable ONLY by this user, that is have a mode
- *              of 0600.  If this all is not met, ERROR 100 is
- *              returned.
- * Note:        The cookie should be the MIT-MAGIC-COOKIE-1,
- *              the first one gdm can find in the XAUTHORITY
- *              file for this display.  If that's not what you
- *              use you should generate one first.  The cookie
- *              should be in hex form.
- * Supported since: 2.3.90.4
- * Arguments: <display to run on> <uid of requesting user>
- *            <xauth cookie for the display> <xauth file>
- * Answers:
- *   OK <display>
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      1 = No more flexi servers
- *      2 = Startup errors
- *      3 = X failed
- *      4 = X too busy
- *      5 = Nested display can't connect
- *      6 = No server binary
- *      100 = Not authenticated
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_FLEXI_XNEST_USER  "FLEXI_XNEST_USER" /* <username> <display> <uid> <xauth cookie> <xauth file> */
-/* FLEXI_XNEXT_USER: Start a new flexible nested display and 
- *              initialize the greeter with the given username
- * Note:        The cookie should be the MIT-MAGIC-COOKIE-1,
- *              the first one gdm can find in the XAUTHORITY
- *              file for this display.  If that's not what you
- *              use you should generate one first.  The cookie
- *              should be in hex form.
- * Supported since: 2.17.7
- * Arguments: <username> <display to run on> <uid of requesting user>
- *            <xauth cookie for the display> <xauth file>
- * Answers:
- *   OK <display>
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      1 = No more flexi servers
- *      2 = Startup errors
- *      3 = X failed
- *      4 = X too busy
- *      5 = Nested display can't connect
- *      6 = No server binary
- *      100 = Not authenticated
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_ADD_DYNAMIC_DISPLAY	"ADD_DYNAMIC_DISPLAY" 
-/*
- * ADD_DYNAMIC_DISPLAY: Create a new server definition that will
- *                      run on the specified display leaving it
- *                      in DISPLAY_CONFIG state.
- * Supported since: 2.8.0.0
- * Arguments: <display to run on>=<server>
- *   Where <server> is either a configuration named in the
- *   GDM configuration a literal command name.
- * Answers:
- *  OK
- *  ERROR
- *     0 = Not implemented
- *     2 = Existing display
- *     3 = No server string
- *     4 = Display startup failure
- *     100 = Not authenticated
- *     200 - Dynamic Displays not allowed
- *     999 = Unknown error
- */
-#define GDM_SUP_RELEASE_DYNAMIC_DISPLAYS	"RELEASE_DYNAMIC_DISPLAYS"
-/*
- * RELEASE_DYNAMIC_DISPLAYS: Release and begin managing dynamic displays
- *                           currently in DISPLAY_CONFIG state
- * Supported since: 2.8.0.0
- * Arguments: <display to release>
- * Answers:
- *  OK
- *  ERROR
- *     0 = Not implemented
- *     1 = Bad display number
- *     100 = Not authenticated
- *     200 = Dynamic Displays not allowed
- *     999 = Unknown error
- */
-#define GDM_SUP_REMOVE_DYNAMIC_DISPLAY	"REMOVE_DYNAMIC_DISPLAY" 
-/*
- * REMOVE_DYNAMIC_DISPLAY: Remove a dynamic display, killing the server
- *                         and purging the display configuration
- * Supported since: 2.8.0.0
- * Arguments: <display to remove>
- * Answers:
- *  OK
- *  ERROR
- *     0 = Not implemented
- *     1 = Bad display number
- *     100 = Not authenticated
- *     200 = Dynamic Displays not allowed
- *     999 = Unknown error
- */
-#define GDM_SUP_ATTACHED_SERVERS "ATTACHED_SERVERS" /* None */
-#define GDM_SUP_CONSOLE_SERVERS  "CONSOLE_SERVERS"  /* None */
-/* ATTACHED_SERVERS: List all attached displays.  Doesn't list XDMCP
- *                   and xnest non-attached displays.
- * Note:             This command used to be named CONSOLE_SERVERS,
- *                   which is still recognized for backwards
- *                   compatibility.  The optional pattern argument
- *                   is supported as of version 2.8.0.0.
- * Supported since: 2.2.4.0
- * Arguments: <pattern> (optional)
- *   With no argument, all dynamic displays are returned. The optional
- *   <pattern> is a string that may contain glob characters '*', '?', and
- *   '[]'. Only displays that match the pattern will be returned.
- * Answers:
- *   OK <server>;<server>;...
- *
- *   <server> is <display>,<logged in user>,<vt or xnest display>
- *
- *   <logged in user> can be empty in case no one logged in yet,
- *   and <vt> can be -1 if it's not known or not supported (on non-Linux
- *   for example).  If the display is an xnest display and is an attached one
- *   (that is, it is an xnest inside another attached display) it is listed
- *   and instead of vt, it lists the parent display in standard form.
- *
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_ALL_SERVERS  "ALL_SERVERS" /* None */
-/* ALL_SERVERS: List all displays, including attached, remote, xnest.
- *              This can for example be useful to figure out if
- *              the display you are on is managed by the gdm daemon,
- *              by seeing if it is in the list.  It is also somewhat
- *              like the 'w' command but for graphical sessions.
- * Supported since: 2.4.2.96
- * Arguments: None
- * Answers:
- *   OK <server>;<server>;...
- *
- *   <server> is <display>,<logged in user>
- *
- *   <logged in user> can be empty in case no one logged in yet
- *
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_GET_SERVER_LIST "GET_SERVER_LIST" /* None */
-/* GET_SERVER_LIST:  Get a list of the server sections from
- *                   the configuration file. 
- * Supported since: 2.13.0.4
- * Arguments: None 
- * Answers:
- *   OK <value>;<value>;...
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      1 = No servers found
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_GET_SERVER_DETAILS "GET_SERVER_DETAILS" /* <server> <key> */
-/* GET_SERVER_DETAILS:  Get detail information for a specific server.
- * Supported since: 2.13.0.4
- * Arguments: <server> <key>
- *   Key values include:
- *     ID        - Returns the server id
- *     NAME      - Returns the server name
- *     COMMAND   - Returns the server command
- *     FLEXIBLE  - Returns "true" if flexible, "false" otherwise
- *     CHOOSABLE - Returns "true" if choosable, "false" otherwise
- *     HANDLED   - Returns "true" if handled, "false" otherwise
- *     CHOOSER   - Returns "true" if chooser, "false" otherwise
- *     PRIORITY  - Returns process priority
- * Answers: 
- *   OK <value>
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      1 = Server not found
- *      2 = Key not valid
- *      50 = Unsupported key
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_GET_CONFIG "GET_CONFIG" /* <key> */
-/* GET_CONFIG:  Get configuration value for key.  Useful so
- *              that other applications can request configuration
- *              information from GDM.  Any key defined as GDM_KEY_*
- *              in gdm.h is supported.  Starting with version 2.13.0.2
- *              translated keys (such as "greeter/GdmWelcome[cs]" are
- *              supported via GET_CONFIG.  Also starting with version
- *              2.13.0.2 it is no longer necessary to include the
- *              default value (i.e. you can use key "greeter/IncludeAll"
- *              instead of having to use "greeter/IncludeAll=false".
- *              Starting with version 2.14.4, GDM supports per-display
- *              configuration (for GUI slave clients only) and accepts
- *              the display argument to retrieve per-display value (if
- *              any.
- * Supported since: 2.6.0.9
- * Arguments: <key> [<display>]
- * Answers:
- *   OK <value>
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      50 = Unsupported key
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_GET_CONFIG_FILE  "GET_CONFIG_FILE" /* None */
-/* GET_CONFIG_FILE: Get defaults config file location being used by
- #                  the daemon.   If the GDM daemon was started
- *                  with the --config option, it will return
- *                  the value passed in via that argument.
- * Supported since: 2.8.0.2
- * Arguments: None
- * Answers:
- *   OK <full path to GDM configuration file>
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_GET_CUSTOM_CONFIG_FILE  "GET_CUSTOM_CONFIG_FILE" /* None */
-/* GET_CONFIG_FILE: Get custom config file location being used by
- #                  the daemon. 
- * Supported since: 2.14.0.0
- * Arguments: None
- * Answers:
- *   OK <full path to GDM custom configuration file>
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      1 = File not found
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_UPDATE_CONFIG "UPDATE_CONFIG" /* <key> */
-/* UPDATE_CONFIG: Tell the daemon to re-read a key from the
- *                GDM configuration file.   Any user can request
- *                that values are re-read but the daemon will
- *                only do so if the file has been modified
- *                since GDM first read the file.  Only users
- *                who can change the GDM configuration file
- *                (normally writable only by the root user) can
- *                actually modify the GDM configuration.  This
- *                command is useful to cause the GDM to update
- *                itself to recognize a change made to the GDM
- *                configuration file by the root user.
- *
- *                Starting with version 2.13.0.0, all GDM keys are
- *                supported except for the following:
- *
- *                    daemon/PidFile
- *                    daemon/ConsoleNotify
- *                    daemon/User
- *                    daemon/Group
- *                    daemon/LogDir
- *                    daemon/ServAuthDir
- *                    daemon/UserAuthDir
- *                    daemon/UserAuthFile
- *                    daemon/UserAuthFBDir
- *
- *                GDM also supports the following Psuedokeys:
- *
- *                xdmcp/PARAMETERS (2.3.90.2) updates the following:
- *                    xdmcp/MaxPending
- *                    xdmcp/MaxSessions
- *                    xdmcp/MaxWait
- *                    xdmcp/DisplaysPerHost
- *                    xdmcp/HonorIndirect
- *                    xdmcp/MaxPendingIndirect
- *                    xdmcp/MaxWaitIndirect
- *                    xdmcp/PingIntervalSeconds (only affects new connections)
- *
- *                 xservers/PARAMETERS (2.13.0.4) updates the following:
- *                    all [server-foo] sections.
- *
- *                 Supported keys for previous versions of GDM:
- *
- *                    security/AllowRoot (2.3.90.2)
- *                    security/AllowRemoteRoot (2.3.90.2)
- *                    security/AllowRemoteAutoLogin (2.3.90.2)
- *                    security/RetryDelay (2.3.90.2)
- *                    security/DisallowTCP (2.4.2.0)
- *                    daemon/Greeter (2.3.90.2)
- *                    daemon/RemoteGreeter (2.3.90.2)
- *                    xdmcp/Enable (2.3.90.2)
- *                    xdmcp/Port (2.3.90.2)
- *                    daemon/TimedLogin (2.3.90.3)
- *                    daemon/TimedLoginEnable (2.3.90.3)
- *                    daemon/TimedLoginDelay (2.3.90.3)
- *                    greeter/SystemMenu (2.3.90.3)
- *                    greeter/ConfigAvailable (2.3.90.3)
- *                    greeter/ChooserButton (2.4.2.0)
- *                    greeter/SoundOnLoginFile (2.5.90.0)
- *                    daemon/AddGtkModules (2.5.90.0)
- *                    daemon/GtkModulesList (2.5.90.0)
- * Supported since: 2.3.90.2
- * Arguments: <key>
- *   <key> is just the base part of the key such as "security/AllowRemoteRoot"
- * Answers:
- *   OK
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      50 = Unsupported key
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_GREETERPIDS  "GREETERPIDS" /* None */
-/* GREETERPIDS: List all greeter pids so that one can send HUP
- *              to them for config rereading.  Of course one
- *              must be root to do that.
- * Supported since: 2.3.90.2
- * Arguments: None
- * Answers:
- *   OK <pid>;<pid>;...
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_QUERY_LOGOUT_ACTION "QUERY_LOGOUT_ACTION" /* None */
-/* QUERY_LOGOUT_ACTION: Query which logout actions are possible
- *                      Only supported on connections that passed
- *                      AUTH_LOCAL.
- * Supported since: 2.5.90.0
- * Answers:
- *   OK <action>;<action>;...
- *      Where action is one of HALT, REBOOT, SUSPEND or CUSTOM_CMDX (where X in [0,GDM_CUSTOM_COMMAND_MAX)).
- *      An empty list can also be returned if no action is possible.  A '!' is appended
- *      to an action if it was already set with SET_LOGOUT_ACTION or
- *      SET_SAFE_LOGOUT_ACTION.  Note that SET_LOGOUT_ACTION has precedence
- *      over SET_SAFE_LOGOUT_ACTION.
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      100 = Not authenticated
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_QUERY_CUSTOM_CMD_LABELS "QUERY_CUSTOM_CMD_LABELS" /* None */
-/* QUERY_CUSTOM_CMD_LABELS: Query labels belonging to exported custom commands
- *                          Only supported on connections that passed
- *                          AUTH_LOCAL.
- * Supported since: 2.5.90.0
- * Answers:
- *   OK <label1>;<label2>;...
- *      Where labelX is one of the labels belonging to CUSTOM_CMDX (where X in [0,GDM_CUSTOM_COMMAND_MAX)).
- *      An empty list can also be returned if none of the custom commands are 
- *      exported outside login manager (no CustomCommandIsPersistent options are set to true).  
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      100 = Not authenticated
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_QUERY_CUSTOM_CMD_NO_RESTART_STATUS "QUERY_CUSTOM_CMD_NO_RESTART_STATUS" /* None */
-/* QUERY_CUSTOM_CMD_NO_RESTART_STATUS: Query NoRestart config options for each of custom commands
- *                                     Only supported on connections that passed
- *                                     AUTH_LOCAL.
- * Supported since: 2.5.90.0
- * Answers:
- *   OK <status>
- *      Where each bit of the status represents NoRestart value for each of the custom commands.
- *      bit on (1):  NoRestart = true, 
- *      bit off (0): NoRestart = false.
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      100 = Not authenticated
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_SET_LOGOUT_ACTION "SET_LOGOUT_ACTION" /* <action> */
-/* SET_LOGOUT_ACTION: Tell the daemon to halt/restart/suspend after
- *                    slave process exits.  Only supported on
- *                    connections that passed AUTH_LOCAL.
- * Supported since: 2.5.90.0
- * Arguments: <action>
- *   NONE           Set exit action to 'none'
- *   HALT           Set exit action to 'halt'
- *   REBOOT         Set exit action to 'reboot'
- *   SUSPEND        Set exit action to 'suspend'
- *   CUSTOM_CMDX    Set exit action to 'custom command X' where where X in [0,GDM_CUSTOM_COMMAND_MAX)
- * Answers:
- *   OK
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      7 = Unknown logout action, or not available
- *      100 = Not authenticated
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_SET_SAFE_LOGOUT_ACTION "SET_SAFE_LOGOUT_ACTION" /* <action> */
-/* SET_SAFE_LOGOUT_ACTION: Tell the daemon to halt/restart/suspend
- *                         after everybody logs out.  If only one
- *                         person logs out, then this is obviously
- *                         the same as the SET_LOGOUT_ACTION.  Note
- *                         that SET_LOGOUT_ACTION has precendence
- *                         over SET_SAFE_LOGOUT_ACTION if it is set
- *                         to something other then NONE.  If no one
- *                         is logged in, then the action takes effect
- *                         immedeately.  Only supported on connections
- *                         that passed AUTH_LOCAL.
- * Supported since: 2.5.90.0
- * Arguments: <action>
- *   NONE           Set exit action to 'none'
- *   HALT           Set exit action to 'halt'
- *   REBOOT         Set exit action to 'reboot'
- *   SUSPEND        Set exit action to 'suspend'
- *   CUSTOM_CMDX    Set exit action to 'custom command X' where where X in [0,GDM_CUSTOM_COMMAND_MAX)
- *
- * Answers:
- *   OK
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      7 = Unknown logout action, or not available
- *      100 = Not authenticated
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_LOGOUT_ACTION_NONE	          "NONE"
-#define GDM_SUP_LOGOUT_ACTION_HALT	          "HALT"
-#define GDM_SUP_LOGOUT_ACTION_REBOOT	          "REBOOT"
-#define GDM_SUP_LOGOUT_ACTION_SUSPEND	          "SUSPEND"
-#define GDM_SUP_LOGOUT_ACTION_CUSTOM_CMD_TEMPLATE "CUSTOM_CMD"
-/*
- */
-#define GDM_SUP_QUERY_VT "QUERY_VT" /* None */
-/* QUERY_VT:  Ask the daemon about which VT we are currently on.
- *            This is useful for logins which don't own
- *            /dev/console but are still console logins.  Only
- *            supported on Linux currently, other places will
- *            just get ERROR 8.  This is also the way to query
- *            if VT support is available in the daemon in the
- *            first place.  Only supported on connections that
- *            passed AUTH_LOCAL.
- * Supported since: 2.5.90.0
- * Arguments: None
- * Answers:
- *   OK <vt number>
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      8 = Virtual terminals not supported
- *      100 = Not authenticated
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_SET_VT "SET_VT" /* <vt> */
-/* SET_VT:  Change to the specified virtual terminal.
- *          This is useful for logins which don't own /dev/console
- *          but are still console logins.  Only supported on Linux
- *          currently, other places will just get ERROR 8.
- *          Only supported on connections that passed AUTH_LOCAL.
- * Supported since: 2.5.90.0
- * Arguments: None
- * Answers:
- *   OK
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      8 = Virtual terminals not supported
- *      9 = Invalid virtual terminal number
- *      100 = Not authenticated
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_SERVER_BUSY "SERVER_BUSY" /* None */
-/* SERVER_BUSY:  Returns true if half or more of the daemon's sockets are
- *               busy, false otherwise.  Used by slave programs which want
- *               to ensure they do not overhwelm the server.
- * Supported since: 2.13.0.8
- * Arguments: None 
- * Answers:
- *   OK <value>
- *   ERROR <err number> <english error description>
- *      0 = Not implemented
- *      200 = Too many messages
- *      999 = Unknown error
- */
-#define GDM_SUP_GET_SERVER_DETAILS "GET_SERVER_DETAILS" /* <server> <key> */
-#define GDM_SUP_CLOSE        "CLOSE" /* None */
-/* CLOSE: Close sockets connection
- * Supported since: 2.2.4.0
- * Arguments: None
- * Answers: None
- */
-
-/* User flags for the SUP protocol */
-enum {
-	GDM_SUP_FLAG_AUTHENTICATED = 0x1, /* authenticated as a local user,
-					  * from a local display we started */
-	GDM_SUP_FLAG_AUTH_GLOBAL = 0x2 /* authenticated with global cookie */
-};
-
-/* Macros to check authentication level */
-#define GDM_CONN_AUTHENTICATED(conn) \
-	((gdm_connection_get_user_flags (conn) & GDM_SUP_FLAG_AUTHENTICATED) || \
-	 (gdm_connection_get_user_flags (conn) & GDM_SUP_FLAG_AUTH_GLOBAL))
-
-#define GDM_CONN_AUTH_GLOBAL(conn) \
-	 (gdm_connection_get_user_flags (conn) & GDM_SUP_FLAG_AUTH_GLOBAL)
-
-
-#define NEVER_FAILS_seteuid(uid) \
-	{ int r = 0; \
-	  if (geteuid () != uid) \
-	    r = seteuid (uid); \
-	  if G_UNLIKELY (r != 0) \
-        gdm_fail ("GDM file %s: line %d (%s): Cannot run seteuid to %d: %s", \
-		  __FILE__,						\
-		  __LINE__,						\
-		  __PRETTY_FUNCTION__,					\
-                  (int)uid,						\
-		  strerror (errno));			}
-#define NEVER_FAILS_setegid(gid) \
-	{ int r = 0; \
-	  if (getegid () != gid) \
-	    r = setegid (gid); \
-	  if G_UNLIKELY (r != 0) \
-        gdm_fail ("GDM file %s: line %d (%s): Cannot run setegid to %d: %s", \
-		  __FILE__,						\
-		  __LINE__,						\
-		  __PRETTY_FUNCTION__,					\
-                  (int)gid,						\
-		  strerror (errno));			}
-
-/* first goes to euid-root and then sets the egid and euid, to make sure
- * this succeeds */
-#define NEVER_FAILS_root_set_euid_egid(uid,gid) \
-	{ NEVER_FAILS_seteuid (0); \
-	  NEVER_FAILS_setegid (gid); \
-	  if (uid != 0) { NEVER_FAILS_seteuid (uid); } }
-
 #endif /* GDM_H */
 
 /* EOF */
Index: daemon/filecheck.c
===================================================================
--- daemon/filecheck.c	(revision 4731)
+++ daemon/filecheck.c	(working copy)
@@ -1,4 +1,6 @@
-/* GDM - The GNOME Display Manager
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * 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
@@ -19,7 +21,6 @@
 #include "config.h"
 
 #include <glib/gi18n.h>
-#include <syslog.h>
 #include <sys/stat.h>
 
 #include "gdm.h"
@@ -30,7 +31,7 @@
 
 /**
  * gdm_file_check:
- * @caller: String to be prepended to syslog error messages.
+ * @caller: String to be prepended to error messages.
  * @user: User id for the user owning the file/dir.
  * @dir: Directory to be examined.
  * @file: File to be examined.
@@ -44,171 +45,178 @@
 
 /* we should be euid the user BTW */
 gboolean
-gdm_file_check (const gchar *caller, uid_t user, const gchar *dir,
-		const gchar *file, gboolean absentok,
-		gboolean absentdirok, gint maxsize, gint perms)
+gdm_file_check (const gchar *caller,
+                uid_t user,
+                const gchar *dir,
+		const gchar *file,
+                gboolean absentok,
+		gboolean absentdirok,
+                gint maxsize,
+                gint perms)
 {
-    struct stat statbuf;
-    gchar *fullpath;
-    gchar *dirautofs;
-    int r;
-
-    if (ve_string_empty (dir) ||
-	ve_string_empty (file))
-	    return FALSE;
-
-    /* Stat on automounted directory - append the '/.' to dereference mount point.
-       Do this only if GdmSupportAutomount is true (default is false)
-       2006-09-22, Jerzy Borkowski, CAMK */
-    if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_SUPPORT_AUTOMOUNT)) {
-        dirautofs = g_strconcat(dir, "/.", NULL);
-        VE_IGNORE_EINTR (r = stat (dirautofs, &statbuf));
-        g_free(dirautofs);
-    }
-    /* Stat directory */
-    else {
-        VE_IGNORE_EINTR (r = stat (dir, &statbuf));
-    }
-            
-    if (r < 0) {
-	    if ( ! absentdirok)
-		 syslog (LOG_WARNING, _("%s: Directory %s does not exist."),
-			 caller, dir);
-	    return FALSE;
-    }
-
-    /* Check if dir is owned by the user ... 
-       Only, if GDM_KEY_CHECK_DIR_OWNER is true (default)
-       This is a "hack" for directories not owned by 
-       the user.
-       2004-06-22, Andreas Schubert, MATHEMA Software GmbH */
-
-    if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_CHECK_DIR_OWNER) && (statbuf.st_uid != user)) {
-        syslog (LOG_WARNING, _("%s: %s is not owned by uid %d."), caller, dir, user);
-        return FALSE;
-    }
-    
-    /* ... if group has write permission ... */
-    if G_UNLIKELY (perms < 1 && (statbuf.st_mode & S_IWGRP) == S_IWGRP) {
-	syslog (LOG_WARNING, _("%s: %s is writable by group."), caller, dir);
-	return FALSE;
-    }
-
-    /* ... and if others have write permission. */
-    if G_UNLIKELY (perms < 2 && (statbuf.st_mode & S_IWOTH) == S_IWOTH) {
-	syslog (LOG_WARNING, _("%s: %s is writable by other."), caller, dir);
-	return FALSE;
-    }
-
-    fullpath = g_build_filename (dir, file, NULL);
-
-    /* Stat file */
-    VE_IGNORE_EINTR (r = g_stat (fullpath, &statbuf));
-    if (r < 0) {
-        /* Return true if file does not exist and that is ok */
-	if (absentok) { 
-	    g_free (fullpath);
-	    return TRUE;
+	struct stat statbuf;
+	gchar *fullpath;
+	gchar *dirautofs;
+	int r;
+
+	if (ve_string_empty (dir) ||
+	    ve_string_empty (file))
+		return FALSE;
+
+	/* Stat on automounted directory - append the '/.' to dereference mount point.
+	   Do this only if GdmSupportAutomount is true (default is false)
+	   2006-09-22, Jerzy Borkowski, CAMK */
+	if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_SUPPORT_AUTOMOUNT)) {
+		dirautofs = g_strconcat(dir, "/.", NULL);
+		VE_IGNORE_EINTR (r = stat (dirautofs, &statbuf));
+		g_free(dirautofs);
 	}
+	/* Stat directory */
 	else {
-	    syslog (LOG_WARNING, _("%s: %s does not exist but must exist."), caller, fullpath);
-	    g_free (fullpath);
-	    return FALSE;
-	}
-    }
-
-    /* Check that it is a regular file ... */
-    if G_UNLIKELY (! S_ISREG (statbuf.st_mode)) {
-	syslog (LOG_WARNING, _("%s: %s is not a regular file."), caller, fullpath);
-	g_free (fullpath);
-	return FALSE;
-    }
+		VE_IGNORE_EINTR (r = stat (dir, &statbuf));
+	}
 
-    /* ... owned by the user ... */
-    if G_UNLIKELY (statbuf.st_uid != user) {
-	syslog (LOG_WARNING, _("%s: %s is not owned by uid %d."), caller, fullpath, user);
-	g_free (fullpath);
-	return FALSE;
-    }
+	if (r < 0) {
+		if ( ! absentdirok)
+			g_warning (_("%s: Directory %s does not exist."),
+				   caller, dir);
+		return FALSE;
+	}
 
-    /* ... unwritable by group ... */
-    if G_UNLIKELY (perms < 1 && (statbuf.st_mode & S_IWGRP) == S_IWGRP) {
-	syslog (LOG_WARNING, _("%s: %s is writable by group."), caller, fullpath);
-	g_free (fullpath);
-	return FALSE;
-    }
+	/* Check if dir is owned by the user ...
+	   Only, if GDM_KEY_CHECK_DIR_OWNER is true (default)
+	   This is a "hack" for directories not owned by
+	   the user.
+	   2004-06-22, Andreas Schubert, MATHEMA Software GmbH */
+
+	if G_UNLIKELY (gdm_daemon_config_get_value_bool (GDM_KEY_CHECK_DIR_OWNER) && (statbuf.st_uid != user)) {
+		g_warning (_("%s: %s is not owned by uid %d."), caller, dir, user);
+		return FALSE;
+	}
 
-    /* ... unwritable by others ... */
-    if G_UNLIKELY (perms < 2 && (statbuf.st_mode & S_IWOTH) == S_IWOTH) {
-	syslog (LOG_WARNING, _("%s: %s is writable by group/other."), caller, fullpath);
-	g_free (fullpath);
-	return FALSE;
-    }
+	/* ... if group has write permission ... */
+	if G_UNLIKELY (perms < 1 && (statbuf.st_mode & S_IWGRP) == S_IWGRP) {
+		g_warning (_("%s: %s is writable by group."), caller, dir);
+		return FALSE;
+	}
 
-    /* ... and smaller than sysadmin specified limit. */
-    if G_UNLIKELY (maxsize && statbuf.st_size > maxsize) {
-	syslog (LOG_WARNING, _("%s: %s is bigger than sysadmin specified maximum file size."), 
-		caller, fullpath);
-	g_free (fullpath);
-	return FALSE;
-    }
+	/* ... and if others have write permission. */
+	if G_UNLIKELY (perms < 2 && (statbuf.st_mode & S_IWOTH) == S_IWOTH) {
+		g_warning (_("%s: %s is writable by other."), caller, dir);
+		return FALSE;
+	}
 
-    g_free (fullpath);
+	fullpath = g_build_filename (dir, file, NULL);
 
-    /* Yeap, this file is ok */
-    return TRUE;
+	/* Stat file */
+	VE_IGNORE_EINTR (r = g_stat (fullpath, &statbuf));
+	if (r < 0) {
+		/* Return true if file does not exist and that is ok */
+		if (absentok) {
+			g_free (fullpath);
+			return TRUE;
+		}
+		else {
+			g_warning (_("%s: %s does not exist but must exist."), caller, fullpath);
+			g_free (fullpath);
+			return FALSE;
+		}
+	}
+
+	/* Check that it is a regular file ... */
+	if G_UNLIKELY (! S_ISREG (statbuf.st_mode)) {
+		g_warning (_("%s: %s is not a regular file."), caller, fullpath);
+		g_free (fullpath);
+		return FALSE;
+	}
+
+	/* ... owned by the user ... */
+	if G_UNLIKELY (statbuf.st_uid != user) {
+		g_warning (_("%s: %s is not owned by uid %d."), caller, fullpath, user);
+		g_free (fullpath);
+		return FALSE;
+	}
+
+	/* ... unwritable by group ... */
+	if G_UNLIKELY (perms < 1 && (statbuf.st_mode & S_IWGRP) == S_IWGRP) {
+		g_warning (_("%s: %s is writable by group."), caller, fullpath);
+		g_free (fullpath);
+		return FALSE;
+	}
+
+	/* ... unwritable by others ... */
+	if G_UNLIKELY (perms < 2 && (statbuf.st_mode & S_IWOTH) == S_IWOTH) {
+		g_warning (_("%s: %s is writable by group/other."), caller, fullpath);
+		g_free (fullpath);
+		return FALSE;
+	}
+
+	/* ... and smaller than sysadmin specified limit. */
+	if G_UNLIKELY (maxsize && statbuf.st_size > maxsize) {
+		g_warning (_("%s: %s is bigger than sysadmin specified maximum file size."),
+			   caller, fullpath);
+		g_free (fullpath);
+		return FALSE;
+	}
+
+	g_free (fullpath);
+
+	/* Yeap, this file is ok */
+	return TRUE;
 }
 
 /* we should be euid the user BTW */
 gboolean
-gdm_auth_file_check (const gchar *caller, uid_t user, const gchar *authfile, gboolean absentok, struct stat *s)
+gdm_auth_file_check (const gchar *caller,
+                     uid_t user,
+                     const gchar *authfile,
+                     gboolean absentok,
+                     struct stat *s)
 {
-    struct stat statbuf;
-    gint usermaxfile;
-    int r;
-
-    if (ve_string_empty (authfile))
-	    return FALSE;
-
-    /* Stat file */
-    VE_IGNORE_EINTR (r = g_lstat (authfile, &statbuf));
-    if (s != NULL)
-	    *s = statbuf;
-    if (r < 0) {
-	    if (absentok)
-		    return TRUE;
-	    syslog (LOG_WARNING, _("%s: %s does not exist but must exist."), caller, authfile);
-	    return FALSE;
-    }
-
-    /* Check that it is a regular file ... */
-    if G_UNLIKELY (! S_ISREG (statbuf.st_mode)) {
-	syslog (LOG_WARNING, _("%s: %s is not a regular file."), caller, authfile);
-	return FALSE;
-    }
-
-    /* ... owned by the user ... */
-    if G_UNLIKELY (statbuf.st_uid != user) {
-	syslog (LOG_WARNING, _("%s: %s is not owned by uid %d."), caller, authfile, user);
-	return FALSE;
-    }
-
-    /* ... has right permissions ... */
-    if G_UNLIKELY (statbuf.st_mode & 0077) {
-	syslog (LOG_WARNING, "%s: %s has wrong permissions (should be 0600)", caller, authfile);
-	return FALSE;
-    }
-
-    usermaxfile = gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE);
-    /* ... and smaller than sysadmin specified limit. */
-    if G_UNLIKELY (usermaxfile && statbuf.st_size > usermaxfile) {
-	syslog (LOG_WARNING, _("%s: %s is bigger than sysadmin specified maximum file size."), 
-		caller, authfile);
-	return FALSE;
-    }
+	struct stat statbuf;
+	gint usermaxfile;
+	int r;
+
+	if (ve_string_empty (authfile))
+		return FALSE;
+
+	/* Stat file */
+	VE_IGNORE_EINTR (r = g_lstat (authfile, &statbuf));
+	if (s != NULL)
+		*s = statbuf;
+	if (r < 0) {
+		if (absentok)
+			return TRUE;
+		g_warning (_("%s: %s does not exist but must exist."), caller, authfile);
+		return FALSE;
+	}
 
-    /* Yeap, this file is ok */
-    return TRUE;
-}
+	/* Check that it is a regular file ... */
+	if G_UNLIKELY (! S_ISREG (statbuf.st_mode)) {
+		g_warning (_("%s: %s is not a regular file."), caller, authfile);
+		return FALSE;
+	}
+
+	/* ... owned by the user ... */
+	if G_UNLIKELY (statbuf.st_uid != user) {
+		g_warning (_("%s: %s is not owned by uid %d."), caller, authfile, user);
+		return FALSE;
+	}
+
+	/* ... has right permissions ... */
+	if G_UNLIKELY (statbuf.st_mode & 0077) {
+		g_warning ("%s: %s has wrong permissions (should be 0600)", caller, authfile);
+		return FALSE;
+	}
+
+	usermaxfile = gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE);
+	/* ... and smaller than sysadmin specified limit. */
+	if G_UNLIKELY (usermaxfile && statbuf.st_size > usermaxfile) {
+		g_warning (_("%s: %s is bigger than sysadmin specified maximum file size."),
+			caller, authfile);
+		return FALSE;
+	}
 
-/* EOF */
+	/* Yeap, this file is ok */
+	return TRUE;
+}
Index: daemon/verify-pam.c
===================================================================
--- daemon/verify-pam.c	(revision 4731)
+++ daemon/verify-pam.c	(working copy)
@@ -18,11 +18,12 @@
 
 #include "config.h"
 
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
 #include <grp.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <unistd.h>
-#include <stdlib.h>
 #include <syslog.h>
 #include <security/pam_appl.h>
 #include <pwd.h>
@@ -39,8 +40,11 @@
 #include "errorgui.h"
 
 #include "gdm-common.h"
+#include "gdm-log.h"
 #include "gdm-daemon-config.h"
 
+#include "gdm-socket-protocol.h"
+
 #ifdef	HAVE_LOGINDEVPERM
 #include <libdevinfo.h>
 #endif	/* HAVE_LOGINDEVPERM */
@@ -515,9 +519,9 @@ gdm_verify_pam_conv (int num_msg, struct
     }
 
     /* Workaround to avoid gdm messages being logged as PAM_pwdb */
-    closelog ();
-    openlog ("gdm", LOG_PID, LOG_DAEMON);
-    
+    gdm_log_shutdown ();
+    gdm_log_init ();
+
     for (replies = 0; replies < num_msg; replies++) {
 	const char *m = (*msg)[replies].msg;
 	m = perhaps_translate_message (m);
@@ -1141,8 +1145,8 @@ authenticate_again:
     }
 
     /* Workaround to avoid gdm messages being logged as PAM_pwdb */
-    closelog ();
-    openlog ("gdm", LOG_PID, LOG_DAEMON);
+    gdm_log_shutdown ();
+    gdm_log_init ();
 
     cur_gdm_disp = NULL;
 
@@ -1225,8 +1229,8 @@ authenticate_again:
     pamh = NULL;
     
     /* Workaround to avoid gdm messages being logged as PAM_pwdb */
-    closelog ();
-    openlog ("gdm", LOG_PID, LOG_DAEMON);
+    gdm_log_shutdown ();
+    gdm_log_init ();
 
     g_free (login);
 
@@ -1433,8 +1437,8 @@ gdm_verify_setup_user (GdmDisplay *d, co
 
 
     /* Workaround to avoid gdm messages being logged as PAM_pwdb */
-    closelog ();
-    openlog ("gdm", LOG_PID, LOG_DAEMON);
+    gdm_log_shutdown ();
+    gdm_log_init ();
 
     cur_gdm_disp = NULL;
 
@@ -1478,8 +1482,8 @@ gdm_verify_setup_user (GdmDisplay *d, co
     pamh = NULL;
     
     /* Workaround to avoid gdm messages being logged as PAM_pwdb */
-    closelog ();
-    openlog ("gdm", LOG_PID, LOG_DAEMON);
+    gdm_log_shutdown ();
+    gdm_log_init ();
 
     cur_gdm_disp = NULL;
 
@@ -1557,8 +1561,8 @@ gdm_verify_cleanup (GdmDisplay *d)
 #endif  /* HAVE_LOGINDEVPERM */
 
 		/* Workaround to avoid gdm messages being logged as PAM_pwdb */
-		closelog ();
-		openlog ("gdm", LOG_PID, LOG_DAEMON);
+                gdm_log_shutdown ();
+                gdm_log_init ();
 	}
 
 	/* Clear the group setup */
@@ -1591,8 +1595,8 @@ gdm_verify_check (void)
 		&standalone_pamc, &ph) != PAM_SUCCESS) {
 		ph = NULL; /* be anal */
 
-		closelog ();
-		openlog ("gdm", LOG_PID, LOG_DAEMON);
+                gdm_log_shutdown ();
+                gdm_log_init ();
 
 		if (gdm_daemon_config_get_value_bool (GDM_KEY_CONSOLE_NOTIFY))
 			gdm_text_message_dialog
@@ -1604,8 +1608,8 @@ gdm_verify_check (void)
 	if (ph != NULL)
 		pam_end (ph, PAM_SUCCESS);
 
-	closelog ();
-	openlog ("gdm", LOG_PID, LOG_DAEMON);
+        gdm_log_shutdown ();
+        gdm_log_init ();
 }
 
 /* used in pam */
Index: daemon/xdmcp.h
===================================================================
--- daemon/xdmcp.h	(revision 4731)
+++ daemon/xdmcp.h	(working copy)
@@ -28,11 +28,72 @@
 #include "gdm.h"
 #endif /* HAVE_LIBXDMCP */
 
+typedef struct _GdmIndirectDisplay GdmIndirectDisplay;
+struct _GdmIndirectDisplay {
+	int id;
+#ifdef ENABLE_IPV6
+       struct sockaddr_storage* dsp_sa;
+       struct in6_addr* chosen_host6;
+#else
+	struct sockaddr_in* dsp_sa;
+#endif
+	time_t acctime;
+	struct in_addr *chosen_host;
+};
+
+/* NOTE: Timeout and max are hardcoded */
+typedef struct _GdmForwardQuery GdmForwardQuery;
+struct _GdmForwardQuery {
+	time_t acctime;
+#ifdef ENABLE_IPV6
+       struct sockaddr_storage* dsp_sa;
+       struct sockaddr_storage* from_sa;
+#else
+	struct sockaddr_in* dsp_sa;
+	struct sockaddr_in* from_sa;
+#endif
+};
+
+#define GDM_MAX_FORWARD_QUERIES 10
+#define GDM_FORWARD_QUERY_TIMEOUT 30
+
+/* some extra XDMCP opcodes that xdm will happily ignore since they'll be
+ * the wrong XDMCP version anyway */
+#define GDM_XDMCP_PROTOCOL_VERSION 1001
+enum {
+	GDM_XDMCP_FIRST_OPCODE = 1000, /*just a marker, not an opcode */
+
+	GDM_XDMCP_MANAGED_FORWARD = 1000,
+		/* manager (master) -> manager
+		 * A packet with MANAGED_FORWARD is sent to the
+		 * manager that sent the forward query from the manager to
+		 * which forward query was sent.  It indicates that the forward
+		 * was fully processed and that the client now has either
+		 * a managed session, or has been sent denial, refuse or failed.
+		 * (if the denial gets lost then client gets dumped into the
+		 * chooser again).  This should be resent a few times
+		 * until some (short) timeout or until GOT_MANAGED_FORWARD
+		 * is sent.  GDM sends at most 3 packates with 1.5 seconds
+		 * between each.
+		 *
+		 * Argument is ARRAY8 with the address of the originating host */
+	GDM_XDMCP_GOT_MANAGED_FORWARD,
+		/* manager -> manager (master)
+		 * A single packet with GOT_MANAGED_FORWARD is sent to indicate
+		 * that we did receive the MANAGED_FORWARD packet.  The argument
+		 * must match the MANAGED_FORWARD one or it will just be ignored.
+		 *
+		 * Argument is ARRAY8 with the address of the originating host */
+	GDM_XDMCP_LAST_OPCODE /*just a marker, not an opcode */
+};
+
 /* Note that these are defined as empty stubs if there is no XDMCP support */
 gboolean	gdm_xdmcp_init	(void);
 void		gdm_xdmcp_run	(void);
 void		gdm_xdmcp_close	(void);
 
+void		gdm_xdmcp_recount_sessions (void);
+
 void gdm_xdmcp_migrate (GdmDisplay *from, GdmDisplay *to);
 
 #ifdef HAVE_LIBXDMCP
Index: daemon/gdm-daemon-config-entries.h
===================================================================
--- daemon/gdm-daemon-config-entries.h	(revision 4731)
+++ daemon/gdm-daemon-config-entries.h	(working copy)
@@ -387,7 +387,7 @@ static const GdmConfigEntry gdm_daemon_c
 	{ GDM_CONFIG_GROUP_GUI, "AllowGtkThemeChange", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_ALLOW_GTK_THEME_CHANGE },
 	{ GDM_CONFIG_GROUP_GUI, "GtkThemesToAllow", GDM_CONFIG_VALUE_STRING, "all", GDM_ID_GTK_THEMES_TO_ALLOW },
 
-	{ GDM_CONFIG_GROUP_GREETER, "Browser", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_BROWSER },
+	{ GDM_CONFIG_GROUP_GREETER, "Browser", GDM_CONFIG_VALUE_BOOL, "true", GDM_ID_BROWSER },
 	{ GDM_CONFIG_GROUP_GREETER, "Include", GDM_CONFIG_VALUE_STRING, "", GDM_ID_INCLUDE },
 	{ GDM_CONFIG_GROUP_GREETER, "Exclude", GDM_CONFIG_VALUE_STRING, "bin,daemon,adm,lp,sync,shutdown,halt,mail,news,uucp,operator,nobody,gdm,postgres,pvm,rpm,nfsnobody,pcap", GDM_ID_EXCLUDE },
 	{ GDM_CONFIG_GROUP_GREETER, "IncludeAll", GDM_CONFIG_VALUE_BOOL, "false", GDM_ID_INCLUDE_ALL },
Index: daemon/verify-shadow.c
===================================================================
--- daemon/verify-shadow.c	(revision 4731)
+++ daemon/verify-shadow.c	(working copy)
@@ -19,7 +19,6 @@
 #include "config.h"
 
 #include <glib/gi18n.h>
-#include <syslog.h>
 #include <pwd.h>
 #include <shadow.h>
 #include <grp.h>
Index: daemon/md5.h
===================================================================
--- daemon/md5.h	(revision 4731)
+++ daemon/md5.h	(working copy)
@@ -19,6 +19,8 @@
 #ifndef GdmMD5_H
 #define GdmMD5_H
 
+#include <glib.h>
+
 struct GdmMD5Context {
 	guint32 buf[4];
 	guint32 bits[2];
Index: daemon/auth.c
===================================================================
--- daemon/auth.c	(revision 4731)
+++ daemon/auth.c	(working copy)
@@ -41,6 +41,7 @@
 #include "auth.h"
 
 #include "gdm-common.h"
+#include "gdm-log.h"
 #include "gdm-daemon-config.h"
 
 /* Ensure we know about FamilyInternetV6 even if what we're compiling
Index: daemon/verify-crypt.c
===================================================================
--- daemon/verify-crypt.c	(revision 4731)
+++ daemon/verify-crypt.c	(working copy)
@@ -19,7 +19,6 @@
 #include "config.h"
 
 #include <glib/gi18n.h>
-#include <syslog.h>
 #include <pwd.h>
 #include <grp.h>
 #include <sys/types.h>
Index: daemon/server.c
===================================================================
--- daemon/server.c	(revision 4731)
+++ daemon/server.c	(working copy)
@@ -36,7 +36,6 @@
 #include <sys/resource.h>
 #include <strings.h>
 #include <signal.h>
-#include <syslog.h>
 #include <errno.h>
 #include <time.h>
 #include <ctype.h>
@@ -52,8 +51,11 @@
 #include "getvt.h"
 
 #include "gdm-common.h"
+#include "gdm-log.h"
 #include "gdm-daemon-config.h"
 
+#include "gdm-socket-protocol.h"
+
 /* Local prototypes */
 static void gdm_server_spawn (GdmDisplay *d, const char *vtarg);
 static void gdm_server_usr1_handler (gint);
@@ -1193,7 +1195,7 @@ gdm_server_spawn (GdmDisplay *d, const c
 	/* the pops whacked mask again */
         gdm_unset_signals ();
 
-	closelog ();
+	gdm_log_shutdown ();
 
 	/* close things */
 	gdm_close_all_descriptors (0 /* from */, -1 /* except */, -1 /* except2 */);
@@ -1204,7 +1206,7 @@ gdm_server_spawn (GdmDisplay *d, const c
 	gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
 	gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
 
-	openlog ("gdm", LOG_PID, LOG_DAEMON);
+	gdm_log_init ();
 
 	/* Rotate the X server logs */
 	rotate_logs (d->name);
Index: daemon/cookie.c
===================================================================
--- daemon/cookie.c	(revision 4731)
+++ daemon/cookie.c	(working copy)
@@ -31,7 +31,6 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <syslog.h>
 #include <string.h>
 #include <fcntl.h>
 #include <sys/time.h>
Index: daemon/verify.h
===================================================================
--- daemon/verify.h	(revision 4731)
+++ daemon/verify.h	(working copy)
@@ -20,6 +20,7 @@
 #define GDM_VERIFY_H
 
 #include "gdm.h"
+#include "display.h"
 
 /* If username is NULL, we ask, if local is FALSE, don't start
  * the timed login timer */
Index: daemon/slave.c
===================================================================
--- daemon/slave.c	(revision 4731)
+++ daemon/slave.c	(working copy)
@@ -62,7 +62,6 @@
 #include <grp.h>
 #include <errno.h>
 #include <time.h>
-#include <syslog.h>
 
 #ifdef HAVE_TSOL
 #include <user_attr.h>
@@ -91,8 +90,11 @@
 #include "display.h"
 
 #include "gdm-common.h"
+#include "gdm-log.h"
 #include "gdm-daemon-config.h"
 
+#include "gdm-socket-protocol.h"
+
 #ifdef WITH_CONSOLE_KIT
 #include "gdmconsolekit.h"
 #endif
@@ -108,7 +110,7 @@ static gboolean do_timed_login = FALSE; 
 					   login the timed login */
 static gboolean do_configurator = FALSE; /* if this is true, login as root
 					  * and start the configurator */
-static gboolean do_cancel = FALSE; /* if this is true, go back to 
+static gboolean do_cancel = FALSE; /* if this is true, go back to
                                       username entry & unselect face
                                       browser (if present) */
 static gboolean do_restart_greeter = FALSE; /* if this is true, whack the
@@ -275,7 +277,7 @@ run_session_output (gboolean read_until_
 	int r, written;
 	uid_t old;
 	gid_t oldg;
-	
+
 	old = geteuid ();
 	oldg = getegid ();
 
@@ -355,8 +357,8 @@ run_session_output (gboolean read_until_
 		if G_UNLIKELY (d->xsession_errors_bytes >= MAX_XSESSION_ERRORS_BYTES &&
 			       ! got_xfsz_signal) {
 			VE_IGNORE_EINTR (write (d->xsession_errors_fd,
-					     "\n...Too much output, ignoring rest...\n",
-					     strlen ("\n...Too much output, ignoring rest...\n")));
+						"\n...Too much output, ignoring rest...\n",
+						strlen ("\n...Too much output, ignoring rest...\n")));
 		}
 
 		/* there wasn't more then buf available, so no need to try reading
@@ -721,9 +723,9 @@ gdm_slave_xfsz_handler (int signal)
 }
 #endif /* SIGXFSZ */
 
-void 
+void
 gdm_slave_start (GdmDisplay *display)
-{  
+{
 	time_t first_time;
 	int death_count;
 	struct sigaction alrm, term, child, usr2;
@@ -821,7 +823,7 @@ gdm_slave_start (GdmDisplay *display)
 	sigemptyset (&child.sa_mask);
 	sigaddset (&child.sa_mask, SIGCHLD);
 
-	if G_UNLIKELY (sigaction (SIGCHLD, &child, NULL) < 0) 
+	if G_UNLIKELY (sigaction (SIGCHLD, &child, NULL) < 0)
 		gdm_slave_exit (DISPLAY_ABORT, _("%s: Error setting up %s signal handler: %s"),
 				"gdm_slave_start", "CHLD", strerror (errno));
 
@@ -933,15 +935,15 @@ gdm_tsol_init (GdmDisplay *display)
 	int firsterror;
 
 	have_suntsol_extension = XQueryExtension (display->dsp,
-			"SUN_TSOL",
-			&opcode,
-			&firstevent,
-			&firsterror);
+						  "SUN_TSOL",
+						  &opcode,
+						  &firstevent,
+						  &firsterror);
 }
 #endif
 
-static void 
-gdm_screen_init (GdmDisplay *display) 
+static void
+gdm_screen_init (GdmDisplay *display)
 {
 #ifdef HAVE_XFREE_XINERAMA
 	int (* old_xerror_handler) (Display *, XErrorEvent *);
@@ -991,28 +993,28 @@ gdm_screen_init (GdmDisplay *display) 
 		XFree (xscreens);
 	} else
 #elif HAVE_SOLARIS_XINERAMA
- /* This code from GDK, Copyright (C) 2002 Sun Microsystems */
- 	int opcode;
+		/* This code from GDK, Copyright (C) 2002 Sun Microsystems */
+		int opcode;
 	int firstevent;
 	int firsterror;
 	int n_monitors = 0;
 
 	gboolean have_xinerama = FALSE;
 	have_xinerama = XQueryExtension (display->dsp,
-			"XINERAMA",
-			&opcode,
-			&firstevent,
-			&firsterror);
+					 "XINERAMA",
+					 &opcode,
+					 &firstevent,
+					 &firsterror);
 
 	if (have_xinerama) {
-	
+
 		int result;
 		XRectangle monitors[MAXFRAMEBUFFERS];
 		unsigned char  hints[16];
 		int xineramascreen;
-		
+
 		result = XineramaGetInfo (display->dsp, 0, monitors, hints, &n_monitors);
-		/* Yes I know it should be Success but the current implementation 
+		/* Yes I know it should be Success but the current implementation
 		 * returns the num of monitor
 		 */
 		if G_UNLIKELY (result <= 0)
@@ -1038,15 +1040,15 @@ gdm_screen_init (GdmDisplay *display) 
 
 	} else
 #endif
-	{
-		display->screenx = 0;
-		display->screeny = 0;
-		display->screenwidth = 0; /* we'll use the gdk size */
-		display->screenheight = 0;
+		{
+			display->screenx = 0;
+			display->screeny = 0;
+			display->screenwidth = 0; /* we'll use the gdk size */
+			display->screenheight = 0;
 
-		display->lrh_offsetx = 0;
-		display->lrh_offsety = 0;
-	}
+			display->lrh_offsetx = 0;
+			display->lrh_offsety = 0;
+		}
 }
 
 static void
@@ -1148,7 +1150,7 @@ ask_migrate (const char *migrate_to)
 
 	askbuttons_msg = g_strdup_printf ("askbuttons_msg=%s$$options_msg1=%s$$options_msg2=%s$$options_msg3=%s$$options_msg4=%s", msg, but[0], but[1], but[2], but[3]);
 
-       
+
 	gdm_slave_send_string (GDM_SOP_SHOW_ASKBUTTONS_DIALOG, askbuttons_msg);
 
 	r = atoi (gdm_ack_response);
@@ -1180,7 +1182,7 @@ gdm_slave_check_user_wants_to_log_in (co
 
 	gdm_slave_send_string (GDM_SOP_QUERYLOGIN, user);
 	if G_LIKELY (ve_string_empty (gdm_ack_response))
-	       return TRUE;	
+		return TRUE;
 	vec = g_strsplit (gdm_ack_response, ",", -1);
 	if (vec == NULL)
 		return TRUE;
@@ -1256,7 +1258,7 @@ gdm_slave_check_user_wants_to_log_in (co
 
 		if (migrate_to == NULL)
 			return TRUE;
-		
+
 		gdm_slave_send_string (GDM_SOP_MIGRATE, migrate_to);
 		g_free (migrate_to);
 
@@ -1288,181 +1290,181 @@ gdm_slave_check_user_wants_to_log_in (co
 
 static gboolean do_xfailed_on_xio_error = FALSE;
 
-static void 
+static void
 gdm_slave_run (GdmDisplay *display)
-{  
-    gint openretries = 0;
-    gint maxtries = 0;
-    gint pinginterval = gdm_daemon_config_get_value_int (GDM_KEY_PING_INTERVAL);
-    
-    gdm_reset_locale ();
-
-    /* Reset d since gdm_slave_run is called in a loop */
-    d = display;
-
-    gdm_random_tick ();
-
-    if (d->sleep_before_run > 0) {
-	    gdm_debug ("gdm_slave_run: Sleeping %d seconds before server start", d->sleep_before_run);
-	    gdm_sleep_no_signal (d->sleep_before_run);
-	    d->sleep_before_run = 0;
-
-	    check_notifies_now ();
-    }
-
-    /*
-     * Set it before we run the server, it may be that we're using
-     * the XOpenDisplay to find out if a server is ready (as with 
-     * nested display)
-     */
-    d->dsp = NULL;
-
-    /* if this is local display start a server if one doesn't
-     * exist */
-    if (SERVER_IS_LOCAL (d) &&
-	d->servpid <= 0) {
-	    if G_UNLIKELY ( ! gdm_server_start (d,
-						TRUE /* try_again_if_busy */,
-						FALSE /* treat_as_flexi */,
-						20 /* min_flexi_disp */,
-						5 /* flexi_retries */)) {
-		    /* We're really not sure what is going on,
-		     * so we throw up our hands and tell the user
-		     * that we've given up.  The error is likely something
-		     * internal. */
-		    gdm_text_message_dialog
-			    (C_(N_("Could not start the X\n"
-				   "server (your graphical environment)\n"
-				   "due to some internal error.\n"
-				   "Please contact your system administrator\n"
-				   "or check your syslog to diagnose.\n"
-				   "In the meantime this display will be\n"
-				   "disabled.  Please restart GDM when\n"
-				   "the problem is corrected.")));
-		    gdm_slave_quick_exit (DISPLAY_ABORT);
-	    }
-	    gdm_slave_send_num (GDM_SOP_XPID, d->servpid);
-
-	    check_notifies_now ();
-    }
-
-    /* We can use d->handled from now on on this display,
-     * since the lookup was done in server start */
-    
-    g_setenv ("DISPLAY", d->name, TRUE);
-    g_unsetenv ("XAUTHORITY"); /* just in case it's set */
-
-    gdm_auth_set_local_auth (d);
-
-    if (d->handled) {
-	    /* Now the display name and hostname is final */
-
-	    const char *automaticlogin = gdm_daemon_config_get_value_string (GDM_KEY_AUTOMATIC_LOGIN);
-	    const char *timedlogin     = gdm_daemon_config_get_value_string (GDM_KEY_TIMED_LOGIN);
-
-	    if (gdm_daemon_config_get_value_bool (GDM_KEY_AUTOMATIC_LOGIN_ENABLE) && 
-		! ve_string_empty (automaticlogin)) {
-		    g_free (ParsedAutomaticLogin);
-		    ParsedAutomaticLogin = gdm_parse_enriched_login (automaticlogin,
+{
+	gint openretries = 0;
+	gint maxtries = 0;
+	gint pinginterval = gdm_daemon_config_get_value_int (GDM_KEY_PING_INTERVAL);
+
+	gdm_reset_locale ();
+
+	/* Reset d since gdm_slave_run is called in a loop */
+	d = display;
+
+	gdm_random_tick ();
+
+	if (d->sleep_before_run > 0) {
+		gdm_debug ("gdm_slave_run: Sleeping %d seconds before server start", d->sleep_before_run);
+		gdm_sleep_no_signal (d->sleep_before_run);
+		d->sleep_before_run = 0;
+
+		check_notifies_now ();
+	}
+
+	/*
+	 * Set it before we run the server, it may be that we're using
+	 * the XOpenDisplay to find out if a server is ready (as with
+	 * nested display)
+	 */
+	d->dsp = NULL;
+
+	/* if this is local display start a server if one doesn't
+	 * exist */
+	if (SERVER_IS_LOCAL (d) &&
+	    d->servpid <= 0) {
+		if G_UNLIKELY ( ! gdm_server_start (d,
+						    TRUE /* try_again_if_busy */,
+						    FALSE /* treat_as_flexi */,
+						    20 /* min_flexi_disp */,
+						    5 /* flexi_retries */)) {
+			/* We're really not sure what is going on,
+			 * so we throw up our hands and tell the user
+			 * that we've given up.  The error is likely something
+			 * internal. */
+			gdm_text_message_dialog
+				(C_(N_("Could not start the X\n"
+				       "server (your graphical environment)\n"
+				       "due to some internal error.\n"
+				       "Please contact your system administrator\n"
+				       "or check your syslog to diagnose.\n"
+				       "In the meantime this display will be\n"
+				       "disabled.  Please restart GDM when\n"
+				       "the problem is corrected.")));
+			gdm_slave_quick_exit (DISPLAY_ABORT);
+		}
+		gdm_slave_send_num (GDM_SOP_XPID, d->servpid);
+
+		check_notifies_now ();
+	}
+
+	/* We can use d->handled from now on on this display,
+	 * since the lookup was done in server start */
+
+	g_setenv ("DISPLAY", d->name, TRUE);
+	g_unsetenv ("XAUTHORITY"); /* just in case it's set */
+
+	gdm_auth_set_local_auth (d);
+
+	if (d->handled) {
+		/* Now the display name and hostname is final */
+
+		const char *automaticlogin = gdm_daemon_config_get_value_string (GDM_KEY_AUTOMATIC_LOGIN);
+		const char *timedlogin     = gdm_daemon_config_get_value_string (GDM_KEY_TIMED_LOGIN);
+
+		if (gdm_daemon_config_get_value_bool (GDM_KEY_AUTOMATIC_LOGIN_ENABLE) &&
+		    ! ve_string_empty (automaticlogin)) {
+			g_free (ParsedAutomaticLogin);
+			ParsedAutomaticLogin = gdm_parse_enriched_login (automaticlogin,
+									 display);
+		}
+
+		if (gdm_daemon_config_get_value_bool (GDM_KEY_TIMED_LOGIN_ENABLE) &&
+		    ! ve_string_empty (timedlogin)) {
+			g_free (ParsedTimedLogin);
+			ParsedTimedLogin = gdm_parse_enriched_login (timedlogin,
 								     display);
-	    }
+		}
+	}
 
-	    if (gdm_daemon_config_get_value_bool (GDM_KEY_TIMED_LOGIN_ENABLE) &&
-		! ve_string_empty (timedlogin)) {
-		    g_free (ParsedTimedLogin);
-		    ParsedTimedLogin = gdm_parse_enriched_login (timedlogin,
-								 display);
-	    }
-    }
-    
-    /* X error handlers to avoid the default one (i.e. exit (1)) */
-    do_xfailed_on_xio_error = TRUE;
-    XSetErrorHandler (gdm_slave_xerror_handler);
-    XSetIOErrorHandler (gdm_slave_xioerror_handler);
-    
-    /* We keep our own (windowless) connection (dsp) open to avoid the
-     * X server resetting due to lack of active connections. */
-
-    gdm_debug ("gdm_slave_run: Opening display %s", d->name);
-
-    /* if local then the the server should be ready for openning, so
-     * don't try so long before killing it and trying again */
-    if (SERVER_IS_LOCAL (d))
-	    maxtries = 2;
-    else
-	    maxtries = 10;
-    
-    while (d->handled &&
-	   openretries < maxtries &&
-	   d->dsp == NULL &&
-	   ( ! SERVER_IS_LOCAL (d) || d->servpid > 1)) {
+	/* X error handlers to avoid the default one (i.e. exit (1)) */
+	do_xfailed_on_xio_error = TRUE;
+	XSetErrorHandler (gdm_slave_xerror_handler);
+	XSetIOErrorHandler (gdm_slave_xioerror_handler);
 
-	gdm_sigchld_block_push ();
-	d->dsp = XOpenDisplay (d->name);
-	gdm_sigchld_block_pop ();
-	
-	if G_UNLIKELY (d->dsp == NULL) {
-	    gdm_debug ("gdm_slave_run: Sleeping %d on a retry", 1+openretries*2);
-	    gdm_sleep_no_signal (1+openretries*2);
-	    openretries++;
-	}
-    }
-
-    /* Really this will only be useful for the first local server,
-       since that's the only time this can really be on */
-    while G_UNLIKELY (gdm_wait_for_go) {
-	    struct timeval tv;
-	    /* Wait 1 second. */
-	    tv.tv_sec = 1;
-	    tv.tv_usec = 0;
-	    select (0, NULL, NULL, NULL, &tv);
-	    /* don't want to use sleep since we're using alarm
-	       for pinging */
-	    check_notifies_now ();
-    }
-
-    /* Set the busy cursor */
-    if (d->dsp != NULL) {
-	    Cursor xcursor = XCreateFontCursor (d->dsp, GDK_WATCH);
-	    XDefineCursor (d->dsp,
-			   DefaultRootWindow (d->dsp),
-			   xcursor);
-	    XFreeCursor (d->dsp, xcursor);
-	    XSync (d->dsp, False);
-    }
-
-    /* Just a race avoiding sleep, probably not necessary though,
-     * but doesn't hurt anything */
-    if ( ! d->handled)
-	    gdm_sleep_no_signal (1);
-
-    if (SERVER_IS_LOCAL (d)) {
-	    gdm_slave_send (GDM_SOP_START_NEXT_LOCAL, FALSE);
-    }
-
-    check_notifies_now ();
-
-    /* something may have gone wrong, try xfailed, if local (non-flexi),
-     * the toplevel loop of death will handle us */ 
-    if G_UNLIKELY (d->handled && d->dsp == NULL) {
-	    if (d->type == TYPE_STATIC)
-		    gdm_slave_quick_exit (DISPLAY_XFAILED);
-	    else
-		    gdm_slave_quick_exit (DISPLAY_ABORT);
-    }
-
-    /* OK from now on it's really the user whacking us most likely,
-     * we have already started up well */
-    do_xfailed_on_xio_error = FALSE;
-
-    /* If XDMCP setup pinging */
-    if ( ! SERVER_IS_LOCAL (d) && pinginterval > 0) {
-	    alarm (pinginterval);
-    }
-
-    /* checkout xinerama */
-    if (d->handled)
-	    gdm_screen_init (d);
+	/* We keep our own (windowless) connection (dsp) open to avoid the
+	 * X server resetting due to lack of active connections. */
+
+	gdm_debug ("gdm_slave_run: Opening display %s", d->name);
+
+	/* if local then the the server should be ready for openning, so
+	 * don't try so long before killing it and trying again */
+	if (SERVER_IS_LOCAL (d))
+		maxtries = 2;
+	else
+		maxtries = 10;
+
+	while (d->handled &&
+	       openretries < maxtries &&
+	       d->dsp == NULL &&
+	       ( ! SERVER_IS_LOCAL (d) || d->servpid > 1)) {
+
+		gdm_sigchld_block_push ();
+		d->dsp = XOpenDisplay (d->name);
+		gdm_sigchld_block_pop ();
+
+		if G_UNLIKELY (d->dsp == NULL) {
+			gdm_debug ("gdm_slave_run: Sleeping %d on a retry", 1+openretries*2);
+			gdm_sleep_no_signal (1+openretries*2);
+			openretries++;
+		}
+	}
+
+	/* Really this will only be useful for the first local server,
+	   since that's the only time this can really be on */
+	while G_UNLIKELY (gdm_wait_for_go) {
+		struct timeval tv;
+		/* Wait 1 second. */
+		tv.tv_sec = 1;
+		tv.tv_usec = 0;
+		select (0, NULL, NULL, NULL, &tv);
+		/* don't want to use sleep since we're using alarm
+		   for pinging */
+		check_notifies_now ();
+	}
+
+	/* Set the busy cursor */
+	if (d->dsp != NULL) {
+		Cursor xcursor = XCreateFontCursor (d->dsp, GDK_WATCH);
+		XDefineCursor (d->dsp,
+			       DefaultRootWindow (d->dsp),
+			       xcursor);
+		XFreeCursor (d->dsp, xcursor);
+		XSync (d->dsp, False);
+	}
+
+	/* Just a race avoiding sleep, probably not necessary though,
+	 * but doesn't hurt anything */
+	if ( ! d->handled)
+		gdm_sleep_no_signal (1);
+
+	if (SERVER_IS_LOCAL (d)) {
+		gdm_slave_send (GDM_SOP_START_NEXT_LOCAL, FALSE);
+	}
+
+	check_notifies_now ();
+
+	/* something may have gone wrong, try xfailed, if local (non-flexi),
+	 * the toplevel loop of death will handle us */ 
+	if G_UNLIKELY (d->handled && d->dsp == NULL) {
+		if (d->type == TYPE_STATIC)
+			gdm_slave_quick_exit (DISPLAY_XFAILED);
+		else
+			gdm_slave_quick_exit (DISPLAY_ABORT);
+	}
+
+	/* OK from now on it's really the user whacking us most likely,
+	 * we have already started up well */
+	do_xfailed_on_xio_error = FALSE;
+
+	/* If XDMCP setup pinging */
+	if ( ! SERVER_IS_LOCAL (d) && pinginterval > 0) {
+		alarm (pinginterval);
+	}
+
+	/* checkout xinerama */
+	if (d->handled)
+		gdm_screen_init (d);
 
 #ifdef HAVE_TSOL
 	/* Check out Solaris Trusted Xserver extension */
@@ -1470,107 +1472,107 @@ gdm_slave_run (GdmDisplay *display)
 		gdm_tsol_init (d);
 #endif
 
-    /* check log stuff for the server, this is done here
-     * because it's really a race */
-    if (SERVER_IS_LOCAL (d))
-	    gdm_server_checklog (d);
-
-    if ( ! d->handled) {
-	    /* yay, we now wait for the server to die */
-	    while (d->servpid > 0) {
-		    pause ();
-	    }
-	    gdm_slave_quick_exit (DISPLAY_REMANAGE);
-    } else if (d->use_chooser) {
-	    /* this usually doesn't return */
-	    gdm_slave_chooser ();  /* Run the chooser */
-	    return;
-    } else if (d->type == TYPE_STATIC &&
-	       gdm_first_login &&
-	       ! ve_string_empty (ParsedAutomaticLogin) &&
-	       strcmp (ParsedAutomaticLogin, gdm_root_user ()) != 0) {
-	    gdm_first_login = FALSE;
-
-	    d->logged_in = TRUE;
-	    gdm_slave_send_num (GDM_SOP_LOGGED_IN, TRUE);
-	    gdm_slave_send_string (GDM_SOP_LOGIN, ParsedAutomaticLogin);
-
-	    if (setup_automatic_session (d, ParsedAutomaticLogin)) {
-		    gdm_slave_session_start ();
-	    }
-
-	    gdm_slave_send_num (GDM_SOP_LOGGED_IN, FALSE);
-	    d->logged_in = FALSE;
-	    gdm_slave_send_string (GDM_SOP_LOGIN, "");
-	    logged_in_uid = -1;
-	    logged_in_gid = -1;
-
-	    gdm_debug ("gdm_slave_run: Automatic login done");
-	    
-	    if (remanage_asap) {
-		    gdm_slave_quick_exit (DISPLAY_REMANAGE);
-	    }
-
-	    /* return to gdm_slave_start so that the server
-	     * can be reinitted and all that kind of fun stuff. */
-	    return;
-    }
-
-    if (gdm_first_login)
-	    gdm_first_login = FALSE;
-
-    do {
-	    check_notifies_now ();
-
-	    if ( ! greet) {
-		    gdm_slave_greeter ();  /* Start the greeter */
-		    greeter_no_focus = FALSE;
-		    greeter_disabled = FALSE;
-	    }
-
-	    gdm_slave_wait_for_login (); /* wait for a password */
-
-	    d->logged_in = TRUE;
-	    gdm_slave_send_num (GDM_SOP_LOGGED_IN, TRUE);
-
-	    if (do_timed_login) {
-		    /* timed out into a timed login */
-		    do_timed_login = FALSE;
-		    if (setup_automatic_session (d, ParsedTimedLogin)) {
-			    gdm_slave_send_string (GDM_SOP_LOGIN,
-						   ParsedTimedLogin);
-			    gdm_slave_session_start ();
-		    }
-	    } else {
-		    gdm_slave_send_string (GDM_SOP_LOGIN, login);
-		    gdm_slave_session_start ();
-	    }
-
-	    gdm_slave_send_num (GDM_SOP_LOGGED_IN, FALSE);
-	    d->logged_in = FALSE;
-	    gdm_slave_send_string (GDM_SOP_LOGIN, "");
-	    logged_in_uid = -1;
-	    logged_in_gid = -1;
-
-	    if (remanage_asap) {
-		    gdm_slave_quick_exit (DISPLAY_REMANAGE);
-	    }
-
-	    if (greet) {
-		    greeter_no_focus = FALSE;
-		    gdm_slave_greeter_ctl_no_ret (GDM_FOCUS, "");
-		    greeter_disabled = FALSE;
-		    gdm_slave_greeter_ctl_no_ret (GDM_ENABLE, "");
-		    gdm_slave_greeter_ctl_no_ret (GDM_RESETOK, "");
-	    }
-	    /* Note that greet is only true if the above was no 'login',
-	     * so no need to reinit the server nor rebake cookies
-	     * nor such nonsense */
-    } while (greet);
-
-    /* If XDMCP stop pinging */
-    if ( ! SERVER_IS_LOCAL (d))
-	    alarm (0);
+	/* check log stuff for the server, this is done here
+	 * because it's really a race */
+	if (SERVER_IS_LOCAL (d))
+		gdm_server_checklog (d);
+
+	if ( ! d->handled) {
+		/* yay, we now wait for the server to die */
+		while (d->servpid > 0) {
+			pause ();
+		}
+		gdm_slave_quick_exit (DISPLAY_REMANAGE);
+	} else if (d->use_chooser) {
+		/* this usually doesn't return */
+		gdm_slave_chooser ();  /* Run the chooser */
+		return;
+	} else if (d->type == TYPE_STATIC &&
+		   gdm_first_login &&
+		   ! ve_string_empty (ParsedAutomaticLogin) &&
+		   strcmp (ParsedAutomaticLogin, gdm_root_user ()) != 0) {
+		gdm_first_login = FALSE;
+
+		d->logged_in = TRUE;
+		gdm_slave_send_num (GDM_SOP_LOGGED_IN, TRUE);
+		gdm_slave_send_string (GDM_SOP_LOGIN, ParsedAutomaticLogin);
+
+		if (setup_automatic_session (d, ParsedAutomaticLogin)) {
+			gdm_slave_session_start ();
+		}
+
+		gdm_slave_send_num (GDM_SOP_LOGGED_IN, FALSE);
+		d->logged_in = FALSE;
+		gdm_slave_send_string (GDM_SOP_LOGIN, "");
+		logged_in_uid = -1;
+		logged_in_gid = -1;
+
+		gdm_debug ("gdm_slave_run: Automatic login done");
+
+		if (remanage_asap) {
+			gdm_slave_quick_exit (DISPLAY_REMANAGE);
+		}
+
+		/* return to gdm_slave_start so that the server
+		 * can be reinitted and all that kind of fun stuff. */
+		return;
+	}
+
+	if (gdm_first_login)
+		gdm_first_login = FALSE;
+
+	do {
+		check_notifies_now ();
+
+		if ( ! greet) {
+			gdm_slave_greeter ();  /* Start the greeter */
+			greeter_no_focus = FALSE;
+			greeter_disabled = FALSE;
+		}
+
+		gdm_slave_wait_for_login (); /* wait for a password */
+
+		d->logged_in = TRUE;
+		gdm_slave_send_num (GDM_SOP_LOGGED_IN, TRUE);
+
+		if (do_timed_login) {
+			/* timed out into a timed login */
+			do_timed_login = FALSE;
+			if (setup_automatic_session (d, ParsedTimedLogin)) {
+				gdm_slave_send_string (GDM_SOP_LOGIN,
+						       ParsedTimedLogin);
+				gdm_slave_session_start ();
+			}
+		} else {
+			gdm_slave_send_string (GDM_SOP_LOGIN, login);
+			gdm_slave_session_start ();
+		}
+
+		gdm_slave_send_num (GDM_SOP_LOGGED_IN, FALSE);
+		d->logged_in = FALSE;
+		gdm_slave_send_string (GDM_SOP_LOGIN, "");
+		logged_in_uid = -1;
+		logged_in_gid = -1;
+
+		if (remanage_asap) {
+			gdm_slave_quick_exit (DISPLAY_REMANAGE);
+		}
+
+		if (greet) {
+			greeter_no_focus = FALSE;
+			gdm_slave_greeter_ctl_no_ret (GDM_FOCUS, "");
+			greeter_disabled = FALSE;
+			gdm_slave_greeter_ctl_no_ret (GDM_ENABLE, "");
+			gdm_slave_greeter_ctl_no_ret (GDM_RESETOK, "");
+		}
+		/* Note that greet is only true if the above was no 'login',
+		 * so no need to reinit the server nor rebake cookies
+		 * nor such nonsense */
+	} while (greet);
+
+	/* If XDMCP stop pinging */
+	if ( ! SERVER_IS_LOCAL (d))
+		alarm (0);
 }
 
 /* A hack really, this will wait around until the first mapped window
@@ -1622,7 +1624,7 @@ focus_first_x_window (const char *class_
 
 	gdm_unset_signals ();
 
-	closelog ();
+	gdm_log_shutdown ();
 
 	gdm_close_all_descriptors (0 /* from */, p[1] /* except */, -1 /* except2 */);
 
@@ -1632,7 +1634,7 @@ focus_first_x_window (const char *class_
 	gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
 	gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
 
-	openlog ("gdm", LOG_PID, LOG_DAEMON);
+	gdm_log_init ();
 
 	/* just in case it's set */
 	g_unsetenv ("XAUTHORITY");
@@ -1705,7 +1707,7 @@ run_config (GdmDisplay *display, struct 
 {
 	pid_t pid;
 
-	/* Lets check if custom.conf exists. If not there 
+	/* Lets check if custom.conf exists. If not there
 	   is no point in launching gdmsetup as it will fail.
 	   We don't need to worry about defaults.conf as
 	   the daemon wont start without it
@@ -1718,7 +1720,7 @@ run_config (GdmDisplay *display, struct 
 				 " login manager config utility."));
 		return;
 	}
-	    
+
 	/* Set the busy cursor */
 	if (d->dsp != NULL) {
 		Cursor xcursor = XCreateFontCursor (d->dsp, GDK_WATCH);
@@ -1743,7 +1745,7 @@ run_config (GdmDisplay *display, struct 
 
 		/* Can't fork */
 		display->sesspid = 0;
-	       
+
 		xcursor = XCreateFontCursor (d->dsp, GDK_LEFT_PTR);
 		XDefineCursor (d->dsp,
 			       DefaultRootWindow (d->dsp),
@@ -1786,7 +1788,7 @@ run_config (GdmDisplay *display, struct 
 			g_setenv ("GDM_GTK_THEME", display->theme_name, TRUE);
 		g_unsetenv ("MAIL");	/* Unset $MAIL for broken shells */
 
-		closelog ();
+		gdm_log_shutdown ();
 
 		gdm_close_all_descriptors (0 /* from */, slave_fifo_pipe_fd /* except */, d->slave_notify_fd /* except2 */);
 
@@ -1796,7 +1798,7 @@ run_config (GdmDisplay *display, struct 
 		gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
 		gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
 
-		openlog ("gdm", LOG_PID, LOG_DAEMON);
+		gdm_log_init ();
 
 		VE_IGNORE_EINTR (g_chdir (pwent->pw_dir));
 		if G_UNLIKELY (errno != 0)
@@ -1844,7 +1846,7 @@ run_config (GdmDisplay *display, struct 
 		_exit (0);
 	} else {
 		GdmWaitPid *wp;
-		
+
 		configurator = TRUE;
 
 		gdm_sigchld_block_push ();
@@ -2272,7 +2274,7 @@ run_pictures (void)
 			int written;
 
 			VE_IGNORE_EINTR (bytes = fread (buf, sizeof (char),
-						     max_write, fp));
+							max_write, fp));
 
 			if (bytes <= 0)
 				break;
@@ -2322,7 +2324,7 @@ run_pictures (void)
 			if (bytes > 0)
 				i += bytes;
 		}
-			
+
 		gdm_slave_greeter_ctl_no_ret (GDM_READPIC, "done");
 
 		NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
@@ -2361,12 +2363,12 @@ copy_auth_file (uid_t fromuid, uid_t tou
 		errno = 0;
 		fromfd = open (file, O_RDONLY
 #ifdef O_NOCTTY
-				     |O_NOCTTY
+			       |O_NOCTTY
 #endif
 #ifdef O_NOFOLLOW
-				     |O_NOFOLLOW
+			       |O_NOFOLLOW
 #endif
-				    );
+			       );
 	} while G_UNLIKELY (errno == EINTR);
 
 	if G_UNLIKELY (fromfd < 0) {
@@ -2377,7 +2379,7 @@ copy_auth_file (uid_t fromuid, uid_t tou
 	NEVER_FAILS_root_set_euid_egid (0, 0);
 
 	name = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR),
-		d->name, ".XnestAuth");
+				  d->name, ".XnestAuth");
 
 	VE_IGNORE_EINTR (g_unlink (name));
 	VE_IGNORE_EINTR (authfd = open (name, O_EXCL|O_TRUNC|O_WRONLY|O_CREAT, 0600));
@@ -2473,297 +2475,297 @@ exec_command (const char *command, const
 static void
 gdm_slave_greeter (void)
 {
-    gint pipe1[2], pipe2[2];  
-    struct passwd *pwent;
-    pid_t pid;
-    const char *command;
-    const char *defaultpath;
-    const char *gdmuser;
-    const char *moduleslist;
-    
-    gdm_debug ("gdm_slave_greeter: Running greeter on %s", d->name);
-    
-    /* Run the init script. gdmslave suspends until script has terminated */
-    gdm_slave_exec_script (d, gdm_daemon_config_get_value_string (GDM_KEY_DISPLAY_INIT_DIR),
-			   NULL, NULL, FALSE /* pass_stdout */);
-
-    /* Open a pipe for greeter communications */
-    if G_UNLIKELY (pipe (pipe1) < 0)
-	gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't init pipe to gdmgreeter"),
-			"gdm_slave_greeter");
-    if G_UNLIKELY (pipe (pipe2) < 0) {
-	VE_IGNORE_EINTR (close (pipe1[0]));
-	VE_IGNORE_EINTR (close (pipe1[1]));
-	gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't init pipe to gdmgreeter"),
-			"gdm_slave_greeter");
-    }
-
-    /* hackish ain't it */
-    create_temp_auth_file ();
-    
-    /* Fork. Parent is gdmslave, child is greeter process. */
-    gdm_sigchld_block_push ();
-    gdm_sigterm_block_push ();
-    greet = TRUE;
-    pid = d->greetpid = fork ();
-    if (pid == 0)
-	    gdm_unset_signals ();
-    gdm_sigterm_block_pop ();
-    gdm_sigchld_block_pop ();
-
-    switch (pid) {
-	
-    case 0:
-	setsid ();
+	gint pipe1[2], pipe2[2];
+	struct passwd *pwent;
+	pid_t pid;
+	const char *command;
+	const char *defaultpath;
+	const char *gdmuser;
+	const char *moduleslist;
 
-	gdm_unset_signals ();
+	gdm_debug ("gdm_slave_greeter: Running greeter on %s", d->name);
 
-	/* Plumbing */
-	VE_IGNORE_EINTR (close (pipe1[1]));
-	VE_IGNORE_EINTR (close (pipe2[0]));
+	/* Run the init script. gdmslave suspends until script has terminated */
+	gdm_slave_exec_script (d, gdm_daemon_config_get_value_string (GDM_KEY_DISPLAY_INIT_DIR),
+			       NULL, NULL, FALSE /* pass_stdout */);
 
-	VE_IGNORE_EINTR (dup2 (pipe1[0], STDIN_FILENO));
-	VE_IGNORE_EINTR (dup2 (pipe2[1], STDOUT_FILENO));
+	/* Open a pipe for greeter communications */
+	if G_UNLIKELY (pipe (pipe1) < 0)
+		gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't init pipe to gdmgreeter"),
+				"gdm_slave_greeter");
+	if G_UNLIKELY (pipe (pipe2) < 0) {
+		VE_IGNORE_EINTR (close (pipe1[0]));
+		VE_IGNORE_EINTR (close (pipe1[1]));
+		gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't init pipe to gdmgreeter"),
+				"gdm_slave_greeter");
+	}
 
-	closelog ();
+	/* hackish ain't it */
+	create_temp_auth_file ();
 
-	gdm_close_all_descriptors (2 /* from */, slave_fifo_pipe_fd/* except */, d->slave_notify_fd/* except2 */);
+	/* Fork. Parent is gdmslave, child is greeter process. */
+	gdm_sigchld_block_push ();
+	gdm_sigterm_block_push ();
+	greet = TRUE;
+	pid = d->greetpid = fork ();
+	if (pid == 0)
+		gdm_unset_signals ();
+	gdm_sigterm_block_pop ();
+	gdm_sigchld_block_pop ();
 
-	gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
+	switch (pid) {
 
-	openlog ("gdm", LOG_PID, LOG_DAEMON);
-	
-	if G_UNLIKELY (setgid (gdm_daemon_config_get_gdmgid ()) < 0) 
-	    gdm_child_exit (DISPLAY_ABORT,
-			    _("%s: Couldn't set groupid to %d"),
-			    "gdm_slave_greeter", gdm_daemon_config_get_gdmgid ());
-
-	gdmuser = gdm_daemon_config_get_value_string (GDM_KEY_USER);
-	if G_UNLIKELY (initgroups (gdmuser, gdm_daemon_config_get_gdmgid ()) < 0)
-            gdm_child_exit (DISPLAY_ABORT,
-			    _("%s: initgroups () failed for %s"),
-			    "gdm_slave_greeter", gdmuser);
-	
-	if G_UNLIKELY (setuid (gdm_daemon_config_get_gdmuid ()) < 0) 
-	    gdm_child_exit (DISPLAY_ABORT,
-			    _("%s: Couldn't set userid to %d"),
-			    "gdm_slave_greeter", gdm_daemon_config_get_gdmuid ());
+	case 0:
+		setsid ();
 
-	gdm_restoreenv ();
-	gdm_reset_locale ();
-	
-	g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE);
-	g_setenv ("DISPLAY", d->name, TRUE);
+		gdm_unset_signals ();
 
-	/* hackish ain't it */
-	set_xnest_parent_stuff ();
+		/* Plumbing */
+		VE_IGNORE_EINTR (close (pipe1[1]));
+		VE_IGNORE_EINTR (close (pipe2[0]));
 
-	g_setenv ("LOGNAME", gdmuser, TRUE);
-	g_setenv ("USER", gdmuser, TRUE);
-	g_setenv ("USERNAME", gdmuser, TRUE);
-	g_setenv ("GDM_GREETER_PROTOCOL_VERSION",
-		      GDM_GREETER_PROTOCOL_VERSION, TRUE);
-	g_setenv ("GDM_VERSION", VERSION, TRUE);
-	g_unsetenv ("MAIL");	/* Unset $MAIL for broken shells */
+		VE_IGNORE_EINTR (dup2 (pipe1[0], STDIN_FILENO));
+		VE_IGNORE_EINTR (dup2 (pipe2[1], STDOUT_FILENO));
 
-	pwent = getpwnam (gdmuser);
-	if G_LIKELY (pwent != NULL) {
-		/* Note that usually this doesn't exist */
-		if (pwent->pw_dir != NULL &&
-		    g_file_test (pwent->pw_dir, G_FILE_TEST_EXISTS))
-			g_setenv ("HOME", pwent->pw_dir, TRUE);
-		else
-			g_setenv ("HOME",
-				ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)),
-				TRUE); /* Hack */
-		g_setenv ("SHELL", pwent->pw_shell, TRUE);
-	} else {
-		g_setenv ("HOME",
-			 ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)),
-			 TRUE); /* Hack */
-		g_setenv ("SHELL", "/bin/sh", TRUE);
-	}
-
-	defaultpath = gdm_daemon_config_get_value_string (GDM_KEY_PATH);
-	if (ve_string_empty (g_getenv ("PATH"))) {
-		g_setenv ("PATH", defaultpath, TRUE);
-	} else if ( ! ve_string_empty (defaultpath)) {
-		gchar *temp_string = g_strconcat (g_getenv ("PATH"),
-			":", defaultpath, NULL);
-		g_setenv ("PATH", temp_string, TRUE);
-		g_free (temp_string);
-	}
-	g_setenv ("RUNNING_UNDER_GDM", "true", TRUE);
-	if ( ! ve_string_empty (d->theme_name))
-		g_setenv ("GDM_GTK_THEME", d->theme_name, TRUE);
-
-	if (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG_GESTURES)) {
-		g_setenv ("GDM_DEBUG_GESTURES", "true", TRUE);
-	}
-
-	/* Note that this is just informative, the slave will not listen to
-	 * the greeter even if it does something it shouldn't on a non-local
-	 * display so it's not a security risk */
-	if (d->attached) {
-		g_setenv ("GDM_IS_LOCAL", "yes", TRUE);
-	} else {
-		g_unsetenv ("GDM_IS_LOCAL");
-	}
+		gdm_log_shutdown ();
 
-	/* this is again informal only, if the greeter does time out it will
-	 * not actually login a user if it's not enabled for this display */
-	if (d->timed_login_ok) {
-		if (ParsedTimedLogin == NULL)
-			g_setenv ("GDM_TIMED_LOGIN_OK", " ", TRUE);
-		else
-			g_setenv ("GDM_TIMED_LOGIN_OK", ParsedTimedLogin, TRUE);
-	} else {
-		g_unsetenv ("GDM_TIMED_LOGIN_OK");
-	}
+		gdm_close_all_descriptors (2 /* from */, slave_fifo_pipe_fd/* except */, d->slave_notify_fd/* except2 */);
 
-	if (SERVER_IS_FLEXI (d)) {
-		g_setenv ("GDM_FLEXI_SERVER", "yes", TRUE);
-	} else {
-		g_unsetenv ("GDM_FLEXI_SERVER");
-	}
+		gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
 
-	if G_UNLIKELY (gdm_emergency_server) {
-		gdm_error_box (d,
-			       GTK_MESSAGE_ERROR,
-			       _("No servers were defined in the "
-				 "configuration file and XDMCP was "
-				 "disabled.  This can only be a "
-				 "configuration error.  GDM has started "
-				 "a single server for you.  You should "
-				 "log in and fix the configuration.  "
-				 "Note that automatic and timed logins "
-				 "are disabled now."));
-		g_unsetenv ("GDM_TIMED_LOGIN_OK");
-	}
+		gdm_log_init ();
 
-	if G_UNLIKELY (d->failsafe_xserver) {
-		gdm_error_box (d,
-			       GTK_MESSAGE_ERROR,
-			       _("Could not start the regular X "
-				 "server (your graphical environment) "
-				 "and so this is a failsafe X server.  "
-				 "You should log in and properly "
-				 "configure the X server."));
-	}
+		if G_UNLIKELY (setgid (gdm_daemon_config_get_gdmgid ()) < 0)
+			gdm_child_exit (DISPLAY_ABORT,
+					_("%s: Couldn't set groupid to %d"),
+					"gdm_slave_greeter", gdm_daemon_config_get_gdmgid ());
 
-	if G_UNLIKELY (d->busy_display) {
-		char *msg = g_strdup_printf
-			(_("The specified display number was busy, so "
-			   "this server was started on display %s."),
-			 d->name);
-		gdm_error_box (d, GTK_MESSAGE_ERROR, msg);
-		g_free (msg);
-	}
+		gdmuser = gdm_daemon_config_get_value_string (GDM_KEY_USER);
+		if G_UNLIKELY (initgroups (gdmuser, gdm_daemon_config_get_gdmgid ()) < 0)
+			gdm_child_exit (DISPLAY_ABORT,
+					_("%s: initgroups () failed for %s"),
+					"gdm_slave_greeter", gdmuser);
 
-	if (d->attached)
-		command = gdm_daemon_config_get_value_string (GDM_KEY_GREETER);
-	else
-		command = gdm_daemon_config_get_value_string (GDM_KEY_REMOTE_GREETER);
+		if G_UNLIKELY (setuid (gdm_daemon_config_get_gdmuid ()) < 0)
+			gdm_child_exit (DISPLAY_ABORT,
+					_("%s: Couldn't set userid to %d"),
+					"gdm_slave_greeter", gdm_daemon_config_get_gdmuid ());
 
-	if G_UNLIKELY (d->try_different_greeter) {
-		/* FIXME: we should also really be able to do standalone failsafe
-		   login, but that requires some work and is perhaps an overkill. */
-		/* This should handle mostly the case where gdmgreeter is crashing
-		   and we'd want to start gdmlogin for the user so that at least
-		   something works instead of a flickering screen */
-		gdm_error_box (d,
-			       GTK_MESSAGE_ERROR,
-			       _("The greeter application appears to be crashing. "
-				 "Attempting to use a different one."));
-		if (strstr (command, "gdmlogin") != NULL) {
-			/* in case it is gdmlogin that's crashing
-			   try the themed greeter for luck */
-			command = LIBEXECDIR "/gdmgreeter";
-		} else {
-			/* in all other cases, try the gdmlogin (standard greeter)
-			   proggie */
-			command = LIBEXECDIR "/gdmlogin";
-		}
-	}
+		gdm_restoreenv ();
+		gdm_reset_locale ();
 
-	moduleslist = gdm_daemon_config_get_value_string (GDM_KEY_GTK_MODULES_LIST);
-
-	if (gdm_daemon_config_get_value_bool (GDM_KEY_ADD_GTK_MODULES) &&
-	    ! ve_string_empty (moduleslist) &&
-	    /* don't add modules if we're trying to prevent crashes,
-	       perhaps it's the modules causing the problem in the first place */
-	    ! d->try_different_greeter) {
-		gchar *modules = g_strdup_printf ("--gtk-module=%s", moduleslist);
-		exec_command (command, modules);
-		/* Something went wrong */
-		gdm_error (_("%s: Cannot start greeter with gtk modules: %s. Trying without modules"),
-			   "gdm_slave_greeter",
-			   moduleslist);
-		g_free (modules);
-	}
-	exec_command (command, NULL);
+		g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE);
+		g_setenv ("DISPLAY", d->name, TRUE);
 
-	gdm_error (_("%s: Cannot start greeter trying default: %s"),
-		   "gdm_slave_greeter",
-		   LIBEXECDIR "/gdmlogin");
-
-	g_setenv ("GDM_WHACKED_GREETER_CONFIG", "true", TRUE);
-
-	exec_command (LIBEXECDIR "/gdmlogin", NULL);
-
-	VE_IGNORE_EINTR (execl (LIBEXECDIR "/gdmlogin", LIBEXECDIR "/gdmlogin", NULL));
-
-	gdm_error_box (d,
-		       GTK_MESSAGE_ERROR,
-		       _("Cannot start the greeter application; "
-			 "you will not be able to log in.  "
-			 "This display will be disabled.  "
-			 "Try logging in by other means and "
-			 "editing the configuration file"));
-	
-	/* If no greeter we really have to disable the display */
-	gdm_child_exit (DISPLAY_ABORT, _("%s: Error starting greeter on display %s"), "gdm_slave_greeter", d->name);
-	
-    case -1:
-	d->greetpid = 0;
-	gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't fork gdmgreeter process"), "gdm_slave_greeter");
-	
-    default:
-	VE_IGNORE_EINTR (close (pipe1[0]));
-	VE_IGNORE_EINTR (close (pipe2[1]));
+		/* hackish ain't it */
+		set_xnest_parent_stuff ();
 
-	whack_greeter_fds ();
+		g_setenv ("LOGNAME", gdmuser, TRUE);
+		g_setenv ("USER", gdmuser, TRUE);
+		g_setenv ("USERNAME", gdmuser, TRUE);
+		g_setenv ("GDM_GREETER_PROTOCOL_VERSION",
+			  GDM_GREETER_PROTOCOL_VERSION, TRUE);
+		g_setenv ("GDM_VERSION", VERSION, TRUE);
+		g_unsetenv ("MAIL");	/* Unset $MAIL for broken shells */
 
-	greeter_fd_out = pipe1[1];
-	greeter_fd_in = pipe2[0];
-	
-	gdm_debug ("gdm_slave_greeter: Greeter on pid %d", (int)pid);
+		pwent = getpwnam (gdmuser);
+		if G_LIKELY (pwent != NULL) {
+			/* Note that usually this doesn't exist */
+			if (pwent->pw_dir != NULL &&
+			    g_file_test (pwent->pw_dir, G_FILE_TEST_EXISTS))
+				g_setenv ("HOME", pwent->pw_dir, TRUE);
+			else
+				g_setenv ("HOME",
+					  ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)),
+					  TRUE); /* Hack */
+			g_setenv ("SHELL", pwent->pw_shell, TRUE);
+		} else {
+			g_setenv ("HOME",
+				  ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)),
+				  TRUE); /* Hack */
+			g_setenv ("SHELL", "/bin/sh", TRUE);
+		}
 
-	gdm_slave_send_num (GDM_SOP_GREETPID, d->greetpid);
+		defaultpath = gdm_daemon_config_get_value_string (GDM_KEY_PATH);
+		if (ve_string_empty (g_getenv ("PATH"))) {
+			g_setenv ("PATH", defaultpath, TRUE);
+		} else if ( ! ve_string_empty (defaultpath)) {
+			gchar *temp_string = g_strconcat (g_getenv ("PATH"),
+							  ":", defaultpath, NULL);
+			g_setenv ("PATH", temp_string, TRUE);
+			g_free (temp_string);
+		}
+		g_setenv ("RUNNING_UNDER_GDM", "true", TRUE);
+		if ( ! ve_string_empty (d->theme_name))
+			g_setenv ("GDM_GTK_THEME", d->theme_name, TRUE);
 
-	run_pictures (); /* Append pictures to greeter if browsing is on */
+		if (gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG_GESTURES)) {
+			g_setenv ("GDM_DEBUG_GESTURES", "true", TRUE);
+		}
 
-	check_notifies_now ();
-	break;
-    }
-}
+		/* Note that this is just informative, the slave will not listen to
+		 * the greeter even if it does something it shouldn't on a non-local
+		 * display so it's not a security risk */
+		if (d->attached) {
+			g_setenv ("GDM_IS_LOCAL", "yes", TRUE);
+		} else {
+			g_unsetenv ("GDM_IS_LOCAL");
+		}
 
-/* This should not call anything that could cause a syslog in case we
- * are in a signal */
-void
-gdm_slave_send (const char *str, gboolean wait_for_ack)
-{
-	int fd;
-	char *fifopath;
-	int i;
-	uid_t old;
+		/* this is again informal only, if the greeter does time out it will
+		 * not actually login a user if it's not enabled for this display */
+		if (d->timed_login_ok) {
+			if (ParsedTimedLogin == NULL)
+				g_setenv ("GDM_TIMED_LOGIN_OK", " ", TRUE);
+			else
+				g_setenv ("GDM_TIMED_LOGIN_OK", ParsedTimedLogin, TRUE);
+		} else {
+			g_unsetenv ("GDM_TIMED_LOGIN_OK");
+		}
 
-	if ( ! gdm_wait_for_ack)
-		wait_for_ack = FALSE;
+		if (SERVER_IS_FLEXI (d)) {
+			g_setenv ("GDM_FLEXI_SERVER", "yes", TRUE);
+		} else {
+			g_unsetenv ("GDM_FLEXI_SERVER");
+		}
 
-	if (wait_for_ack) {
-		gdm_got_ack = FALSE;
-		g_free (gdm_ack_response);
+		if G_UNLIKELY (gdm_emergency_server) {
+			gdm_error_box (d,
+				       GTK_MESSAGE_ERROR,
+				       _("No servers were defined in the "
+					 "configuration file and XDMCP was "
+					 "disabled.  This can only be a "
+					 "configuration error.  GDM has started "
+					 "a single server for you.  You should "
+					 "log in and fix the configuration.  "
+					 "Note that automatic and timed logins "
+					 "are disabled now."));
+			g_unsetenv ("GDM_TIMED_LOGIN_OK");
+		}
+
+		if G_UNLIKELY (d->failsafe_xserver) {
+			gdm_error_box (d,
+				       GTK_MESSAGE_ERROR,
+				       _("Could not start the regular X "
+					 "server (your graphical environment) "
+					 "and so this is a failsafe X server.  "
+					 "You should log in and properly "
+					 "configure the X server."));
+		}
+
+		if G_UNLIKELY (d->busy_display) {
+			char *msg = g_strdup_printf
+				(_("The specified display number was busy, so "
+				   "this server was started on display %s."),
+				 d->name);
+			gdm_error_box (d, GTK_MESSAGE_ERROR, msg);
+			g_free (msg);
+		}
+
+		if (d->attached)
+			command = gdm_daemon_config_get_value_string (GDM_KEY_GREETER);
+		else
+			command = gdm_daemon_config_get_value_string (GDM_KEY_REMOTE_GREETER);
+
+		if G_UNLIKELY (d->try_different_greeter) {
+			/* FIXME: we should also really be able to do standalone failsafe
+			   login, but that requires some work and is perhaps an overkill. */
+			/* This should handle mostly the case where gdmgreeter is crashing
+			   and we'd want to start gdmlogin for the user so that at least
+			   something works instead of a flickering screen */
+			gdm_error_box (d,
+				       GTK_MESSAGE_ERROR,
+				       _("The greeter application appears to be crashing. "
+					 "Attempting to use a different one."));
+			if (strstr (command, "gdmlogin") != NULL) {
+				/* in case it is gdmlogin that's crashing
+				   try the themed greeter for luck */
+				command = LIBEXECDIR "/gdmgreeter";
+			} else {
+				/* in all other cases, try the gdmlogin (standard greeter)
+				   proggie */
+				command = LIBEXECDIR "/gdmlogin";
+			}
+		}
+
+		moduleslist = gdm_daemon_config_get_value_string (GDM_KEY_GTK_MODULES_LIST);
+
+		if (gdm_daemon_config_get_value_bool (GDM_KEY_ADD_GTK_MODULES) &&
+		    ! ve_string_empty (moduleslist) &&
+		    /* don't add modules if we're trying to prevent crashes,
+		       perhaps it's the modules causing the problem in the first place */
+		    ! d->try_different_greeter) {
+			gchar *modules = g_strdup_printf ("--gtk-module=%s", moduleslist);
+			exec_command (command, modules);
+			/* Something went wrong */
+			gdm_error (_("%s: Cannot start greeter with gtk modules: %s. Trying without modules"),
+				   "gdm_slave_greeter",
+				   moduleslist);
+			g_free (modules);
+		}
+		exec_command (command, NULL);
+
+		gdm_error (_("%s: Cannot start greeter trying default: %s"),
+			   "gdm_slave_greeter",
+			   LIBEXECDIR "/gdmlogin");
+
+		g_setenv ("GDM_WHACKED_GREETER_CONFIG", "true", TRUE);
+
+		exec_command (LIBEXECDIR "/gdmlogin", NULL);
+
+		VE_IGNORE_EINTR (execl (LIBEXECDIR "/gdmlogin", LIBEXECDIR "/gdmlogin", NULL));
+
+		gdm_error_box (d,
+			       GTK_MESSAGE_ERROR,
+			       _("Cannot start the greeter application; "
+				 "you will not be able to log in.  "
+				 "This display will be disabled.  "
+				 "Try logging in by other means and "
+				 "editing the configuration file"));
+
+		/* If no greeter we really have to disable the display */
+		gdm_child_exit (DISPLAY_ABORT, _("%s: Error starting greeter on display %s"), "gdm_slave_greeter", d->name);
+
+	case -1:
+		d->greetpid = 0;
+		gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Can't fork gdmgreeter process"), "gdm_slave_greeter");
+
+	default:
+		VE_IGNORE_EINTR (close (pipe1[0]));
+		VE_IGNORE_EINTR (close (pipe2[1]));
+
+		whack_greeter_fds ();
+
+		greeter_fd_out = pipe1[1];
+		greeter_fd_in = pipe2[0];
+
+		gdm_debug ("gdm_slave_greeter: Greeter on pid %d", (int)pid);
+
+		gdm_slave_send_num (GDM_SOP_GREETPID, d->greetpid);
+
+		run_pictures (); /* Append pictures to greeter if browsing is on */
+
+		check_notifies_now ();
+		break;
+	}
+}
+
+/* This should not call anything that could cause a syslog in case we
+ * are in a signal */
+void
+gdm_slave_send (const char *str, gboolean wait_for_ack)
+{
+	int fd;
+	char *fifopath;
+	int i;
+	uid_t old;
+
+	if ( ! gdm_wait_for_ack)
+		wait_for_ack = FALSE;
+
+	if (wait_for_ack) {
+		gdm_got_ack = FALSE;
+		g_free (gdm_ack_response);
 		gdm_ack_response = NULL;
 	}
 
@@ -2781,7 +2783,7 @@ gdm_slave_send (const char *str, gboolea
 		   in main daemon just abort the main daemon.  */
 		/* Use the fifo as a fallback only now that we have a pipe */
 		fifopath = g_build_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR),
-			".gdmfifo", NULL);
+					     ".gdmfifo", NULL);
 		old = geteuid ();
 		if (old != 0)
 			seteuid (0);
@@ -2838,9 +2840,9 @@ gdm_slave_send (const char *str, gboolea
         } else {
 		for (i = 0;
 		     wait_for_ack &&
-		     ! gdm_got_ack &&
-		     parent_exists () &&
-		     i < 10;
+			     ! gdm_got_ack &&
+			     parent_exists () &&
+			     i < 10;
 		     i++) {
 			if (in_usr2_signal > 0) {
 				fd_set rfds;
@@ -2863,7 +2865,7 @@ gdm_slave_send (const char *str, gboolea
 				tv.tv_usec = 0;
 				select (0, NULL, NULL, NULL, &tv);
 				/* don't want to use sleep since we're using alarm
-				for pinging */
+				   for pinging */
 			}
 		}
 	}
@@ -3025,10 +3027,10 @@ gdm_slave_chooser (void)
 		/* Plumbing */
 		VE_IGNORE_EINTR (close (p[0]));
 
-		if (p[1] != STDOUT_FILENO) 
+		if (p[1] != STDOUT_FILENO)
 			VE_IGNORE_EINTR (dup2 (p[1], STDOUT_FILENO));
 
-		closelog ();
+		gdm_log_shutdown ();
 
 		VE_IGNORE_EINTR (close (0));
 		gdm_close_all_descriptors (2 /* from */, slave_fifo_pipe_fd /* except */, d->slave_notify_fd /* except2 */);
@@ -3036,9 +3038,9 @@ gdm_slave_chooser (void)
 		gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */
 		gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
 
-		openlog ("gdm", LOG_PID, LOG_DAEMON);
+		gdm_log_init ();
 
-		if G_UNLIKELY (setgid (gdm_daemon_config_get_gdmgid ()) < 0) 
+		if G_UNLIKELY (setgid (gdm_daemon_config_get_gdmgid ()) < 0)
 			gdm_child_exit (DISPLAY_ABORT,
 					_("%s: Couldn't set groupid to %d"),
 					"gdm_slave_chooser", gdm_daemon_config_get_gdmgid ());
@@ -3049,7 +3051,7 @@ gdm_slave_chooser (void)
 					_("%s: initgroups () failed for %s"),
 					"gdm_slave_chooser", gdmuser);
 
-		if G_UNLIKELY (setuid (gdm_daemon_config_get_gdmuid ()) < 0) 
+		if G_UNLIKELY (setuid (gdm_daemon_config_get_gdmuid ()) < 0)
 			gdm_child_exit (DISPLAY_ABORT,
 					_("%s: Couldn't set userid to %d"),
 					"gdm_slave_chooser", gdm_daemon_config_get_gdmuid ());
@@ -3075,13 +3077,13 @@ gdm_slave_chooser (void)
 				g_setenv ("HOME", pwent->pw_dir, TRUE);
 			else
 				g_setenv ("HOME",
-					ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)),
-					TRUE); /* Hack */
+					  ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)),
+					  TRUE); /* Hack */
 			g_setenv ("SHELL", pwent->pw_shell, TRUE);
 		} else {
 			g_setenv ("HOME",
-				ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)),
-				TRUE); /* Hack */
+				  ve_sure_string (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR)),
+				  TRUE); /* Hack */
 			g_setenv ("SHELL", "/bin/sh", TRUE);
 		}
 
@@ -3090,7 +3092,7 @@ gdm_slave_chooser (void)
 			g_setenv ("PATH", defaultpath, TRUE);
 		} else if ( ! ve_string_empty (defaultpath)) {
 			gchar *temp_string = g_strconcat (g_getenv ("PATH"),
-				":", defaultpath, NULL);
+							  ":", defaultpath, NULL);
 			g_setenv ("PATH", temp_string, TRUE);
 			g_free (temp_string);
 		}
@@ -3395,7 +3397,7 @@ gdm_selinux_setup (const char *login)
 	int ret=-1;
 	char *seuser=NULL;
 	char *level=NULL;
- 
+
 	/* If selinux is not enabled, then we don't do anything */
 	if (is_selinux_enabled () <= 0)
 		return TRUE;
@@ -3415,7 +3417,7 @@ gdm_selinux_setup (const char *login)
 
 	if (setexeccon (scontext) != 0) {
 		gdm_error ("SELinux gdm login: unable to set executable context %s.",
-			  (char *)scontext);
+			   (char *)scontext);
 		gdm_fdprintf (2, "SELinux gdm login: unable to set executable context %s.",
 			      (char *)scontext);
 		freecon (scontext);
@@ -3496,13 +3498,13 @@ session_child_run (struct passwd *pwent,
 	if (d->attached) {
 		greeter = gdm_daemon_config_get_value_string (GDM_KEY_GREETER);
 	} else {
-		greeter = gdm_daemon_config_get_value_string (GDM_KEY_REMOTE_GREETER);		
+		greeter = gdm_daemon_config_get_value_string (GDM_KEY_REMOTE_GREETER);
 	}
-	
+
 	if (strstr (greeter, "gdmlogin") != NULL) {
-		g_setenv ("GDM_GREETER_TYPE", "PLAIN", TRUE);	
+		g_setenv ("GDM_GREETER_TYPE", "PLAIN", TRUE);
 	} else if (strstr (greeter, "gdmgreeter") != NULL) {
-		g_setenv ("GDM_GREETER_TYPE", "THEMED", TRUE);	
+		g_setenv ("GDM_GREETER_TYPE", "THEMED", TRUE);
 	} else {
 		/* huh? */
 		g_setenv ("GDM_GREETER_TYPE", "unknown", TRUE);
@@ -3513,7 +3515,7 @@ session_child_run (struct passwd *pwent,
                                               pwent->pw_name, pwent,
 					      TRUE /* pass_stdout */) != EXIT_SUCCESS &&
 		       /* ignore errors in failsafe modes */
-		       ! failsafe) 
+		       ! failsafe)
 		/* If script fails reset X server and restart greeter */
 		gdm_child_exit (DISPLAY_REMANAGE,
 				_("%s: Execution of PreSession script returned > 0. Aborting."), "session_child_run");
@@ -3577,9 +3579,9 @@ session_child_run (struct passwd *pwent,
 	VE_IGNORE_EINTR (g_chmod (GDM_AUTHFILE (d), 0640));
 
 	setpgid (0, 0);
-	
+
 	umask (022);
-	
+
 	/* setup the verify env vars */
 	if G_UNLIKELY ( ! gdm_verify_setup_env (d))
 		gdm_child_exit (DISPLAY_REMANAGE,
@@ -3602,15 +3604,15 @@ session_child_run (struct passwd *pwent,
                 struct stat s0, s1, s2;
                 gint        s0_ret, s1_ret, s2_ret;
                 gint        iceauth_fd;
- 
-		 NEVER_FAILS_root_set_euid_egid (0, 0);
+
+		NEVER_FAILS_root_set_euid_egid (0, 0);
 
                 iceauth_fd = open (".ICEauthority", O_RDONLY);
- 
+
                 s0_ret = stat (home_dir, &s0);
                 s1_ret = lstat (".ICEauthority", &s1);
                 s2_ret = fstat (iceauth_fd, &s2);
- 
+
                 if (iceauth_fd >= 0 &&
                     s0_ret == 0 &&
                     s0.st_uid == pwent->pw_uid &&
@@ -3637,7 +3639,7 @@ session_child_run (struct passwd *pwent,
                                 pwent->pw_gid);
                         fchmod (iceauth_fd, S_IRUSR | S_IWUSR);
                 }
- 
+
                 if (iceauth_fd >= 0)
                         close (iceauth_fd);
         }
@@ -3654,7 +3656,7 @@ session_child_run (struct passwd *pwent,
 				  "Aborting."), "session_child_run",
 				login);
 #else
-	if G_UNLIKELY (setuid (pwent->pw_uid) < 0) 
+	if G_UNLIKELY (setuid (pwent->pw_uid) < 0)
 		gdm_child_exit (DISPLAY_REMANAGE,
 				_("%s: Could not become %s. Aborting."), "session_child_run", login);
 #endif
@@ -3669,15 +3671,15 @@ session_child_run (struct passwd *pwent,
 
 	/* just in case there is some weirdness going on */
 	VE_IGNORE_EINTR (g_chdir (home_dir));
-	
+
         if (usrcfgok && home_dir_ok)
 		gdm_daemon_config_set_user_session_lang (savesess, savelang, home_dir, save_session, language);
-	
-	closelog ();
+
+	gdm_log_shutdown ();
 
 	gdm_close_all_descriptors (3 /* from */, slave_fifo_pipe_fd /* except */, d->slave_notify_fd /* except2 */);
 
-	openlog ("gdm", LOG_PID, LOG_DAEMON);
+	gdm_log_init ();
 
 	argv[0] = NULL;
 	argv[1] = NULL;
@@ -3693,12 +3695,12 @@ session_child_run (struct passwd *pwent,
 	if (strcmp (session, GDM_SESSION_FAILSAFE_XTERM) != 0 &&
 	    strcmp (session, GDM_SESSION_FAILSAFE_GNOME) != 0) {
 		exec = gdm_daemon_config_get_session_exec (session,
-			FALSE /* check_try_exec */);
+							   FALSE /* check_try_exec */);
 
 		if G_UNLIKELY (exec == NULL) {
 			gchar *msg = g_strdup_printf (
-				_("No Exec line in the session file: %s.  Running the GNOME failsafe session instead"),
-				session);
+						      _("No Exec line in the session file: %s.  Running the GNOME failsafe session instead"),
+						      session);
 
 			gdm_error (_("%s: %s"), "session_child_run", msg);
 			gdm_error_box (d, GTK_MESSAGE_ERROR, msg);
@@ -3753,7 +3755,7 @@ session_child_run (struct passwd *pwent,
 #ifdef HAVE_TSOL
 		if (have_suntsol_extension == TRUE) {
 			/* Trusted Path will be preserved as long as the sys admin
-		     * doesn't put anything stupid in gdm.conf */
+			 * doesn't put anything stupid in gdm.conf */
 			argv[0] = g_strdup ("/usr/bin/tsoljdslabel");
 			argv[1] = find_prog ("gnome-session");
 			if G_UNLIKELY (argv[1] == NULL) {
@@ -3772,35 +3774,35 @@ session_child_run (struct passwd *pwent,
 				gdm_error_box
 					(d, GTK_MESSAGE_INFO,
 					 _("This is the Failsafe GNOME session.  "
-				   "You will be logged into the 'Default' "
-				   "session of GNOME without the startup scripts "
-				   "being run.  This should be used to fix problems "
-				   "in your installation."));
+					   "You will be logged into the 'Default' "
+					   "session of GNOME without the startup scripts "
+					   "being run.  This should be used to fix problems "
+					   "in your installation."));
 			}
 		} else {
 #endif
-		argv[0] = find_prog ("gnome-session");
-		if G_UNLIKELY (argv[0] == NULL) {
-			/* yaikes */
-			gdm_error (_("%s: gnome-session not found for a failsafe GNOME session; trying xterm"),
-				   "session_child_run");
-			session = GDM_SESSION_FAILSAFE_XTERM;
-			gdm_error_box
-				(d, GTK_MESSAGE_ERROR,
-				 _("Could not find the GNOME installation.  "
-				   "Running the \"Failsafe xterm\" "
-				   "session instead."));
-		} else {
-			argv[1] = "--failsafe";
-			argv[2] = NULL;
-			gdm_error_box
-				(d, GTK_MESSAGE_INFO,
-				 _("This is the Failsafe GNOME session.  "
-				   "You will be logged into the 'Default' "
-				   "session of GNOME without the startup scripts "
-				   "being run.  This should be used to fix problems "
-				   "in your installation."));
-		}
+			argv[0] = find_prog ("gnome-session");
+			if G_UNLIKELY (argv[0] == NULL) {
+				/* yaikes */
+				gdm_error (_("%s: gnome-session not found for a failsafe GNOME session; trying xterm"),
+					   "session_child_run");
+				session = GDM_SESSION_FAILSAFE_XTERM;
+				gdm_error_box
+					(d, GTK_MESSAGE_ERROR,
+					 _("Could not find the GNOME installation.  "
+					   "Running the \"Failsafe xterm\" "
+					   "session instead."));
+			} else {
+				argv[1] = "--failsafe";
+				argv[2] = NULL;
+				gdm_error_box
+					(d, GTK_MESSAGE_INFO,
+					 _("This is the Failsafe GNOME session.  "
+					   "You will be logged into the 'Default' "
+					   "session of GNOME without the startup scripts "
+					   "being run.  This should be used to fix problems "
+					   "in your installation."));
+			}
 #ifdef HAVE_TSOL
 		}
 #endif
@@ -3835,12 +3837,12 @@ session_child_run (struct passwd *pwent,
 				argv[3] = argv[4] = argv[5] = argv[6] = NULL;
 				gdm_error_box
 					(d, GTK_MESSAGE_INFO,
-				 	_("This is the Failsafe xterm session.  "
-				 	  "You will be logged into a terminal "
-				 	  "console so that you may fix your system "
-				 	  "if you cannot log in any other way.  "
-				 	  "To exit the terminal emulator, type "
-				 	  "'exit' and an enter into the window."));
+					 _("This is the Failsafe xterm session.  "
+					   "You will be logged into a terminal "
+					   "console so that you may fix your system "
+					   "if you cannot log in any other way.  "
+					   "To exit the terminal emulator, type "
+					   "'exit' and an enter into the window."));
 				focus_first_x_window ("xterm");
 			} else if (gdm_can_i_assume_root_role (pwent) == TRUE) {
 				argv[3] = "-C";
@@ -3849,24 +3851,24 @@ session_child_run (struct passwd *pwent,
 				argv[6] = NULL;
 				gdm_error_box
 					(d, GTK_MESSAGE_INFO,
-				 	_("This is the Failsafe xterm session.  "
-				 	  "You will be logged into a terminal "
-					  "console and be prompted to enter the "
-					  "password for root so that you may fix "
-					  "your system if you cannot log in any "
-					  "other way. To exit the terminal "
-					  "emulator, type 'exit' and an enter "
-					  "into the window."));
+					 _("This is the Failsafe xterm session.  "
+					   "You will be logged into a terminal "
+					   "console and be prompted to enter the "
+					   "password for root so that you may fix "
+					   "your system if you cannot log in any "
+					   "other way. To exit the terminal "
+					   "emulator, type 'exit' and an enter "
+					   "into the window."));
 				focus_first_x_window ("xterm");
 			} else {
 				/* Normal user without root role - get lost */
 				gdm_error_box
 					(d, GTK_MESSAGE_INFO,
-				 	_("The failsafe session is restricted to "
-				 	  "users who have been assigned the root "
-					  "role. If you cannot log in any other "
-					  "way please contact your system "
-					  "administrator"));
+					 _("The failsafe session is restricted to "
+					   "users who have been assigned the root "
+					   "role. If you cannot log in any other "
+					   "way please contact your system "
+					   "administrator"));
 				_exit (66);
 			}
 #endif /* HAVE_TSOL */
@@ -3890,7 +3892,7 @@ session_child_run (struct passwd *pwent,
 			focus_first_x_window ("xterm");
 		}
 		failsafe = TRUE;
-	} 
+	}
 
 #ifdef HAVE_TSOL
 	gdm_debug ("Running %s %s %s %s %s %s for %s on %s",
@@ -3933,7 +3935,7 @@ session_child_run (struct passwd *pwent,
 #ifdef CAN_USE_SETPENV
 	/* Call the function setpenv which instanciates the extern variable "newenv" */
 	setpenv (login, (PENV_INIT | PENV_NOEXEC), NULL, NULL);
-	
+
 	/* Add the content of the "newenv" variable to the environment */
 	for (i=0; newenv != NULL && newenv[i] != NULL; i++) {
 		char *env_str = g_strdup (newenv[i]);
@@ -3962,7 +3964,7 @@ session_child_run (struct passwd *pwent,
 
 	/* will go to .xsession-errors */
 #ifdef HAVE_TSOL
-	fprintf (stderr, _("%s: Could not exec %s %s %s %s %s %s"), 
+	fprintf (stderr, _("%s: Could not exec %s %s %s %s %s %s"),
 		 "session_child_run",
 		 argv[0],
 		 ve_sure_string (argv[1]),
@@ -3971,25 +3973,25 @@ session_child_run (struct passwd *pwent,
 		 ve_sure_string (argv[4]),
 		 ve_sure_string (argv[5]));
 
-	gdm_error ( _("%s: Could not exec %s %s %s %s %s %s"), 
-		 "session_child_run",
-		 argv[0],
-		 ve_sure_string (argv[1]),
-		 ve_sure_string (argv[2]),
-		 ve_sure_string (argv[3]),
-		 ve_sure_string (argv[4]),
-		 ve_sure_string (argv[5]));
+	gdm_error ( _("%s: Could not exec %s %s %s %s %s %s"),
+		    "session_child_run",
+		    argv[0],
+		    ve_sure_string (argv[1]),
+		    ve_sure_string (argv[2]),
+		    ve_sure_string (argv[3]),
+		    ve_sure_string (argv[4]),
+		    ve_sure_string (argv[5]));
 #else
-	fprintf (stderr, _("%s: Could not exec %s %s %s"), 
-		 "session_child_run",
-		 argv[0],
-		 ve_sure_string (argv[1]),
-		 ve_sure_string (argv[2]));
-	gdm_error ( _("%s: Could not exec %s %s %s"), 
+	fprintf (stderr, _("%s: Could not exec %s %s %s"),
 		 "session_child_run",
 		 argv[0],
 		 ve_sure_string (argv[1]),
 		 ve_sure_string (argv[2]));
+	gdm_error ( _("%s: Could not exec %s %s %s"),
+		    "session_child_run",
+		    argv[0],
+		    ve_sure_string (argv[1]),
+		    ve_sure_string (argv[2]));
 #endif
 
 	/* if we can't read and exec the session, then make a nice
@@ -3999,7 +4001,7 @@ session_child_run (struct passwd *pwent,
 		 /* we can't really be any more specific */
 		 _("Cannot start the session due to some "
 		   "internal error."));
-	
+
 	/* ends as if nothing bad happened */
 	_exit (0);
 }
@@ -4024,436 +4026,434 @@ finish_session_output (gboolean do_read)
 static void
 gdm_slave_session_start (void)
 {
-    struct passwd *pwent;
-    const char *home_dir = NULL;
-    char *save_session = NULL, *session = NULL, *language = NULL, *usrsess, *usrlang;
-    char *gnome_session = NULL;
+	struct passwd *pwent;
+	const char *home_dir = NULL;
+	char *save_session = NULL, *session = NULL, *language = NULL, *usrsess, *usrlang;
+	char *gnome_session = NULL;
 #ifdef WITH_CONSOLE_KIT
-    char *ck_session_cookie;
+	char *ck_session_cookie;
 #endif
-    char *tmp;
-    gboolean savesess = FALSE, savelang = FALSE;
-    gboolean usrcfgok = FALSE, authok = FALSE;
-    gboolean home_dir_ok = FALSE;
-    gboolean failsafe = FALSE;
-    time_t session_start_time, end_time; 
-    pid_t pid;
-    GdmWaitPid *wp;
-    uid_t uid;
-    gid_t gid;
-    int logpipe[2];
-    int logfilefd;
-
-    gdm_debug ("gdm_slave_session_start: Attempting session for user '%s'",
-	       login);
-
-    pwent = getpwnam (login);
-
-    if G_UNLIKELY (pwent == NULL)  {
-	    /* This is sort of an "assert", this should NEVER happen */
-	    if (greet)
-		    gdm_slave_whack_greeter ();
-	    gdm_slave_exit (DISPLAY_REMANAGE,
-			    _("%s: User passed auth but getpwnam (%s) failed!"), "gdm_slave_session_start", login);
-    }
-
-    logged_in_uid = uid = pwent->pw_uid;
-    logged_in_gid = gid = pwent->pw_gid;
-
-    /* Run the PostLogin script */
-    if G_UNLIKELY (gdm_slave_exec_script (d, gdm_daemon_config_get_value_string (GDM_KEY_POSTLOGIN),
-					  login, pwent,
-					  TRUE /* pass_stdout */) != EXIT_SUCCESS &&
-		   /* ignore errors in failsafe modes */
-		   ! failsafe) {
-	    gdm_verify_cleanup (d);
-	    gdm_error (_("%s: Execution of PostLogin script returned > 0. Aborting."), "gdm_slave_session_start");
-	    /* script failed so just try again */
-	    return;
-		
-
-    }
-
-    /*
-     * Set euid, gid to user before testing for user's $HOME since root
-     * does not always have access to the user's $HOME directory.
-     */
-    if G_UNLIKELY (setegid (pwent->pw_gid) != 0 ||
-		   seteuid (pwent->pw_uid) != 0) {
-	    gdm_error ("Cannot set effective user/group id");
-	    gdm_verify_cleanup (d);
-	    session_started = FALSE;
-	    return;
-    }
-
-    if G_UNLIKELY (pwent->pw_dir == NULL ||
-		   ! g_file_test (pwent->pw_dir, G_FILE_TEST_IS_DIR)) {
-	    char *yesno_msg;
-	    char *msg = g_strdup_printf (
-		     _("Your home directory is listed as: '%s' "
-		       "but it does not appear to exist.  "
-		       "Do you want to log in with the / (root) "
-		       "directory as your home directory? "
-		       "It is unlikely anything will work unless "
-		       "you use a failsafe session."),
-		     ve_sure_string (pwent->pw_dir));
-
-	    /* Set euid, egid to root:gdm to manage user interaction */
-            seteuid (0);
-            setegid (gdm_daemon_config_get_gdmgid ());
-
-	    gdm_error (_("%s: Home directory for %s: '%s' does not exist!"),
-		       "gdm_slave_session_start",
-		       login,
-		       ve_sure_string (pwent->pw_dir));
-
-	    /* Check what the user wants to do */
-           yesno_msg = g_strdup_printf ("yesno_msg=%s", msg);
-           gdm_slave_send_string (GDM_SOP_SHOW_YESNO_DIALOG, yesno_msg);
-
-           g_free (yesno_msg);
-
-           if (strcmp (gdm_ack_response, "no") == 0) {
-               gdm_verify_cleanup (d);
-               session_started = FALSE;
-
-               g_free (msg);
-               g_free (gdm_ack_response);
-               gdm_ack_response = NULL;
-               return;
-            }
-
-	    g_free (msg);
-            g_free (gdm_ack_response);
-            gdm_ack_response = NULL;
-
-	    /* Reset euid, egid back to user */
-	    if G_UNLIKELY (setegid (pwent->pw_gid) != 0 ||
-			   seteuid (pwent->pw_uid) != 0) {
-		    gdm_error ("Cannot set effective user/group id");
-		    gdm_verify_cleanup (d);
-		    session_started = FALSE;
-		    return;
-	    }
-
-	    home_dir_ok = FALSE;
-	    home_dir = "/";
-    } else {
-	    home_dir_ok = TRUE;
-	    home_dir = pwent->pw_dir;
-    }
-
-    if G_LIKELY (home_dir_ok) {
-	    /* Sanity check on ~user/.dmrc */
-	    usrcfgok = gdm_file_check ("gdm_slave_session_start", pwent->pw_uid,
-				       home_dir, ".dmrc", TRUE, FALSE,
-				       gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE),
-				       gdm_daemon_config_get_value_int (GDM_KEY_RELAX_PERM));
-    } else {
-	    usrcfgok = FALSE;
-    }
-
-    if G_LIKELY (usrcfgok) {
-	    gdm_daemon_config_get_user_session_lang (&usrsess, &usrlang, home_dir, &savesess);
-    } else {
-	/* This won't get displayed if the .dmrc file simply doesn't
-	 * exist since we pass absentok=TRUE when we call gdm_file_check
+	char *tmp;
+	gboolean savesess = FALSE, savelang = FALSE;
+	gboolean usrcfgok = FALSE, authok = FALSE;
+	gboolean home_dir_ok = FALSE;
+	gboolean failsafe = FALSE;
+	time_t session_start_time, end_time; 
+	pid_t pid;
+	GdmWaitPid *wp;
+	uid_t uid;
+	gid_t gid;
+	int logpipe[2];
+	int logfilefd;
+
+	gdm_debug ("gdm_slave_session_start: Attempting session for user '%s'",
+		   login);
+
+	pwent = getpwnam (login);
+
+	if G_UNLIKELY (pwent == NULL)  {
+		/* This is sort of an "assert", this should NEVER happen */
+		if (greet)
+			gdm_slave_whack_greeter ();
+		gdm_slave_exit (DISPLAY_REMANAGE,
+				_("%s: User passed auth but getpwnam (%s) failed!"), "gdm_slave_session_start", login);
+	}
+
+	logged_in_uid = uid = pwent->pw_uid;
+	logged_in_gid = gid = pwent->pw_gid;
+
+	/* Run the PostLogin script */
+	if G_UNLIKELY (gdm_slave_exec_script (d, gdm_daemon_config_get_value_string (GDM_KEY_POSTLOGIN),
+					      login, pwent,
+					      TRUE /* pass_stdout */) != EXIT_SUCCESS &&
+		       /* ignore errors in failsafe modes */
+		       ! failsafe) {
+		gdm_verify_cleanup (d);
+		gdm_error (_("%s: Execution of PostLogin script returned > 0. Aborting."), "gdm_slave_session_start");
+		/* script failed so just try again */
+		return;
+	}
+
+	/*
+	 * Set euid, gid to user before testing for user's $HOME since root
+	 * does not always have access to the user's $HOME directory.
 	 */
-	gdm_error_box (d,
-		GTK_MESSAGE_WARNING,
-		_("User's $HOME/.dmrc file is being ignored.  "
-		  "This prevents the default session "
-		  "and language from being saved.  File "
-		  "should be owned by user and have 644 "
-		  "permissions.  User's $HOME directory "
-		  "must be owned by user and not writable "
-		  "by other users."));
-	usrsess = g_strdup ("");
-	usrlang = g_strdup ("");
-    }
-
-    NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
-
-    if (greet) {
-	    tmp = gdm_ensure_extension (usrsess, ".desktop");
-	    session = gdm_slave_greeter_ctl (GDM_SESS, tmp);
-	    g_free (tmp);
-
-	    if (session != NULL &&
-		strcmp (session, GDM_RESPONSE_CANCEL) == 0) {
-		    gdm_debug ("User canceled login");
-		    gdm_verify_cleanup (d);
-		    session_started = FALSE;
-		    g_free (usrlang);
-		    return;
-	    }
-
-	    language = gdm_slave_greeter_ctl (GDM_LANG, usrlang);
-	    if (language != NULL && 
-		strcmp (language, GDM_RESPONSE_CANCEL) == 0) {
-		    gdm_debug ("User canceled login");
-		    gdm_verify_cleanup (d);
-		    session_started = FALSE;
-		    g_free (usrlang);
-		    return;
-	    }
-    } else {
-	    session = g_strdup (usrsess);
-	    language = g_strdup (usrlang);
-    }
-
-    tmp = gdm_strip_extension (session, ".desktop");
-    g_free (session);
-    session = tmp;
-
-    if (ve_string_empty (session)) {
-	    g_free (session);
-	    session = find_a_session ();
-	    if (session == NULL) {
-		    /* we're running out of options */
-		    session = g_strdup (GDM_SESSION_FAILSAFE_GNOME);
-	    }
-    }
-
-    if G_LIKELY (ve_string_empty (language)) {
-	    g_free (language);
-	    language = NULL;
-    }
-
-    g_free (usrsess);
-    g_free (usrlang);
-
-    gdm_debug ("Initial setting: session: '%s' language: '%s'\n",
-	       session, ve_sure_string (language));
-
-    /* save this session as the users session */
-    save_session = g_strdup (session);
-
-    if (greet) {
-	    char *ret = gdm_slave_greeter_ctl (GDM_SSESS, "");
-	    if ( ! ve_string_empty (ret))
-		    savesess = TRUE;
-	    g_free (ret);
-
-	    ret = gdm_slave_greeter_ctl (GDM_SLANG, "");
-	    if ( ! ve_string_empty (ret))
-		    savelang = TRUE;
-	    g_free (ret);
-
-	    gdm_debug ("gdm_slave_session_start: Authentication completed. Whacking greeter");
-
-	    gdm_slave_whack_greeter ();
-    }
-
-    if (gdm_daemon_config_get_value_bool (GDM_KEY_KILL_INIT_CLIENTS))
-	    gdm_server_whack_clients (d->dsp);
-
-    /* Now that we will set up the user authorization we will
-       need to run session_stop to whack it */
-    session_started = TRUE;
-
-    /* Setup cookie -- We need this information during cleanup, thus
-     * cookie handling is done before fork()ing */
-
-    if G_UNLIKELY (setegid (pwent->pw_gid) != 0 ||
-		   seteuid (pwent->pw_uid) != 0) {
-	    gdm_error ("Cannot set effective user/group id");
-	    gdm_slave_quick_exit (DISPLAY_REMANAGE);
-    }
-
-    authok = gdm_auth_user_add (d, pwent->pw_uid,
-				/* Only pass the home_dir if
-				 * it was ok */
-				home_dir_ok ? home_dir : NULL);
-
-    /* FIXME: this should be smarter and only do this on out-of-diskspace
-     * errors */
-    if G_UNLIKELY ( ! authok && home_dir_ok) {
-	    /* try wiping the .xsession-errors file (and perhaps other things)
-	       in an attempt to gain disk space */
-	    if (wipe_xsession_errors (pwent, home_dir, home_dir_ok)) {
-		    gdm_error ("Tried wiping some old user session errors files "
-			       "to make disk space and will try adding user auth "
-			       "files again");
-		    /* Try again */
-		    authok = gdm_auth_user_add (d, pwent->pw_uid,
-						/* Only pass the home_dir if
-						 * it was ok */
-						home_dir_ok ? home_dir : NULL);
-	    }
-    }
-
-    NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
-    
-    if G_UNLIKELY ( ! authok) {
-	    gdm_debug ("gdm_slave_session_start: Auth not OK");
-
-	    gdm_error_box (d,
-			   GTK_MESSAGE_ERROR,
-			   _("GDM could not write to your authorization "
-			     "file.  This could mean that you are out of "
-			     "disk space or that your home directory could "
-			     "not be opened for writing.  In any case, it "
-			     "is not possible to log in.  Please contact "
-			     "your system administrator"));
-
-	    gdm_slave_session_stop (FALSE /* run_post_session */,
-				    FALSE /* no_shutdown_check */);
-
-	    gdm_slave_quick_exit (DISPLAY_REMANAGE);
-    }
-
-    if G_UNLIKELY (strcmp (session, GDM_SESSION_FAILSAFE_GNOME) == 0 ||
-		   strcmp (session, GDM_SESSION_FAILSAFE_XTERM) == 0 ||
-		   g_ascii_strcasecmp (session, "failsafe") == 0 /* hack */)
-	    failsafe = TRUE;
-
-    if G_LIKELY ( ! failsafe) {
-	    char *exec = gdm_daemon_config_get_session_exec (session, FALSE /* check_try_exec */);
-	    if ( ! ve_string_empty (exec) &&
-		strcmp (exec, "failsafe") == 0)
-		    failsafe = TRUE;
-	    g_free (exec);
-    }
-
-    /* Write out the Xservers file */
-    gdm_slave_send_num (GDM_SOP_WRITE_X_SERVERS, 0 /* bogus */);
-
-    if G_LIKELY (d->dsp != NULL) {
-	    Cursor xcursor;
-
-	    XSetInputFocus (d->dsp, PointerRoot,
-			    RevertToPointerRoot, CurrentTime);
-
-	    /* return left pointer */
-	    xcursor = XCreateFontCursor (d->dsp, GDK_LEFT_PTR);
-	    XDefineCursor (d->dsp,
-			   DefaultRootWindow (d->dsp),
-			   xcursor);
-	    XFreeCursor (d->dsp, xcursor);
-	    XSync (d->dsp, False);
-    }
-
-    /* Init the ~/.xsession-errors stuff */
-    d->xsession_errors_bytes = 0;
-    d->xsession_errors_fd = -1;
-    d->session_output_fd = -1;
-
-    logfilefd = open_xsession_errors (pwent,
-				      failsafe,
-				      home_dir,
-				      home_dir_ok);
-    if G_UNLIKELY (logfilefd < 0 ||
-		   pipe (logpipe) != 0) {
-	    if (logfilefd >= 0)
-		    VE_IGNORE_EINTR (close (logfilefd));
-	    logfilefd = -1;
-    }
-
-    /* don't completely rely on this, the user
-     * could reset time or do other crazy things */
-    session_start_time = time (NULL);
+	if G_UNLIKELY (setegid (pwent->pw_gid) != 0 ||
+		       seteuid (pwent->pw_uid) != 0) {
+		gdm_error ("Cannot set effective user/group id");
+		gdm_verify_cleanup (d);
+		session_started = FALSE;
+		return;
+	}
+
+	if G_UNLIKELY (pwent->pw_dir == NULL ||
+		       ! g_file_test (pwent->pw_dir, G_FILE_TEST_IS_DIR)) {
+		char *yesno_msg;
+		char *msg = g_strdup_printf (
+					     _("Your home directory is listed as: '%s' "
+					       "but it does not appear to exist.  "
+					       "Do you want to log in with the / (root) "
+					       "directory as your home directory? "
+					       "It is unlikely anything will work unless "
+					       "you use a failsafe session."),
+					     ve_sure_string (pwent->pw_dir));
+
+		/* Set euid, egid to root:gdm to manage user interaction */
+		seteuid (0);
+		setegid (gdm_daemon_config_get_gdmgid ());
+
+		gdm_error (_("%s: Home directory for %s: '%s' does not exist!"),
+			   "gdm_slave_session_start",
+			   login,
+			   ve_sure_string (pwent->pw_dir));
+
+		/* Check what the user wants to do */
+		yesno_msg = g_strdup_printf ("yesno_msg=%s", msg);
+		gdm_slave_send_string (GDM_SOP_SHOW_YESNO_DIALOG, yesno_msg);
+
+		g_free (yesno_msg);
+
+		if (strcmp (gdm_ack_response, "no") == 0) {
+			gdm_verify_cleanup (d);
+			session_started = FALSE;
+
+			g_free (msg);
+			g_free (gdm_ack_response);
+			gdm_ack_response = NULL;
+			return;
+		}
+
+		g_free (msg);
+		g_free (gdm_ack_response);
+		gdm_ack_response = NULL;
+
+		/* Reset euid, egid back to user */
+		if G_UNLIKELY (setegid (pwent->pw_gid) != 0 ||
+			       seteuid (pwent->pw_uid) != 0) {
+			gdm_error ("Cannot set effective user/group id");
+			gdm_verify_cleanup (d);
+			session_started = FALSE;
+			return;
+		}
+
+		home_dir_ok = FALSE;
+		home_dir = "/";
+	} else {
+		home_dir_ok = TRUE;
+		home_dir = pwent->pw_dir;
+	}
+
+	if G_LIKELY (home_dir_ok) {
+		/* Sanity check on ~user/.dmrc */
+		usrcfgok = gdm_file_check ("gdm_slave_session_start", pwent->pw_uid,
+					   home_dir, ".dmrc", TRUE, FALSE,
+					   gdm_daemon_config_get_value_int (GDM_KEY_USER_MAX_FILE),
+					   gdm_daemon_config_get_value_int (GDM_KEY_RELAX_PERM));
+	} else {
+		usrcfgok = FALSE;
+	}
+
+	if G_LIKELY (usrcfgok) {
+		gdm_daemon_config_get_user_session_lang (&usrsess, &usrlang, home_dir, &savesess);
+	} else {
+		/* This won't get displayed if the .dmrc file simply doesn't
+		 * exist since we pass absentok=TRUE when we call gdm_file_check
+		 */
+		gdm_error_box (d,
+			       GTK_MESSAGE_WARNING,
+			       _("User's $HOME/.dmrc file is being ignored.  "
+				 "This prevents the default session "
+				 "and language from being saved.  File "
+				 "should be owned by user and have 644 "
+				 "permissions.  User's $HOME directory "
+				 "must be owned by user and not writable "
+				 "by other users."));
+		usrsess = g_strdup ("");
+		usrlang = g_strdup ("");
+	}
+
+	NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
+
+	if (greet) {
+		tmp = gdm_ensure_extension (usrsess, ".desktop");
+		session = gdm_slave_greeter_ctl (GDM_SESS, tmp);
+		g_free (tmp);
+
+		if (session != NULL &&
+		    strcmp (session, GDM_RESPONSE_CANCEL) == 0) {
+			gdm_debug ("User canceled login");
+			gdm_verify_cleanup (d);
+			session_started = FALSE;
+			g_free (usrlang);
+			return;
+		}
+
+		language = gdm_slave_greeter_ctl (GDM_LANG, usrlang);
+		if (language != NULL &&
+		    strcmp (language, GDM_RESPONSE_CANCEL) == 0) {
+			gdm_debug ("User canceled login");
+			gdm_verify_cleanup (d);
+			session_started = FALSE;
+			g_free (usrlang);
+			return;
+		}
+	} else {
+		session = g_strdup (usrsess);
+		language = g_strdup (usrlang);
+	}
+
+	tmp = gdm_strip_extension (session, ".desktop");
+	g_free (session);
+	session = tmp;
+
+	if (ve_string_empty (session)) {
+		g_free (session);
+		session = find_a_session ();
+		if (session == NULL) {
+			/* we're running out of options */
+			session = g_strdup (GDM_SESSION_FAILSAFE_GNOME);
+		}
+	}
+
+	if G_LIKELY (ve_string_empty (language)) {
+		g_free (language);
+		language = NULL;
+	}
+
+	g_free (usrsess);
+	g_free (usrlang);
+
+	gdm_debug ("Initial setting: session: '%s' language: '%s'\n",
+		   session, ve_sure_string (language));
+
+	/* save this session as the users session */
+	save_session = g_strdup (session);
+
+	if (greet) {
+		char *ret = gdm_slave_greeter_ctl (GDM_SSESS, "");
+		if ( ! ve_string_empty (ret))
+			savesess = TRUE;
+		g_free (ret);
+
+		ret = gdm_slave_greeter_ctl (GDM_SLANG, "");
+		if ( ! ve_string_empty (ret))
+			savelang = TRUE;
+		g_free (ret);
+
+		gdm_debug ("gdm_slave_session_start: Authentication completed. Whacking greeter");
+
+		gdm_slave_whack_greeter ();
+	}
+
+	if (gdm_daemon_config_get_value_bool (GDM_KEY_KILL_INIT_CLIENTS))
+		gdm_server_whack_clients (d->dsp);
+
+	/* Now that we will set up the user authorization we will
+	   need to run session_stop to whack it */
+	session_started = TRUE;
+
+	/* Setup cookie -- We need this information during cleanup, thus
+	 * cookie handling is done before fork()ing */
+
+	if G_UNLIKELY (setegid (pwent->pw_gid) != 0 ||
+		       seteuid (pwent->pw_uid) != 0) {
+		gdm_error ("Cannot set effective user/group id");
+		gdm_slave_quick_exit (DISPLAY_REMANAGE);
+	}
+
+	authok = gdm_auth_user_add (d, pwent->pw_uid,
+				    /* Only pass the home_dir if
+				     * it was ok */
+				    home_dir_ok ? home_dir : NULL);
+
+	/* FIXME: this should be smarter and only do this on out-of-diskspace
+	 * errors */
+	if G_UNLIKELY ( ! authok && home_dir_ok) {
+		/* try wiping the .xsession-errors file (and perhaps other things)
+		   in an attempt to gain disk space */
+		if (wipe_xsession_errors (pwent, home_dir, home_dir_ok)) {
+			gdm_error ("Tried wiping some old user session errors files "
+				   "to make disk space and will try adding user auth "
+				   "files again");
+			/* Try again */
+			authok = gdm_auth_user_add (d, pwent->pw_uid,
+						    /* Only pass the home_dir if
+						     * it was ok */
+						    home_dir_ok ? home_dir : NULL);
+		}
+	}
+
+	NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
+
+	if G_UNLIKELY ( ! authok) {
+		gdm_debug ("gdm_slave_session_start: Auth not OK");
+
+		gdm_error_box (d,
+			       GTK_MESSAGE_ERROR,
+			       _("GDM could not write to your authorization "
+				 "file.  This could mean that you are out of "
+				 "disk space or that your home directory could "
+				 "not be opened for writing.  In any case, it "
+				 "is not possible to log in.  Please contact "
+				 "your system administrator"));
+
+		gdm_slave_session_stop (FALSE /* run_post_session */,
+					FALSE /* no_shutdown_check */);
+
+		gdm_slave_quick_exit (DISPLAY_REMANAGE);
+	}
+
+	if G_UNLIKELY (strcmp (session, GDM_SESSION_FAILSAFE_GNOME) == 0 ||
+		       strcmp (session, GDM_SESSION_FAILSAFE_XTERM) == 0 ||
+		       g_ascii_strcasecmp (session, "failsafe") == 0 /* hack */)
+		failsafe = TRUE;
+
+	if G_LIKELY ( ! failsafe) {
+		char *exec = gdm_daemon_config_get_session_exec (session, FALSE /* check_try_exec */);
+		if ( ! ve_string_empty (exec) &&
+		     strcmp (exec, "failsafe") == 0)
+			failsafe = TRUE;
+		g_free (exec);
+	}
+
+	/* Write out the Xservers file */
+	gdm_slave_send_num (GDM_SOP_WRITE_X_SERVERS, 0 /* bogus */);
+
+	if G_LIKELY (d->dsp != NULL) {
+		Cursor xcursor;
+
+		XSetInputFocus (d->dsp, PointerRoot,
+				RevertToPointerRoot, CurrentTime);
+
+		/* return left pointer */
+		xcursor = XCreateFontCursor (d->dsp, GDK_LEFT_PTR);
+		XDefineCursor (d->dsp,
+			       DefaultRootWindow (d->dsp),
+			       xcursor);
+		XFreeCursor (d->dsp, xcursor);
+		XSync (d->dsp, False);
+	}
+
+	/* Init the ~/.xsession-errors stuff */
+	d->xsession_errors_bytes = 0;
+	d->xsession_errors_fd = -1;
+	d->session_output_fd = -1;
+
+	logfilefd = open_xsession_errors (pwent,
+					  failsafe,
+					  home_dir,
+					  home_dir_ok);
+	if G_UNLIKELY (logfilefd < 0 ||
+		       pipe (logpipe) != 0) {
+		if (logfilefd >= 0)
+			VE_IGNORE_EINTR (close (logfilefd));
+		logfilefd = -1;
+	}
+
+	/* don't completely rely on this, the user
+	 * could reset time or do other crazy things */
+	session_start_time = time (NULL);
 
 #ifdef WITH_CONSOLE_KIT
-    ck_session_cookie = open_ck_session (pwent, d, session);
+	ck_session_cookie = open_ck_session (pwent, d, session);
 #endif
 
-    /* Start user process */
-    gdm_sigchld_block_push ();
-    gdm_sigterm_block_push ();
-    pid = d->sesspid = fork ();
-    if (pid == 0)
-	    gdm_unset_signals ();
-    gdm_sigterm_block_pop ();
-    gdm_sigchld_block_pop ();
-
-    switch (pid) {
-	
-    case -1:
-	gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Error forking user session"), "gdm_slave_session_start");
-	
-    case 0:
-	if G_LIKELY (logfilefd >= 0) {
-		VE_IGNORE_EINTR (close (logpipe[0]));
-	}
-	/* Never returns */
-	session_child_run (pwent,
-			   logpipe[1],
-			   failsafe,
-			   home_dir,
-			   home_dir_ok,
+	/* Start user process */
+	gdm_sigchld_block_push ();
+	gdm_sigterm_block_push ();
+	pid = d->sesspid = fork ();
+	if (pid == 0)
+		gdm_unset_signals ();
+	gdm_sigterm_block_pop ();
+	gdm_sigchld_block_pop ();
+
+	switch (pid) {
+
+	case -1:
+		gdm_slave_exit (DISPLAY_REMANAGE, _("%s: Error forking user session"), "gdm_slave_session_start");
+
+	case 0:
+		if G_LIKELY (logfilefd >= 0) {
+			VE_IGNORE_EINTR (close (logpipe[0]));
+		}
+		/* Never returns */
+		session_child_run (pwent,
+				   logpipe[1],
+				   failsafe,
+				   home_dir,
+				   home_dir_ok,
 #ifdef WITH_CONSOLE_KIT
-			   ck_session_cookie,
+				   ck_session_cookie,
 #endif
-			   session,
-			   save_session,
+				   session,
+				   save_session,
+
+				   ((gdm_system_locale != (char *) NULL) &&
+				    ( (language == NULL) ||
+				      ((language != NULL) && (strcmp (language, "") == 0))) == TRUE ?
+				    gdm_system_locale : language),
+				   gnome_session,
+				   usrcfgok,
+				   savesess,
+				   savelang);
+		gdm_assert_not_reached ();
+
+	default:
+		break;
+	}
+
+	/* this clears internal cache */
+	gdm_daemon_config_get_session_exec (NULL, FALSE);
+
+	if G_LIKELY (logfilefd >= 0)  {
+		d->xsession_errors_fd = logfilefd;
+		d->session_output_fd = logpipe[0];
+		/* make the output read fd non-blocking */
+		fcntl (d->session_output_fd, F_SETFL, O_NONBLOCK);
+		VE_IGNORE_EINTR (close (logpipe[1]));
+	}
+
+	/* We must be root for this, and we are, but just to make sure */
+	NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
+	/* Reset all the process limits, pam may have set some up for our process and that
+	   is quite evil.  But pam is generally evil, so this is to be expected. */
+	gdm_reset_limits ();
+
+	g_free (session);
+	g_free (save_session);
+	g_free (language);
+	g_free (gnome_session);
+
+	gdm_slave_send_num (GDM_SOP_SESSPID, pid);
+
+	gdm_sigchld_block_push ();
+	wp = slave_waitpid_setpid (d->sesspid);
+	gdm_sigchld_block_pop ();
 
-			   ((gdm_system_locale != (char *) NULL) &&
-			   ( (language == NULL) ||
-			   ((language != NULL) && (strcmp (language, "") == 0))) == TRUE ?
-			   gdm_system_locale : language),
-			   gnome_session,
-			   usrcfgok,
-			   savesess,
-			   savelang);
-	gdm_assert_not_reached ();
-	
-    default:
-	break;
-    }
-    
-    /* this clears internal cache */
-    gdm_daemon_config_get_session_exec (NULL, FALSE);
-
-    if G_LIKELY (logfilefd >= 0)  {
-	    d->xsession_errors_fd = logfilefd;
-	    d->session_output_fd = logpipe[0];
-	    /* make the output read fd non-blocking */
-	    fcntl (d->session_output_fd, F_SETFL, O_NONBLOCK);
-	    VE_IGNORE_EINTR (close (logpipe[1]));
-    }
-
-    /* We must be root for this, and we are, but just to make sure */
-    NEVER_FAILS_root_set_euid_egid (0, gdm_daemon_config_get_gdmgid ());
-    /* Reset all the process limits, pam may have set some up for our process and that
-       is quite evil.  But pam is generally evil, so this is to be expected. */
-    gdm_reset_limits ();
-
-    g_free (session);
-    g_free (save_session);
-    g_free (language);
-    g_free (gnome_session);
-
-    gdm_slave_send_num (GDM_SOP_SESSPID, pid);
-
-    gdm_sigchld_block_push ();
-    wp = slave_waitpid_setpid (d->sesspid);
-    gdm_sigchld_block_pop ();
-
-    slave_waitpid (wp);
-
-    d->sesspid = 0;
-
-    /* finish reading the session output if any of it is still there */
-    finish_session_output (TRUE);
-
-    /* Now still as root make the system authfile readable by others,
-       and therefore by the gdm user */
-    VE_IGNORE_EINTR (g_chmod (GDM_AUTHFILE (d), 0644));
-
-    end_time = time (NULL);
-
-    gdm_debug ("Session: start_time: %ld end_time: %ld",
-	       (long)session_start_time, (long)end_time);
-
-    /* 66 is a very magical number signifying failure in GDM */
-    if G_UNLIKELY ((d->last_sess_status != 66) &&
-		   (/* sanity */ end_time >= session_start_time) &&
-		   (end_time - 10 <= session_start_time) &&
-		   /* only if the X server still exist! */
-		   d->servpid > 1) {
-	    char *msg_string;
-	    char *error_msg =
+	slave_waitpid (wp);
+
+	d->sesspid = 0;
+
+	/* finish reading the session output if any of it is still there */
+	finish_session_output (TRUE);
+
+	/* Now still as root make the system authfile readable by others,
+	   and therefore by the gdm user */
+	VE_IGNORE_EINTR (g_chmod (GDM_AUTHFILE (d), 0644));
+
+	end_time = time (NULL);
+
+	gdm_debug ("Session: start_time: %ld end_time: %ld",
+		   (long)session_start_time, (long)end_time);
+
+	/* 66 is a very magical number signifying failure in GDM */
+	if G_UNLIKELY ((d->last_sess_status != 66) &&
+		       (/* sanity */ end_time >= session_start_time) &&
+		       (end_time - 10 <= session_start_time) &&
+		       /* only if the X server still exist! */
+		       d->servpid > 1) {
+		char *msg_string;
+		char *error_msg =
 			_("Your session only lasted less than "
 			  "10 seconds.  If you have not logged out "
 			  "yourself, this could mean that there is "
@@ -4462,34 +4462,34 @@ gdm_slave_session_start (void)
 			  "one of the failsafe sessions to see if you "
 			  "can fix this problem.");
 
-	    /* FIXME: perhaps do some checking to display a better error,
-	     * such as gnome-session missing and such things. */
-	    gdm_debug ("Session less than 10 seconds!");
-	    msg_string = g_strdup_printf ("type=%d$$error_msg=%s$$details_label=%s$$details_file=%s$$uid=%d$$gid=%d",
-					  GTK_MESSAGE_WARNING,error_msg, 
-					  (d->xsession_errors_filename != NULL) ?
-					  _("View details (~/.xsession-errors file)") :
-					  NULL,
-					  d->xsession_errors_filename,
-					  0, 0);
+		/* FIXME: perhaps do some checking to display a better error,
+		 * such as gnome-session missing and such things. */
+		gdm_debug ("Session less than 10 seconds!");
+		msg_string = g_strdup_printf ("type=%d$$error_msg=%s$$details_label=%s$$details_file=%s$$uid=%d$$gid=%d",
+					      GTK_MESSAGE_WARNING,error_msg, 
+					      (d->xsession_errors_filename != NULL) ?
+					      _("View details (~/.xsession-errors file)") :
+					      NULL,
+					      d->xsession_errors_filename,
+					      0, 0);
 
-	    gdm_slave_send_string (GDM_SOP_SHOW_ERROR_DIALOG, msg_string);
+		gdm_slave_send_string (GDM_SOP_SHOW_ERROR_DIALOG, msg_string);
 
-	    g_free (msg_string);
+		g_free (msg_string);
 
-    }
+	}
 
 #ifdef WITH_CONSOLE_KIT
-    if (ck_session_cookie != NULL) {
-	    close_ck_session (ck_session_cookie);
-	    g_free (ck_session_cookie);
-    }
+	if (ck_session_cookie != NULL) {
+		close_ck_session (ck_session_cookie);
+		g_free (ck_session_cookie);
+	}
 #endif
 
-    gdm_slave_session_stop (pid != 0 /* run_post_session */,
-			    FALSE /* no_shutdown_check */);
+	gdm_slave_session_stop (pid != 0 /* run_post_session */,
+				FALSE /* no_shutdown_check */);
 
-    gdm_debug ("gdm_slave_session_start: Session ended OK (now all finished)");
+	gdm_debug ("gdm_slave_session_start: Session ended OK (now all finished)");
 }
 
 
@@ -4498,137 +4498,137 @@ static void
 gdm_slave_session_stop (gboolean run_post_session,
 			gboolean no_shutdown_check)
 {
-    struct passwd *pwent;
-    char *x_servers_file;
-    char *local_login;
-
-    in_session_stop++;
-
-    session_started = FALSE;
-
-    local_login = login;
-    login = NULL;
-
-    /* don't use NEVER_FAILS_ here this can be called from places
-       kind of exiting and it's ok if this doesn't work (when shouldn't
-       it work anyway? */
-    seteuid (0);
-    setegid (0);
-
-    gdm_slave_send_num (GDM_SOP_SESSPID, 0);
-
-    /* Now still as root make the system authfile not readable by others,
-       and therefore not by the gdm user */
-    if (GDM_AUTHFILE (d) != NULL) {
-	    VE_IGNORE_EINTR (g_chmod (GDM_AUTHFILE (d), 0640));
-    }
-
-    gdm_debug ("gdm_slave_session_stop: %s on %s", local_login, d->name);
-
-    /* Note we use the info in the structure here since if we get passed
-     * a 0 that means the process is already dead.
-     * FIXME: Maybe we should waitpid here, note make sure this will
-     * not create a hang! */
-    gdm_sigchld_block_push ();
-    if (d->sesspid > 1)
-	    kill (- (d->sesspid), SIGTERM);
-    gdm_sigchld_block_pop ();
-
-    finish_session_output (run_post_session /* do_read */);
-    
-    if (local_login == NULL)
-	    pwent = NULL;
-    else
-	    pwent = getpwnam (local_login);	/* PAM overwrites our pwent */
-
-    x_servers_file = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR),
-					d->name, ".Xservers");
-
-    /* if there was a session that ran, run the PostSession script */
-    if (run_post_session) {
-	    /* Execute post session script */
-	    gdm_debug ("gdm_slave_session_stop: Running post session script");
-	    gdm_slave_exec_script (d, gdm_daemon_config_get_value_string (GDM_KEY_POSTSESSION), local_login, pwent,
-				   FALSE /* pass_stdout */);
-    }
-
-    VE_IGNORE_EINTR (g_unlink (x_servers_file));
-    g_free (x_servers_file);
-
-    g_free (local_login);
-
-    if (pwent != NULL) {
-	    seteuid (0); /* paranoia */
-	    /* Remove display from ~user/.Xauthority */
-	    if G_LIKELY (setegid (pwent->pw_gid) == 0 &&
-			 seteuid (pwent->pw_uid) == 0) {
-		    gdm_auth_user_remove (d, pwent->pw_uid);
-	    }
-
-	    /* don't use NEVER_FAILS_ here this can be called from places
-	       kind of exiting and it's ok if this doesn't work (when shouldn't
-	       it work anyway? */
-	    seteuid (0);
-	    setegid (0);
-    }
-
-    logged_in_uid = -1;
-    logged_in_gid = -1;
-
-    /* things are going to be killed, so ignore errors */
-    XSetErrorHandler (ignore_xerror_handler);
-
-    gdm_verify_cleanup (d);
+	struct passwd *pwent;
+	char *x_servers_file;
+	char *local_login;
+
+	in_session_stop++;
+
+	session_started = FALSE;
+
+	local_login = login;
+	login = NULL;
+
+	/* don't use NEVER_FAILS_ here this can be called from places
+	   kind of exiting and it's ok if this doesn't work (when shouldn't
+	   it work anyway? */
+	seteuid (0);
+	setegid (0);
+
+	gdm_slave_send_num (GDM_SOP_SESSPID, 0);
+
+	/* Now still as root make the system authfile not readable by others,
+	   and therefore not by the gdm user */
+	if (GDM_AUTHFILE (d) != NULL) {
+		VE_IGNORE_EINTR (g_chmod (GDM_AUTHFILE (d), 0640));
+	}
+
+	gdm_debug ("gdm_slave_session_stop: %s on %s", local_login, d->name);
+
+	/* Note we use the info in the structure here since if we get passed
+	 * a 0 that means the process is already dead.
+	 * FIXME: Maybe we should waitpid here, note make sure this will
+	 * not create a hang! */
+	gdm_sigchld_block_push ();
+	if (d->sesspid > 1)
+		kill (- (d->sesspid), SIGTERM);
+	gdm_sigchld_block_pop ();
+
+	finish_session_output (run_post_session /* do_read */);
+
+	if (local_login == NULL)
+		pwent = NULL;
+	else
+		pwent = getpwnam (local_login);	/* PAM overwrites our pwent */
+
+	x_servers_file = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR),
+					    d->name, ".Xservers");
+
+	/* if there was a session that ran, run the PostSession script */
+	if (run_post_session) {
+		/* Execute post session script */
+		gdm_debug ("gdm_slave_session_stop: Running post session script");
+		gdm_slave_exec_script (d, gdm_daemon_config_get_value_string (GDM_KEY_POSTSESSION), local_login, pwent,
+				       FALSE /* pass_stdout */);
+	}
 
-    in_session_stop --;
+	VE_IGNORE_EINTR (g_unlink (x_servers_file));
+	g_free (x_servers_file);
+
+	g_free (local_login);
+
+	if (pwent != NULL) {
+		seteuid (0); /* paranoia */
+		/* Remove display from ~user/.Xauthority */
+		if G_LIKELY (setegid (pwent->pw_gid) == 0 &&
+			     seteuid (pwent->pw_uid) == 0) {
+			gdm_auth_user_remove (d, pwent->pw_uid);
+		}
+
+		/* don't use NEVER_FAILS_ here this can be called from places
+		   kind of exiting and it's ok if this doesn't work (when shouldn't
+		   it work anyway? */
+		seteuid (0);
+		setegid (0);
+	}
+
+	logged_in_uid = -1;
+	logged_in_gid = -1;
+
+	/* things are going to be killed, so ignore errors */
+	XSetErrorHandler (ignore_xerror_handler);
 
-    if (need_to_quit_after_session_stop) {
-	    gdm_debug ("gdm_slave_session_stop: Final cleanup");
+	gdm_verify_cleanup (d);
 
-	    gdm_slave_quick_exit (exit_code_to_use);
-    }
+	in_session_stop --;
+
+	if (need_to_quit_after_session_stop) {
+		gdm_debug ("gdm_slave_session_stop: Final cleanup");
+
+		gdm_slave_quick_exit (exit_code_to_use);
+	}
 
 #ifdef __linux__
-    /* If on Linux and the runlevel is 0 or 6 and not the runlevel that
-       we were started in, then we are restarting or halting the machine.
-       Probably the user selected halt or restart from the logout
-       menu.  In this case we can really just sleep for a few seconds and
-       basically wait to be killed.  I will set the default for 30 seconds
-       and let people yell at me if this breaks something.  It shouldn't.
-       In fact it should fix things so that the login screen is not brought
-       up again and then whacked.  Waiting is safer then DISPLAY_ABORT,
-       since if we really do get this wrong, then at the worst case the
-       user will wait for a few moments. */
-    if ( ! need_to_quit_after_session_stop &&
-	 ! no_shutdown_check &&
-	g_access ("/sbin/runlevel", X_OK) == 0) {
-	    char ign;
-	    int rnl;
-	    FILE *fp = popen ("/sbin/runlevel", "r");
-	    if (fp != NULL &&
-		fscanf (fp, "%c %d", &ign, &rnl) == 2 &&
-		(rnl == 0 || rnl == 6) &&
-		rnl != gdm_normal_runlevel) {
-		    /* this is a stupid loop, but we may be getting signals,
-		       so we don't want to just do sleep (30) */
-		    time_t c = time (NULL);
-		    gdm_info (_("GDM detected a halt or restart "
-				"in progress."));
-		    pclose (fp);
-		    while (c + 30 >= time (NULL)) {
-			    struct timeval tv;
-			    /* Wait 30 seconds. */
-			    tv.tv_sec = 30;
-			    tv.tv_usec = 0;
-			    select (0, NULL, NULL, NULL, &tv);
-			    /* don't want to use sleep since we're using alarm
-			       for pinging */
-		    }
-		    /* hmm, didn't get TERM, weird */
-	    } else if (fp != NULL) {
-		    pclose (fp);
-	    }
-    }
+	/* If on Linux and the runlevel is 0 or 6 and not the runlevel that
+	   we were started in, then we are restarting or halting the machine.
+	   Probably the user selected halt or restart from the logout
+	   menu.  In this case we can really just sleep for a few seconds and
+	   basically wait to be killed.  I will set the default for 30 seconds
+	   and let people yell at me if this breaks something.  It shouldn't.
+	   In fact it should fix things so that the login screen is not brought
+	   up again and then whacked.  Waiting is safer then DISPLAY_ABORT,
+	   since if we really do get this wrong, then at the worst case the
+	   user will wait for a few moments. */
+	if ( ! need_to_quit_after_session_stop &&
+	     ! no_shutdown_check &&
+	     g_access ("/sbin/runlevel", X_OK) == 0) {
+		char ign;
+		int rnl;
+		FILE *fp = popen ("/sbin/runlevel", "r");
+		if (fp != NULL &&
+		    fscanf (fp, "%c %d", &ign, &rnl) == 2 &&
+		    (rnl == 0 || rnl == 6) &&
+		    rnl != gdm_normal_runlevel) {
+			/* this is a stupid loop, but we may be getting signals,
+			   so we don't want to just do sleep (30) */
+			time_t c = time (NULL);
+			gdm_info (_("GDM detected a halt or restart "
+				    "in progress."));
+			pclose (fp);
+			while (c + 30 >= time (NULL)) {
+				struct timeval tv;
+				/* Wait 30 seconds. */
+				tv.tv_sec = 30;
+				tv.tv_usec = 0;
+				select (0, NULL, NULL, NULL, &tv);
+				/* don't want to use sleep since we're using alarm
+				   for pinging */
+			}
+			/* hmm, didn't get TERM, weird */
+		} else if (fp != NULL) {
+			pclose (fp);
+		}
+	}
 #endif /* __linux__ */
 }
 
@@ -4723,134 +4723,134 @@ gdm_slave_alrm_handler (int sig)
 }
 
 /* Called on every SIGCHLD */
-void 
+void
 gdm_slave_child_handler (int sig)
 {
-    gint status;
-    pid_t pid;
-    uid_t old;
-
-    if G_UNLIKELY (already_in_slave_start_jmp)
-	    return;
-
-    gdm_in_signal++;
-
-    old = geteuid ();
-    if (old != 0)
-	    seteuid (0);
-    
-    while ((pid = waitpid (-1, &status, WNOHANG)) > 0) {
-        GSList *li;
-
-	for (li = slave_waitpids; li != NULL; li = li->next) {
-		GdmWaitPid *wp = li->data;
-		if (wp->pid == pid) {
-			wp->pid = -1;
-			if (slave_waitpid_w >= 0) {
-				VE_IGNORE_EINTR (write (slave_waitpid_w, "!", 1));
+	gint status;
+	pid_t pid;
+	uid_t old;
+
+	if G_UNLIKELY (already_in_slave_start_jmp)
+		return;
+
+	gdm_in_signal++;
+
+	old = geteuid ();
+	if (old != 0)
+		seteuid (0);
+
+	while ((pid = waitpid (-1, &status, WNOHANG)) > 0) {
+		GSList *li;
+
+		for (li = slave_waitpids; li != NULL; li = li->next) {
+			GdmWaitPid *wp = li->data;
+			if (wp->pid == pid) {
+				wp->pid = -1;
+				if (slave_waitpid_w >= 0) {
+					VE_IGNORE_EINTR (write (slave_waitpid_w, "!", 1));
+				}
 			}
 		}
-	}
-	
-	if (pid == d->greetpid && greet) {
-		if (WIFEXITED (status) &&
-		    WEXITSTATUS (status) == DISPLAY_RESTARTGREETER) {
-			/* FIXME: shouldn't do this from
-			   a signal handler */
-			/*gdm_slave_desensitize_config ();*/
 
-			greet = FALSE;
-			d->greetpid = 0;
-			whack_greeter_fds ();
-			gdm_slave_send_num (GDM_SOP_GREETPID, 0);
+		if (pid == d->greetpid && greet) {
+			if (WIFEXITED (status) &&
+			    WEXITSTATUS (status) == DISPLAY_RESTARTGREETER) {
+				/* FIXME: shouldn't do this from
+				   a signal handler */
+				/*gdm_slave_desensitize_config ();*/
+
+				greet = FALSE;
+				d->greetpid = 0;
+				whack_greeter_fds ();
+				gdm_slave_send_num (GDM_SOP_GREETPID, 0);
 
-			do_restart_greeter = TRUE;
-			if (restart_greeter_now) {
-				slave_waitpid_notify ();
-			} else {
-				interrupted = TRUE;
+				do_restart_greeter = TRUE;
+				if (restart_greeter_now) {
+					slave_waitpid_notify ();
+				} else {
+					interrupted = TRUE;
+				}
+				continue;
 			}
-			continue;
-		}
 
-		whack_greeter_fds ();
+			whack_greeter_fds ();
 
-		/* if greet is TRUE, then the greeter died outside of our
-		 * control really, so clean up and die, something is wrong
-		 * The greeter is only allowed to pass back these
-		 * exit codes, else we'll just remanage */
-		if (WIFEXITED (status) &&
-		    (WEXITSTATUS (status) == DISPLAY_ABORT ||
-		     WEXITSTATUS (status) == DISPLAY_REBOOT ||
-		     WEXITSTATUS (status) == DISPLAY_HALT ||
-		     WEXITSTATUS (status) == DISPLAY_SUSPEND ||
-		     WEXITSTATUS (status) == DISPLAY_RUN_CHOOSER ||
-		     WEXITSTATUS (status) == DISPLAY_RESTARTGDM ||
-		     WEXITSTATUS (status) == DISPLAY_GREETERFAILED)) {
-			exit_code_to_use = WEXITSTATUS (status);
-			SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY);
-		} else {
-			if (WIFSIGNALED (status) &&
-			    (WTERMSIG (status) == SIGSEGV ||
-			     WTERMSIG (status) == SIGABRT ||
-			     WTERMSIG (status) == SIGPIPE ||
-			     WTERMSIG (status) == SIGBUS)) {
-				exit_code_to_use = DISPLAY_GREETERFAILED;
+			/* if greet is TRUE, then the greeter died outside of our
+			 * control really, so clean up and die, something is wrong
+			 * The greeter is only allowed to pass back these
+			 * exit codes, else we'll just remanage */
+			if (WIFEXITED (status) &&
+			    (WEXITSTATUS (status) == DISPLAY_ABORT ||
+			     WEXITSTATUS (status) == DISPLAY_REBOOT ||
+			     WEXITSTATUS (status) == DISPLAY_HALT ||
+			     WEXITSTATUS (status) == DISPLAY_SUSPEND ||
+			     WEXITSTATUS (status) == DISPLAY_RUN_CHOOSER ||
+			     WEXITSTATUS (status) == DISPLAY_RESTARTGDM ||
+			     WEXITSTATUS (status) == DISPLAY_GREETERFAILED)) {
+				exit_code_to_use = WEXITSTATUS (status);
 				SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY);
 			} else {
-				/* weird error return, interpret as failure */
-				if (WIFEXITED (status) &&
-				    WEXITSTATUS (status) == 1)
+				if (WIFSIGNALED (status) &&
+				    (WTERMSIG (status) == SIGSEGV ||
+				     WTERMSIG (status) == SIGABRT ||
+				     WTERMSIG (status) == SIGPIPE ||
+				     WTERMSIG (status) == SIGBUS)) {
 					exit_code_to_use = DISPLAY_GREETERFAILED;
-				SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY);
+					SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY);
+				} else {
+					/* weird error return, interpret as failure */
+					if (WIFEXITED (status) &&
+					    WEXITSTATUS (status) == 1)
+						exit_code_to_use = DISPLAY_GREETERFAILED;
+					SIGNAL_EXIT_WITH_JMP (d, JMP_JUST_QUIT_QUICKLY);
+				}
 			}
-		}
-	} else if (pid != 0 && pid == d->sesspid) {
-		d->sesspid = 0;
-		if (WIFEXITED (status))
-			d->last_sess_status = WEXITSTATUS (status);
-		else
-			d->last_sess_status = -1;
-	} else if (pid != 0 && pid == d->chooserpid) {
-		d->chooserpid = 0;
-	} else if (pid != 0 && pid == d->servpid) {
-		if (d->servstat == SERVER_RUNNING)
-			gdm_server_whack_lockfile (d);
-		d->servstat = SERVER_DEAD;
-		d->servpid = 0;
-		gdm_server_wipe_cookies (d);
-		gdm_slave_whack_temp_auth_file ();
+		} else if (pid != 0 && pid == d->sesspid) {
+			d->sesspid = 0;
+			if (WIFEXITED (status))
+				d->last_sess_status = WEXITSTATUS (status);
+			else
+				d->last_sess_status = -1;
+		} else if (pid != 0 && pid == d->chooserpid) {
+			d->chooserpid = 0;
+		} else if (pid != 0 && pid == d->servpid) {
+			if (d->servstat == SERVER_RUNNING)
+				gdm_server_whack_lockfile (d);
+			d->servstat = SERVER_DEAD;
+			d->servpid = 0;
+			gdm_server_wipe_cookies (d);
+			gdm_slave_whack_temp_auth_file ();
 
-		gdm_slave_send_num (GDM_SOP_XPID, 0);
+			gdm_slave_send_num (GDM_SOP_XPID, 0);
 
-		/* whack the session good */
-		if (d->sesspid > 1) {
-			gdm_slave_send_num (GDM_SOP_SESSPID, 0);
-			kill (- (d->sesspid), SIGTERM);
-		}
-		if (d->greetpid > 1) {
-			gdm_slave_send_num (GDM_SOP_GREETPID, 0);
-			kill (d->greetpid, SIGTERM);
-		}
-		if (d->chooserpid > 1) {
-			gdm_slave_send_num (GDM_SOP_CHOOSERPID, 0);
-			kill (d->chooserpid, SIGTERM);
+			/* whack the session good */
+			if (d->sesspid > 1) {
+				gdm_slave_send_num (GDM_SOP_SESSPID, 0);
+				kill (- (d->sesspid), SIGTERM);
+			}
+			if (d->greetpid > 1) {
+				gdm_slave_send_num (GDM_SOP_GREETPID, 0);
+				kill (d->greetpid, SIGTERM);
+			}
+			if (d->chooserpid > 1) {
+				gdm_slave_send_num (GDM_SOP_CHOOSERPID, 0);
+				kill (d->chooserpid, SIGTERM);
+			}
+
+			/* just in case we restart again wait at least
+			   one sec to avoid races */
+			if (d->sleep_before_run < 1)
+				d->sleep_before_run = 1;
+		} else if (pid == extra_process) {
+			/* an extra process died, yay! */
+			extra_process = 0;
+			extra_status = status;
 		}
-
-		/* just in case we restart again wait at least
-		   one sec to avoid races */
-		if (d->sleep_before_run < 1)
-			d->sleep_before_run = 1;
-	} else if (pid == extra_process) {
-		/* an extra process died, yay! */
-		extra_process = 0;
-	    	extra_status = status;
 	}
-    }
-    if (old != 0)
-	    seteuid (old);
+	if (old != 0)
+		seteuid (old);
 
-    gdm_in_signal--;
+	gdm_in_signal--;
 }
 
 static void
@@ -4926,7 +4926,7 @@ gdm_slave_handle_usr2_message (void)
 				if (s[2] == '0') {
 					gdm_ack_response =  g_strdup ("no");
 				} else {
-				gdm_ack_response =  g_strdup ("yes");
+					gdm_ack_response =  g_strdup ("yes");
 				}
 			} else if (s[1] == GDM_SLAVE_NOTIFY_ASKBUTTONS_RESPONSE) {
 				gdm_ack_response = g_strdup (&s[2]);
@@ -4961,8 +4961,8 @@ gdm_slave_usr2_handler (int sig)
 static gint
 gdm_slave_xerror_handler (Display *disp, XErrorEvent *evt)
 {
-    gdm_debug ("gdm_slave_xerror_handler: X error - display doesn't respond");
-    return (0);
+	gdm_debug ("gdm_slave_xerror_handler: X error - display doesn't respond");
+	return (0);
 }
 
 /* We usually respond to fatal errors by restarting the display */
@@ -5031,7 +5031,7 @@ check_for_interruption (const char *msg)
 			 * it is allowed for this display (it's only allowed
 			 * for the first local display) and if it's set up
 			 * correctly */
-			if ((d->attached || gdm_daemon_config_get_value_bool (GDM_KEY_ALLOW_REMOTE_AUTOLOGIN)) 
+			if ((d->attached || gdm_daemon_config_get_value_bool (GDM_KEY_ALLOW_REMOTE_AUTOLOGIN))
                             && d->timed_login_ok &&
 			    ! ve_string_empty (ParsedTimedLogin) &&
                             strcmp (ParsedTimedLogin, gdm_root_user ()) != 0 &&
@@ -5052,8 +5052,8 @@ check_for_interruption (const char *msg)
 			    gdm_daemon_config_get_value_bool_per_display (d->name, GDM_KEY_SYSTEM_MENU) &&
 			    ! ve_string_empty (gdm_daemon_config_get_value_string (GDM_KEY_SUSPEND))) {
 			    	gchar *msg = g_strdup_printf ("%s %ld", 
-					GDM_SOP_SUSPEND_MACHINE,
-					(long)getpid ());
+							      GDM_SOP_SUSPEND_MACHINE,
+							      (long)getpid ());
 
 				gdm_slave_send (msg, FALSE /* wait_for_ack */);
 				g_free (msg);
@@ -5078,8 +5078,8 @@ check_for_interruption (const char *msg)
 			if (d->attached &&
 			    ! ve_string_empty (&msg[2])) {
 				gchar *message = g_strdup_printf ("%s %ld %s", 
-					GDM_SOP_CUSTOM_CMD,
-					(long)getpid (), &msg[2]);
+								  GDM_SOP_CUSTOM_CMD,
+								  (long)getpid (), &msg[2]);
 
 				gdm_slave_send (message, TRUE);
 				g_free (message);
@@ -5107,54 +5107,54 @@ check_for_interruption (const char *msg)
 }
 
 
-char * 
+char *
 gdm_slave_greeter_ctl (char cmd, const char *str)
 {
-    char *buf = NULL;
-    int c;
+	char *buf = NULL;
+	int c;
+
+	/* There is no spoon^H^H^H^H^Hgreeter */
+	if G_UNLIKELY ( ! greet)
+		return NULL;
 
-    /* There is no spoon^H^H^H^H^Hgreeter */
-    if G_UNLIKELY ( ! greet)
-	    return NULL;
-
-    check_notifies_now ();
-
-    if ( ! ve_string_empty (str)) {
-	    gdm_fdprintf (greeter_fd_out, "%c%c%s\n", STX, cmd, str);
-    } else {
-	    gdm_fdprintf (greeter_fd_out, "%c%c\n", STX, cmd);
-    }
+	check_notifies_now ();
+
+	if ( ! ve_string_empty (str)) {
+		gdm_fdprintf (greeter_fd_out, "%c%c%s\n", STX, cmd, str);
+	} else {
+		gdm_fdprintf (greeter_fd_out, "%c%c\n", STX, cmd);
+	}
 
 #if defined (_POSIX_PRIORITY_SCHEDULING) && defined (HAVE_SCHED_YIELD)
-    /* let the other process (greeter) do its stuff */
-    sched_yield ();
+	/* let the other process (greeter) do its stuff */
+	sched_yield ();
 #endif
 
-    do {
-      g_free (buf);
-      buf = NULL;
-      /* Skip random junk that might have accumulated */
-      do {
-	    c = gdm_fdgetc (greeter_fd_in);
-      } while (c != EOF && c != STX);
-    
-      if (c == EOF ||
-	  (buf = gdm_fdgets (greeter_fd_in)) == NULL) {
-	      interrupted = TRUE;
-	      /* things don't seem well with the greeter, it probably died */
-	      return NULL;
-      }
-    } while (check_for_interruption (buf) && ! interrupted);
-
-    /* user responses take kind of random amount of time */
-    gdm_random_tick ();
-
-    if ( ! ve_string_empty (buf)) {
-	    return buf;
-    } else {
-	    g_free (buf);
-	    return NULL;
-    }
+	do {
+		g_free (buf);
+		buf = NULL;
+		/* Skip random junk that might have accumulated */
+		do {
+			c = gdm_fdgetc (greeter_fd_in);
+		} while (c != EOF && c != STX);
+
+		if (c == EOF ||
+		    (buf = gdm_fdgets (greeter_fd_in)) == NULL) {
+			interrupted = TRUE;
+			/* things don't seem well with the greeter, it probably died */
+			return NULL;
+		}
+	} while (check_for_interruption (buf) && ! interrupted);
+
+	/* user responses take kind of random amount of time */
+	gdm_random_tick ();
+
+	if ( ! ve_string_empty (buf)) {
+		return buf;
+	} else {
+		g_free (buf);
+		return NULL;
+	}
 }
 
 void
@@ -5163,92 +5163,92 @@ gdm_slave_greeter_ctl_no_ret (char cmd, 
 	g_free (gdm_slave_greeter_ctl (cmd, str));
 }
 
-static void 
+static void
 gdm_slave_quick_exit (gint status)
 {
-    /* just for paranoia's sake */
-    /* don't use NEVER_FAILS_ here this can be called from places
-       kind of exiting and it's ok if this doesn't work (when shouldn't
-       it work anyway? */
-    seteuid (0);
-    setegid (0);
+	/* just for paranoia's sake */
+	/* don't use NEVER_FAILS_ here this can be called from places
+	   kind of exiting and it's ok if this doesn't work (when shouldn't
+	   it work anyway? */
+	seteuid (0);
+	setegid (0);
 
-    if (d != NULL) {
-	    gdm_debug ("gdm_slave_quick_exit: Will kill everything from the display");
+	if (d != NULL) {
+		gdm_debug ("gdm_slave_quick_exit: Will kill everything from the display");
 
-	    /* just in case we do get the XIOError,
-	       don't run session_stop since we've
-	       requested a quick exit */
-	    session_started = FALSE;
+		/* just in case we do get the XIOError,
+		   don't run session_stop since we've
+		   requested a quick exit */
+		session_started = FALSE;
 
-	    /* No need to send the PIDS to the daemon
-	     * since we'll just exit cleanly */
+		/* No need to send the PIDS to the daemon
+		 * since we'll just exit cleanly */
 
-	    /* Push and never pop */
-	    gdm_sigchld_block_push ();
+		/* Push and never pop */
+		gdm_sigchld_block_push ();
 
-	    /* Kill children where applicable */
-	    if (d->greetpid > 1)
-		    kill (d->greetpid, SIGTERM);
-	    d->greetpid = 0;
+		/* Kill children where applicable */
+		if (d->greetpid > 1)
+			kill (d->greetpid, SIGTERM);
+		d->greetpid = 0;
 
-	    if (d->chooserpid > 1)
-		    kill (d->chooserpid, SIGTERM);
-	    d->chooserpid = 0;
+		if (d->chooserpid > 1)
+			kill (d->chooserpid, SIGTERM);
+		d->chooserpid = 0;
 
-	    if (d->sesspid > 1)
-		    kill (-(d->sesspid), SIGTERM);
-	    d->sesspid = 0;
+		if (d->sesspid > 1)
+			kill (-(d->sesspid), SIGTERM);
+		d->sesspid = 0;
 
-	    if (extra_process > 1)
-		    kill (-(extra_process), SIGTERM);
-	    extra_process = 0;
+		if (extra_process > 1)
+			kill (-(extra_process), SIGTERM);
+		extra_process = 0;
 
-	    gdm_verify_cleanup (d);
-	    gdm_server_stop (d);
+		gdm_verify_cleanup (d);
+		gdm_server_stop (d);
 
-	    if (d->servpid > 1)
-		    kill (d->servpid, SIGTERM);
-	    d->servpid = 0;
+		if (d->servpid > 1)
+			kill (d->servpid, SIGTERM);
+		d->servpid = 0;
 
-	    gdm_debug ("gdm_slave_quick_exit: Killed everything from the display");
-    }
+		gdm_debug ("gdm_slave_quick_exit: Killed everything from the display");
+	}
 
-    _exit (status);
+	_exit (status);
 }
 
-static void 
+static void
 gdm_slave_exit (gint status, const gchar *format, ...)
 {
-    va_list args;
-    gchar *s;
+	va_list args;
+	gchar *s;
+
+	va_start (args, format);
+	s = g_strdup_vprintf (format, args);
+	va_end (args);
+
+	gdm_error ("%s", s);
 
-    va_start (args, format);
-    s = g_strdup_vprintf (format, args);
-    va_end (args);
-    
-    gdm_error ("%s", s);
-    
-    g_free (s);
+	g_free (s);
 
-    gdm_slave_quick_exit (status);
+	gdm_slave_quick_exit (status);
 }
 
-static void 
+static void
 gdm_child_exit (gint status, const gchar *format, ...)
 {
-    va_list args;
-    gchar *s;
+	va_list args;
+	gchar *s;
+
+	va_start (args, format);
+	s = g_strdup_vprintf (format, args);
+	va_end (args);
 
-    va_start (args, format);
-    s = g_strdup_vprintf (format, args);
-    va_end (args);
-    
-    syslog (LOG_ERR, "%s", s);
-    
-    g_free (s);
+	g_error ("%s", s);
 
-    _exit (status);
+	g_free (s);
+
+	_exit (status);
 }
 
 void
@@ -5291,7 +5291,7 @@ set_xnest_parent_stuff (void)
 		g_setenv ("GDM_PARENT_DISPLAY", d->parent_disp, TRUE);
 		if (d->parent_temp_auth_file != NULL) {
 			g_setenv ("GDM_PARENT_XAUTHORITY",
-				      d->parent_temp_auth_file, TRUE);
+				  d->parent_temp_auth_file, TRUE);
 			g_free (d->parent_temp_auth_file);
 			d->parent_temp_auth_file = NULL;
 		}
@@ -5302,161 +5302,161 @@ static gint
 gdm_slave_exec_script (GdmDisplay *d, const gchar *dir, const char *login,
 		       struct passwd *pwent, gboolean pass_stdout)
 {
-    pid_t pid;
-    char *script;
-    gchar **argv;
-    gint status;
-    char *x_servers_file;
-
-    if G_UNLIKELY (!d || ve_string_empty (dir))
-	return EXIT_SUCCESS;
-
-    script = g_build_filename (dir, d->name, NULL);
-    if (g_access (script, R_OK|X_OK) != 0) {
-	    g_free (script);
-	    script = NULL;
-    }
-    if (script == NULL &&
-	! ve_string_empty (d->hostname)) {
-	    script = g_build_filename (dir, d->hostname, NULL);
-	    if (g_access (script, R_OK|X_OK) != 0) {
-		    g_free (script);
-		    script = NULL;
-	    }
-    }
-    if (script == NULL &&
-	SERVER_IS_XDMCP (d)) {
-	    script = g_build_filename (dir, "XDMCP", NULL);
-	    if (g_access (script, R_OK|X_OK) != 0) {
-		    g_free (script);
-		    script = NULL;
-	    }
-    }
-    if (script == NULL &&
-	SERVER_IS_FLEXI (d)) {
-	    script = g_build_filename (dir, "Flexi", NULL);
-	    if (g_access (script, R_OK|X_OK) != 0) {
-		    g_free (script);
-		    script = NULL;
-	    }
-    }
-    if (script == NULL) {
-	    script = g_build_filename (dir, "Default", NULL);
-	    if (g_access (script, R_OK|X_OK) != 0) {
-		    g_free (script);
-		    script = NULL;
-	    }
-    }
-    
-    if (script == NULL) {
-	    return EXIT_SUCCESS;
-    }
-
-    create_temp_auth_file ();
-
-    pid = gdm_fork_extra ();
-
-    switch (pid) {
-	    
-    case 0:
-        closelog ();
+	pid_t pid;
+	char *script;
+	gchar **argv;
+	gint status;
+	char *x_servers_file;
 
-	VE_IGNORE_EINTR (close (0));
-	gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */
+	if G_UNLIKELY (!d || ve_string_empty (dir))
+		return EXIT_SUCCESS;
 
-	if ( ! pass_stdout) {
-		VE_IGNORE_EINTR (close (1));
-		VE_IGNORE_EINTR (close (2));
-		/* No error checking here - if it's messed the best response
-		 * is to ignore & try to continue */
-		gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
-		gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
+	script = g_build_filename (dir, d->name, NULL);
+	if (g_access (script, R_OK|X_OK) != 0) {
+		g_free (script);
+		script = NULL;
+	}
+	if (script == NULL &&
+	    ! ve_string_empty (d->hostname)) {
+		script = g_build_filename (dir, d->hostname, NULL);
+		if (g_access (script, R_OK|X_OK) != 0) {
+			g_free (script);
+			script = NULL;
+		}
+	}
+	if (script == NULL &&
+	    SERVER_IS_XDMCP (d)) {
+		script = g_build_filename (dir, "XDMCP", NULL);
+		if (g_access (script, R_OK|X_OK) != 0) {
+			g_free (script);
+			script = NULL;
+		}
+	}
+	if (script == NULL &&
+	    SERVER_IS_FLEXI (d)) {
+		script = g_build_filename (dir, "Flexi", NULL);
+		if (g_access (script, R_OK|X_OK) != 0) {
+			g_free (script);
+			script = NULL;
+		}
+	}
+	if (script == NULL) {
+		script = g_build_filename (dir, "Default", NULL);
+		if (g_access (script, R_OK|X_OK) != 0) {
+			g_free (script);
+			script = NULL;
+		}
 	}
 
-	gdm_close_all_descriptors (3 /* from */, -1 /* except */, -1 /* except2 */);
+	if (script == NULL) {
+		return EXIT_SUCCESS;
+	}
 
-	openlog ("gdm", LOG_PID, LOG_DAEMON);
+	create_temp_auth_file ();
 
-        if (login != NULL) {
-	        g_setenv ("LOGNAME", login, TRUE);
-	        g_setenv ("USER", login, TRUE);
-	        g_setenv ("USERNAME", login, TRUE);
-        } else {
-		const char *gdmuser = gdm_daemon_config_get_value_string (GDM_KEY_USER);
-	        g_setenv ("LOGNAME", gdmuser, TRUE);
-	        g_setenv ("USER", gdmuser, TRUE);
-	        g_setenv ("USERNAME", gdmuser, TRUE);
-        }
-        if (pwent != NULL) {
-		if (ve_string_empty (pwent->pw_dir)) {
-			g_setenv ("HOME", "/", TRUE);
-			g_setenv ("PWD", "/", TRUE);
-			VE_IGNORE_EINTR (g_chdir ("/"));
+	pid = gdm_fork_extra ();
+
+	switch (pid) {
+	case 0:
+		gdm_log_shutdown ();
+
+		VE_IGNORE_EINTR (close (0));
+		gdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */
+
+		if ( ! pass_stdout) {
+			VE_IGNORE_EINTR (close (1));
+			VE_IGNORE_EINTR (close (2));
+			/* No error checking here - if it's messed the best response
+			 * is to ignore & try to continue */
+			gdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */
+			gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */
+		}
+
+		gdm_close_all_descriptors (3 /* from */, -1 /* except */, -1 /* except2 */);
+
+		gdm_log_init ();
+
+		if (login != NULL) {
+			g_setenv ("LOGNAME", login, TRUE);
+			g_setenv ("USER", login, TRUE);
+			g_setenv ("USERNAME", login, TRUE);
 		} else {
-			g_setenv ("HOME", pwent->pw_dir, TRUE);
-			g_setenv ("PWD", pwent->pw_dir, TRUE);
-			VE_IGNORE_EINTR (g_chdir (pwent->pw_dir));
-			if (errno != 0) {
-				VE_IGNORE_EINTR (g_chdir ("/"));
+			const char *gdmuser = gdm_daemon_config_get_value_string (GDM_KEY_USER);
+			g_setenv ("LOGNAME", gdmuser, TRUE);
+			g_setenv ("USER", gdmuser, TRUE);
+			g_setenv ("USERNAME", gdmuser, TRUE);
+		}
+		if (pwent != NULL) {
+			if (ve_string_empty (pwent->pw_dir)) {
+				g_setenv ("HOME", "/", TRUE);
 				g_setenv ("PWD", "/", TRUE);
+				VE_IGNORE_EINTR (g_chdir ("/"));
+			} else {
+				g_setenv ("HOME", pwent->pw_dir, TRUE);
+				g_setenv ("PWD", pwent->pw_dir, TRUE);
+				VE_IGNORE_EINTR (g_chdir (pwent->pw_dir));
+				if (errno != 0) {
+					VE_IGNORE_EINTR (g_chdir ("/"));
+					g_setenv ("PWD", "/", TRUE);
+				}
 			}
+			g_setenv ("SHELL", pwent->pw_shell, TRUE);
+		} else {
+			g_setenv ("HOME", "/", TRUE);
+			g_setenv ("PWD", "/", TRUE);
+			VE_IGNORE_EINTR (g_chdir ("/"));
+			g_setenv ("SHELL", "/bin/sh", TRUE);
 		}
-	        g_setenv ("SHELL", pwent->pw_shell, TRUE);
-        } else {
-	        g_setenv ("HOME", "/", TRUE);
-		g_setenv ("PWD", "/", TRUE);
-		VE_IGNORE_EINTR (g_chdir ("/"));
-	        g_setenv ("SHELL", "/bin/sh", TRUE);
-        }
 
-	set_xnest_parent_stuff ();
+		set_xnest_parent_stuff ();
 
-	/* some env for use with the Pre and Post scripts */
-	x_servers_file = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR),
-					    d->name, ".Xservers");
-	g_setenv ("X_SERVERS", x_servers_file, TRUE);
-	g_free (x_servers_file);
-	if (SERVER_IS_XDMCP (d))
-		g_setenv ("REMOTE_HOST", d->hostname, TRUE);
+		/* some env for use with the Pre and Post scripts */
+		x_servers_file = gdm_make_filename (gdm_daemon_config_get_value_string (GDM_KEY_SERV_AUTHDIR),
+						    d->name, ".Xservers");
+		g_setenv ("X_SERVERS", x_servers_file, TRUE);
+		g_free (x_servers_file);
+		if (SERVER_IS_XDMCP (d))
+			g_setenv ("REMOTE_HOST", d->hostname, TRUE);
+
+		/* Runs as root */
+		if (GDM_AUTHFILE (d) != NULL)
+			g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE);
+		else
+			g_unsetenv ("XAUTHORITY");
+		g_setenv ("DISPLAY", d->name, TRUE);
+		g_setenv ("PATH", gdm_daemon_config_get_value_string (GDM_KEY_ROOT_PATH), TRUE);
+		g_setenv ("RUNNING_UNDER_GDM", "true", TRUE);
+		if ( ! ve_string_empty (d->theme_name))
+			g_setenv ("GDM_GTK_THEME", d->theme_name, TRUE);
+		g_unsetenv ("MAIL");
 
-	/* Runs as root */
-	if (GDM_AUTHFILE (d) != NULL)
-		g_setenv ("XAUTHORITY", GDM_AUTHFILE (d), TRUE);
-	else
-		g_unsetenv ("XAUTHORITY");
-        g_setenv ("DISPLAY", d->name, TRUE);
-	g_setenv ("PATH", gdm_daemon_config_get_value_string (GDM_KEY_ROOT_PATH), TRUE);
-	g_setenv ("RUNNING_UNDER_GDM", "true", TRUE);
-	if ( ! ve_string_empty (d->theme_name))
-		g_setenv ("GDM_GTK_THEME", d->theme_name, TRUE);
-	g_unsetenv ("MAIL");
+		argv = NULL;
+		g_shell_parse_argv (script, NULL, &argv, NULL);
 
-	argv = NULL;
-	g_shell_parse_argv (script, NULL, &argv, NULL);
+		VE_IGNORE_EINTR (execv (argv[0], argv));
+		g_error (_("%s: Failed starting: %s"),
+			 "gdm_slave_exec_script",
+			 script);
+		_exit (EXIT_SUCCESS);
 
-	VE_IGNORE_EINTR (execv (argv[0], argv));
-	syslog (LOG_ERR, _("%s: Failed starting: %s"), "gdm_slave_exec_script",
-		script);
-	_exit (EXIT_SUCCESS);
-	    
-    case -1:
-	gdm_slave_whack_temp_auth_file ();
-	g_free (script);
-	syslog (LOG_ERR, _("%s: Can't fork script process!"), "gdm_slave_exec_script");
-	return EXIT_SUCCESS;
-	
-    default:
-	gdm_wait_for_extra (&status);
+	case -1:
+		gdm_slave_whack_temp_auth_file ();
+		g_free (script);
+		g_error (_("%s: Can't fork script process!"), "gdm_slave_exec_script");
+		return EXIT_SUCCESS;
 
-	gdm_slave_whack_temp_auth_file ();
+	default:
+		gdm_wait_for_extra (&status);
 
-	g_free (script);
+		gdm_slave_whack_temp_auth_file ();
 
-	if (WIFEXITED (status))
-	    return WEXITSTATUS (status);
-	else
-	    return EXIT_SUCCESS;
-    }
+		g_free (script);
+
+		if (WIFEXITED (status))
+			return WEXITSTATUS (status);
+		else
+			return EXIT_SUCCESS;
+	}
 }
 
 gboolean
@@ -5482,150 +5482,149 @@ gdm_slave_action_pending (void)
 	return TRUE;
 }
 
-/* The user name for automatic/timed login may be parameterized by 
+/* The user name for automatic/timed login may be parameterized by
    host/display. */
 
 static gchar *
 gdm_parse_enriched_login (const gchar *s, GdmDisplay *display)
 {
-    gchar cmd, in_buffer[20];
-    GString *str;
-    gint pipe1[2], in_buffer_len;  
-    gchar **argv;
-    pid_t pid;
+	gchar cmd, in_buffer[20];
+	GString *str;
+	gint pipe1[2], in_buffer_len;
+	gchar **argv;
+	pid_t pid;
 
-    if (s == NULL)
-	return (NULL);
+	if (s == NULL)
+		return (NULL);
 
-    str = g_string_new (NULL);
+	str = g_string_new (NULL);
 
-    while (s[0] != '\0') {
+	while (s[0] != '\0') {
 
-	if (s[0] == '%' && s[1] != 0) {
-		cmd = s[1];
-		s++;
+		if (s[0] == '%' && s[1] != 0) {
+			cmd = s[1];
+			s++;
 
-		switch (cmd) {
+			switch (cmd) {
 
-		case 'h': 
-			g_string_append (str, display->hostname);
-			break;
+			case 'h':
+				g_string_append (str, display->hostname);
+				break;
 
-		case 'd': 
-			g_string_append (str, display->name);
-			break;
+			case 'd':
+				g_string_append (str, display->name);
+				break;
 
-		case '%':
-			g_string_append_c (str, '%');
-			break;
+			case '%':
+				g_string_append_c (str, '%');
+				break;
 
-		default:
-			break;
-		};
-	} else {
-		g_string_append_c (str, *s);
+			default:
+				break;
+			};
+		} else {
+			g_string_append_c (str, *s);
+		}
+		s++;
 	}
-	s++;
-    }
 
-    /* Sometimes it is not convenient to use the display or hostname as
-       user name. A script may be used to generate the automatic/timed
-       login name based on the display/host by ending the name with the
-       pipe symbol '|'. */
-
-    if (str->len > 0 && str->str[str->len - 1] == '|') {
-      g_string_truncate (str, str->len - 1);
-      if G_UNLIKELY (pipe (pipe1) < 0) {
-        gdm_error (_("%s: Failed creating pipe"),
-		   "gdm_parse_enriched_login");
-      } else {
-	pid = gdm_fork_extra ();
+	/* Sometimes it is not convenient to use the display or hostname as
+	   user name. A script may be used to generate the automatic/timed
+	   login name based on the display/host by ending the name with the
+	   pipe symbol '|'. */
+
+	if (str->len > 0 && str->str[str->len - 1] == '|') {
+		g_string_truncate (str, str->len - 1);
+		if G_UNLIKELY (pipe (pipe1) < 0) {
+			gdm_error (_("%s: Failed creating pipe"),
+				   "gdm_parse_enriched_login");
+		} else {
+			pid = gdm_fork_extra ();
 
-        switch (pid) {
-	    
-        case 0:
-	    /* The child will write the username to stdout based on the DISPLAY
-	       environment variable. */
-
-            VE_IGNORE_EINTR (close (pipe1[0]));
-            if G_LIKELY (pipe1[1] != STDOUT_FILENO)  {
-	      VE_IGNORE_EINTR (dup2 (pipe1[1], STDOUT_FILENO));
-	    }
-
-	    closelog ();
-
-	    gdm_close_all_descriptors (3 /* from */, pipe1[1] /* except */, -1 /* except2 */);
-
-	    openlog ("gdm", LOG_PID, LOG_DAEMON);
-
-	    /* runs as root */
-	    if (GDM_AUTHFILE (display) != NULL)
-		    g_setenv ("XAUTHORITY", GDM_AUTHFILE (display), TRUE);
-	    else
-		    g_unsetenv ("XAUTHORITY");
-	    g_setenv ("DISPLAY", display->name, TRUE);
-	    if (SERVER_IS_XDMCP (display))
-		    g_setenv ("REMOTE_HOST", display->hostname, TRUE);
-	    g_setenv ("PATH", gdm_daemon_config_get_value_string (GDM_KEY_ROOT_PATH), TRUE);
-	    g_setenv ("SHELL", "/bin/sh", TRUE);
-	    g_setenv ("RUNNING_UNDER_GDM", "true", TRUE);
-	    if ( ! ve_string_empty (d->theme_name))
-		    g_setenv ("GDM_GTK_THEME", d->theme_name, TRUE);
-	    g_unsetenv ("MAIL");
-
-	    argv = NULL;
-	    g_shell_parse_argv (str->str, NULL, &argv, NULL);
-
-	    VE_IGNORE_EINTR (execv (argv[0], argv));
-	    gdm_error (_("%s: Failed executing: %s"),
-		       "gdm_parse_enriched_login",
-		       str->str);
-	    _exit (EXIT_SUCCESS);
-
-        case -1:
-	    gdm_error (_("%s: Can't fork script process!"),
-		       "gdm_parse_enriched_login");
-            VE_IGNORE_EINTR (close (pipe1[0]));
-            VE_IGNORE_EINTR (close (pipe1[1]));
-	    break;
-
-        default:
-	    /* The parent reads username from the pipe a chunk at a time */
-            VE_IGNORE_EINTR (close (pipe1[1]));
-            g_string_truncate (str, 0);
-	    do {
-		    VE_IGNORE_EINTR (in_buffer_len = read (pipe1[0], in_buffer,
-							sizeof (in_buffer) - 1));
-		    if (in_buffer_len > 0) {
-			    in_buffer[in_buffer_len] = '\0';
-			    g_string_append (str, in_buffer);
-		    }
-            } while (in_buffer_len > 0);
+			switch (pid) {
+			case 0:
+				/* The child will write the username to stdout based on the DISPLAY
+				   environment variable. */
+
+				VE_IGNORE_EINTR (close (pipe1[0]));
+				if G_LIKELY (pipe1[1] != STDOUT_FILENO)  {
+					VE_IGNORE_EINTR (dup2 (pipe1[1], STDOUT_FILENO));
+				}
 
-            if (str->len > 0 && str->str[str->len - 1] == '\n')
-              g_string_truncate (str, str->len - 1);
+				gdm_log_shutdown ();
 
-            VE_IGNORE_EINTR (close (pipe1[0]));
+				gdm_close_all_descriptors (3 /* from */, pipe1[1] /* except */, -1 /* except2 */);
 
-	    gdm_wait_for_extra (NULL);
-        }
-      }
-    }
+				gdm_log_init ();
 
-    if (!ve_string_empty(str->str) && gdm_is_user_valid(str->str))
-	    return g_string_free (str, FALSE);
-    else
-    {
-        /* "If an empty or otherwise invalid username is returned [by the script]
-         *  automatic login [and timed login] is not performed." -- GDM manual 
-	 */
-	/* fixme: also turn off automatic login */
-	gdm_daemon_config_set_value_bool(GDM_KEY_TIMED_LOGIN_ENABLE, FALSE);
-	d->timed_login_ok = FALSE;
-	do_timed_login = FALSE;
-	g_string_free(str, TRUE);
-	return NULL;
-    }
+				/* runs as root */
+				if (GDM_AUTHFILE (display) != NULL)
+					g_setenv ("XAUTHORITY", GDM_AUTHFILE (display), TRUE);
+				else
+					g_unsetenv ("XAUTHORITY");
+				g_setenv ("DISPLAY", display->name, TRUE);
+				if (SERVER_IS_XDMCP (display))
+					g_setenv ("REMOTE_HOST", display->hostname, TRUE);
+				g_setenv ("PATH", gdm_daemon_config_get_value_string (GDM_KEY_ROOT_PATH), TRUE);
+				g_setenv ("SHELL", "/bin/sh", TRUE);
+				g_setenv ("RUNNING_UNDER_GDM", "true", TRUE);
+				if ( ! ve_string_empty (d->theme_name))
+					g_setenv ("GDM_GTK_THEME", d->theme_name, TRUE);
+				g_unsetenv ("MAIL");
+
+				argv = NULL;
+				g_shell_parse_argv (str->str, NULL, &argv, NULL);
+
+				VE_IGNORE_EINTR (execv (argv[0], argv));
+				gdm_error (_("%s: Failed executing: %s"),
+					   "gdm_parse_enriched_login",
+					   str->str);
+				_exit (EXIT_SUCCESS);
+
+			case -1:
+				gdm_error (_("%s: Can't fork script process!"),
+					   "gdm_parse_enriched_login");
+				VE_IGNORE_EINTR (close (pipe1[0]));
+				VE_IGNORE_EINTR (close (pipe1[1]));
+				break;
+
+			default:
+				/* The parent reads username from the pipe a chunk at a time */
+				VE_IGNORE_EINTR (close (pipe1[1]));
+				g_string_truncate (str, 0);
+				do {
+					VE_IGNORE_EINTR (in_buffer_len = read (pipe1[0], in_buffer,
+									       sizeof (in_buffer) - 1));
+					if (in_buffer_len > 0) {
+						in_buffer[in_buffer_len] = '\0';
+						g_string_append (str, in_buffer);
+					}
+				} while (in_buffer_len > 0);
+
+				if (str->len > 0 && str->str[str->len - 1] == '\n')
+					g_string_truncate (str, str->len - 1);
+
+				VE_IGNORE_EINTR (close (pipe1[0]));
+
+				gdm_wait_for_extra (NULL);
+			}
+		}
+	}
+
+	if (!ve_string_empty(str->str) && gdm_is_user_valid(str->str))
+		return g_string_free (str, FALSE);
+	else
+		{
+			/* "If an empty or otherwise invalid username is returned [by the script]
+			 *  automatic login [and timed login] is not performed." -- GDM manual 
+			 */
+			/* fixme: also turn off automatic login */
+			gdm_daemon_config_set_value_bool(GDM_KEY_TIMED_LOGIN_ENABLE, FALSE);
+			d->timed_login_ok = FALSE;
+			do_timed_login = FALSE;
+			g_string_free(str, TRUE);
+			return NULL;
+		}
 }
 
 static void
@@ -5680,7 +5679,7 @@ gdm_slave_handle_notify (const char *msg
 			    strlen (GDM_NOTIFY_CUSTOM_CMD_TEMPLATE)) == 0) {
     	        if (sscanf (msg, GDM_NOTIFY_CUSTOM_CMD_TEMPLATE "%d", &val) == 1) {
 			gchar * key_string = g_strdup_printf(_("%s%d="), GDM_KEY_CUSTOM_CMD_TEMPLATE, val);
-			/* This assumes that the number of commands is < 100, i.e two digits 
+			/* This assumes that the number of commands is < 100, i.e two digits
 			   if that is not the case then this will fail */
 			gdm_daemon_config_set_value_string (key_string, ((gchar *)&msg[strlen (GDM_NOTIFY_CUSTOM_CMD_TEMPLATE) + 2]));
 			g_free(key_string);
@@ -5699,11 +5698,11 @@ gdm_slave_handle_notify (const char *msg
 					}
 				}
 			}
-		}		
+		}
 	} else if (strncmp (msg, GDM_NOTIFY_REMOTE_GREETER " ",
 			    strlen (GDM_NOTIFY_REMOTE_GREETER) + 1) == 0) {
 		gdm_daemon_config_set_value_string (GDM_KEY_REMOTE_GREETER,
-			(gchar *)(&msg[strlen (GDM_NOTIFY_REMOTE_GREETER) + 1]));
+						    (gchar *)(&msg[strlen (GDM_NOTIFY_REMOTE_GREETER) + 1]));
 		if ( ! d->attached) {
 			do_restart_greeter = TRUE;
 			if (restart_greeter_now) {
@@ -5737,25 +5736,25 @@ gdm_slave_handle_notify (const char *msg
 	} else if (strncmp (msg, GDM_NOTIFY_SOUND_ON_LOGIN_FILE " ",
 			    strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FILE) + 1) == 0) {
 		gdm_daemon_config_set_value_string (GDM_KEY_SOUND_ON_LOGIN_FILE,
-			(gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FILE) + 1]));
+						    (gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FILE) + 1]));
 		if (d->greetpid > 1)
 			kill (d->greetpid, SIGHUP);
 	} else if (strncmp (msg, GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE " ",
 			    strlen (GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE) + 1) == 0) {
 		gdm_daemon_config_set_value_string (GDM_KEY_SOUND_ON_LOGIN_SUCCESS_FILE,
-			(gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE) + 1]));
+						    (gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_SUCCESS_FILE) + 1]));
 		if (d->greetpid > 1)
 			kill (d->greetpid, SIGHUP);
 	} else if (strncmp (msg, GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE " ",
 			    strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE) + 1) == 0) {
 		gdm_daemon_config_set_value_string (GDM_KEY_SOUND_ON_LOGIN_FAILURE_FILE,
-			(gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE) + 1]));
+						    (gchar *)(&msg[strlen (GDM_NOTIFY_SOUND_ON_LOGIN_FAILURE_FILE) + 1]));
 		if (d->greetpid > 1)
 			kill (d->greetpid, SIGHUP);
 	} else if (strncmp (msg, GDM_NOTIFY_GTK_MODULES_LIST " ",
 			    strlen (GDM_NOTIFY_GTK_MODULES_LIST) + 1) == 0) {
 		gdm_daemon_config_set_value_string (GDM_KEY_GTK_MODULES_LIST,
-			(gchar *)(&msg[strlen (GDM_NOTIFY_GTK_MODULES_LIST) + 1]));
+						    (gchar *)(&msg[strlen (GDM_NOTIFY_GTK_MODULES_LIST) + 1]));
 
 		if (gdm_daemon_config_get_value_bool (GDM_KEY_ADD_GTK_MODULES)) {
 			do_restart_greeter = TRUE;
@@ -5815,7 +5814,7 @@ gdm_can_i_assume_root_role (struct passw
 		return FALSE;
 
 	freeroles = roles = g_strdup (kva_match (uattr->attr, USERATTR_ROLES_KW));
-    if (roles == NULL) {
+	if (roles == NULL) {
 		return FALSE;
 	}
 
@@ -5838,6 +5837,5 @@ gdm_can_i_assume_root_role (struct passw
 gboolean
 gdm_is_user_valid (const char *username)
 {
-    return (NULL != getpwnam (username));
+	return (NULL != getpwnam (username));
 }
-/* EOF */
Index: daemon/server.h
===================================================================
--- daemon/server.h	(revision 4731)
+++ daemon/server.h	(working copy)
@@ -1,4 +1,6 @@
-/* GDM - The GNOME Display Manager
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * 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
@@ -19,7 +21,30 @@
 #ifndef GDM_SERVER_H
 #define GDM_SERVER_H
 
-#include "gdm.h"
+#include "display.h"
+
+typedef struct _GdmXserver GdmXserver;
+
+struct _GdmXserver
+{
+	char *id;
+	char *name;
+	char *command;
+	gboolean flexible;
+	gboolean choosable; /* not implemented yet */
+	gboolean chooser; /* instead of greeter, run chooser */
+	gboolean handled;
+	int number;
+	int priority;
+};
+
+/* These are the servstat values, also used as server
+ * process exit codes */
+#define SERVER_TIMEOUT 2	/* Server didn't start */
+#define SERVER_DEAD 250		/* Server stopped */
+#define SERVER_PENDING 251	/* Server started but not ready for connections yet */
+#define SERVER_RUNNING 252	/* Server running and ready for connections */
+#define SERVER_ABORT 253	/* Server failed badly. Suspending display. */
 
 /* Wipe cookie files */
 void		gdm_server_wipe_cookies	(GdmDisplay *disp);
Index: daemon/gdm-daemon-config.c
===================================================================
--- daemon/gdm-daemon-config.c	(revision 4731)
+++ daemon/gdm-daemon-config.c	(working copy)
@@ -38,6 +38,7 @@
 #include <unistd.h>
 #include <ctype.h>
 #include <fcntl.h>
+#include <string.h>
 #include <sys/types.h>
 #include <sys/resource.h>
 #include <sys/stat.h>
@@ -49,8 +50,6 @@
 #include <glib.h>
 #include <glib/gi18n.h>
 
-#include "gdm-common.h"
-
 #include "gdm.h"
 #include "verify.h"
 #include "gdm-net.h"
@@ -59,19 +58,23 @@
 #include "filecheck.h"
 #include "slave.h"
 
+#include "gdm-common.h"
 #include "gdm-config.h"
+#include "gdm-log.h"
 #include "gdm-daemon-config.h"
 
+#include "gdm-socket-protocol.h"
+
 static GdmConfig *daemon_config = NULL;
 
 extern gboolean no_console;
 extern gboolean gdm_emergency_server;
 
-GSList *displays          = NULL;
-GSList *xservers          = NULL;
+static GSList *displays          = NULL;
+static GSList *xservers   = NULL;
 
-gint high_display_num = 0;
-char *custom_config_file = NULL;
+static gint high_display_num = 0;
+static char *custom_config_file = NULL;
 
 static uid_t GdmUserId;   /* Userid  under which gdm should run */
 static gid_t GdmGroupId;  /* Gruopid under which gdm should run */
@@ -138,6 +141,41 @@ gdm_daemon_config_get_custom_config_file
 }
 
 /**
+ * gdm_daemon_config_get_display_list
+ *
+ * Returns the list of displays being used.
+ */
+GSList *
+gdm_daemon_config_get_display_list (void)
+{
+	return displays;
+}
+
+GSList *
+gdm_daemon_config_display_list_append (GdmDisplay *display)
+{
+	displays = g_slist_append (displays, display);
+	return displays;
+}
+
+GSList *
+gdm_daemon_config_display_list_insert (GdmDisplay *display)
+{
+        displays = g_slist_insert_sorted (displays,
+                                          display,
+                                          gdm_daemon_config_compare_displays);
+	return displays;
+}
+
+GSList *
+gdm_daemon_config_display_list_remove (GdmDisplay *display)
+{
+	displays = g_slist_remove (displays, display);
+
+	return displays;
+}
+
+/**
  * gdm_daemon_config_get_value_int
  *
  * Gets an integer configuration option by key.  The option must
@@ -234,10 +272,61 @@ gdm_daemon_config_get_value_string (cons
 }
 
 /**
+ * gdm_daemon_config_get_bool_for_id
+ *
+ * Gets a boolean configuration option by ID.  The option must
+ * first be loaded, say, by calling gdm_daemon_config_parse.
+ */
+gboolean
+gdm_daemon_config_get_bool_for_id (int id)
+{
+	gboolean val;
+
+	val = FALSE;
+	gdm_config_get_bool_for_id (daemon_config, id, &val);
+
+	return val;
+}
+
+/**
+ * gdm_daemon_config_get_int_for_id
+ *
+ * Gets a integer configuration option by ID.  The option must
+ * first be loaded, say, by calling gdm_daemon_config_parse.
+ */
+int
+gdm_daemon_config_get_int_for_id (int id)
+{
+	int val;
+
+	val = -1;
+	gdm_config_get_int_for_id (daemon_config, id, &val);
+
+	return val;
+}
+
+/**
+ * gdm_daemon_config_get_string_for_id
+ *
+ * Gets a string configuration option by ID.  The option must
+ * first be loaded, say, by calling gdm_daemon_config_parse.
+ */
+const char *
+gdm_daemon_config_get_string_for_id (int id)
+{
+	const char *val;
+
+	val = NULL;
+	gdm_config_peek_string_for_id (daemon_config, id, &val);
+
+	return val;
+}
+
+/**
  * gdm_daemon_config_get_value_bool
  *
  * Gets a boolean configuration option by key.  The option must
- * first be loaded, say, by calling gdm_config_parse.
+ * first be loaded, say, by calling gdm_daemon_config_parse.
  */
 gboolean
 gdm_daemon_config_get_value_bool (const char *keystring)
Index: daemon/cookie.h
===================================================================
--- daemon/cookie.h	(revision 4731)
+++ daemon/cookie.h	(working copy)
@@ -20,6 +20,7 @@
 #define GDM_COOKIE_H
 
 #include "gdm.h"
+#include "display.h"
 
 void gdm_cookie_generate (GdmDisplay *);
 /* Add some more time based randomness, should be done
Index: daemon/slave.h
===================================================================
--- daemon/slave.h	(revision 4731)
+++ daemon/slave.h	(working copy)
@@ -20,8 +20,9 @@
 #define GDM_SLAVE_H
 
 #include <glib.h>
-#include <X11/Xlib.h>
+
 #include "gdm.h"
+#include "display.h"
 
 void     gdm_slave_start       (GdmDisplay *d);
 void     gdm_slave_greeter_ctl_no_ret (char cmd, const char *str);
Index: daemon/choose.c
===================================================================
--- daemon/choose.c	(revision 4731)
+++ daemon/choose.c	(working copy)
@@ -22,7 +22,6 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <syslog.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -44,8 +43,11 @@
 #include "xdmcp.h"
 
 #include "gdm-common.h"
+#include "gdm-log.h"
 #include "gdm-daemon-config.h"
 
+#include "gdm-socket-protocol.h"
+
 static gint ipending = 0;
 static GSList *indirect = NULL;
 
Index: daemon/gdm-daemon-config.h
===================================================================
--- daemon/gdm-daemon-config.h	(revision 4731)
+++ daemon/gdm-daemon-config.h	(working copy)
@@ -22,13 +22,32 @@
 #ifndef _GDM_DAEMON_CONFIG_H
 #define _GDM_DAEMON_CONFIG_H
 
+#include "server.h"
 #include "gdm-daemon-config-entries.h"
 
 G_BEGIN_DECLS
 
+const char *   gdm_daemon_config_get_string_for_id    (int id);
+gboolean       gdm_daemon_config_get_bool_for_id      (int id);
+int            gdm_daemon_config_get_int_for_id       (int id);
+
+void           gdm_daemon_config_parse                (const char *config_file);
+GdmXserver *   gdm_daemon_config_find_xserver         (const gchar *id);
+gchar *        gdm_daemon_config_get_xservers         (void);
+GSList *       gdm_daemon_config_get_display_list     (void);
+GSList *       gdm_daemon_config_display_list_append  (GdmDisplay *display);
+GSList *       gdm_daemon_config_display_list_insert  (GdmDisplay *display);
+GSList *       gdm_daemon_config_display_list_remove  (GdmDisplay *display);
+uid_t          gdm_daemon_config_get_gdmuid           (void);
+uid_t          gdm_daemon_config_get_gdmgid           (void);
+gint           gdm_daemon_config_get_high_display_num (void);
+void           gdm_daemon_config_set_high_display_num (gint val);
+
+/* deprecated */
 gchar*         gdm_daemon_config_get_display_custom_config_file (const gchar *display);
 gchar*         gdm_daemon_config_get_custom_config_file (void);
 
+
 const char*    gdm_daemon_config_get_value_string     (const gchar *key);
 gboolean       gdm_daemon_config_get_value_bool       (const gchar *key);
 gint           gdm_daemon_config_get_value_int        (const gchar *key);
@@ -39,7 +58,6 @@ gboolean       gdm_daemon_config_get_val
 gint           gdm_daemon_config_get_value_int_per_display    (const gchar *display,
                                                                const gchar *key);
 
-
 void           gdm_daemon_config_set_value_string     (const gchar *key,
                                                        const gchar *value);
 void           gdm_daemon_config_set_value_bool       (const gchar *key,
@@ -60,15 +78,8 @@ void           gdm_daemon_config_to_stri
 gboolean       gdm_daemon_config_update_key           (const gchar *key);
 
 
-void           gdm_daemon_config_parse                (const char *config_file);
-GdmXserver *   gdm_daemon_config_find_xserver         (const gchar *id);
-gchar *        gdm_daemon_config_get_xservers         (void);
 int            gdm_daemon_config_compare_displays     (gconstpointer a,
                                                        gconstpointer b);
-uid_t          gdm_daemon_config_get_gdmuid           (void);
-uid_t          gdm_daemon_config_get_gdmgid           (void);
-gint           gdm_daemon_config_get_high_display_num (void);
-void           gdm_daemon_config_set_high_display_num (gint val);
 gboolean       gdm_daemon_config_is_valid_key         (const gchar *key);
 gboolean       gdm_daemon_config_signal_terminthup_was_notified  (void);
 
Index: daemon/choose.h
===================================================================
--- daemon/choose.h	(revision 4731)
+++ daemon/choose.h	(working copy)
@@ -20,6 +20,7 @@
 #define CHOOSE_H
 
 #include "gdm.h"
+#include "xdmcp.h"
 
 #ifdef ENABLE_IPV6
 GdmIndirectDisplay *   gdm_choose_indirect_alloc (struct sockaddr_storage *clnt_sa);
Index: daemon/Makefile.am
===================================================================
--- daemon/Makefile.am	(revision 4731)
+++ daemon/Makefile.am	(working copy)
@@ -1,4 +1,4 @@
-## Process this file with automake to produce makefile.in
+NULL =
 
 # Note that we have cflags for just about everything even if
 # we don't link to everything
@@ -35,7 +35,8 @@ INCLUDES = \
 #	-DGNOME_DISABLE_DEPRECATED			\
 #
 
-sbin_PROGRAMS = gdm-binary
+sbin_PROGRAMS = gdm-binary		\
+	$(NULL)
 
 gdm_binary_SOURCES = \
 	gdm.c \
@@ -71,20 +72,27 @@ gdm_binary_SOURCES = \
 	gdm-net.c \
 	gdm-net.h \
 	getvt.c \
-	getvt.h
+	getvt.h	\
+	$(NULL)
 
-EXTRA_gdm_binary_SOURCES = verify-pam.c verify-crypt.c verify-shadow.c
-
-CONSOLE_KIT_SOURCES = \
-	gdmconsolekit.c \
-	gdmconsolekit.h
+EXTRA_gdm_binary_SOURCES = 	\
+	verify-pam.c		\
+	verify-crypt.c		\
+	verify-shadow.c		\
+	$(NULL)
+
+CONSOLE_KIT_SOURCES = 		\
+	gdmconsolekit.c		\
+	gdmconsolekit.h		\
+	$(NULL)
 
 EXTRA_gdm_binary_SOURCES += $(CONSOLE_KIT_SOURCES)
 
 # Note that these libs are in LDFLAGS because they should come before
 # everything else on the link line as they may override stuff
-gdm_binary_LDFLAGS = \
-	$(EXTRA_DAEMON_LIBS)
+gdm_binary_LDFLAGS =				\
+	$(EXTRA_DAEMON_LIBS)			\
+	$(NULL)
 
 gdm_binary_LDADD = \
 	$(DAEMON_LIBS)				\
@@ -99,7 +107,7 @@ gdm_binary_LDADD = \
 	-lXau					\
 	-lX11					\
 	-lXext					\
-	-lpopt
+	$(NULL)
 
 if WITH_CONSOLE_KIT
 gdm_binary_SOURCES += $(CONSOLE_KIT_SOURCES)
Index: daemon/misc.c
===================================================================
--- daemon/misc.c	(revision 4731)
+++ daemon/misc.c	(working copy)
@@ -1,4 +1,6 @@
-/* GDM - The GNOME Display Manager
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * 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
@@ -18,7 +20,6 @@
 
 #include "config.h"
 
-#include <syslog.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <dirent.h>
@@ -57,6 +58,7 @@
 #include "slave.h"
 
 #include "gdm-common.h"
+#include "gdm-log.h"
 #include "gdm-daemon-config.h"
 
 extern char **environ;
@@ -66,7 +68,7 @@ extern int extra_status;
 extern pid_t gdm_main_pid;
 extern gboolean preserve_ld_vars;
 extern int gdm_in_signal;
-extern GSList *displays;
+
 extern char *gdm_charset;
 
 #ifdef ENABLE_IPV6
@@ -178,142 +180,6 @@ have_ipv6 (void)
 }
 #endif
 
-
-static void
-do_syslog (int type, const char *s)
-{
-	if (gdm_in_signal > 0) {
-		char *m = g_strdup_printf (GDM_SOP_SYSLOG " %ld %d %s",
-					   (long)getpid (), type, s);
-		gdm_slave_send (m, FALSE);
-		g_free (m);
-	} else {
-		syslog (type, "%s", s);
-	}
-}
-
-
-/**
- * gdm_fail:
- * @format: printf style format string
- * @...: Optional arguments
- *
- * Logs fatal error condition and aborts master daemon.  Also sleeps
- * for 30 seconds to avoid looping if gdm is started by init.  
- */
-void 
-gdm_fail (const gchar *format, ...)
-{
-    va_list args;
-    char *s;
-
-    va_start (args, format);
-    s = g_strdup_vprintf (format, args);
-    va_end (args);
-
-    /* Log to both syslog and stderr */
-    do_syslog (LOG_CRIT, s);
-    if (getpid () == gdm_main_pid) {
-	    gdm_fdprintf (2, "%s\n", s);
-    }
-
-    g_free (s);
-
-    /* If main process do final cleanup to kill all processes */
-    if (getpid () == gdm_main_pid) {
-	    gdm_final_cleanup ();
-    } else if ( ! gdm_slave_final_cleanup ()) {
-	    /* If we weren't even a slave do some random cleanup only */
-	    /* FIXME: is this all fine? */
-	    gdm_sigchld_block_push ();
-	    if (extra_process > 1 && extra_process != getpid ()) {
-		    /* we sigterm extra processes, and we don't wait */
-		    kill (-(extra_process), SIGTERM);
-		    extra_process = 0;
-	    }
-	    gdm_sigchld_block_pop ();
-    }
-
-    closelog ();
-
-    /* Slow down respawning if we're started from init */
-    if (getppid () == 1)
-	sleep (30);
-
-    exit (EXIT_FAILURE);
-}
-
-
-/**
- * gdm_info:
- * @format: printf style format string
- * @...: Optional arguments
- *
- * Log non-fatal information to syslog
- */
-void 
-gdm_info (const gchar *format, ...)
-{
-    va_list args;
-    char *s;
-
-    va_start (args, format);
-    s = g_strdup_vprintf (format, args);
-    va_end (args);
-
-    do_syslog (LOG_INFO, s);
-    
-    g_free (s);
-}
-
-/**
- * gdm_error:
- * @format: printf style format string
- * @...: Optional arguments
- *
- * Log non-fatal error condition to syslog
- */
-void 
-gdm_error (const gchar *format, ...)
-{
-    va_list args;
-    char *s;
-
-    va_start (args, format);
-    s = g_strdup_vprintf (format, args);
-    va_end (args);
-
-    do_syslog (LOG_ERR, s);
-    
-    g_free (s);
-}
-
-/**
- * gdm_debug:
- * @format: printf style format string
- * @...: Optional arguments
- *
- * Log debug information to syslog if debugging is enabled.
- */
-void 
-gdm_debug (const gchar *format, ...)
-{
-    va_list args;
-    char *s;
-
-    if G_LIKELY (! gdm_daemon_config_get_value_bool (GDM_KEY_DEBUG))
-	return;
-
-    va_start (args, format);
-    s = g_strdup_vprintf (format, args);
-    va_end (args);
-
-    do_syslog (LOG_ERR, s);	/* Maybe should be LOG_DEBUG, but then normally
-				 * you wouldn't get it in the log.  ??? */
-    
-    g_free (s);
-}
-
 void
 gdm_fdprintf (int fd, const gchar *format, ...)
 {
@@ -441,6 +307,9 @@ gdm_get_free_display (int start, uid_t s
 		char buf[256];
 		FILE *fp;
 		int r;
+                GSList *displays;
+
+                displays = gdm_daemon_config_get_display_list ();
 
 		for (li = displays; li != NULL; li = li->next) {
 			GdmDisplay *dsp = li->data;
@@ -759,7 +628,7 @@ gdm_exec_wait (char * const *argv, gbool
 
 	pid = gdm_fork_extra ();
 	if (pid == 0) {
-		closelog ();
+		gdm_log_shutdown ();
 
 		gdm_close_all_descriptors (0 /* from */, -1 /* except */, -1 /* except2 */);
 
@@ -775,7 +644,7 @@ gdm_exec_wait (char * const *argv, gbool
 			gdm_desetuid ();
 		}
 
-		openlog ("gdm", LOG_PID, LOG_DAEMON);
+		gdm_log_init ();
 
 		if (no_display) {
 			g_unsetenv ("DISPLAY");
Index: daemon/gdm-net.c
===================================================================
--- daemon/gdm-net.c	(revision 4731)
+++ daemon/gdm-net.c	(working copy)
@@ -30,13 +30,13 @@
 #include <ctype.h>
 #include <fcntl.h>
 #include <errno.h>
-#include <syslog.h>
 
 #include "gdm.h"
 #include "misc.h"
 #include "gdm-net.h"
 
 #include "gdm-common.h"
+#include "gdm-log.h"
 #include "gdm-daemon-config.h"
 
 /*
Index: config/gdm.conf.in
===================================================================
--- config/gdm.conf.in	(revision 4731)
+++ config/gdm.conf.in	(working copy)
@@ -339,13 +339,13 @@ Enable=false
 #PositionY=0
 
 # Enable the Face browser.  Note that the Browser key is only used by the
-# standard login (gdmlogin) program.  The Face Browser is enabled in 
+# standard login (gdmlogin) program.  The Face Browser is enabled in
 # the Graphical greeter by selecting a theme that includes the Face
 # Browser, such as happygnome-list.  The other configuration values that
 # affect the Face Browser (MinimalUID, DefaultFace, Include, Exclude,
 # IncludeAll, GlobalFaceDir) are used by both the Standard and Themed
 # greeter.
-Browser=false
+Browser=true
 # The default picture in the browser.
 #DefaultFace=@pixmapdir@/nobody.png
 # User ID's less than the MinimalUID value will not be included in the face
