summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Lebl <jirka@5z.com>2001-01-09 23:48:14 +0000
committerGeorge Lebl <jirka@src.gnome.org>2001-01-09 23:48:14 +0000
commit911a8ace383764aff9fbec05913283a8113d294f (patch)
tree8d08612561547f8c57b21cf4c9a7e987f47cceef
parent7fc980eb62860063a692c9ff2ae2340e944ae8c4 (diff)
downloadgdm-911a8ace383764aff9fbec05913283a8113d294f.tar.gz
Many changes, too many to write a changelog for. Applied most of the
Tue Jan 09 18:50:51 2001 George Lebl <jirka@5z.com> * Many changes, too many to write a changelog for. Applied most of the redhat and helix patches. On the login screen make a window over the entire window and proxy key events back to the entry to get xdm like keyboard grab behaviour without a grab. When starting local displays call gdm_display_manage to actually fork the slave. Try cleaning up after self when messing with signal handlers. When killing clients, ignore x errors. Kill clients on the same display connection since opening a new one won't work. Kill the alarm on the ping since it made no sense, and didn't work in the first place.
-rw-r--r--ChangeLog13
-rw-r--r--README10
-rw-r--r--THIS_MODULE_IS_DEAD6
-rw-r--r--TODO2
-rwxr-xr-xconfig/Gnome.in2
-rw-r--r--config/gdm9
-rw-r--r--config/gdm.conf.in11
-rw-r--r--config/locale.alias30
-rw-r--r--daemon/auth.c2
-rw-r--r--daemon/display.c27
-rw-r--r--daemon/gdm.c224
-rw-r--r--daemon/gdm.h18
-rw-r--r--daemon/misc.c19
-rw-r--r--daemon/server.c149
-rw-r--r--daemon/slave.c126
-rw-r--r--daemon/verify-pam.c2
-rw-r--r--daemon/xdmcp.c54
-rw-r--r--gui/gdmlogin.c93
-rw-r--r--po/Makefile.in.in26
19 files changed, 660 insertions, 163 deletions
diff --git a/ChangeLog b/ChangeLog
index 9776b897..a4058521 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+Tue Jan 09 18:50:51 2001 George Lebl <jirka@5z.com>
+
+ * Many changes, too many to write a changelog for. Applied most of
+ the redhat and helix patches. On the login screen make a window
+ over the entire window and proxy key events back to the entry to
+ get xdm like keyboard grab behaviour without a grab. When starting
+ local displays call gdm_display_manage to actually fork the slave.
+ Try cleaning up after self when messing with signal handlers.
+ When killing clients, ignore x errors. Kill clients on the same
+ display connection since opening a new one won't work. Kill the
+ alarm on the ping since it made no sense, and didn't work in the
+ first place.
+
2000-12-17 Marius Andreiana <mandreiana@yahoo.com>
* configure.in: Added ro (Romanian) to ALL_LINGUAS
diff --git a/README b/README
index 7ab9cb3f..08fcd617 100644
--- a/README
+++ b/README
@@ -1,3 +1,13 @@
+-------------------------------------------------------------------------
+Note:
+
+Since gdm3 is not done yet, I'm maintaining this version of gdm until
+gdm3 is out and stable enough for use. Send all patches for gdm2 to me
+and not martin as he's working on gdm3 (maybe helping him out with gdm3
+might make more sense in the long run).
+
+-George <jirka@5z.com>
+-------------------------------------------------------------------------
GDM - GNOME DISPLAY MANAGER
diff --git a/THIS_MODULE_IS_DEAD b/THIS_MODULE_IS_DEAD
deleted file mode 100644
index d20f954c..00000000
--- a/THIS_MODULE_IS_DEAD
+++ /dev/null
@@ -1,6 +0,0 @@
-
-This module is no longer maintained.
-
-GDM3 is in development but has not been checked in yet.
-
-
diff --git a/TODO b/TODO
index 44021639..9e5655de 100644
--- a/TODO
+++ b/TODO
@@ -3,8 +3,6 @@ Finish gdmconfig and gdmface.
Both language and country locale selection support.
-Grab root window.
-
gdmlogin should honor user geometry parameters.
Keyboard layout menu.
diff --git a/config/Gnome.in b/config/Gnome.in
index cf429391..15ae3887 100755
--- a/config/Gnome.in
+++ b/config/Gnome.in
@@ -13,6 +13,6 @@ done
if [ -x "$HOME/.gnomerc" ]; then
exec "$HOME/.gnomerc"
else
- exec "@sysconfdir@/gnomerc"
+ exec "@sysconfdir@/gdm/gnomerc"
fi
diff --git a/config/gdm b/config/gdm
index 71ff8d13..1d2e0816 100644
--- a/config/gdm
+++ b/config/gdm
@@ -1,8 +1,7 @@
#%PAM-1.0
-auth required /lib/security/pam_pwdb.so shadow nullok
+auth required /lib/security/pam_stack.so service=system-auth
auth required /lib/security/pam_nologin.so
-account required /lib/security/pam_pwdb.so
-password required /lib/security/pam_cracklib.so
-password required /lib/security/pam_pwdb.so shadow nullok use_authtok
-session required /lib/security/pam_pwdb.so
+account required /lib/security/pam_stack.so service=system-auth
+password required /lib/security/pam_stack.so service=system-auth
+session required /lib/security/pam_stack.so service=system-auth
session optional /lib/security/pam_console.so
diff --git a/config/gdm.conf.in b/config/gdm.conf.in
index 3d1c33b6..2a665cdb 100644
--- a/config/gdm.conf.in
+++ b/config/gdm.conf.in
@@ -20,11 +20,11 @@ UserAuthFBDir=/tmp
UserAuthFile=.Xauthority
[security]
-AllowRoot=0
+AllowRoot=1
RelaxPermissions=0
RetryDelay=3
UserMaxFile=65536
-VerboseAuth=1
+VerboseAuth=0
[xdmcp]
Enable=0
@@ -37,7 +37,7 @@ MaxWaitIndirect=30
Port=177
[gui]
-GtkRC=
+GtkRC=@datadir@/themes/Default/gtk/gtkrc
MaxIconWidth=128
MaxIconHeight=128
@@ -52,9 +52,12 @@ Icon=@pixmapdir@/gdm.xpm
LocaleFile=@localedir@/locale.alias
Logo=@pixmapdir@/gnome-logo-large.png
Quiver=1
-SystemMenu=0
+SystemMenu=1
Welcome=Welcome to %n
Welcome[es]=Bienvenido a %n
+Welcome[de]=Willkommen auf %n
+Welcome[fr]=Bienvenue sur %n
+Welcome[cs]=Vítejte na %n
[chooser]
DefaultHostImg=@pixmapdir@/nohost.png
diff --git a/config/locale.alias b/config/locale.alias
index f9abf015..82e31031 100644
--- a/config/locale.alias
+++ b/config/locale.alias
@@ -1,5 +1,5 @@
-# Locale name alias data base
-# Copyright (C) 1995 Free Software Foundation, Inc.
+# Locale name alias data base.
+# Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
#
# 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
@@ -22,34 +22,38 @@
# All entries are case independent.
# Note: This file is far from being complete. If you have a value for
-# your own site which you think might be useful for others too, share it
-# with the rest of us. Send it to bug-gnu-utils@prep.ai.mit.edu.
+# your own site which you think might be useful for others too, share
+# it with the rest of us. Send it using the `glibcbug' script to
+# bugs@gnu.org.
+catalan ca_ES.ISO-8859-1
+croatian hr_HR.ISO-8859-2
czech cs_CZ.ISO-8859-2
+danish da_DK.ISO-8859-1
dansk da_DK.ISO-8859-1
deutsch de_DE.ISO-8859-1
dutch nl_NL.ISO-8859-1
-english en_US.ISO-8859-1
-eesti et_EE.ISO-8859-1
+english en.ISO-8859-1
finnish fi_FI.ISO-8859-1
français fr_FR.ISO-8859-1
french fr_FR.ISO-8859-1
german de_DE.ISO-8859-1
greek el_GR.ISO-8859-7
hebrew iw_IL.ISO-8859-8
+hrvatski hr_HR.ISO-8859-2
hungarian hu_HU.ISO-8859-2
icelandic is_IS.ISO-8859-1
-italian it_CH.ISO-8859-1
-japanese ja_JP.EUC
-korean ko_KR.eucKR
-norsk no_NO.ISO-8859-1
+italian it_IT.ISO-8859-1
+japanese ja_JP.SJIS
+japanese.euc ja_JP.eucJP
+norwegian no_NO.ISO-8859-1
polish pl_PL.ISO-8859-2
portuguese pt_PT.ISO-8859-1
romanian ro_RO.ISO-8859-2
-russian ru_SU.ISO-8859-5
+russian ru_RU.ISO-8859-5
slovak sk_SK.ISO-8859-2
-slovene sl_CS.ISO-8859-2
+slovene sl_SI.ISO-8859-2
+slovenian sl_SI.ISO-8859-2
spanish es_ES.ISO-8859-1
swedish sv_SE.ISO-8859-1
turkish tr_TR.ISO-8859-9
-
diff --git a/daemon/auth.c b/daemon/auth.c
index 93934e9d..f4c2dcf3 100644
--- a/daemon/auth.c
+++ b/daemon/auth.c
@@ -321,7 +321,7 @@ gdm_auth_user_remove (GdmDisplay *d, uid_t user)
* to it. So we better play it safe... */
if (! gdm_file_check ("gdm_auth_user_remove", user, authdir, authfile,
- FALSE, GdmUserMaxFile, GdmRelaxPerms)) {
+ TRUE, GdmUserMaxFile, GdmRelaxPerms)) {
gdm_error (_("gdm_auth_user_remove: Ignoring suspiciously looking cookie file %s"), d->userauth);
return;
diff --git a/daemon/display.c b/daemon/display.c
index c2d5a308..6d498481 100644
--- a/daemon/display.c
+++ b/daemon/display.c
@@ -144,18 +144,20 @@ gdm_display_dispose (GdmDisplay *d)
if (d->type == TYPE_XDMCP) {
displays = g_slist_remove (displays, d);
sessions--;
+ d->type = -1;
}
if (d->name) {
gdm_debug ("gdm_display_dispose: Disposing %s", d->name);
g_free (d->name);
+ d->name = NULL;
}
- if (d->hostname)
- g_free (d->hostname);
+ g_free (d->hostname);
+ d->hostname = NULL;
- if (d->authfile)
- g_free (d->authfile);
+ g_free (d->authfile);
+ d->authfile = NULL;
if (d->auths) {
GSList *tmpauth = d->auths;
@@ -166,19 +168,20 @@ gdm_display_dispose (GdmDisplay *d)
}
g_slist_free (d->auths);
+ d->auths = NULL;
}
- if (d->userauth)
- g_free (d->userauth);
+ g_free (d->userauth);
+ d->userauth = NULL;
- if (d->command)
- g_free (d->command);
+ g_free (d->command);
+ d->command = NULL;
- if (d->cookie)
- g_free (d->cookie);
+ g_free (d->cookie);
+ d->cookie = NULL;
- if (d->bcookie)
- g_free (d->bcookie);
+ g_free (d->bcookie);
+ d->bcookie = NULL;
g_free (d);
}
diff --git a/daemon/gdm.c b/daemon/gdm.c
index 7db96ac5..0cdebfee 100644
--- a/daemon/gdm.c
+++ b/daemon/gdm.c
@@ -44,8 +44,6 @@ static void gdm_config_parse (void);
static void gdm_local_servers_start (GdmDisplay *d);
static void gdm_daemonify (void);
static void gdm_local_servers_start (GdmDisplay *d);
-static void gdm_child_handler (gint sig);
-static void gdm_term_handler (int sig);
/* Global vars */
GSList *displays; /* List of displays managed */
@@ -318,20 +316,12 @@ gdm_local_servers_start (GdmDisplay *d)
{
if (d && d->type == TYPE_LOCAL) {
gdm_debug ("gdm_local_servers_start: Starting %s", d->name);
- gdm_slave_start (d);
+ gdm_display_manage (d);
}
}
-
-/**
- * gdm_child_handler:
- * @sig: Signal value
- *
- * ACME Funeral Services
- */
-
static void
-gdm_child_handler (gint sig)
+gdm_cleanup_children (void)
{
pid_t pid;
gint exitstatus = 0, status = 0;
@@ -344,7 +334,7 @@ gdm_child_handler (gint sig)
if (WIFEXITED (exitstatus))
status = WEXITSTATUS (exitstatus);
- gdm_debug ("gdm_child_handler: child %d returned %d", pid, status);
+ gdm_debug ("gdm_cleanup_children: child %d returned %d", pid, status);
if (pid < 1)
return;
@@ -400,58 +390,76 @@ gdm_child_handler (gint sig)
/* This is a local server so we start a new slave */
if (d->type == TYPE_LOCAL)
- gdm_slave_start (d);
-
+ gdm_display_manage (d);
/* Remote displays will send a request to be managed */
- if (d->type == TYPE_XDMCP)
+ else if (d->type == TYPE_XDMCP)
gdm_display_unmanage (d);
break;
}
-}
-
-/**
- * gdm_term_handler:
- * @sig: Signal value
- *
- * Shutdown all displays and terminate the gdm process
- */
+ gdm_quit ();
+}
static void
-gdm_term_handler (int sig)
+term_cleanup (void)
{
- sigset_t mask;
-
- gdm_debug ("gdm_term_handler: Got TERM/INT. Going down!");
-
- /* Block SIGCHLD */
- sigemptyset (&mask);
- sigaddset (&mask, SIGCHLD);
- sigprocmask (SIG_BLOCK, &mask, NULL);
-
- /* Unmanage all displays */
- g_slist_foreach (displays, (GFunc) gdm_display_unmanage, NULL);
-
- /* Cleanup */
- closelog();
- unlink (GdmPidFile);
+ sigset_t mask;
+
+ gdm_debug ("term_cleanup: Got TERM/INT. Going down!");
+
+ sigemptyset (&mask);
+ sigaddset (&mask, SIGCHLD);
+ sigprocmask (SIG_BLOCK, &mask, NULL);
+
+ g_slist_foreach (displays, (GFunc) gdm_display_unmanage, NULL);
+
+ closelog();
+ unlink (GdmPidFile);
+
+ exit (EXIT_SUCCESS);
+}
- exit (EXIT_SUCCESS);
+static gboolean
+mainloop_sig_callback (gint8 sig, gpointer data)
+{
+ gdm_debug ("mainloop_sig_callback: Got signal %d", (int)sig);
+ switch (sig)
+ {
+ case SIGCHLD:
+ gdm_cleanup_children ();
+ break;
+
+ case SIGINT:
+ case SIGTERM:
+ term_cleanup ();
+ break;
+
+ default:
+ break;
+ }
+
+ return TRUE;
}
+static void
+signal_notify (int sig)
+{
+ g_signal_notify (sig);
+}
/*
* main: The main daemon control
*/
+static GMainLoop *main_loop;
+
int
main (int argc, char *argv[])
{
sigset_t mask;
struct sigaction term, child;
FILE *pf;
- GMainLoop *main_loop;
/* XDM compliant error message */
if (getuid())
@@ -492,7 +500,11 @@ main (int argc, char *argv[])
gdm_daemonify();
/* Signal handling */
- term.sa_handler = gdm_term_handler;
+ g_signal_add (SIGCHLD, mainloop_sig_callback, NULL);
+ g_signal_add (SIGTERM, mainloop_sig_callback, NULL);
+ g_signal_add (SIGINT, mainloop_sig_callback, NULL);
+
+ term.sa_handler = signal_notify;
term.sa_flags = SA_RESTART;
sigemptyset (&term.sa_mask);
@@ -502,7 +514,7 @@ main (int argc, char *argv[])
if (sigaction (SIGINT, &term, NULL) < 0)
gdm_fail (_("gdm_main: Error setting up INT signal handler"));
- child.sa_handler = gdm_child_handler;
+ child.sa_handler = signal_notify;
child.sa_flags = SA_RESTART|SA_NOCLDSTOP;
sigemptyset (&child.sa_mask);
sigaddset (&child.sa_mask, SIGCHLD);
@@ -531,10 +543,132 @@ main (int argc, char *argv[])
gdm_xdmcp_run();
}
- g_main_run (main_loop);
+ /* We always exit via exit(), and sadly we need to g_main_quit()
+ * at times not knowing if it's this main or a recursive one we're
+ * quitting.
+ */
+ while (1)
+ {
+ gdm_run ();
+ gdm_debug ("main: Exited main loop");
+ }
return EXIT_SUCCESS; /* Not reached */
}
+/* signal main loop support */
+
+
+typedef struct _GSignalData GSignalData;
+struct _GSignalData
+{
+ guint8 index;
+ guint8 shift;
+ GSignalFunc callback;
+};
+
+static gboolean g_signal_prepare (gpointer source_data,
+ GTimeVal *current_time,
+ gint *timeout,
+ gpointer user_data);
+static gboolean g_signal_check (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data);
+static gboolean g_signal_dispatch (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data);
+
+static GSourceFuncs signal_funcs = {
+ g_signal_prepare,
+ g_signal_check,
+ g_signal_dispatch,
+ g_free
+};
+static guint32 signals_notified[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+static gboolean
+g_signal_prepare (gpointer source_data,
+ GTimeVal *current_time,
+ gint *timeout,
+ gpointer user_data)
+{
+ GSignalData *signal_data = source_data;
+
+ return signals_notified[signal_data->index] & (1 << signal_data->shift);
+}
+
+static gboolean
+g_signal_check (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data)
+{
+ GSignalData *signal_data = source_data;
+
+ return signals_notified[signal_data->index] & (1 << signal_data->shift);
+}
+
+static gboolean
+g_signal_dispatch (gpointer source_data,
+ GTimeVal *current_time,
+ gpointer user_data)
+{
+ GSignalData *signal_data = source_data;
+
+ signals_notified[signal_data->index] &= ~(1 << signal_data->shift);
+
+ return signal_data->callback (-128 + signal_data->index * 32 + signal_data->shift, user_data);
+}
+
+guint
+g_signal_add (gint8 signal,
+ GSignalFunc function,
+ gpointer data)
+{
+ return g_signal_add_full (G_PRIORITY_DEFAULT, signal, function, data, NULL);
+}
+
+guint
+g_signal_add_full (gint priority,
+ gint8 signal,
+ GSignalFunc function,
+ gpointer data,
+ GDestroyNotify destroy)
+{
+ GSignalData *signal_data;
+ guint s = 128 + signal;
+
+ g_return_val_if_fail (function != NULL, 0);
+
+ signal_data = g_new (GSignalData, 1);
+ signal_data->index = s / 32;
+ signal_data->shift = s % 32;
+ signal_data->callback = function;
+
+ return g_source_add (priority, TRUE, &signal_funcs, signal_data, data, destroy);
+}
+
+void
+g_signal_notify (gint8 signal)
+{
+ guint index, shift;
+ guint s = 128 + signal;
+
+ index = s / 32;
+ shift = s % 32;
+
+ signals_notified[index] |= 1 << shift;
+}
+
+void
+gdm_run (void)
+{
+ g_main_run (main_loop);
+}
+
+void
+gdm_quit (void)
+{
+ g_main_quit (main_loop);
+}
/* EOF */
diff --git a/daemon/gdm.h b/daemon/gdm.h
index a0b9f13c..46c8c29b 100644
--- a/daemon/gdm.h
+++ b/daemon/gdm.h
@@ -157,6 +157,9 @@ struct _GdmDisplay {
pid_t slavepid;
pid_t chooserpid;
time_t acctime;
+ time_t last_start_time;
+ gint retry_count;
+ gboolean disabled;
};
@@ -177,6 +180,21 @@ struct _GdmChooserDisplay {
time_t acctime;
};
+typedef gboolean (*GSignalFunc) (gint8 signal,
+ gpointer data);
+guint g_signal_add (gint8 signal,
+ GSignalFunc function,
+ gpointer data);
+guint g_signal_add_full (gint priority,
+ gint8 signal,
+ GSignalFunc function,
+ gpointer data,
+ GDestroyNotify destroy);
+void g_signal_notify (gint8 signal);
+
+
+void gdm_run (void);
+void gdm_quit (void);
#endif /* __GDM_H__ */
diff --git a/daemon/misc.c b/daemon/misc.c
index 99e37d17..7d70759e 100644
--- a/daemon/misc.c
+++ b/daemon/misc.c
@@ -130,12 +130,15 @@ gdm_debug (const gchar *format, ...)
va_list args;
gchar *s;
- if (! GdmDebug)
+ if (/*0 &&*/ ! GdmDebug)
return;
va_start (args, format);
s = g_strdup_vprintf (format, args);
va_end (args);
+
+ /* UGLY DEBUGGING HACK! */
+ /*{ FILE *fp = fopen ("/tmp/foo.gdm", "a"); fprintf (fp, "%s\n", s); fflush (fp); fclose (fp); };*/
syslog (LOG_ERR, s); /* FIXME: LOG_DEBUG */
@@ -162,13 +165,21 @@ gdm_debug (const gchar *format, ...)
*
* Afterall, providing the programmer with a nice, consistent
* interface is what the standard C Library is all about. - Duh!
+ *
+ * Note from George:
+ * You cannot free the last env as it could have been something else
+ * and could still be in the env! We just have to leak, there is no
+ * recourse.
+ * -George
*/
#ifndef HAVE_SETENV
gint
gdm_setenv (const gchar *var, const gchar *value)
{
+#if 0
static gchar *lastenv = NULL; /* Holds last successful assignment pointer */
+#endif
gchar *envstr; /* Temporary environment string */
gint result; /* Return value from the putenv() call */
@@ -189,12 +200,14 @@ gdm_setenv (const gchar *var, const gchar *value)
/* Stuff the resulting string into the environment */
result = putenv (envstr);
+#if 0
/* If putenv() succeeded and lastenv is set, free the old pointer */
if (result == 0 && lastenv)
g_free (lastenv);
/* Save the current string pointer for the next gdm_setenv call */
lastenv = envstr;
+#endif
return result;
}
@@ -204,7 +217,9 @@ gdm_setenv (const gchar *var, const gchar *value)
gint
gdm_unsetenv (const gchar *var)
{
+#if 0
static gchar *lastenv = NULL; /* Holds last successful assignment pointer */
+#endif
gchar *envstr; /* Temporary environment string */
gint result; /* Return value from the putenv() call */
@@ -221,12 +236,14 @@ gdm_unsetenv (const gchar *var)
/* Stuff the resulting string into the environment */
result = putenv (envstr);
+#if 0
/* If putenv() succeeded and lastenv is set, free the old pointer */
if (result == 0 && lastenv)
g_free (lastenv);
/* Save the current string pointer for the next gdm_setenv call */
lastenv = envstr;
+#endif
return result;
}
diff --git a/daemon/server.c b/daemon/server.c
index df979d6e..193096d6 100644
--- a/daemon/server.c
+++ b/daemon/server.c
@@ -42,10 +42,10 @@ static const gchar RCSid[]="$Id$";
/* Local prototypes */
-void gdm_server_spawn (GdmDisplay *d);
-void gdm_server_usr1_handler (gint);
-void gdm_server_alarm_handler (gint);
-void gdm_server_child_handler (gint);
+static void gdm_server_spawn (GdmDisplay *d);
+static void gdm_server_usr1_handler (gint);
+static void gdm_server_alarm_handler (gint);
+static void gdm_server_child_handler (gint);
/* Configuration options */
extern gchar *argdelim;
@@ -56,8 +56,81 @@ extern gint GdmXdmcp;
extern sigset_t sysmask;
/* Global vars */
-GdmDisplay *d;
+GdmDisplay *d = NULL;
+static gboolean
+gdm_server_check_loop (GdmDisplay *disp)
+{
+ time_t now;
+ time_t since_last;
+
+ now = time (NULL);
+
+ if (disp->disabled)
+ return FALSE;
+
+ if (disp->last_start_time > now || disp->last_start_time == 0)
+ {
+ /* Reset everything if this is the first time in this
+ * function, or if the system clock got reset backward.
+ */
+ disp->last_start_time = now;
+ disp->retry_count = 1;
+
+ gdm_debug ("Resetting counts for loop of death detection");
+
+ return TRUE;
+ }
+
+ since_last = now - disp->last_start_time;
+
+ /* If it's been at least 1.5 minutes since the last startup
+ * attempt, then we reset everything.
+ */
+
+ if (since_last >= 90)
+ {
+ disp->last_start_time = now;
+ disp->retry_count = 1;
+
+ gdm_debug ("Resetting counts for loop of death detection, 90 seconds elapsed.");
+
+ return TRUE;
+ }
+
+ /* If we've tried too many times we bail out. i.e. this means we
+ * tried too many times in the 90-second period.
+ */
+ if (disp->retry_count > 4)
+ {
+ gchar *msg;
+ msg = g_strdup_printf (_("Failed to start X server several times in a short time period; disabling display %s"), disp->name);
+ gdm_error (msg);
+ g_free (msg);
+ disp->disabled = TRUE;
+
+ gdm_debug ("Failed to start X server after several retries; aborting.");
+
+ exit (SERVER_ABORT);
+ }
+
+ /* At least 8 seconds between start attempts,
+ * so you can try to kill gdm from the console
+ * in these gaps.
+ */
+ if (since_last < 8)
+ {
+ gdm_debug ("Sleeping %d seconds before next X server restart attempt",
+ 8 - since_last);
+ sleep (8 - since_last);
+ now = time (NULL);
+ }
+
+ disp->retry_count += 1;
+ disp->last_start_time = now;
+
+ return TRUE;
+}
/**
* gdm_server_start:
@@ -70,15 +143,22 @@ gboolean
gdm_server_start (GdmDisplay *disp)
{
struct sigaction usr1, chld, alrm;
+ struct sigaction old_usr1, old_chld, old_alrm;
sigset_t mask;
+ gboolean retvalue;
if (!disp)
return FALSE;
d = disp;
d->servtries = 0;
-
+
gdm_debug ("gdm_server_start: %s", d->name);
+
+ if (!gdm_server_check_loop (disp))
+ return FALSE;
+
+ gdm_debug ("Attempting to start X server");
/* Create new cookie */
gdm_auth_secure_display (d);
@@ -89,7 +169,7 @@ gdm_server_start (GdmDisplay *disp)
usr1.sa_flags = SA_RESTART|SA_RESETHAND;
sigemptyset (&usr1.sa_mask);
- if (sigaction (SIGUSR1, &usr1, NULL) < 0) {
+ if (sigaction (SIGUSR1, &usr1, &old_usr1) < 0) {
gdm_error (_("gdm_server_start: Error setting up USR1 signal handler"));
return FALSE;
}
@@ -99,8 +179,9 @@ gdm_server_start (GdmDisplay *disp)
chld.sa_flags = SA_RESTART|SA_RESETHAND;
sigemptyset (&chld.sa_mask);
- if (sigaction (SIGCHLD, &chld, NULL) < 0) {
+ if (sigaction (SIGCHLD, &chld, &old_chld) < 0) {
gdm_error (_("gdm_server_start: Error setting up CHLD signal handler"));
+ sigaction (SIGUSR1, &old_usr1, NULL);
return FALSE;
}
@@ -109,8 +190,10 @@ gdm_server_start (GdmDisplay *disp)
alrm.sa_flags = SA_RESTART|SA_RESETHAND;
sigemptyset (&alrm.sa_mask);
- if (sigaction (SIGALRM, &alrm, NULL) < 0) {
+ if (sigaction (SIGALRM, &alrm, &old_alrm) < 0) {
gdm_error (_("gdm_server_start: Error setting up ALRM signal handler"));
+ sigaction (SIGUSR1, &old_usr1, NULL);
+ sigaction (SIGCHLD, &old_chld, NULL);
return FALSE;
}
@@ -123,10 +206,17 @@ gdm_server_start (GdmDisplay *disp)
/* fork X server process */
gdm_server_spawn (d);
-
+
+/* hmmm perhaps this is b0rk, dunno, gonna revert to
+ * the beta 2/4 or whatever it was way of doing things
+ * (with the patches)
+ * -George */
+
+ retvalue = FALSE;
+
/* Wait for X server to send ready signal */
while (d->servtries < 5) {
- pause();
+ gdm_run ();
switch (d->servstat) {
@@ -145,22 +235,31 @@ gdm_server_start (GdmDisplay *disp)
alarm (0);
gdm_debug ("gdm_server_start: Completed %s!", d->name);
-
- return TRUE;
+
+ retvalue = TRUE;
+ goto spawn_done;
case SERVER_ABORT:
alarm (0);
gdm_debug ("gdm_server_start: Server %s died during startup!", d->name);
sigprocmask (SIG_SETMASK, &sysmask, NULL);
- return FALSE;
+ retvalue = FALSE;
+ goto spawn_done;
default:
break;
}
}
- return FALSE;
+spawn_done:
+
+ /* restore default handlers */
+ sigaction (SIGUSR1, &old_usr1, NULL);
+ sigaction (SIGCHLD, &old_chld, NULL);
+ sigaction (SIGALRM, &old_alrm, NULL);
+
+ return retvalue;
}
@@ -171,7 +270,7 @@ gdm_server_start (GdmDisplay *disp)
* forks an actual X server process
*/
-void
+static void
gdm_server_spawn (GdmDisplay *d)
{
struct sigaction usr1;
@@ -279,10 +378,12 @@ gdm_server_stop (GdmDisplay *d)
* Received when the server is ready to accept connections
*/
-void
+static void
gdm_server_usr1_handler (gint sig)
{
d->servstat = SERVER_RUNNING; /* Server ready to accept connections */
+
+ gdm_quit ();
}
@@ -293,10 +394,12 @@ gdm_server_usr1_handler (gint sig)
* Server start timeout handler
*/
-void
+static void
gdm_server_alarm_handler (gint signal)
{
d->servstat = SERVER_TIMEOUT; /* Server didn't start */
+
+ gdm_quit ();
}
@@ -307,10 +410,14 @@ gdm_server_alarm_handler (gint signal)
* Received when server died during startup
*/
-void
+static void
gdm_server_child_handler (gint signal)
{
+ gdm_debug ("gdm_server_child_handler: Got SIGCHLD, server abort");
+
d->servstat = SERVER_ABORT; /* Server died unexpectedly */
+
+ gdm_quit ();
}
@@ -352,6 +459,10 @@ gdm_server_alloc (gint id, gchar *command)
d->sessionid = 0;
d->acctime = 0;
d->dsp = NULL;
+
+ d->last_start_time = 0;
+ d->retry_count = 0;
+ d->disabled = FALSE;
g_free (dname);
g_free (hostname);
diff --git a/daemon/slave.c b/daemon/slave.c
index 546a29c7..f03ff590 100644
--- a/daemon/slave.c
+++ b/daemon/slave.c
@@ -83,10 +83,11 @@ static void gdm_slave_session_cleanup (void);
static void gdm_slave_term_handler (int sig);
static void gdm_slave_child_handler (int sig);
static void gdm_slave_windows_kill (void);
-static void gdm_slave_xsync_handler (int sig);
+/* static void gdm_slave_xsync_handler (int sig); */
static gboolean gdm_slave_xsync_ping (void);
static void gdm_slave_exit (gint status, const gchar *format, ...);
static gint gdm_slave_exec_script (GdmDisplay*, gchar *dir);
+static gchar* gdm_get_user_shell(void);
void
@@ -160,7 +161,7 @@ gdm_slave_start (GdmDisplay *display)
}
-void
+static void
gdm_slave_greeter (void)
{
gint pipe1[2], pipe2[2];
@@ -249,8 +250,8 @@ gdm_slave_greeter (void)
}
-void
-gdm_slave_session_start ()
+static void
+gdm_slave_session_start (void)
{
gchar *cfgdir, *sesspath;
struct stat statbuf;
@@ -258,6 +259,7 @@ gdm_slave_session_start ()
gchar *session, *language, *usrsess, *usrlang;
gboolean savesess = FALSE, savelang = FALSE, usrcfgok = FALSE, authok = FALSE;
gint i;
+ char *shell;
pwent = getpwnam (login);
@@ -344,10 +346,13 @@ gdm_slave_session_start ()
gdm_setenv ("PATH", GdmDefaultPath);
/* Set locale */
- if (!strcasecmp (language, "english"))
+ if (strcasecmp (language, "english") == 0) {
gdm_setenv ("LANG", "C");
- else
+ gdm_setenv ("GDM_LANG", "C");
+ } else {
gdm_setenv ("LANG", language);
+ gdm_setenv ("GDM_LANG", language);
+ }
/* If script fails reset X server and restart greeter */
if (gdm_slave_exec_script (d, GdmPreSession) != EXIT_SUCCESS)
@@ -366,6 +371,7 @@ gdm_slave_session_start ()
seteuid (0);
if (!authok) {
+ gdm_debug ("gdm_slave_session_start: Auth not OK");
gdm_slave_session_stop();
gdm_slave_session_cleanup();
@@ -427,9 +433,13 @@ gdm_slave_session_start ()
/* Restore sigmask inherited from init */
sigprocmask (SIG_SETMASK, &sysmask, NULL);
- execl (sesspath, NULL);
+ shell = gdm_get_user_shell ();
+
+ execl (shell, "-", "-c", sesspath, NULL);
gdm_error (_("gdm_slave_session_start: Could not start session `%s'"), sesspath);
+
+ g_free (shell);
gdm_slave_session_stop();
gdm_slave_session_cleanup();
@@ -443,13 +453,15 @@ gdm_slave_session_start ()
/* Wait for the user's session to exit */
waitpid (d->sesspid, 0, 0);
+ gdm_debug ("gdm_slave_session_start: Session ended OK");
+
gdm_slave_session_stop();
gdm_slave_session_cleanup();
}
-void
-gdm_slave_session_stop ()
+static void
+gdm_slave_session_stop (void)
{
struct passwd *pwent;
@@ -474,8 +486,7 @@ gdm_slave_session_stop ()
seteuid (0);
}
-
-void
+static void
gdm_slave_session_cleanup (void)
{
gdm_debug ("gdm_slave_session_cleanup: %s on %s", login, d->name);
@@ -491,11 +502,41 @@ gdm_slave_session_cleanup (void)
gdm_slave_windows_kill();
XCloseDisplay (d->dsp);
+ d->dsp = NULL;
}
exit (DISPLAY_REMANAGE);
}
+static gchar*
+gdm_get_user_shell(void)
+{
+ struct passwd *pw;
+ int i;
+ /*char *shell;*/
+ static char *shells [] = {
+ "/bin/bash", "/bin/zsh", "/bin/tcsh", "/bin/ksh",
+ "/bin/csh", "/bin/sh", 0
+ };
+
+#if 0
+ if ((shell = getenv ("SHELL"))){
+ return g_strconcat (shell, NULL);
+ }
+#endif
+ pw = getpwuid(getuid());
+ if (pw && pw->pw_shell) {
+ return g_strdup (pw->pw_shell);
+ }
+
+ for (i = 0; shells [i]; i++) {
+ if (g_file_exists (shells [i])){
+ return g_strdup (shells[i]);
+ }
+ }
+
+ return g_strdup("/bin/sh");
+}
static void
gdm_slave_term_handler (int sig)
@@ -514,6 +555,7 @@ gdm_slave_term_handler (int sig)
gdm_debug ("gdm_slave_term_handler: Whacking client connections");
gdm_slave_windows_kill();
XCloseDisplay (d->dsp);
+ d->dsp = NULL;
exit (DISPLAY_ABORT);
}
@@ -525,6 +567,8 @@ gdm_slave_child_handler (int sig)
{
gint status;
pid_t pid;
+
+ gdm_debug ("gdm_slave_child_handler");
while ((pid = waitpid (-1, &status, WNOHANG)) > 0) {
gdm_debug ("gdm_slave_child_handler: %d died", pid);
@@ -536,8 +580,10 @@ gdm_slave_child_handler (int sig)
if (WIFEXITED (status))
exit (WEXITSTATUS (status));
else {
- if (d && d->dsp)
+ if (d && d->dsp) {
XCloseDisplay (d->dsp);
+ d->dsp = NULL;
+ }
exit (DISPLAY_REMANAGE);
}
@@ -549,6 +595,17 @@ gdm_slave_child_handler (int sig)
}
}
+static gint
+ignore_xerror (Display *disp, XErrorEvent *event)
+{
+ return 0;
+}
+static gint
+ignore_xioerror (Display *disp)
+{
+ return 0;
+}
+
/* Only kills clients, not connections. This keeps the server alive */
static void
@@ -557,18 +614,28 @@ gdm_slave_windows_kill (void)
Window root, parent, *children;
gint child, screen, nchildren;
Display *disp = NULL;
+ gint (* xerror) (Display *, XErrorEvent *);
+ gint (* xioerror) (Display *);
+ /* this seems just wrong! */
+#if 0
disp=XOpenDisplay (d->name);
if (!disp) {
gdm_debug ("gdm_slave_windows_kill: Could not open display %s", d->name);
return;
}
+#endif
+
+ disp = d->dsp;
gdm_debug ("gdm_slave_windows_kill: Killing windows on %s", d->name);
gdm_setenv ("XAUTHORITY", d->authfile);
gdm_setenv ("DISPLAY", d->name);
+
+ xerror = XSetErrorHandler (ignore_xerror);
+ xioerror = XSetIOErrorHandler (ignore_xioerror);
for (screen = 0 ; screen < ScreenCount (disp) ; screen++) {
@@ -588,6 +655,9 @@ gdm_slave_windows_kill (void)
}
XSync (disp, FALSE);
+
+ XSetErrorHandler (xerror);
+ XSetIOErrorHandler (xioerror);
}
@@ -595,9 +665,9 @@ gdm_slave_windows_kill (void)
static gint
gdm_slave_xerror_handler (Display *disp, XErrorEvent *evt)
{
- gdm_debug ("gdm_slave_windows_kill_error_handler: X error - display doesn't respond");
+ gdm_debug ("gdm_slave_xerror_handler: X error - display doesn't respond");
pingack = FALSE;
- return (TRUE);
+ return (0);
}
@@ -610,37 +680,49 @@ gdm_slave_xioerror_handler (Display *disp)
if (login)
gdm_slave_session_stop();
- gdm_error (_("gdm_slave_windows_kill_ioerror_handler: Fatal X error - Restarting %s"), d->name);
+ gdm_error (_("gdm_slave_xioerror_handler: Fatal X error - Restarting %s"), d->name);
exit (DISPLAY_REMANAGE);
}
+#if 0
static void
gdm_slave_xsync_handler (int sig)
{
gdm_debug ("gdm_slave_xsync_handler: Xping failed for display %s", d->name);
pingack = FALSE;
}
+#endif
+/* I don't understand how the alarm stuff would even work here, I mean
+ * yes it would set the pingback var if XSync hangs, but other then that
+ * it doesn't stop the hang */
static gboolean
gdm_slave_xsync_ping (void)
{
+#if 0
struct sigaction sigalarm;
sigset_t mask, omask;
+#endif
+ gint (* xerror) (Display *, XErrorEvent *);
+ gint (* xioerror) (Display *);
gdm_debug ("gdm_slave_xsync_ping: Pinging %s", d->name);
pingack = TRUE;
- XSetErrorHandler (gdm_slave_xerror_handler);
- XSetIOErrorHandler (gdm_slave_xioerror_handler);
-
+ xerror = XSetErrorHandler (gdm_slave_xerror_handler);
+ xioerror = XSetIOErrorHandler (gdm_slave_xioerror_handler);
+
+#if 0
sigalarm.sa_handler = gdm_slave_xsync_handler;
sigalarm.sa_flags = 0;
sigemptyset (&sigalarm.sa_mask);
-
+#endif
+
+#if 0
if (sigaction (SIGALRM, &sigalarm, NULL) < 0)
gdm_slave_exit (DISPLAY_ABORT, _("gdm_slave_xsync_ping: Error setting up ALARM signal handler"));
@@ -649,13 +731,19 @@ gdm_slave_xsync_ping (void)
sigprocmask (SIG_UNBLOCK, &mask, &omask);
alarm (10);
+#endif
XSync (d->dsp, TRUE);
+#if 0
alarm (0);
sigprocmask (SIG_SETMASK, &omask, NULL);
+#endif
gdm_debug ("gdm_slave_xsync_ping: %s returned %d", d->name, pingack);
+
+ XSetErrorHandler (xerror);
+ XSetIOErrorHandler (xioerror);
return (pingack);
}
diff --git a/daemon/verify-pam.c b/daemon/verify-pam.c
index 8b960502..d7426175 100644
--- a/daemon/verify-pam.c
+++ b/daemon/verify-pam.c
@@ -181,7 +181,7 @@ gdm_verify_user (const gchar *display)
/* The verbose authentication is turned on, output the error
* message from the PAM subsystem */
if (GdmVerboseAuth)
- gdm_slave_greeter_ctl (GDM_MSGERR, (gchar *) pam_strerror (pamh, pamerr));
+ gdm_slave_greeter_ctl (GDM_MSGERR, _("Authentication failed"));
pam_end (pamh, pamerr);
pamh = NULL;
diff --git a/daemon/xdmcp.c b/daemon/xdmcp.c
index 928c3506..ab119f99 100644
--- a/daemon/xdmcp.c
+++ b/daemon/xdmcp.c
@@ -115,7 +115,7 @@ extern gint GdmMaxIndirectWait; /* Max wait between INDIRECT_QUERY and MANAGE */
extern gint GdmDispPerHost; /* Max number of displays per remote host */
/* Local prototypes */
-static void gdm_xdmcp_decode_packet (void);
+static gboolean gdm_xdmcp_decode_packet (void);
static void gdm_xdmcp_handle_query (struct sockaddr_in *clnt_sa, gint len, gint type);
static void gdm_xdmcp_send_forward_query (GdmIndirectDisplay *id, ARRAYofARRAY8Ptr authlist);
static void gdm_xdmcp_handle_forward_query (struct sockaddr_in *clnt_sa, gint len);
@@ -261,7 +261,7 @@ gdm_xdmcp_close (void)
}
-static void
+static gboolean
gdm_xdmcp_decode_packet (void)
{
struct sockaddr_in clnt_sa;
@@ -276,17 +276,17 @@ gdm_xdmcp_decode_packet (void)
if (!XdmcpFill (xdmcpfd, &buf, &clnt_sa, &sa_len)) {
gdm_error (_("gdm_xdmcp_decode: Could not create XDMCP buffer!"));
- return;
+ return TRUE;
}
if (!XdmcpReadHeader (&buf, &header)) {
gdm_error (_("gdm_xdmcp_decode: Could not read XDMCP header!"));
- return;
+ return TRUE;
}
if (header.version != XDM_PROTOCOL_VERSION) {
gdm_error (_("gdm_xdmcp_decode: Incorrect XDMCP version!"));
- return;
+ return TRUE;
}
gdm_debug ("gdm_xdmcp_decode: Received opcode %s from client %s",
@@ -329,6 +329,8 @@ gdm_xdmcp_decode_packet (void)
inet_ntoa (clnt_sa.sin_addr));
break;
}
+
+ return TRUE;
}
@@ -431,12 +433,15 @@ gdm_xdmcp_handle_forward_query (struct sockaddr_in *clnt_sa, gint len)
/* Read display port */
if (! XdmcpReadARRAY8 (&buf, &clnt_port)) {
+ XdmcpDisposeARRAYofARRAY8 (&clnt_addr);
gdm_error (_("gdm_xdmcp_handle_forward_query: Could not read display port number"));
return;
}
/* Extract array of authentication names from Xdmcp packet */
if (! XdmcpReadARRAYofARRAY8 (&buf, &clnt_authlist)) {
+ XdmcpDisposeARRAYofARRAY8 (&clnt_addr);
+ XdmcpDisposeARRAYofARRAY8 (&clnt_port);
gdm_error (_("gdm_xdmcp_handle_forward_query: Could not extract authlist from packet"));
return;
}
@@ -453,7 +458,7 @@ gdm_xdmcp_handle_forward_query (struct sockaddr_in *clnt_sa, gint len)
if (len != explen) {
gdm_error (_("gdm_xdmcp_handle_forward_query: Error in checksum"));
- return;
+ goto out;
}
/* Find client port number */
@@ -461,7 +466,7 @@ gdm_xdmcp_handle_forward_query (struct sockaddr_in *clnt_sa, gint len)
port = port*256+clnt_port.data[i];
/* Find client address. Ugly, ugly. Endianness sucks... */
- memmove (&ia.s_addr, clnt_addr.data, clnt_addr.length);
+ memmove (&ia.s_addr, clnt_addr.data, MIN(clnt_addr.length, sizeof(ia.s_addr)));
gdm_debug ("gdm_xdmcp_handle_forward_query: Got FORWARD_QUERY from display: %s, port %d",
inet_ntoa (ia), port);
@@ -472,14 +477,18 @@ gdm_xdmcp_handle_forward_query (struct sockaddr_in *clnt_sa, gint len)
disp_sa->sin_port = htons (port);
disp_sa->sin_addr.s_addr = ia.s_addr;
- /* Cleanup */
- XdmcpDisposeARRAYofARRAY8 (&clnt_authlist);
-
/* Check with tcp_wrappers if display is allowed to access */
if (gdm_xdmcp_host_allow (disp_sa))
gdm_xdmcp_send_willing (disp_sa);
else
gdm_xdmcp_send_unwilling (disp_sa, FORWARD_QUERY);
+
+ out:
+ g_free(disp_sa);
+ /* Cleanup */
+ XdmcpDisposeARRAYofARRAY8 (&clnt_authlist);
+ XdmcpDisposeARRAYofARRAY8 (&clnt_port);
+ XdmcpDisposeARRAYofARRAY8 (&clnt_addr);
}
@@ -506,7 +515,6 @@ gdm_xdmcp_send_willing (struct sockaddr_in *clnt_sa)
XdmcpFlush (xdmcpfd, &buf, clnt_sa, sizeof (struct sockaddr_in));
}
-
static void
gdm_xdmcp_send_unwilling (struct sockaddr_in *clnt_sa, gint type)
{
@@ -534,13 +542,13 @@ gdm_xdmcp_send_unwilling (struct sockaddr_in *clnt_sa, gint type)
static void
gdm_xdmcp_handle_request (struct sockaddr_in *clnt_sa, gint len)
{
- static CARD16 clnt_dspnum;
- static ARRAY16 clnt_conntyp;
- static ARRAYofARRAY8 clnt_addr;
- static ARRAY8 clnt_authname;
- static ARRAY8 clnt_authdata;
- static ARRAYofARRAY8 clnt_authorization;
- static ARRAY8 clnt_manufacturer;
+ CARD16 clnt_dspnum;
+ ARRAY16 clnt_conntyp;
+ ARRAYofARRAY8 clnt_addr;
+ ARRAY8 clnt_authname;
+ ARRAY8 clnt_authdata;
+ ARRAYofARRAY8 clnt_authorization;
+ ARRAY8 clnt_manufacturer;
gint explen;
gint i;
gboolean mitauth = FALSE;
@@ -631,6 +639,13 @@ gdm_xdmcp_handle_request (struct sockaddr_in *clnt_sa, gint len)
gdm_xdmcp_send_accept (clnt_sa, clnt_dspnum);
else
gdm_xdmcp_send_decline (clnt_sa);
+
+ XdmcpDisposeARRAY8 (&clnt_authname);
+ XdmcpDisposeARRAY8 (&clnt_authdata);
+ XdmcpDisposeARRAY8 (&clnt_manufacturer);
+ XdmcpDisposeARRAYofARRAY8 (&clnt_addr);
+ XdmcpDisposeARRAYofARRAY8 (&clnt_authorization);
+ XdmcpDisposeARRAY16 (&clnt_conntyp);
}
@@ -770,6 +785,7 @@ gdm_xdmcp_handle_manage (struct sockaddr_in *clnt_sa, gint len)
if (logfd != -1) {
dup2 (logfd, 1);
dup2 (logfd, 2);
+ close (logfd);
}
else
gdm_error (_("gdm_xdmcp_handle_manage: Could not open logfile for display %s!"), d->name);
@@ -791,6 +807,8 @@ gdm_xdmcp_handle_manage (struct sockaddr_in *clnt_sa, gint len)
gdm_debug ("gdm_xdmcp_handle_manage: Failed to look up session id %d", clnt_sessid);
gdm_xdmcp_send_refuse (clnt_sa, clnt_sessid);
}
+
+ XdmcpDisposeARRAY8(&clnt_dspclass);
}
diff --git a/gui/gdmlogin.c b/gui/gdmlogin.c
index a7b0b475..50a00f9e 100644
--- a/gui/gdmlogin.c
+++ b/gui/gdmlogin.c
@@ -28,6 +28,8 @@
#include <signal.h>
#include <dirent.h>
#include <gdk/gdkx.h>
+#include <X11/X.h>
+#include <X11/Xlib.h>
#include <pwd.h>
#include <sys/utsname.h>
@@ -61,10 +63,12 @@ static GtkWidget *login;
static GtkWidget *label;
static GtkWidget *entry;
static GtkWidget *msg;
+static gboolean first_message = TRUE;
static GtkWidget *win;
static GtkWidget *sessmenu;
static GtkWidget *langmenu;
static GdkWindow *rootwin;
+static GdkWindow *rootwin_overlay;
static GnomeIconList *browser;
static GdkImlibImage *defface;
@@ -397,7 +401,7 @@ gdm_login_parse_config (void)
GdmLocaleFile = gnome_config_get_string (GDM_KEY_LOCFILE);
GdmDefaultLocale = gnome_config_get_string (GDM_KEY_LOCALE);
GdmSessionDir = gnome_config_get_string (GDM_KEY_SESSDIR);
- GdmWelcome=gnome_config_get_string (GDM_KEY_WELCOME);
+ GdmWelcome=gnome_config_get_translated_string (GDM_KEY_WELCOME);
GdmGtkRC = gnome_config_get_string (GDM_KEY_GTKRC);
GdmExclude = gnome_config_get_string (GDM_KEY_EXCLUDE);
GdmGlobalFaceDir = gnome_config_get_string (GDM_KEY_FACEDIR);
@@ -458,7 +462,9 @@ gdm_login_session_lookup (gchar* savedsess)
gtk_widget_set_sensitive (GTK_WIDGET (sessmenu), FALSE);
/* Previously saved session not found in ~user/.gnome/gdm */
- if (savedsess && ! strlen (savedsess)) {
+ if ( ! (savedsess != NULL &&
+ strcmp ("(null)", savedsess) != 0 &&
+ savedsess[0] != '\0')) {
/* If "Last" is chosen run Default, else run user's current selection */
if (!strcasecmp (cursess, lastsess))
session = defsess;
@@ -544,6 +550,9 @@ gdm_login_language_lookup (gchar* savedlang)
}
else
language = savedlang;
+
+ /* Now this is utterly ugly, but I suppose it works */
+ language[0] = tolower (language[0]);
}
@@ -822,6 +831,15 @@ gdm_login_ctrl_handler (GIOChannel *source, GIOCondition cond, gint fd)
case GDM_PROMPT:
g_io_channel_read (source, buf, PIPE_SIZE-1, &len);
buf[len-1] = '\0';
+
+ /* Turn off the message whenever the prompt changes,
+ this is sort of a hack. Also, don't turn it off
+ the first time. Yeah I know. */
+ if (first_message)
+ first_message = FALSE;
+ else
+ gtk_label_set (GTK_LABEL(msg), "");
+
gtk_label_set (GTK_LABEL (label), buf);
gtk_widget_show (GTK_WIDGET (label));
gtk_entry_set_text (GTK_ENTRY (entry), "");
@@ -834,6 +852,15 @@ gdm_login_ctrl_handler (GIOChannel *source, GIOCondition cond, gint fd)
case GDM_NOECHO:
g_io_channel_read (source, buf, PIPE_SIZE-1, &len);
buf[len-1] = '\0';
+
+ /* Turn off the message whenever the prompt changes,
+ this is sort of a hack. Also, don't turn it off
+ the first time. Yeah I know. */
+ if (first_message)
+ first_message = FALSE;
+ else
+ gtk_label_set (GTK_LABEL(msg), "");
+
gtk_label_set (GTK_LABEL(label), buf);
gtk_widget_show (GTK_WIDGET (label));
gtk_entry_set_text (GTK_ENTRY (entry), "");
@@ -1003,6 +1030,62 @@ gdm_login_browser_unselect (GtkWidget *widget, gint selected, GdkEvent *event)
return (TRUE);
}
+static GdkFilterReturn
+root_keys_filter (GdkXEvent *gdk_xevent,
+ GdkEvent *event,
+ gpointer data)
+{
+ XEvent *xevent = (XEvent *)gdk_xevent;
+ XEvent new_xevent;
+
+ if (xevent->type != KeyPress &&
+ xevent->type != KeyRelease)
+ return GDK_FILTER_CONTINUE;
+
+ if (entry->window == NULL)
+ return GDK_FILTER_CONTINUE;
+
+ /* EVIIIIIIIIIL, but works */
+ /* -George */
+ new_xevent = *xevent;
+ new_xevent.xany.window = GDK_WINDOW_XWINDOW (entry->window);
+ XSendEvent (GDK_DISPLAY (),
+ GDK_WINDOW_XWINDOW (entry->window),
+ True, NoEventMask, &new_xevent);
+
+ return GDK_FILTER_CONTINUE;
+}
+
+static void
+gdm_init_root_window_overlay (void)
+{
+ GdkWindowAttr attributes;
+ gint attributes_mask;
+
+ attributes.window_type = GDK_WINDOW_TEMP;
+ attributes.x = 0;
+ attributes.y = 0;
+ attributes.width = gdk_screen_width ();
+ attributes.height = gdk_screen_height ();
+ attributes.wclass = GDK_INPUT_ONLY;
+ attributes.event_mask = (GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_MASK |
+ GDK_POINTER_MOTION_HINT_MASK |
+ GDK_KEY_PRESS_MASK |
+ GDK_KEY_RELEASE_MASK |
+ GDK_ENTER_NOTIFY_MASK |
+ GDK_LEAVE_NOTIFY_MASK);
+ attributes_mask = GDK_WA_X | GDK_WA_Y;
+
+ rootwin_overlay = gdk_window_new (NULL,
+ &attributes,
+ attributes_mask);
+
+ gdk_window_show (rootwin_overlay);
+
+ gdk_window_add_filter (rootwin_overlay, root_keys_filter, NULL);
+}
static void
gdm_login_gui_init (void)
@@ -1022,6 +1105,8 @@ gdm_login_gui_init (void)
rootwin = gdk_window_foreign_new (GDK_ROOT_WINDOW ());
+ gdm_init_root_window_overlay ();
+
login = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_ref (login);
gtk_object_set_data_full (GTK_OBJECT (login), "login", login,
@@ -1263,6 +1348,7 @@ gdm_login_gui_init (void)
(GtkAttachOptions) (GTK_FILL), 0, 10);
msg = gtk_label_new (_("Please enter your login"));
+ first_message = TRUE;
gtk_widget_set_name(msg, "Message");
gtk_widget_ref (msg);
gtk_object_set_data_full (GTK_OBJECT (login), "msg", msg,
@@ -1510,6 +1596,9 @@ main (int argc, char *argv[])
gnome_preferences_set_dialog_position (GTK_WIN_POS_CENTER);
+ bindtextdomain (PACKAGE, GNOMELOCALEDIR);
+ textdomain (PACKAGE);
+
gdm_login_parse_config();
if (GdmBrowser)
diff --git a/po/Makefile.in.in b/po/Makefile.in.in
index cf3aa8cb..111b40fc 100644
--- a/po/Makefile.in.in
+++ b/po/Makefile.in.in
@@ -24,8 +24,6 @@ gnulocaledir = $(prefix)/share/locale
gettextsrcdir = $(prefix)/share/gettext/po
subdir = po
-DESTDIR =
-
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
MKINSTALLDIRS = $(top_srcdir)/@MKINSTALLDIRS@
@@ -113,16 +111,16 @@ install-data: install-data-@USE_NLS@
install-data-no: all
install-data-yes: all
if test -r "$(MKINSTALLDIRS)"; then \
- $(MKINSTALLDIRS) $(DESTDIR)$(datadir); \
+ $(MKINSTALLDIRS) $(datadir); \
else \
- $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(datadir); \
+ $(SHELL) $(top_srcdir)/mkinstalldirs $(datadir); \
fi
@catalogs='$(CATALOGS)'; \
for cat in $$catalogs; do \
cat=`basename $$cat`; \
case "$$cat" in \
- *.gmo) destdir=$(DESTDIR)$(gnulocaledir);; \
- *) destdir=$(DESTDIR)$(localedir);; \
+ *.gmo) destdir=$(gnulocaledir);; \
+ *) destdir=$(localedir);; \
esac; \
lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
dir=$$destdir/$$lang/LC_MESSAGES; \
@@ -155,12 +153,12 @@ install-data-yes: all
done
if test "$(PACKAGE)" = "gettext"; then \
if test -r "$(MKINSTALLDIRS)"; then \
- $(MKINSTALLDIRS) $(DESTDIR)$(gettextsrcdir); \
+ $(MKINSTALLDIRS) $(gettextsrcdir); \
else \
- $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(gettextsrcdir); \
+ $(SHELL) $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \
fi; \
$(INSTALL_DATA) $(srcdir)/Makefile.in.in \
- $(DESTDIR)$(gettextsrcdir)/Makefile.in.in; \
+ $(gettextsrcdir)/Makefile.in.in; \
else \
: ; \
fi
@@ -173,12 +171,12 @@ uninstall:
for cat in $$catalogs; do \
cat=`basename $$cat`; \
lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
- rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
- rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
- rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
- rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
done
- rm -f $(DESTDIR)$(gettextsrcdir)/po-Makefile.in.in
+ rm -f $(gettextsrcdir)/po-Makefile.in.in
check: all