diff options
author | William Jon McCann <mccann@src.gnome.org> | 2007-06-08 01:18:08 +0000 |
---|---|---|
committer | William Jon McCann <mccann@src.gnome.org> | 2007-06-08 01:18:08 +0000 |
commit | c4adefa73913fb5d448c6dd74dc58eb3a67c7376 (patch) | |
tree | dda3f1a3696ee8ea5917a751277ad0dbca008de6 | |
parent | fd6e91f3fee22b0c9389ffe91265f4099e688501 (diff) | |
download | gdm-c4adefa73913fb5d448c6dd74dc58eb3a67c7376.tar.gz |
Make the session object talk to the greeter!
svn path=/branches/mccann-gobject/; revision=4973
28 files changed, 2960 insertions, 2972 deletions
diff --git a/common/gdm-settings-client.c b/common/gdm-settings-client.c index b5cef069..aaeedf9a 100644 --- a/common/gdm-settings-client.c +++ b/common/gdm-settings-client.c @@ -79,10 +79,10 @@ get_value (const char *key, G_TYPE_INVALID); if (! res) { if (error != NULL) { - g_debug ("Failed to get value for %s: %s", key, error->message); + /*g_debug ("Failed to get value for %s: %s", key, error->message);*/ g_error_free (error); } else { - g_debug ("Failed to get value for %s", key); + /*g_debug ("Failed to get value for %s", key);*/ } return FALSE; diff --git a/common/gdm-settings-keys.h b/common/gdm-settings-keys.h index a349564a..576c6b3d 100644 --- a/common/gdm-settings-keys.h +++ b/common/gdm-settings-keys.h @@ -25,6 +25,10 @@ G_BEGIN_DECLS +/* List delimiter for config file lists */ +#define GDM_DELIMITER_MODULES ":" +#define GDM_DELIMITER_THEMES "/:" + #define GDM_KEY_CHOOSER "daemon/Chooser" #define GDM_KEY_AUTOMATIC_LOGIN_ENABLE "daemon/AutomaticLoginEnable" #define GDM_KEY_AUTOMATIC_LOGIN "daemon/AutomaticLogin" diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 3b573889..7a298075 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -69,8 +69,8 @@ libexec_PROGRAMS = \ gdm_slave_SOURCES = \ slave-main.c \ - gdm-greeter.c \ - gdm-greeter.h \ + gdm-greeter-proxy.c \ + gdm-greeter-proxy.h \ gdm-server.c \ gdm-server.h \ gdm-session.c \ diff --git a/daemon/gdm-greeter-proxy.c b/daemon/gdm-greeter-proxy.c new file mode 100644 index 00000000..1467e240 --- /dev/null +++ b/daemon/gdm-greeter-proxy.c @@ -0,0 +1,1130 @@ +/* -*- 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. + * + */ + +#include "config.h" + +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <errno.h> +#include <ctype.h> +#include <pwd.h> +#include <grp.h> + +#if defined (_POSIX_PRIORITY_SCHEDULING) && defined (HAVE_SCHED_YIELD) +#include <sched.h> +#endif + +#include <glib.h> +#include <glib/gi18n.h> +#include <glib-object.h> +#define DBUS_API_SUBJECT_TO_CHANGE +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> + +#include <X11/Xlib.h> /* for Display */ + +#include "gdm-common.h" +#include "filecheck.h" + +#include "gdm-greeter-proxy.h" + +#define GDM_GREETER_SERVER_DBUS_PATH "/org/gnome/DisplayManager/GreeterServer" +#define GDM_GREETER_SERVER_DBUS_INTERFACE "org.gnome.DisplayManager.GreeterServer" + + +extern char **environ; + +#define GDM_GREETER_PROXY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_GREETER_PROXY, GdmGreeterProxyPrivate)) + +struct GdmGreeterProxyPrivate +{ + char *command; + GPid pid; + + char *user_name; + char *group_name; + + char *x11_display_name; + char *x11_authority_file; + + int user_max_filesize; + + gboolean interrupted; + gboolean always_restart_greeter; + + guint child_watch_id; + + DBusServer *server; + char *server_address; + DBusConnection *greeter_connection; +}; + +enum { + PROP_0, + PROP_X11_DISPLAY_NAME, + PROP_X11_AUTHORITY_FILE, + PROP_USER_NAME, + PROP_GROUP_NAME, +}; + +enum { + ANSWER, + STARTED, + STOPPED, + LAST_SIGNAL +}; + +static guint signals [LAST_SIGNAL] = { 0, }; + +static void gdm_greeter_proxy_class_init (GdmGreeterProxyClass *klass); +static void gdm_greeter_proxy_init (GdmGreeterProxy *greeter_proxy); +static void gdm_greeter_proxy_finalize (GObject *object); + +G_DEFINE_TYPE (GdmGreeterProxy, gdm_greeter_proxy, G_TYPE_OBJECT) + +static gboolean +send_dbus_message (DBusConnection *connection, + DBusMessage *message) +{ + gboolean is_connected; + gboolean sent; + + g_return_val_if_fail (message != NULL, FALSE); + + if (connection == NULL) { + g_debug ("There is no valid connection"); + return FALSE; + } + + is_connected = dbus_connection_get_is_connected (connection); + if (! is_connected) { + g_warning ("Not connected!"); + return FALSE; + } + + sent = dbus_connection_send (connection, message, NULL); + + return sent; +} + +static void +send_dbus_string_signal (GdmGreeterProxy *greeter_proxy, + const char *name, + const char *text) +{ + DBusMessage *message; + DBusMessageIter iter; + + g_return_if_fail (greeter_proxy != NULL); + + message = dbus_message_new_signal (GDM_GREETER_SERVER_DBUS_PATH, + GDM_GREETER_SERVER_DBUS_INTERFACE, + name); + + dbus_message_iter_init_append (message, &iter); + dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &text); + + if (! send_dbus_message (greeter_proxy->priv->greeter_connection, message)) { + g_debug ("Could not send %s signal", name); + } + + dbus_message_unref (message); +} + +gboolean +gdm_greeter_proxy_info_query (GdmGreeterProxy *greeter_proxy, + const char *text) +{ + send_dbus_string_signal (greeter_proxy, "InfoQuery", text); + + return TRUE; +} + +gboolean +gdm_greeter_proxy_secret_info_query (GdmGreeterProxy *greeter_proxy, + const char *text) +{ + send_dbus_string_signal (greeter_proxy, "SecretInfoQuery", text); + return TRUE; +} + +gboolean +gdm_greeter_proxy_info (GdmGreeterProxy *greeter_proxy, + const char *text) +{ + send_dbus_string_signal (greeter_proxy, "Info", text); + return TRUE; +} + +gboolean +gdm_greeter_proxy_problem (GdmGreeterProxy *greeter_proxy, + const char *text) +{ + send_dbus_string_signal (greeter_proxy, "Problem", text); + return TRUE; +} + +static void +change_user (GdmGreeterProxy *greeter_proxy) + +{ + struct passwd *pwent; + struct group *grent; + + if (greeter_proxy->priv->user_name == NULL) { + return; + } + + pwent = getpwnam (greeter_proxy->priv->user_name); + if (pwent == NULL) { + g_warning (_("GreeterProxy was to be spawned by user %s but that user doesn't exist"), + greeter_proxy->priv->user_name); + _exit (1); + } + + grent = getgrnam (greeter_proxy->priv->group_name); + if (grent == NULL) { + g_warning (_("GreeterProxy was to be spawned by group %s but that user doesn't exist"), + greeter_proxy->priv->group_name); + _exit (1); + } + + g_debug ("Changing (uid:gid) for child process to (%d:%d)", + pwent->pw_uid, + grent->gr_gid); + + if (pwent->pw_uid != 0) { + if (setgid (grent->gr_gid) < 0) { + g_warning (_("Couldn't set groupid to %d"), + grent->gr_gid); + _exit (1); + } + + if (initgroups (pwent->pw_name, pwent->pw_gid) < 0) { + g_warning (_("initgroups () failed for %s"), + pwent->pw_name); + _exit (1); + } + + if (setuid (pwent->pw_uid) < 0) { + g_warning (_("Couldn't set userid to %d"), + (int)pwent->pw_uid); + _exit (1); + } + } else { + gid_t groups[1] = { 0 }; + + if (setgid (0) < 0) { + g_warning (_("Couldn't set groupid to 0")); + /* Don't error out, it's not fatal, if it fails we'll + * just still be */ + } + + /* this will get rid of any suplementary groups etc... */ + setgroups (1, groups); + } +} + +static void +greeter_proxy_child_setup (GdmGreeterProxy *greeter_proxy) +{ + change_user (greeter_proxy); +} + +static void +listify_hash (const char *key, + const char *value, + GPtrArray *env) +{ + char *str; + str = g_strdup_printf ("%s=%s", key, value); + g_ptr_array_add (env, str); +} + +static GPtrArray * +get_greeter_environment (GdmGreeterProxy *greeter_proxy) +{ + GPtrArray *env; + char **l; + GHashTable *hash; + struct passwd *pwent; + + env = g_ptr_array_new (); + + /* create a hash table of current environment, then update keys has necessary */ + hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + +#if 0 + for (l = environ; *l != NULL; l++) { + char **str; + str = g_strsplit (*l, "=", 2); + g_hash_table_insert (hash, str[0], str[1]); + } +#endif + + g_hash_table_insert (hash, g_strdup ("GDM_GREETER_DBUS_ADDRESS"), g_strdup (greeter_proxy->priv->server_address)); + + g_hash_table_insert (hash, g_strdup ("XAUTHORITY"), g_strdup (greeter_proxy->priv->x11_authority_file)); + g_hash_table_insert (hash, g_strdup ("DISPLAY"), g_strdup (greeter_proxy->priv->x11_display_name)); + +#if 0 + /* hackish ain't it */ + set_xnest_parent_stuff (); +#endif + + g_hash_table_insert (hash, g_strdup ("LOGNAME"), g_strdup (greeter_proxy->priv->user_name)); + g_hash_table_insert (hash, g_strdup ("USER"), g_strdup (greeter_proxy->priv->user_name)); + g_hash_table_insert (hash, g_strdup ("USERNAME"), g_strdup (greeter_proxy->priv->user_name)); + + g_hash_table_insert (hash, g_strdup ("GDM_VERSION"), g_strdup (VERSION)); + g_hash_table_remove (hash, "MAIL"); + + g_hash_table_insert (hash, g_strdup ("HOME"), g_strdup ("/")); + g_hash_table_insert (hash, g_strdup ("PWD"), g_strdup ("/")); + g_hash_table_insert (hash, g_strdup ("SHELL"), g_strdup ("/bin/sh")); + + pwent = getpwnam (greeter_proxy->priv->user_name); + if (pwent != NULL) { + if (pwent->pw_dir != NULL && pwent->pw_dir[0] != '\0') { + g_hash_table_insert (hash, g_strdup ("HOME"), g_strdup (pwent->pw_dir)); + g_hash_table_insert (hash, g_strdup ("PWD"), g_strdup (pwent->pw_dir)); + } + + g_hash_table_insert (hash, g_strdup ("SHELL"), g_strdup (pwent->pw_shell)); + } + +#if 0 + 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); + } +#endif + + g_hash_table_insert (hash, g_strdup ("RUNNING_UNDER_GDM"), g_strdup ("true")); + +#if 0 + 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 ("G_DEBUG_GESTURES", "true", TRUE); + } +#endif + +#if 0 + if (SERVER_IS_FLEXI (d)) { + g_setenv ("GDM_FLEXI_SERVER", "yes", TRUE); + } else { + g_unsetenv ("GDM_FLEXI_SERVER"); + } +#endif + + + g_hash_table_foreach (hash, (GHFunc)listify_hash, env); + g_hash_table_destroy (hash); + + g_ptr_array_add (env, NULL); + + return env; +} + +static void +gdm_slave_whack_temp_auth_file (GdmGreeterProxy *greeter_proxy) +{ +#if 0 + uid_t old; + + old = geteuid (); + if (old != 0) + seteuid (0); + if (d->parent_temp_auth_file != NULL) { + VE_IGNORE_EINTR (g_unlink (d->parent_temp_auth_file)); + } + g_free (d->parent_temp_auth_file); + d->parent_temp_auth_file = NULL; + if (old != 0) + seteuid (old); +#endif +} + + +static void +create_temp_auth_file (GdmGreeterProxy *greeter_proxy) +{ +#if 0 + if (d->type == TYPE_FLEXI_XNEST && + d->parent_auth_file != NULL) { + if (d->parent_temp_auth_file != NULL) { + VE_IGNORE_EINTR (g_unlink (d->parent_temp_auth_file)); + } + g_free (d->parent_temp_auth_file); + d->parent_temp_auth_file = + copy_auth_file (d->server_uid, + gdm_daemon_config_get_gdmuid (), + d->parent_auth_file); + } +#endif +} + +static void +gdm_slave_quick_exit (GdmGreeterProxy *greeter_proxy) +{ + /* FIXME */ + _exit (1); +} + +static void +greeter_proxy_child_watch (GPid pid, + int status, + GdmGreeterProxy *greeter_proxy) +{ + g_debug ("child (pid:%d) done (%s:%d)", + (int) pid, + WIFEXITED (status) ? "status" + : WIFSIGNALED (status) ? "signal" + : "unknown", + WIFEXITED (status) ? WEXITSTATUS (status) + : WIFSIGNALED (status) ? WTERMSIG (status) + : -1); + + g_spawn_close_pid (greeter_proxy->priv->pid); + greeter_proxy->priv->pid = -1; +} + +/* Note: Use abstract sockets like dbus does by default on Linux. Abstract + * sockets are only available on Linux. + */ +static char * +generate_address (void) +{ + char *path; +#if defined (__linux__) + int i; + char tmp[9]; + + for (i = 0; i < 8; i++) { + if (g_random_int_range (0, 2) == 0) { + tmp[i] = g_random_int_range ('a', 'z' + 1); + } else { + tmp[i] = g_random_int_range ('A', 'Z' + 1); + } + } + tmp[8] = '\0'; + + path = g_strdup_printf ("unix:abstract=/tmp/gdm-greeter-%s", tmp); +#else + path = g_strdup ("unix:tmpdir=/tmp/gdm-greeter"); +#endif + + return path; +} + +static DBusHandlerResult +greeter_handle_child_message (DBusConnection *connection, + DBusMessage *message, + void *user_data) +{ + GdmGreeterProxy *greeter_proxy = GDM_GREETER_PROXY (user_data); + + if (dbus_message_is_method_call (message, GDM_GREETER_SERVER_DBUS_INTERFACE, "AnswerQuery")) { + DBusMessage *reply; + DBusError error; + const char *text; + + dbus_error_init (&error); + if (! dbus_message_get_args (message, &error, + DBUS_TYPE_STRING, &text, + DBUS_TYPE_INVALID)) { + g_warning ("ERROR: %s", error.message); + } + + g_debug ("AnswerQuery: %s", text); + + reply = dbus_message_new_method_return (message); + dbus_connection_send (connection, reply, NULL); + dbus_message_unref (reply); + + g_signal_emit (greeter_proxy, signals [ANSWER], 0, text); + + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult +do_introspect (DBusConnection *connection, + DBusMessage *message) +{ + DBusMessage *reply; + GString *xml; + char *xml_string; + + g_debug ("Do introspect"); + + /* standard header */ + xml = g_string_new ("<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n" + "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n" + "<node>\n" + " <interface name=\"org.freedesktop.DBus.Introspectable\">\n" + " <method name=\"Introspect\">\n" + " <arg name=\"data\" direction=\"out\" type=\"s\"/>\n" + " </method>\n" + " </interface>\n"); + + /* interface */ + xml = g_string_append (xml, + " <interface name=\"org.gnome.DisplayManager.GreeterServer\">\n" + " <method name=\"AnswerQuery\">\n" + " <arg name=\"text\" direction=\"in\" type=\"s\"/>\n" + " </method>\n" + " <signal name=\"Info\">\n" + " <arg name=\"text\" type=\"s\"/>\n" + " </signal>\n" + " <signal name=\"Problem\">\n" + " <arg name=\"text\" type=\"s\"/>\n" + " </signal>\n" + " <signal name=\"InfoQuery\">\n" + " <arg name=\"text\" type=\"s\"/>\n" + " </signal>\n" + " <signal name=\"SecretInfoQuery\">\n" + " <arg name=\"text\" type=\"s\"/>\n" + " </signal>\n" + " </interface>\n"); + + reply = dbus_message_new_method_return (message); + + xml = g_string_append (xml, "</node>\n"); + xml_string = g_string_free (xml, FALSE); + + dbus_message_append_args (reply, + DBUS_TYPE_STRING, &xml_string, + DBUS_TYPE_INVALID); + + g_free (xml_string); + + if (reply == NULL) { + g_error ("No memory"); + } + + if (! dbus_connection_send (connection, reply, NULL)) { + g_error ("No memory"); + } + + dbus_message_unref (reply); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static DBusHandlerResult +greeter_server_message_handler (DBusConnection *connection, + DBusMessage *message, + void *user_data) +{ + GdmGreeterProxy *greeter_proxy = GDM_GREETER_PROXY (user_data); + + g_debug ("greeter_server_message_handler: destination=%s obj_path=%s interface=%s method=%s", + dbus_message_get_destination (message), + dbus_message_get_path (message), + dbus_message_get_interface (message), + dbus_message_get_member (message)); + + + if (dbus_message_is_method_call (message, "org.freedesktop.DBus", "AddMatch")) { + DBusMessage *reply; + + reply = dbus_message_new_method_return (message); + + if (reply == NULL) { + g_error ("No memory"); + } + + if (! dbus_connection_send (connection, reply, NULL)) { + g_error ("No memory"); + } + + dbus_message_unref (reply); + + return DBUS_HANDLER_RESULT_HANDLED; + } else if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected") && + strcmp (dbus_message_get_path (message), DBUS_PATH_LOCAL) == 0) { + + /*dbus_connection_unref (connection);*/ + + return DBUS_HANDLER_RESULT_HANDLED; + } else if (dbus_message_is_method_call (message, "org.freedesktop.DBus.Introspectable", "Introspect")) { + return do_introspect (connection, message); + } else { + return greeter_handle_child_message (connection, message, user_data); + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static void +greeter_server_unregister_handler (DBusConnection *connection, + void *user_data) +{ + GdmGreeterProxy *greeter_proxy = GDM_GREETER_PROXY (user_data); + + g_debug ("greeter_server_unregister_handler"); +} + +static DBusHandlerResult +connection_filter_function (DBusConnection *connection, + DBusMessage *message, + void *user_data) +{ + GdmGreeterProxy *greeter_proxy = GDM_GREETER_PROXY (user_data); + const char *path; + + path = dbus_message_get_path (message); + + g_debug ("obj_path=%s interface=%s method=%s", + dbus_message_get_path (message), + dbus_message_get_interface (message), + dbus_message_get_member (message)); + + if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected") + && strcmp (path, DBUS_PATH_LOCAL) == 0) { + + g_debug ("Disconnected"); + + dbus_connection_unref (connection); + greeter_proxy->priv->greeter_connection = NULL; + } else if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) { + + + } else { + return greeter_server_message_handler (connection, message, user_data); + } + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static dbus_bool_t +allow_user_function (DBusConnection *connection, + unsigned long uid, + void *data) +{ + GdmGreeterProxy *greeter_proxy = GDM_GREETER_PROXY (data); + struct passwd *pwent; + + if (greeter_proxy->priv->user_name == NULL) { + return FALSE; + } + + pwent = getpwnam (greeter_proxy->priv->user_name); + if (pwent == NULL) { + return FALSE; + } + + if (pwent->pw_uid == uid) { + return TRUE; + } + + return FALSE; +} + +static void +handle_connection (DBusServer *server, + DBusConnection *new_connection, + void *user_data) +{ + GdmGreeterProxy *greeter_proxy = GDM_GREETER_PROXY (user_data); + + g_debug ("Handing new connection"); + + if (greeter_proxy->priv->greeter_connection == NULL) { + DBusObjectPathVTable vtable = { &greeter_server_unregister_handler, + &greeter_server_message_handler, + NULL, NULL, NULL, NULL + }; + + greeter_proxy->priv->greeter_connection = new_connection; + dbus_connection_ref (new_connection); + dbus_connection_setup_with_g_main (new_connection, NULL); + + g_debug ("greeter connection is %p", new_connection); +#if 1 + dbus_connection_add_filter (new_connection, + connection_filter_function, + greeter_proxy, + NULL); +#endif + dbus_connection_set_unix_user_function (new_connection, + allow_user_function, + greeter_proxy, + NULL); + + dbus_connection_register_object_path (new_connection, + GDM_GREETER_SERVER_DBUS_PATH, + &vtable, + greeter_proxy); + + g_signal_emit (greeter_proxy, signals[STARTED], 0); + + } +} + +static gboolean +create_dbus_server (GdmGreeterProxy *greeter_proxy) +{ + DBusServer *server; + DBusError error; + gboolean ret; + char *address; + char *server_address; + const char *auth_mechanisms[] = {"EXTERNAL", NULL}; + + ret = FALSE; + + g_debug ("Creating D-Bus server for greeter"); + + address = generate_address (); + + dbus_error_init (&error); + server = dbus_server_listen (address, &error); + g_free (address); + + if (server == NULL) { + g_warning ("Cannot create D-BUS server for the greeter: %s", error.message); + goto out; + } + + dbus_server_setup_with_g_main (server, NULL); + dbus_server_set_auth_mechanisms (server, auth_mechanisms); + dbus_server_set_new_connection_function (server, + handle_connection, + greeter_proxy, + NULL); + ret = TRUE; + + g_free (greeter_proxy->priv->server_address); + greeter_proxy->priv->server_address = dbus_server_get_address (server); + + g_debug ("D-Bus server listening on %s", greeter_proxy->priv->server_address); + + out: + + return ret; +} + +static gboolean +gdm_greeter_proxy_spawn (GdmGreeterProxy *greeter_proxy) +{ + gchar **argv; + GError *error; + GPtrArray *env; + gboolean ret; + + ret = FALSE; + + create_temp_auth_file (greeter_proxy); + + g_debug ("Running greeter_proxy process: %s", greeter_proxy->priv->command); + + argv = NULL; + if (! g_shell_parse_argv (greeter_proxy->priv->command, NULL, &argv, &error)) { + g_warning ("Could not parse command: %s", error->message); + g_error_free (error); + goto out; + } + + create_dbus_server (greeter_proxy); + + env = get_greeter_environment (greeter_proxy); + + error = NULL; + ret = g_spawn_async_with_pipes (NULL, + argv, + (char **)env->pdata, + G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, + (GSpawnChildSetupFunc)greeter_proxy_child_setup, + greeter_proxy, + &greeter_proxy->priv->pid, + NULL, + NULL, + NULL, + &error); + + g_ptr_array_foreach (env, (GFunc)g_free, NULL); + g_ptr_array_free (env, TRUE); + + if (! ret) { + g_warning ("Could not start command '%s': %s", + greeter_proxy->priv->command, + error->message); + g_error_free (error); + } else { + g_debug ("gdm_slave_greeter_proxy: GreeterProxy on pid %d", (int)greeter_proxy->priv->pid); + } + + greeter_proxy->priv->child_watch_id = g_child_watch_add (greeter_proxy->priv->pid, + (GChildWatchFunc)greeter_proxy_child_watch, + greeter_proxy); + + g_strfreev (argv); + out: + + return ret; +} + +/** + * gdm_greeter_proxy_start: + * @disp: Pointer to a GdmDisplay structure + * + * Starts a local X greeter_proxy. Handles retries and fatal errors properly. + */ + +gboolean +gdm_greeter_proxy_start (GdmGreeterProxy *greeter_proxy) +{ + gboolean res; + + g_debug ("Starting greeter..."); + + res = gdm_greeter_proxy_spawn (greeter_proxy); + + if (res) { + + } + + + return res; +} + +static int +signal_pid (int pid, + int signal) +{ + int status = -1; + + /* perhaps block sigchld */ + + status = kill (pid, signal); + + if (status < 0) { + if (errno == ESRCH) { + g_warning ("Child process %lu was already dead.", + (unsigned long) pid); + } else { + g_warning ("Couldn't kill child process %lu: %s", + (unsigned long) pid, + g_strerror (errno)); + } + } + + /* perhaps unblock sigchld */ + + return status; +} + +static int +wait_on_child (int pid) +{ + int status; + + wait_again: + if (waitpid (pid, &status, 0) < 0) { + if (errno == EINTR) { + goto wait_again; + } else if (errno == ECHILD) { + ; /* do nothing, child already reaped */ + } else { + g_debug ("waitpid () should not fail"); + } + } + + return status; +} + +static void +greeter_proxy_died (GdmGreeterProxy *greeter_proxy) +{ + int exit_status; + + g_debug ("Waiting on process %d", greeter_proxy->priv->pid); + exit_status = wait_on_child (greeter_proxy->priv->pid); + + if (WIFEXITED (exit_status) && (WEXITSTATUS (exit_status) != 0)) { + g_debug ("Wait on child process failed"); + } else { + /* exited normally */ + } + + g_spawn_close_pid (greeter_proxy->priv->pid); + greeter_proxy->priv->pid = -1; + + g_debug ("GreeterProxy died"); +} + +gboolean +gdm_greeter_proxy_stop (GdmGreeterProxy *greeter_proxy) +{ + + if (greeter_proxy->priv->pid <= 1) { + return TRUE; + } + + /* remove watch source before we can wait on child */ + if (greeter_proxy->priv->child_watch_id > 0) { + g_source_remove (greeter_proxy->priv->child_watch_id); + greeter_proxy->priv->child_watch_id = 0; + } + + g_debug ("Stopping greeter_proxy"); + + signal_pid (greeter_proxy->priv->pid, SIGTERM); + greeter_proxy_died (greeter_proxy); + + return TRUE; +} + + +static void +_gdm_greeter_proxy_set_x11_display_name (GdmGreeterProxy *greeter_proxy, + const char *name) +{ + g_free (greeter_proxy->priv->x11_display_name); + greeter_proxy->priv->x11_display_name = g_strdup (name); +} + +static void +_gdm_greeter_proxy_set_x11_authority_file (GdmGreeterProxy *greeter_proxy, + const char *file) +{ + g_free (greeter_proxy->priv->x11_authority_file); + greeter_proxy->priv->x11_authority_file = g_strdup (file); +} + +static void +_gdm_greeter_proxy_set_user_name (GdmGreeterProxy *greeter_proxy, + const char *name) +{ + g_free (greeter_proxy->priv->user_name); + greeter_proxy->priv->user_name = g_strdup (name); +} + +static void +_gdm_greeter_proxy_set_group_name (GdmGreeterProxy *greeter_proxy, + const char *name) +{ + g_free (greeter_proxy->priv->group_name); + greeter_proxy->priv->group_name = g_strdup (name); +} + +static void +gdm_greeter_proxy_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GdmGreeterProxy *self; + + self = GDM_GREETER_PROXY (object); + + switch (prop_id) { + case PROP_X11_DISPLAY_NAME: + _gdm_greeter_proxy_set_x11_display_name (self, g_value_get_string (value)); + break; + case PROP_X11_AUTHORITY_FILE: + _gdm_greeter_proxy_set_x11_authority_file (self, g_value_get_string (value)); + break; + case PROP_USER_NAME: + _gdm_greeter_proxy_set_user_name (self, g_value_get_string (value)); + break; + case PROP_GROUP_NAME: + _gdm_greeter_proxy_set_group_name (self, g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdm_greeter_proxy_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GdmGreeterProxy *self; + + self = GDM_GREETER_PROXY (object); + + switch (prop_id) { + case PROP_X11_DISPLAY_NAME: + g_value_set_string (value, self->priv->x11_display_name); + break; + case PROP_X11_AUTHORITY_FILE: + g_value_set_string (value, self->priv->x11_authority_file); + break; + case PROP_USER_NAME: + g_value_set_string (value, self->priv->user_name); + break; + case PROP_GROUP_NAME: + g_value_set_string (value, self->priv->group_name); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static GObject * +gdm_greeter_proxy_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GdmGreeterProxy *greeter_proxy; + GdmGreeterProxyClass *klass; + + klass = GDM_GREETER_PROXY_CLASS (g_type_class_peek (GDM_TYPE_GREETER_PROXY)); + + greeter_proxy = GDM_GREETER_PROXY (G_OBJECT_CLASS (gdm_greeter_proxy_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + + return G_OBJECT (greeter_proxy); +} + +static void +gdm_greeter_proxy_class_init (GdmGreeterProxyClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gdm_greeter_proxy_get_property; + object_class->set_property = gdm_greeter_proxy_set_property; + object_class->constructor = gdm_greeter_proxy_constructor; + object_class->finalize = gdm_greeter_proxy_finalize; + + g_type_class_add_private (klass, sizeof (GdmGreeterProxyPrivate)); + + g_object_class_install_property (object_class, + PROP_X11_DISPLAY_NAME, + g_param_spec_string ("x11-display-name", + "name", + "name", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, + PROP_X11_AUTHORITY_FILE, + g_param_spec_string ("x11-authority-file", + "authority file", + "authority file", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, + PROP_USER_NAME, + g_param_spec_string ("user-name", + "user name", + "user name", + "gdm", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, + PROP_GROUP_NAME, + g_param_spec_string ("group-name", + "group name", + "group name", + "gdm", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + signals [ANSWER] = + g_signal_new ("answer", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GdmGreeterProxyClass, answer), + NULL, + NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, + 1, + G_TYPE_STRING); + signals [STARTED] = + g_signal_new ("started", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GdmGreeterProxyClass, started), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + signals [STOPPED] = + g_signal_new ("stopped", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GdmGreeterProxyClass, stopped), + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); +} + +static void +gdm_greeter_proxy_init (GdmGreeterProxy *greeter_proxy) +{ + + greeter_proxy->priv = GDM_GREETER_PROXY_GET_PRIVATE (greeter_proxy); + + greeter_proxy->priv->pid = -1; + + greeter_proxy->priv->command = g_strdup (LIBEXECDIR "/gdmgreeter"); + greeter_proxy->priv->user_max_filesize = 65536; +} + +static void +gdm_greeter_proxy_finalize (GObject *object) +{ + GdmGreeterProxy *greeter_proxy; + + g_return_if_fail (object != NULL); + g_return_if_fail (GDM_IS_GREETER_PROXY (object)); + + greeter_proxy = GDM_GREETER_PROXY (object); + + g_return_if_fail (greeter_proxy->priv != NULL); + + gdm_greeter_proxy_stop (greeter_proxy); + + G_OBJECT_CLASS (gdm_greeter_proxy_parent_class)->finalize (object); +} + +GdmGreeterProxy * +gdm_greeter_proxy_new (const char *display_name) +{ + GObject *object; + + object = g_object_new (GDM_TYPE_GREETER_PROXY, + "x11-display-name", display_name, + NULL); + + return GDM_GREETER_PROXY (object); +} diff --git a/daemon/gdm-greeter-proxy.h b/daemon/gdm-greeter-proxy.h new file mode 100644 index 00000000..4458b64b --- /dev/null +++ b/daemon/gdm-greeter-proxy.h @@ -0,0 +1,71 @@ +/* -*- 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. + * + */ + + +#ifndef __GDM_GREETER_PROXY_H +#define __GDM_GREETER_PROXY_H + +#include <glib-object.h> + +G_BEGIN_DECLS + +#define GDM_TYPE_GREETER_PROXY (gdm_greeter_proxy_get_type ()) +#define GDM_GREETER_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_GREETER_PROXY, GdmGreeterProxy)) +#define GDM_GREETER_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_GREETER_PROXY, GdmGreeterProxyClass)) +#define GDM_IS_GREETER_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_GREETER_PROXY)) +#define GDM_IS_GREETER_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_GREETER_PROXY)) +#define GDM_GREETER_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_GREETER_PROXY, GdmGreeterProxyClass)) + +typedef struct GdmGreeterProxyPrivate GdmGreeterProxyPrivate; + +typedef struct +{ + GObject parent; + GdmGreeterProxyPrivate *priv; +} GdmGreeterProxy; + +typedef struct +{ + GObjectClass parent_class; + + void (* answer) (GdmGreeterProxy *greeter_proxy, + const char *text); + void (* started) (GdmGreeterProxy *greeter_proxy); + void (* stopped) (GdmGreeterProxy *greeter_proxy); +} GdmGreeterProxyClass; + +GType gdm_greeter_proxy_get_type (void); +GdmGreeterProxy * gdm_greeter_proxy_new (const char *display_id); +gboolean gdm_greeter_proxy_start (GdmGreeterProxy *greeter_proxy); +gboolean gdm_greeter_proxy_stop (GdmGreeterProxy *greeter_proxy); + + +gboolean gdm_greeter_proxy_info_query (GdmGreeterProxy *greeter_proxy, + const char *text); +gboolean gdm_greeter_proxy_secret_info_query (GdmGreeterProxy *greeter_proxy, + const char *text); +gboolean gdm_greeter_proxy_info (GdmGreeterProxy *greeter_proxy, + const char *text); +gboolean gdm_greeter_proxy_problem (GdmGreeterProxy *greeter_proxy, + const char *text); + +G_END_DECLS + +#endif /* __GDM_GREETER_PROXY_H */ diff --git a/daemon/gdm-greeter.c b/daemon/gdm-greeter.c deleted file mode 100644 index 58e8326f..00000000 --- a/daemon/gdm-greeter.c +++ /dev/null @@ -1,1331 +0,0 @@ -/* -*- 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. - * - */ - -#include "config.h" - -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <errno.h> -#include <ctype.h> -#include <pwd.h> -#include <grp.h> - -#if defined (_POSIX_PRIORITY_SCHEDULING) && defined (HAVE_SCHED_YIELD) -#include <sched.h> -#endif - -#include <glib.h> -#include <glib/gi18n.h> -#include <glib-object.h> - -#include <X11/Xlib.h> /* for Display */ - -#include "gdm-common.h" -#include "filecheck.h" - -#include "gdm-greeter.h" -#include "gdm-socket-protocol.h" - -extern char **environ; - -#define GDM_GREETER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_GREETER, GdmGreeterPrivate)) - -struct GdmGreeterPrivate -{ - char *command; - GPid pid; - - char *user_name; - char *group_name; - - int pipe1[2]; - int pipe2[2]; - - int greeter_fd_in; - int greeter_fd_out; - - char *x11_display_name; - char *x11_authority_file; - - int user_max_filesize; - - gboolean interrupted; - gboolean always_restart_greeter; - - guint child_watch_id; -}; - -enum { - PROP_0, - PROP_X11_DISPLAY_NAME, - PROP_X11_AUTHORITY_FILE, - PROP_USER_NAME, - PROP_GROUP_NAME, -}; - -static void gdm_greeter_class_init (GdmGreeterClass *klass); -static void gdm_greeter_init (GdmGreeter *greeter); -static void gdm_greeter_finalize (GObject *object); - -G_DEFINE_TYPE (GdmGreeter, gdm_greeter, G_TYPE_OBJECT) - -static void -change_user (GdmGreeter *greeter) - -{ - struct passwd *pwent; - struct group *grent; - - if (greeter->priv->user_name == NULL) { - return; - } - - pwent = getpwnam (greeter->priv->user_name); - if (pwent == NULL) { - g_warning (_("Greeter was to be spawned by user %s but that user doesn't exist"), - greeter->priv->user_name); - _exit (1); - } - - grent = getgrnam (greeter->priv->group_name); - if (grent == NULL) { - g_warning (_("Greeter was to be spawned by group %s but that user doesn't exist"), - greeter->priv->group_name); - _exit (1); - } - - g_debug ("Changing (uid:gid) for child process to (%d:%d)", - pwent->pw_uid, - grent->gr_gid); - - if (pwent->pw_uid != 0) { - if (setgid (grent->gr_gid) < 0) { - g_warning (_("Couldn't set groupid to %d"), - grent->gr_gid); - _exit (1); - } - - if (initgroups (pwent->pw_name, pwent->pw_gid) < 0) { - g_warning (_("initgroups () failed for %s"), - pwent->pw_name); - _exit (1); - } - - if (setuid (pwent->pw_uid) < 0) { - g_warning (_("Couldn't set userid to %d"), - (int)pwent->pw_uid); - _exit (1); - } - } else { - gid_t groups[1] = { 0 }; - - if (setgid (0) < 0) { - g_warning (_("Couldn't set groupid to 0")); - /* Don't error out, it's not fatal, if it fails we'll - * just still be */ - } - - /* this will get rid of any suplementary groups etc... */ - setgroups (1, groups); - } -} - -static void -greeter_child_setup (GdmGreeter *greeter) -{ - - /* Plumbing */ - VE_IGNORE_EINTR (close (greeter->priv->pipe1[1])); - VE_IGNORE_EINTR (close (greeter->priv->pipe2[0])); - - VE_IGNORE_EINTR (dup2 (greeter->priv->pipe1[0], STDIN_FILENO)); - VE_IGNORE_EINTR (dup2 (greeter->priv->pipe2[1], STDOUT_FILENO)); - - gdm_close_all_descriptors (2 /* from */, - -1 /* except */, - -1 /* except2 */); - - gdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */ - - change_user (greeter); -} - -static void -listify_hash (const char *key, - const char *value, - GPtrArray *env) -{ - char *str; - str = g_strdup_printf ("%s=%s", key, value); - g_ptr_array_add (env, str); -} - -static GPtrArray * -get_greeter_environment (GdmGreeter *greeter) -{ - GPtrArray *env; - char **l; - GHashTable *hash; - struct passwd *pwent; - - env = g_ptr_array_new (); - - /* create a hash table of current environment, then update keys has necessary */ - hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - -#if 0 - for (l = environ; *l != NULL; l++) { - char **str; - str = g_strsplit (*l, "=", 2); - g_hash_table_insert (hash, str[0], str[1]); - } -#endif - - g_hash_table_insert (hash, g_strdup ("XAUTHORITY"), g_strdup (greeter->priv->x11_authority_file)); - g_hash_table_insert (hash, g_strdup ("DISPLAY"), g_strdup (greeter->priv->x11_display_name)); - -#if 0 - /* hackish ain't it */ - set_xnest_parent_stuff (); -#endif - - g_hash_table_insert (hash, g_strdup ("LOGNAME"), g_strdup (greeter->priv->user_name)); - g_hash_table_insert (hash, g_strdup ("USER"), g_strdup (greeter->priv->user_name)); - g_hash_table_insert (hash, g_strdup ("USERNAME"), g_strdup (greeter->priv->user_name)); - - g_hash_table_insert (hash, g_strdup ("GDM_GREETER_PROTOCOL_VERSION"), g_strdup (GDM_GREETER_PROTOCOL_VERSION)); - g_hash_table_insert (hash, g_strdup ("GDM_VERSION"), g_strdup (VERSION)); - g_hash_table_remove (hash, "MAIL"); - - g_hash_table_insert (hash, g_strdup ("HOME"), g_strdup ("/")); - g_hash_table_insert (hash, g_strdup ("PWD"), g_strdup ("/")); - g_hash_table_insert (hash, g_strdup ("SHELL"), g_strdup ("/bin/sh")); - - pwent = getpwnam (greeter->priv->user_name); - if (pwent != NULL) { - if (pwent->pw_dir != NULL && pwent->pw_dir[0] != '\0') { - g_hash_table_insert (hash, g_strdup ("HOME"), g_strdup (pwent->pw_dir)); - g_hash_table_insert (hash, g_strdup ("PWD"), g_strdup (pwent->pw_dir)); - } - - g_hash_table_insert (hash, g_strdup ("SHELL"), g_strdup (pwent->pw_shell)); - } - -#if 0 - 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); - } -#endif - - g_hash_table_insert (hash, g_strdup ("RUNNING_UNDER_GDM"), g_strdup ("true")); - -#if 0 - 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 ("G_DEBUG_GESTURES", "true", TRUE); - } -#endif - -#if 0 - if (SERVER_IS_FLEXI (d)) { - g_setenv ("GDM_FLEXI_SERVER", "yes", TRUE); - } else { - g_unsetenv ("GDM_FLEXI_SERVER"); - } -#endif - - - g_hash_table_foreach (hash, (GHFunc)listify_hash, env); - g_hash_table_destroy (hash); - - g_ptr_array_add (env, NULL); - - return env; -} - -static void -gdm_slave_whack_temp_auth_file (GdmGreeter *greeter) -{ -#if 0 - uid_t old; - - old = geteuid (); - if (old != 0) - seteuid (0); - if (d->parent_temp_auth_file != NULL) { - VE_IGNORE_EINTR (g_unlink (d->parent_temp_auth_file)); - } - g_free (d->parent_temp_auth_file); - d->parent_temp_auth_file = NULL; - if (old != 0) - seteuid (old); -#endif -} - - -static void -create_temp_auth_file (GdmGreeter *greeter) -{ -#if 0 - if (d->type == TYPE_FLEXI_XNEST && - d->parent_auth_file != NULL) { - if (d->parent_temp_auth_file != NULL) { - VE_IGNORE_EINTR (g_unlink (d->parent_temp_auth_file)); - } - g_free (d->parent_temp_auth_file); - d->parent_temp_auth_file = - copy_auth_file (d->server_uid, - gdm_daemon_config_get_gdmuid (), - d->parent_auth_file); - } -#endif -} - -static void -whack_greeter_fds (GdmGreeter *greeter) -{ - if (greeter->priv->greeter_fd_out > 0) - VE_IGNORE_EINTR (close (greeter->priv->greeter_fd_out)); - greeter->priv->greeter_fd_out = -1; - if (greeter->priv->greeter_fd_in > 0) - VE_IGNORE_EINTR (close (greeter->priv->greeter_fd_in)); - greeter->priv->greeter_fd_in = -1; -} - -/* return true for "there was an interruption received", - and interrupted will be TRUE if we are actually interrupted from doing what - we want. If FALSE is returned, just continue on as we would normally */ -static gboolean -check_for_interruption (GdmGreeter *greeter, - const char *msg) -{ - /* Hell yeah we were interrupted, the greeter died */ - if (msg == NULL) { - greeter->priv->interrupted = TRUE; - return TRUE; - } - - if (msg[0] == BEL) { - /* Different interruptions come here */ - /* Note that we don't want to actually do anything. We want - * to just set some flag and go on and schedule it after we - * dump out of the login in the main login checking loop */ -#if 0 - switch (msg[1]) { - case GDM_INTERRUPT_TIMED_LOGIN: - /* only allow timed login if display is local, - * 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)) - && d->timed_login_ok && - ! ve_string_empty (ParsedTimedLogin) && - strcmp (ParsedTimedLogin, gdm_root_user ()) != 0 && - gdm_daemon_config_get_value_int (GDM_KEY_TIMED_LOGIN_DELAY) > 0) { - do_timed_login = TRUE; - } - break; - case GDM_INTERRUPT_CONFIGURE: - if (d->attached && - gdm_daemon_config_get_value_bool_per_display (GDM_KEY_CONFIG_AVAILABLE, d->name) && - gdm_daemon_config_get_value_bool_per_display (GDM_KEY_SYSTEM_MENU, d->name) && - ! ve_string_empty (gdm_daemon_config_get_value_string (GDM_KEY_CONFIGURATOR))) { - do_configurator = TRUE; - } - break; - case GDM_INTERRUPT_SUSPEND: - if (d->attached && - gdm_daemon_config_get_value_bool_per_display (GDM_KEY_SYSTEM_MENU, d->name) && - ! 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_slave_send (msg, FALSE /* wait_for_ack */); - g_free (msg); - } - /* Not interrupted, continue reading input, - * just proxy this to the master server */ - return TRUE; - case GDM_INTERRUPT_LOGIN_SOUND: - if (d->attached && - ! play_login_sound (gdm_daemon_config_get_value_string (GDM_KEY_SOUND_ON_LOGIN_FILE))) { - gdm_error (_("Login sound requested on non-local display or the play software " - "cannot be run or the sound does not exist")); - } - return TRUE; - case GDM_INTERRUPT_SELECT_USER: - gdm_verify_select_user (&msg[2]); - break; - case GDM_INTERRUPT_CANCEL: - do_cancel = TRUE; - break; - case GDM_INTERRUPT_CUSTOM_CMD: - 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_slave_send (message, TRUE); - g_free (message); - } - return TRUE; - case GDM_INTERRUPT_THEME: - g_free (d->theme_name); - d->theme_name = NULL; - if ( ! ve_string_empty (&msg[2])) - d->theme_name = g_strdup (&msg[2]); - gdm_slave_send_string (GDM_SOP_CHOSEN_THEME, &msg[2]); - return TRUE; - case GDM_INTERRUPT_SELECT_LANG: - if (msg + 2) { - const char *locale; - const char *gdm_system_locale; - - locale = (gchar*)(msg + 3); - gdm_system_locale = setlocale (LC_CTYPE, NULL); - - greeter->priv->always_restart_greeter = (gboolean)(*(msg + 2)); - ve_clearenv (); - if (!strcmp (locale, DEFAULT_LANGUAGE)) { - locale = gdm_system_locale; - } - g_setenv ("GDM_LANG", locale, TRUE); - g_setenv ("LANG", locale, TRUE); - g_unsetenv ("LC_ALL"); - g_unsetenv ("LC_MESSAGES"); - setlocale (LC_ALL, ""); - setlocale (LC_MESSAGES, ""); - gdm_saveenv (); - - do_restart_greeter = TRUE; - } - break; - default: - break; - } -#endif - /* this was an interruption, if it wasn't - * handled then the user will just get an error as if he - * entered an invalid login or passward. Seriously BEL - * cannot be part of a login/password really */ - greeter->priv->interrupted = TRUE; - return TRUE; - } - return FALSE; -} - -static char * -gdm_slave_greeter_ctl (GdmGreeter *greeter, - char cmd, - const char *str) -{ - char *buf = NULL; - int c; - - if ( ! ve_string_empty (str)) { - gdm_fdprintf (greeter->priv->greeter_fd_out, "%c%c%s\n", STX, cmd, str); - } else { - gdm_fdprintf (greeter->priv->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 (); -#endif - - do { - g_free (buf); - buf = NULL; - /* Skip random junk that might have accumulated */ - do { - c = gdm_fdgetc (greeter->priv->greeter_fd_in); - } while (c != EOF && c != STX); - - if (c == EOF || - (buf = gdm_fdgets (greeter->priv->greeter_fd_in)) == NULL) { - greeter->priv->interrupted = TRUE; - /* things don't seem well with the greeter, it probably died */ - return NULL; - } - } while (check_for_interruption (greeter, buf) && ! greeter->priv->interrupted); - - if ( ! ve_string_empty (buf)) { - return buf; - } else { - g_free (buf); - return NULL; - } -} - -static void -gdm_slave_greeter_ctl_no_ret (GdmGreeter *greeter, - char cmd, - const char *str) -{ - g_free (gdm_slave_greeter_ctl (greeter, cmd, str)); -} - -/** - * check_user_file - * check_global_file - * is_in_trusted_pic_dir - * get_facefile_from_gnome2_dir_config - * path_is_local - * gdm_daemon_config_get_facefile_from_home - * gdm_daemon_config_get_facefile_from_global - * - * These functions are used for accessing the user's face image from their - * home directory. - */ -static gboolean -check_user_file (const char *path, - guint uid) -{ - char *dir; - char *file; - gboolean is_ok; - - if (path == NULL) - return FALSE; - - if (g_access (path, R_OK) != 0) - return FALSE; - - dir = g_path_get_dirname (path); - file = g_path_get_basename (path); - - is_ok = gdm_file_check ("run_pictures", - uid, - dir, - file, - TRUE, TRUE, - 0, - 0); - g_free (dir); - g_free (file); - - return is_ok; -} - -static gboolean -check_global_file (const char *path, - guint uid) -{ - if (path == NULL) - return FALSE; - - if (g_access (path, R_OK) != 0) - return FALSE; - - return TRUE; -} - -/* If path starts with a "trusted" directory, don't sanity check things */ -/* This is really somewhat "outdated" as we now really want things in - * the picture dir or in ~/.gnome2/photo */ -static gboolean -is_in_trusted_pic_dir (const char *path) -{ - /* our own pixmap dir is trusted */ - if (strncmp (path, PIXMAPDIR, sizeof (PIXMAPDIR)) == 0) - return TRUE; - - return FALSE; -} - -static gchar * -get_facefile_from_gnome2_dir_config (const char *homedir, - guint uid) -{ - char *picfile = NULL; - char *cfgdir; - - /* Sanity check on ~user/.gnome2/gdm */ - cfgdir = g_build_filename (homedir, ".gnome2", "gdm", NULL); - if (G_LIKELY (check_user_file (cfgdir, uid))) { - GKeyFile *cfg; - char *cfgfile; - - cfgfile = g_build_filename (homedir, ".gnome2", "gdm", NULL); - cfg = g_key_file_new (); - g_key_file_load_from_file (cfg, cfgfile, 0, NULL); - g_free (cfgfile); - - if (cfg != NULL) { - picfile = g_key_file_get_string (cfg, "face", "picture", NULL); - g_key_file_free (cfg); - } - - /* must exist and be absolute (note that this check - * catches empty strings)*/ - /* Note that these days we just set ~/.face */ - if G_UNLIKELY (picfile != NULL && - (picfile[0] != '/' || - /* this catches readability by user */ - g_access (picfile, R_OK) != 0)) { - g_free (picfile); - picfile = NULL; - } - - if (picfile != NULL) { - char buf[PATH_MAX]; - if (realpath (picfile, buf) == NULL) { - g_free (picfile); - picfile = NULL; - } else { - g_free (picfile); - picfile = g_strdup (buf); - } - } - - if G_UNLIKELY (picfile != NULL) { - if (! is_in_trusted_pic_dir (picfile)) { - /* if not in trusted dir, check it out */ - - /* Note that strict permissions checking is done - * on this file. Even if it may not even be owned by the - * user. This setting should ONLY point to pics in trusted - * dirs. */ - if (! check_user_file (picfile, uid)) { - g_free (picfile); - picfile = NULL; - } - } - } - } - g_free (cfgdir); - - return picfile; -} - -static GHashTable *fstype_hash = NULL; -extern char *filesystem_type (char *path, char *relpath, struct stat *statp); - -static gboolean -path_is_local (const char *path) -{ - gpointer local = NULL; - - if (path == NULL) - return FALSE; - - if (fstype_hash == NULL) - fstype_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - else - local = g_hash_table_lookup (fstype_hash, path); - - if (local == NULL) { - struct stat statbuf; - - if (g_stat (path, &statbuf) == 0) { - char *type = filesystem_type ((char *)path, (char *)path, &statbuf); - gboolean is_local = ((strcmp (ve_sure_string (type), "nfs") != 0) && - (strcmp (ve_sure_string (type), "afs") != 0) && - (strcmp (ve_sure_string (type), "autofs") != 0) && - (strcmp (ve_sure_string (type), "unknown") != 0) && - (strcmp (ve_sure_string (type), "ncpfs") != 0)); - local = GINT_TO_POINTER (is_local ? 1 : -1); - g_hash_table_insert (fstype_hash, g_strdup (path), local); - } - } - - return GPOINTER_TO_INT (local) > 0; -} - -static char * -gdm_daemon_config_get_facefile_from_home (const char *homedir, - guint uid) -{ - char *picfile = NULL; - char *path; - gboolean is_local; - - /* special case: look at parent of home to detect autofs - this is so we don't try to trigger an automount */ - path = g_path_get_dirname (homedir); - is_local = path_is_local (path); - g_free (path); - - /* now check that home dir itself is local */ - if (is_local) { - is_local = path_is_local (homedir); - } - - /* Only look at local home directories so we don't try to - read from remote (e.g. NFS) volumes */ - if (! is_local) - return NULL; - - picfile = g_build_filename (homedir, ".face", NULL); - - if (check_user_file (picfile, uid)) - return picfile; - else { - g_free (picfile); - picfile = NULL; - } - - picfile = g_build_filename (homedir, ".face.icon", NULL); - - if (check_user_file (picfile, uid)) - return picfile; - else { - g_free (picfile); - picfile = NULL; - } - - picfile = get_facefile_from_gnome2_dir_config (homedir, uid); - if (check_user_file (picfile, uid)) - return picfile; - else { - g_free (picfile); - picfile = NULL; - } - - /* Nothing found yet, try the old locations */ - - picfile = g_build_filename (homedir, ".gnome2", "photo", NULL); - if (check_user_file (picfile, uid)) - return picfile; - else { - g_free (picfile); - picfile = NULL; - } - - picfile = g_build_filename (homedir, ".gnome", "photo", NULL); - if (check_user_file (picfile, uid)) - return picfile; - else { - g_free (picfile); - picfile = NULL; - } - - return NULL; -} - -static char * -gdm_daemon_config_get_facefile_from_global (const char *username, - guint uid) -{ -#if 0 - char *picfile = NULL; - const char *facedir; - - facedir = gdm_daemon_config_get_value_string (GDM_KEY_GLOBAL_FACE_DIR); - - /* Try the global face directory */ - - picfile = g_build_filename (facedir, username, NULL); - - if (check_global_file (picfile, uid)) - return picfile; - - g_free (picfile); - picfile = gdm_make_filename (facedir, username, ".png"); - - if (check_global_file (picfile, uid)) - return picfile; - - g_free (picfile); -#endif - return NULL; -} - -static void -gdm_slave_quick_exit (GdmGreeter *greeter) -{ - /* FIXME */ - _exit (1); -} - -/* This is VERY evil! */ -static void -run_pictures (GdmGreeter *greeter) -{ - char *response; - int max_write; - char buf[1024]; - size_t bytes; - struct passwd *pwent; - char *picfile; - FILE *fp; - - response = NULL; - for (;;) { - struct stat s; - char *tmp, *ret; - int i, r; - - g_free (response); - response = gdm_slave_greeter_ctl (greeter, GDM_NEEDPIC, ""); - if (ve_string_empty (response)) { - g_free (response); - return; - } - - pwent = getpwnam (response); - if G_UNLIKELY (pwent == NULL) { - gdm_slave_greeter_ctl_no_ret (greeter, GDM_READPIC, ""); - continue; - } - - picfile = NULL; - - NEVER_FAILS_seteuid (0); - if G_UNLIKELY (setegid (pwent->pw_gid) != 0 || - seteuid (pwent->pw_uid) != 0) { - gdm_slave_greeter_ctl_no_ret (greeter, GDM_READPIC, ""); - continue; - } - - picfile = gdm_daemon_config_get_facefile_from_home (pwent->pw_dir, pwent->pw_uid); - - if (! picfile) - picfile = gdm_daemon_config_get_facefile_from_global (pwent->pw_name, pwent->pw_uid); - - if (! picfile) { - gdm_slave_greeter_ctl_no_ret (greeter, GDM_READPIC, ""); - continue; - } - - VE_IGNORE_EINTR (r = g_stat (picfile, &s)); - if G_UNLIKELY (r < 0 || s.st_size > greeter->priv->user_max_filesize) { - gdm_slave_greeter_ctl_no_ret (greeter, GDM_READPIC, ""); - continue; - } - - VE_IGNORE_EINTR (fp = fopen (picfile, "r")); - g_free (picfile); - if G_UNLIKELY (fp == NULL) { - gdm_slave_greeter_ctl_no_ret (greeter, GDM_READPIC, ""); - continue; - } - - tmp = g_strdup_printf ("buffer:%d", (int)s.st_size); - ret = gdm_slave_greeter_ctl (greeter, GDM_READPIC, tmp); - g_free (tmp); - - if G_UNLIKELY (ret == NULL || strcmp (ret, "OK") != 0) { - VE_IGNORE_EINTR (fclose (fp)); - g_free (ret); - continue; - } - g_free (ret); - - gdm_fdprintf (greeter->priv->greeter_fd_out, "%c", STX); - -#ifdef PIPE_BUF - max_write = MIN (PIPE_BUF, sizeof (buf)); -#else - /* apparently Hurd doesn't have PIPE_BUF */ - max_write = fpathconf (greeter->priv->greeter_fd_out, _PC_PIPE_BUF); - /* could return -1 if no limit */ - if (max_write > 0) - max_write = MIN (max_write, sizeof (buf)); - else - max_write = sizeof (buf); -#endif - - i = 0; - while (i < s.st_size) { - int written; - - VE_IGNORE_EINTR (bytes = fread (buf, sizeof (char), - max_write, fp)); - - if (bytes <= 0) - break; - - if G_UNLIKELY (i + bytes > s.st_size) - bytes = s.st_size - i; - - /* write until we succeed in writing something */ - VE_IGNORE_EINTR (written = write (greeter->priv->greeter_fd_out, buf, bytes)); - if G_UNLIKELY (written < 0 && - (errno == EPIPE || errno == EBADF)) { - /* something very, very bad has happened */ - - gdm_slave_quick_exit (greeter); - } - - if G_UNLIKELY (written < 0) - written = 0; - - /* write until we succeed in writing everything */ - while (written < bytes) { - int n; - VE_IGNORE_EINTR (n = write (greeter->priv->greeter_fd_out, &buf[written], bytes-written)); - if G_UNLIKELY (n < 0 && - (errno == EPIPE || errno == EBADF)) { - - /* something very, very bad has happened */ - gdm_slave_quick_exit (greeter); - - } else if G_LIKELY (n > 0) { - written += n; - } - } - - /* we have written bytes bytes if it likes it or not */ - i += bytes; - } - - VE_IGNORE_EINTR (fclose (fp)); - - /* eek, this "could" happen, so just send some garbage */ - while G_UNLIKELY (i < s.st_size) { - bytes = MIN (sizeof (buf), s.st_size - i); - errno = 0; - bytes = write (greeter->priv->greeter_fd_out, buf, bytes); - if G_UNLIKELY (bytes < 0 && (errno == EPIPE || errno == EBADF)) { - - /* something very, very bad has happened */ - gdm_slave_quick_exit (greeter); - - } - if (bytes > 0) - i += bytes; - } - - gdm_slave_greeter_ctl_no_ret (greeter, GDM_READPIC, "done"); - - } - - g_free (response); /* not reached */ -} - -static void -greeter_child_watch (GPid pid, - int status, - GdmGreeter *greeter) -{ - g_debug ("child (pid:%d) done (%s:%d)", - (int) pid, - WIFEXITED (status) ? "status" - : WIFSIGNALED (status) ? "signal" - : "unknown", - WIFEXITED (status) ? WEXITSTATUS (status) - : WIFSIGNALED (status) ? WTERMSIG (status) - : -1); - - g_spawn_close_pid (greeter->priv->pid); - greeter->priv->pid = -1; -} - -static gboolean -gdm_greeter_spawn (GdmGreeter *greeter) -{ - gchar **argv; - GError *error; - GPtrArray *env; - gboolean ret; - - ret = FALSE; - - /* Open a pipe for greeter communications */ - if (pipe (greeter->priv->pipe1) < 0) { - g_warning ("Can't init pipe to gdmgreeter"); - exit (1); - } - - if (pipe (greeter->priv->pipe2) < 0) { - VE_IGNORE_EINTR (close (greeter->priv->pipe1[0])); - VE_IGNORE_EINTR (close (greeter->priv->pipe1[1])); - g_warning ("Can't init pipe to gdmgreeter"); - exit (1); - } - - create_temp_auth_file (greeter); - - g_debug ("Running greeter process: %s", greeter->priv->command); - - argv = NULL; - if (! g_shell_parse_argv (greeter->priv->command, NULL, &argv, &error)) { - g_warning ("Could not parse command: %s", error->message); - g_error_free (error); - goto out; - } - - env = get_greeter_environment (greeter); - - error = NULL; - ret = g_spawn_async_with_pipes (NULL, - argv, - (char **)env->pdata, - G_SPAWN_SEARCH_PATH | G_SPAWN_LEAVE_DESCRIPTORS_OPEN | G_SPAWN_DO_NOT_REAP_CHILD, - (GSpawnChildSetupFunc)greeter_child_setup, - greeter, - &greeter->priv->pid, - NULL, - NULL, - NULL, - &error); - - g_ptr_array_foreach (env, (GFunc)g_free, NULL); - g_ptr_array_free (env, TRUE); - - if (! ret) { - g_warning ("Could not start command '%s': %s", - greeter->priv->command, - error->message); - g_error_free (error); - } else { - - whack_greeter_fds (greeter); - - greeter->priv->greeter_fd_out = greeter->priv->pipe1[1]; - greeter->priv->greeter_fd_in = greeter->priv->pipe2[0]; - - g_debug ("gdm_slave_greeter: Greeter on pid %d", (int)greeter->priv->pid); - } - - greeter->priv->child_watch_id = g_child_watch_add (greeter->priv->pid, - (GChildWatchFunc)greeter_child_watch, - greeter); - - g_strfreev (argv); - out: - - return ret; -} - -/** - * gdm_greeter_start: - * @disp: Pointer to a GdmDisplay structure - * - * Starts a local X greeter. Handles retries and fatal errors properly. - */ - -gboolean -gdm_greeter_start (GdmGreeter *greeter) -{ - gboolean res; - const char *gdmlang; - - res = gdm_greeter_spawn (greeter); - - if (res) { - run_pictures (greeter); /* Append pictures to greeter if browsing is on */ - - if (greeter->priv->always_restart_greeter) - gdm_slave_greeter_ctl_no_ret (greeter, GDM_ALWAYS_RESTART, "Y"); - else - gdm_slave_greeter_ctl_no_ret (greeter, GDM_ALWAYS_RESTART, "N"); - - gdmlang = g_getenv ("GDM_LANG"); - if (gdmlang) - gdm_slave_greeter_ctl_no_ret (greeter, GDM_SETLANG, gdmlang); - } - - - return res; -} - -static int -signal_pid (int pid, - int signal) -{ - int status = -1; - - /* perhaps block sigchld */ - - status = kill (pid, signal); - - if (status < 0) { - if (errno == ESRCH) { - g_warning ("Child process %lu was already dead.", - (unsigned long) pid); - } else { - g_warning ("Couldn't kill child process %lu: %s", - (unsigned long) pid, - g_strerror (errno)); - } - } - - /* perhaps unblock sigchld */ - - return status; -} - -static int -wait_on_child (int pid) -{ - int status; - - wait_again: - if (waitpid (pid, &status, 0) < 0) { - if (errno == EINTR) { - goto wait_again; - } else if (errno == ECHILD) { - ; /* do nothing, child already reaped */ - } else { - g_debug ("waitpid () should not fail"); - } - } - - return status; -} - -static void -greeter_died (GdmGreeter *greeter) -{ - int exit_status; - - g_debug ("Waiting on process %d", greeter->priv->pid); - exit_status = wait_on_child (greeter->priv->pid); - - if (WIFEXITED (exit_status) && (WEXITSTATUS (exit_status) != 0)) { - g_debug ("Wait on child process failed"); - } else { - /* exited normally */ - } - - g_spawn_close_pid (greeter->priv->pid); - greeter->priv->pid = -1; - - g_debug ("Greeter died"); -} - -gboolean -gdm_greeter_stop (GdmGreeter *greeter) -{ - - if (greeter->priv->pid <= 1) { - return TRUE; - } - - /* remove watch source before we can wait on child */ - if (greeter->priv->child_watch_id > 0) { - g_source_remove (greeter->priv->child_watch_id); - greeter->priv->child_watch_id = 0; - } - - g_debug ("Stopping greeter"); - - signal_pid (greeter->priv->pid, SIGTERM); - greeter_died (greeter); - - return TRUE; -} - - -static void -_gdm_greeter_set_x11_display_name (GdmGreeter *greeter, - const char *name) -{ - g_free (greeter->priv->x11_display_name); - greeter->priv->x11_display_name = g_strdup (name); -} - -static void -_gdm_greeter_set_x11_authority_file (GdmGreeter *greeter, - const char *file) -{ - g_free (greeter->priv->x11_authority_file); - greeter->priv->x11_authority_file = g_strdup (file); -} - -static void -_gdm_greeter_set_user_name (GdmGreeter *greeter, - const char *name) -{ - g_free (greeter->priv->user_name); - greeter->priv->user_name = g_strdup (name); -} - -static void -_gdm_greeter_set_group_name (GdmGreeter *greeter, - const char *name) -{ - g_free (greeter->priv->group_name); - greeter->priv->group_name = g_strdup (name); -} - -static void -gdm_greeter_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GdmGreeter *self; - - self = GDM_GREETER (object); - - switch (prop_id) { - case PROP_X11_DISPLAY_NAME: - _gdm_greeter_set_x11_display_name (self, g_value_get_string (value)); - break; - case PROP_X11_AUTHORITY_FILE: - _gdm_greeter_set_x11_authority_file (self, g_value_get_string (value)); - break; - case PROP_USER_NAME: - _gdm_greeter_set_user_name (self, g_value_get_string (value)); - break; - case PROP_GROUP_NAME: - _gdm_greeter_set_group_name (self, g_value_get_string (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gdm_greeter_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GdmGreeter *self; - - self = GDM_GREETER (object); - - switch (prop_id) { - case PROP_X11_DISPLAY_NAME: - g_value_set_string (value, self->priv->x11_display_name); - break; - case PROP_X11_AUTHORITY_FILE: - g_value_set_string (value, self->priv->x11_authority_file); - break; - case PROP_USER_NAME: - g_value_set_string (value, self->priv->user_name); - break; - case PROP_GROUP_NAME: - g_value_set_string (value, self->priv->group_name); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static GObject * -gdm_greeter_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) -{ - GdmGreeter *greeter; - GdmGreeterClass *klass; - - klass = GDM_GREETER_CLASS (g_type_class_peek (GDM_TYPE_GREETER)); - - greeter = GDM_GREETER (G_OBJECT_CLASS (gdm_greeter_parent_class)->constructor (type, - n_construct_properties, - construct_properties)); - - return G_OBJECT (greeter); -} - -static void -gdm_greeter_class_init (GdmGreeterClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->get_property = gdm_greeter_get_property; - object_class->set_property = gdm_greeter_set_property; - object_class->constructor = gdm_greeter_constructor; - object_class->finalize = gdm_greeter_finalize; - - g_type_class_add_private (klass, sizeof (GdmGreeterPrivate)); - - g_object_class_install_property (object_class, - PROP_X11_DISPLAY_NAME, - g_param_spec_string ("x11-display-name", - "name", - "name", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, - PROP_X11_AUTHORITY_FILE, - g_param_spec_string ("x11-authority-file", - "authority file", - "authority file", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - g_object_class_install_property (object_class, - PROP_USER_NAME, - g_param_spec_string ("user-name", - "user name", - "user name", - "gdm", - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - g_object_class_install_property (object_class, - PROP_GROUP_NAME, - g_param_spec_string ("group-name", - "group name", - "group name", - "gdm", - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); -} - -static void -gdm_greeter_init (GdmGreeter *greeter) -{ - - greeter->priv = GDM_GREETER_GET_PRIVATE (greeter); - - greeter->priv->pid = -1; - - greeter->priv->command = g_strdup (LIBEXECDIR "/gdmgreeter"); - greeter->priv->user_max_filesize = 65536; -} - -static void -gdm_greeter_finalize (GObject *object) -{ - GdmGreeter *greeter; - - g_return_if_fail (object != NULL); - g_return_if_fail (GDM_IS_GREETER (object)); - - greeter = GDM_GREETER (object); - - g_return_if_fail (greeter->priv != NULL); - - gdm_greeter_stop (greeter); - - G_OBJECT_CLASS (gdm_greeter_parent_class)->finalize (object); -} - -GdmGreeter * -gdm_greeter_new (const char *display_name) -{ - GObject *object; - - object = g_object_new (GDM_TYPE_GREETER, - "x11-display-name", display_name, - NULL); - - return GDM_GREETER (object); -} diff --git a/daemon/gdm-greeter.h b/daemon/gdm-greeter.h deleted file mode 100644 index 8a000342..00000000 --- a/daemon/gdm-greeter.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- 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. - * - */ - - -#ifndef __GDM_GREETER_H -#define __GDM_GREETER_H - -#include <glib-object.h> - -G_BEGIN_DECLS - -#define GDM_TYPE_GREETER (gdm_greeter_get_type ()) -#define GDM_GREETER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_GREETER, GdmGreeter)) -#define GDM_GREETER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_GREETER, GdmGreeterClass)) -#define GDM_IS_GREETER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_GREETER)) -#define GDM_IS_GREETER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_GREETER)) -#define GDM_GREETER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_GREETER, GdmGreeterClass)) - -typedef struct GdmGreeterPrivate GdmGreeterPrivate; - -typedef struct -{ - GObject parent; - GdmGreeterPrivate *priv; -} GdmGreeter; - -typedef struct -{ - GObjectClass parent_class; - -} GdmGreeterClass; - -GType gdm_greeter_get_type (void); -GdmGreeter * gdm_greeter_new (const char *display_id); -gboolean gdm_greeter_start (GdmGreeter *greeter); -gboolean gdm_greeter_stop (GdmGreeter *greeter); - -G_END_DECLS - -#endif /* __GDM_GREETER_H */ diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c index f1af3a46..472e3fe8 100644 --- a/daemon/gdm-session.c +++ b/daemon/gdm-session.c @@ -630,7 +630,8 @@ gdm_session_class_install_signals (GdmSessionClass *session_class) session_class->info = NULL; gdm_session_signals[PROBLEM] = - g_signal_new ("problem", G_OBJECT_CLASS_TYPE (object_class), + g_signal_new ("problem", + G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GdmSessionClass, problem), NULL, diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h index 2a272bc9..49510d1e 100644 --- a/daemon/gdm-session.h +++ b/daemon/gdm-session.h @@ -35,8 +35,6 @@ G_BEGIN_DECLS #define GDM_SESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GDM_TYPE_SESSION, GdmSessionClass)) #define GDM_SESSION_ERROR (gdm_session_error_quark ()) -typedef enum _GdmSessionError GdmSessionError; - typedef struct _GdmSessionPrivate GdmSessionPrivate; typedef struct @@ -82,7 +80,7 @@ typedef struct int signal_number); } GdmSessionClass; -enum _GdmSessionError { +typedef enum _GdmSessionError { GDM_SESSION_ERROR_GENERIC = 0, GDM_SESSION_ERROR_WITH_SESSION_COMMAND, GDM_SESSION_ERROR_FORKING, @@ -94,43 +92,43 @@ enum _GdmSessionError { GDM_SESSION_ERROR_OPENING_LOG_FILE, GDM_SESSION_ERROR_OPENING_SESSION, GDM_SESSION_ERROR_GIVING_CREDENTIALS -}; +} GdmSessionError; GType gdm_session_get_type (void); GQuark gdm_session_error_quark (void); GdmSession * gdm_session_new (void) G_GNUC_MALLOC; -gboolean gdm_session_open (GdmSession *session, +gboolean gdm_session_open (GdmSession *session, const char *service_name, const char *hostname, const char *console_name, - int standard_output_fd, - int standard_error_fd, - GError **error); + int standard_output_fd, + int standard_error_fd, + GError **error); gboolean gdm_session_open_for_user (GdmSession *session, const char *service_name, const char *username, const char *hostname, const char *console_name, - int standard_output_fd, - int standard_error_fd, - GError **error); -void gdm_session_start_program (GdmSession *session, + int standard_output_fd, + int standard_error_fd, + GError **error); +void gdm_session_start_program (GdmSession *session, const char * const * args); void gdm_session_set_environment_variable (GdmSession *session, - const char *key, - const char *value); + const char *key, + const char *value); void gdm_session_answer_query (GdmSession *session, - const char *answer); + const char *answer); -char * gdm_session_get_username (GdmSession *session); +char * gdm_session_get_username (GdmSession *session); -void gdm_session_close (GdmSession *session); -gboolean gdm_session_is_running (GdmSession *session); +void gdm_session_close (GdmSession *session); +gboolean gdm_session_is_running (GdmSession *session); G_END_DECLS diff --git a/daemon/gdm-slave.c b/daemon/gdm-slave.c index a9752583..6722ab9b 100644 --- a/daemon/gdm-slave.c +++ b/daemon/gdm-slave.c @@ -49,7 +49,8 @@ #include "gdm-slave-glue.h" #include "gdm-server.h" -#include "gdm-greeter.h" +#include "gdm-session.h" +#include "gdm-greeter-proxy.h" extern char **environ; @@ -89,7 +90,8 @@ struct GdmSlavePrivate GdmServer *server; - GdmGreeter *greeter; + GdmGreeterProxy *greeter; + GdmSession *session; DBusGProxy *display_proxy; DBusGConnection *connection; }; @@ -612,6 +614,133 @@ gdm_slave_exec_script (GdmSlave *slave, } static void +on_session_started (GdmSession *session, + GPid pid, + GdmSlave *slave) +{ + g_debug ("session started on pid %d\n", (int) pid); +} + +static void +on_session_exited (GdmSession *session, + int exit_code, + GdmSlave *slave) +{ + g_debug ("session exited with code %d\n", exit_code); + exit (0); +} + +static void +on_session_died (GdmSession *session, + int signal_number, + GdmSlave *slave) +{ + g_debug ("session died with signal %d, (%s)", + signal_number, + g_strsignal (signal_number)); + exit (1); +} + +static void +on_user_verified (GdmSession *session, + GdmSlave *slave) +{ + char *username; + const char *args[] = { "/usr/bin/gedit", "/tmp/foo.log", NULL }; + + username = gdm_session_get_username (session); + + g_debug ("%s%ssuccessfully authenticated\n", + username ? username : "", + username ? " " : ""); + g_free (username); + + gdm_session_start_program (session, args); +} + +static void +on_user_verification_error (GdmSession *session, + GError *error, + GdmSlave *slave) +{ + char *username; + + username = gdm_session_get_username (session); + + g_debug ("%s%scould not be successfully authenticated: %s\n", + username ? username : "", + username ? " " : "", + error->message); + + g_free (username); +} + +static void +on_info (GdmSession *session, + const char *text, + GdmSlave *slave) +{ + g_debug ("Info: %s", text); + gdm_greeter_proxy_info (slave->priv->greeter, text); +} + +static void +on_problem (GdmSession *session, + const char *text, + GdmSlave *slave) +{ + g_debug ("Problem: %s", text); + gdm_greeter_proxy_problem (slave->priv->greeter, text); +} + +static void +on_info_query (GdmSession *session, + const char *text, + GdmSlave *slave) +{ + + g_debug ("Info query: %s", text); + gdm_greeter_proxy_info_query (slave->priv->greeter, text); +} + +static void +on_secret_info_query (GdmSession *session, + const char *text, + GdmSlave *slave) +{ + g_debug ("Secret info query: %s", text); + gdm_greeter_proxy_secret_info_query (slave->priv->greeter, text); +} + +static void +on_greeter_answer (GdmGreeterProxy *greeter, + const char *text, + GdmSlave *slave) +{ + gdm_session_answer_query (slave->priv->session, text); +} + +static void +on_greeter_start (GdmGreeterProxy *greeter, + GdmSlave *slave) +{ + g_debug ("Greeter started"); + + gdm_session_open (slave->priv->session, + "gdm", + NULL /* hostname */, + "/dev/console", + STDOUT_FILENO, + STDERR_FILENO, + NULL); + + /* If XDMCP stop pinging */ + if ( ! slave->priv->display_is_local) { + alarm (0); + } +} + +static void run_greeter (GdmSlave *slave) { @@ -647,16 +776,66 @@ run_greeter (GdmSlave *slave) GDMCONFDIR"/Init", "gdm"); - slave->priv->greeter = gdm_greeter_new (slave->priv->display_name); + slave->priv->session = gdm_session_new (); + + g_signal_connect (slave->priv->session, + "info", + G_CALLBACK (on_info), + slave); + + g_signal_connect (slave->priv->session, + "problem", + G_CALLBACK (on_problem), + slave); + + g_signal_connect (slave->priv->session, + "info-query", + G_CALLBACK (on_info_query), + slave); + + g_signal_connect (slave->priv->session, + "secret-info-query", + G_CALLBACK (on_secret_info_query), + slave); + + g_signal_connect (slave->priv->session, + "user-verified", + G_CALLBACK (on_user_verified), + slave); + + g_signal_connect (slave->priv->session, + "user-verification-error", + G_CALLBACK (on_user_verification_error), + slave); + + g_signal_connect (slave->priv->session, + "session-started", + G_CALLBACK (on_session_started), + slave); + + g_signal_connect (slave->priv->session, + "session-exited", + G_CALLBACK (on_session_exited), + slave); + + g_signal_connect (slave->priv->session, + "session-died", + G_CALLBACK (on_session_died), + slave); + + slave->priv->greeter = gdm_greeter_proxy_new (slave->priv->display_name); + g_signal_connect (slave->priv->greeter, + "answer", + G_CALLBACK (on_greeter_answer), + slave); + g_signal_connect (slave->priv->greeter, + "started", + G_CALLBACK (on_greeter_start), + slave); g_object_set (slave->priv->greeter, "x11-authority-file", slave->priv->display_x11_authority_file, NULL); - gdm_greeter_start (slave->priv->greeter); - - /* If XDMCP stop pinging */ - if ( ! slave->priv->display_is_local) { - alarm (0); - } + gdm_greeter_proxy_start (slave->priv->greeter); } static void @@ -922,11 +1101,17 @@ gdm_slave_stop (GdmSlave *slave) g_debug ("Stopping slave"); if (slave->priv->greeter != NULL) { - gdm_greeter_stop (slave->priv->greeter); + gdm_greeter_proxy_stop (slave->priv->greeter); g_object_unref (slave->priv->greeter); slave->priv->greeter = NULL; } + if (slave->priv->session != NULL) { + gdm_session_close (slave->priv->session); + g_object_unref (slave->priv->session); + slave->priv->session = NULL; + } + if (slave->priv->server != NULL) { gdm_server_stop (slave->priv->server); g_object_unref (slave->priv->server); @@ -950,7 +1135,7 @@ _gdm_slave_set_display_id (GdmSlave *slave, static void gdm_slave_set_property (GObject *object, - guint prop_id, + guint prop_id, const GValue *value, GParamSpec *pspec) { @@ -970,9 +1155,9 @@ gdm_slave_set_property (GObject *object, static void gdm_slave_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) + guint prop_id, + GValue *value, + GParamSpec *pspec) { GdmSlave *self; diff --git a/daemon/gdm-socket-protocol.h b/daemon/gdm-socket-protocol.h index d1ea3b68..2623c2ff 100644 --- a/daemon/gdm-socket-protocol.h +++ b/daemon/gdm-socket-protocol.h @@ -76,9 +76,6 @@ #define GDM_INTERRUPT_CANCEL 'X' #define GDM_INTERRUPT_SELECT_LANG 'O' -/* List delimiter for config file lists */ -#define GDM_DELIMITER_MODULES ":" -#define GDM_DELIMITER_THEMES "/:" /* diff --git a/daemon/test-session.c b/daemon/test-session.c index 8babaf53..ec807e67 100644 --- a/daemon/test-session.c +++ b/daemon/test-session.c @@ -100,8 +100,8 @@ on_info_query (GdmSession *session, answer[strlen(answer) - 1] = '\0'; if (answer[0] == '\0') { - gdm_session_close (session); - g_main_loop_quit (loop); + gdm_session_close (session); + g_main_loop_quit (loop); } else { gdm_session_answer_query (session, answer); } diff --git a/gui/Makefile.am b/gui/Makefile.am index 3b0ddac9..c4c416c3 100644 --- a/gui/Makefile.am +++ b/gui/Makefile.am @@ -1,6 +1,7 @@ NULL = -SUBDIRS = \ +SUBDIRS = + . \ greeter \ modules \ faces \ @@ -41,15 +42,11 @@ INCLUDES = \ # -DGNOME_DISABLE_DEPRECATED \ # -BUILT_SOURCES = \ - gdm-greeter-glue.h \ +noinst_LIBRARIES = \ + libgdmwm.a \ + libgdmguicommon.a \ $(NULL) -gdm-greeter-glue.h: gdm-greeter.xml Makefile.am - dbus-binding-tool --prefix=gdm_greeter --mode=glib-server --output=gdm-greeter-glue.h gdm-greeter.xml - -noinst_LIBRARIES = libgdmwm.a libgdmcommon.a - libexec_PROGRAMS = \ @GDMCHOOSER@ \ $(NULL) @@ -77,7 +74,7 @@ libgdmwm_a_SOURCES = \ gdmwm.h \ $(NULL) -libgdmcommon_a_SOURCES = \ +libgdmguicommon_a_SOURCES = \ gdm-greeter.c \ gdm-greeter.h \ gdmlanguages.c \ @@ -102,7 +99,7 @@ gdmchooser_LDFLAGS = -export-dynamic gdmchooser_LDADD = \ $(EXTRA_CHOOSER_LIBS) \ libgdmwm.a \ - libgdmcommon.a \ + libgdmguicommon.a \ $(GUIGLADE_LIBS) \ $(INTLLIBS) \ $(GLIB_LIBS) \ @@ -120,7 +117,7 @@ gdmchooser_LDADD = \ $(NULL) gdmXnestchooser_LDADD = \ - libgdmcommon.a \ + libgdmguicommon.a \ $(GUI_LIBS) \ $(INTLLIBS) \ $(GLIB_LIBS) \ @@ -135,7 +132,7 @@ gdmXnestchooser_LDADD = \ $(NULL) gdmflexiserver_LDADD = \ - libgdmcommon.a \ + libgdmguicommon.a \ $(GUI_LIBS) \ $(INTLLIBS) \ $(GLIB_LIBS) \ diff --git a/gui/gdm-greeter.c b/gui/gdm-greeter.c index 65ffff0f..2d8c3772 100644 --- a/gui/gdm-greeter.c +++ b/gui/gdm-greeter.c @@ -32,44 +32,33 @@ #include <glib.h> #include <glib/gi18n.h> #include <glib-object.h> -#define DBUS_API_SUBJECT_TO_CHANGE -#include <dbus/dbus-glib.h> -#include <dbus/dbus-glib-lowlevel.h> #include "gdm-greeter.h" -#include "gdm-greeter-glue.h" - #define GDM_GREETER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_GREETER, GdmGreeterPrivate)) -#define GDM_DBUS_PATH "/org/gnome/DisplayGreeter" -#define GDM_GREETER_DBUS_PATH GDM_DBUS_PATH "/Greeter" -#define GDM_GREETER_DBUS_NAME "org.gnome.DisplayGreeter.Greeter" - struct GdmGreeterPrivate { - DBusGProxy *bus_proxy; - DBusGConnection *connection; + gpointer dummy; }; enum { - PROP_0 + PROP_0, }; enum { - FOO, + QUERY_ANSWER, LAST_SIGNAL }; static guint signals [LAST_SIGNAL] = { 0, }; + static void gdm_greeter_class_init (GdmGreeterClass *klass); static void gdm_greeter_init (GdmGreeter *greeter); static void gdm_greeter_finalize (GObject *object); -static gpointer greeter_object = NULL; - -G_DEFINE_TYPE (GdmGreeter, gdm_greeter, G_TYPE_OBJECT) +G_DEFINE_ABSTRACT_TYPE (GdmGreeter, gdm_greeter, G_TYPE_OBJECT) GQuark gdm_greeter_error_quark (void) @@ -82,12 +71,162 @@ gdm_greeter_error_quark (void) return ret; } +static gboolean +gdm_greeter_real_start (GdmGreeter *greeter) +{ + g_return_val_if_fail (GDM_IS_GREETER (greeter), FALSE); + + return TRUE; +} + +gboolean +gdm_greeter_start (GdmGreeter *greeter) +{ + gboolean ret; + + g_return_val_if_fail (GDM_IS_GREETER (greeter), FALSE); + + g_object_ref (greeter); + ret = GDM_GREETER_GET_CLASS (greeter)->start (greeter); + g_object_unref (greeter); + + return ret; +} + +static gboolean +gdm_greeter_real_stop (GdmGreeter *greeter) +{ + g_return_val_if_fail (GDM_IS_GREETER (greeter), FALSE); + + return TRUE; +} + +gboolean +gdm_greeter_stop (GdmGreeter *greeter) +{ + gboolean ret; + + g_return_val_if_fail (GDM_IS_GREETER (greeter), FALSE); + + g_object_ref (greeter); + ret = GDM_GREETER_GET_CLASS (greeter)->stop (greeter); + g_object_unref (greeter); + + return ret; +} + +static gboolean +gdm_greeter_real_info (GdmGreeter *greeter, + const char *text) +{ + g_return_val_if_fail (GDM_IS_GREETER (greeter), FALSE); + + return TRUE; +} + +gboolean +gdm_greeter_info (GdmGreeter *greeter, + const char *text) +{ + gboolean ret; + + g_return_val_if_fail (GDM_IS_GREETER (greeter), FALSE); + + g_object_ref (greeter); + ret = GDM_GREETER_GET_CLASS (greeter)->info (greeter, text); + g_object_unref (greeter); + + return ret; +} + +static gboolean +gdm_greeter_real_problem (GdmGreeter *greeter, + const char *text) +{ + g_return_val_if_fail (GDM_IS_GREETER (greeter), FALSE); + + return TRUE; +} + +gboolean +gdm_greeter_problem (GdmGreeter *greeter, + const char *text) +{ + gboolean ret; + + g_return_val_if_fail (GDM_IS_GREETER (greeter), FALSE); + + g_object_ref (greeter); + ret = GDM_GREETER_GET_CLASS (greeter)->problem (greeter, text); + g_object_unref (greeter); + + return ret; +} + +static gboolean +gdm_greeter_real_info_query (GdmGreeter *greeter, + const char *text) +{ + g_return_val_if_fail (GDM_IS_GREETER (greeter), FALSE); + + return TRUE; +} + +gboolean +gdm_greeter_info_query (GdmGreeter *greeter, + const char *text) +{ + gboolean ret; + + g_return_val_if_fail (GDM_IS_GREETER (greeter), FALSE); + + g_object_ref (greeter); + ret = GDM_GREETER_GET_CLASS (greeter)->info_query (greeter, text); + g_object_unref (greeter); + + return ret; +} + +static gboolean +gdm_greeter_real_secret_info_query (GdmGreeter *greeter, + const char *text) +{ + g_return_val_if_fail (GDM_IS_GREETER (greeter), FALSE); + + return TRUE; +} + +gboolean +gdm_greeter_secret_info_query (GdmGreeter *greeter, + const char *text) +{ + gboolean ret; + + g_return_val_if_fail (GDM_IS_GREETER (greeter), FALSE); + + g_object_ref (greeter); + ret = GDM_GREETER_GET_CLASS (greeter)->secret_info_query (greeter, text); + g_object_unref (greeter); + + return ret; +} + +gboolean +gdm_greeter_answer_query (GdmGreeter *greeter, + const char *text) +{ + g_return_val_if_fail (GDM_IS_GREETER (greeter), FALSE); + + g_debug ("Answer query: %s", text); + + g_signal_emit (greeter, signals[QUERY_ANSWER], 0, text); +} static void -gdm_greeter_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) +gdm_greeter_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { GdmGreeter *self; @@ -101,10 +240,10 @@ gdm_greeter_set_property (GObject *object, } static void -gdm_greeter_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +gdm_greeter_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { GdmGreeter *self; @@ -124,6 +263,7 @@ gdm_greeter_constructor (GType type, { GdmGreeter *greeter; GdmGreeterClass *klass; + gboolean res; klass = GDM_GREETER_CLASS (g_type_class_peek (GDM_TYPE_GREETER)); @@ -135,18 +275,49 @@ gdm_greeter_constructor (GType type, } static void +gdm_greeter_dispose (GObject *object) +{ + GdmGreeter *greeter; + + greeter = GDM_GREETER (object); + + g_debug ("Disposing greeter"); + gdm_greeter_stop (greeter); + + G_OBJECT_CLASS (gdm_greeter_parent_class)->dispose (object); +} + +static void gdm_greeter_class_init (GdmGreeterClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->get_property = gdm_greeter_get_property; object_class->set_property = gdm_greeter_set_property; - object_class->constructor = gdm_greeter_constructor; + object_class->constructor = gdm_greeter_constructor; + object_class->dispose = gdm_greeter_dispose; object_class->finalize = gdm_greeter_finalize; - g_type_class_add_private (klass, sizeof (GdmGreeterPrivate)); + klass->start = gdm_greeter_real_start; + klass->stop = gdm_greeter_real_stop; + klass->info = gdm_greeter_real_info; + klass->problem = gdm_greeter_real_problem; + klass->info_query = gdm_greeter_real_info_query; + klass->secret_info_query = gdm_greeter_real_secret_info_query; + + + signals [QUERY_ANSWER] = + g_signal_new ("query-answer", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GdmGreeterClass, query_answer), + NULL, + NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, + 1, G_TYPE_STRING); - dbus_g_object_type_install_info (GDM_TYPE_GREETER, &dbus_glib_gdm_greeter_object_info); + g_type_class_add_private (klass, sizeof (GdmGreeterPrivate)); } static void @@ -169,20 +340,5 @@ gdm_greeter_finalize (GObject *object) g_return_if_fail (greeter->priv != NULL); - G_OBJECT_CLASS (gdm_greeter_parent_class)->finalize (object); } - -GdmGreeter * -gdm_greeter_new (void) -{ - if (greeter_object != NULL) { - g_object_ref (greeter_object); - } else { - greeter_object = g_object_new (GDM_TYPE_GREETER, NULL); - g_object_add_weak_pointer (greeter_object, - (gpointer *) &greeter_object); - } - - return GDM_GREETER (greeter_object); -} diff --git a/gui/gdm-greeter.h b/gui/gdm-greeter.h index 1019770d..59b20e5c 100644 --- a/gui/gdm-greeter.h +++ b/gui/gdm-greeter.h @@ -45,6 +45,22 @@ typedef struct { GObjectClass parent_class; + /* signals */ + void (* query_answer) (GdmGreeter *greeter, + const char *text); + /* methods */ + gboolean (*start) (GdmGreeter *greeter); + gboolean (*stop) (GdmGreeter *greeter); + + gboolean (*info_query) (GdmGreeter *greeter, + const char *text); + gboolean (*secret_info_query) (GdmGreeter *greeter, + const char *text); + gboolean (*info) (GdmGreeter *greeter, + const char *text); + gboolean (*problem) (GdmGreeter *greeter, + const char *text); + } GdmGreeterClass; typedef enum @@ -57,7 +73,20 @@ typedef enum GQuark gdm_greeter_error_quark (void); GType gdm_greeter_get_type (void); -GdmGreeter * gdm_greeter_new (void); +gboolean gdm_greeter_start (GdmGreeter *greeter); +gboolean gdm_greeter_stop (GdmGreeter *greeter); + +gboolean gdm_greeter_answer_query (GdmGreeter *greeter, + const char *text); + +gboolean gdm_greeter_info_query (GdmGreeter *greeter, + const char *text); +gboolean gdm_greeter_secret_info_query (GdmGreeter *greeter, + const char *text); +gboolean gdm_greeter_info (GdmGreeter *greeter, + const char *text); +gboolean gdm_greeter_problem (GdmGreeter *greeter, + const char *text); G_END_DECLS diff --git a/gui/gdm-greeter.xml b/gui/gdm-greeter.xml deleted file mode 100644 index c1a63100..00000000 --- a/gui/gdm-greeter.xml +++ /dev/null @@ -1,5 +0,0 @@ -<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> -<node> - <interface name="org.gnome.DisplayManager.Greeter"> - </interface> -</node> diff --git a/gui/greeter/Makefile.am b/gui/greeter/Makefile.am index 938362fc..3a072cc7 100644 --- a/gui/greeter/Makefile.am +++ b/gui/greeter/Makefile.am @@ -17,6 +17,7 @@ INCLUDES = \ -DSBINDIR=\""$(sbindir)"\" \ -DPIXMAPDIR=\""$(pixmapdir)"\" \ $(GUI_CFLAGS) \ + $(DBUS_CFLAGS) \ $(PANGO_CFLAGS) \ $(PANGOFT_CFLAGS) \ $(GREETER_CFLAGS) @@ -44,6 +45,8 @@ gdmthemetester: $(srcdir)/gdmthemetester.in gdmgreeter_SOURCES = \ greeter.c \ greeter.h \ + gdm-themed-greeter.c \ + gdm-themed-greeter.h \ greeter_canvas_text.c \ greeter_canvas_text.h \ greeter_canvas_item.c \ @@ -78,9 +81,10 @@ gdmgreeter_LDADD = \ $(EXTRA_GREETER_LIBS) \ -L$(top_builddir)/gui \ -lgdmwm \ - -lgdmcommon \ + -lgdmguicommon \ $(top_builddir)/common/libgdmcommon.a \ $(GLIB_LIBS) \ + $(DBUS_LIBS) \ $(GOBJECT_LIBS) \ $(PANGO_LIBS) \ $(PANGOFT_LIBS) \ diff --git a/gui/greeter/gdm-themed-greeter.c b/gui/greeter/gdm-themed-greeter.c new file mode 100644 index 00000000..5d44b22d --- /dev/null +++ b/gui/greeter/gdm-themed-greeter.c @@ -0,0 +1,1087 @@ +/* -*- 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. + * + */ + +#include "config.h" + +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <unistd.h> +#include <string.h> +#include <signal.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/socket.h> + +#include <glib.h> +#include <glib/gi18n.h> +#include <glib-object.h> +#include <gdk/gdkkeysyms.h> +#include <gtk/gtk.h> + +#include "gdm-greeter.h" +#include "gdm-themed-greeter.h" +#include "gdm-common.h" +#include "gdm-settings-client.h" +#include "gdm-settings-keys.h" + +#include <libgnomecanvas/libgnomecanvas.h> + +#if HAVE_PAM +#include <security/pam_appl.h> +#define PW_ENTRY_SIZE PAM_MAX_RESP_SIZE +#else +#define PW_ENTRY_SIZE GDM_MAX_PASS +#endif + + +#include "gdm.h" +#include "gdmwm.h" +#include "gdmcommon.h" +#include "gdmsession.h" +#include "gdmlanguages.h" +#include "greeter.h" +#include "greeter_configuration.h" +#include "greeter_parser.h" +#include "greeter_geometry.h" +#include "greeter_item_clock.h" +#include "greeter_item_pam.h" +#include "greeter_item_ulist.h" +#include "greeter_item_customlist.h" +#include "greeter_item_capslock.h" +#include "greeter_item_timed.h" +#include "greeter_events.h" +#include "greeter_session.h" +#include "greeter_system.h" + +#define GDM_THEMED_GREETER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_THEMED_GREETER, GdmThemedGreeterPrivate)) + +/* FIXME: hack */ +extern gboolean session_dir_whacked_out; +extern gboolean require_quarter; +extern gint gdm_timed_delay; +extern GtkButton *gtk_ok_button; +extern GtkButton *gtk_start_again_button; + +gboolean greeter_probably_login_prompt = FALSE; +static gboolean first_prompt = TRUE; + +static gboolean ignore_buttons = FALSE; + +gboolean GdmHaltFound = FALSE; +gboolean GdmRebootFound = FALSE; +gboolean *GdmCustomCmdsFound = FALSE; +gboolean GdmAnyCustomCmdsFound = FALSE; +gboolean GdmSuspendFound = FALSE; +gboolean GdmConfiguratorFound = FALSE; +GreeterItemInfo *welcome_string_info; +GreeterItemInfo *root; +GtkWidget *window = NULL; +GtkWidget *canvas = NULL; + +enum { + RESPONSE_RESTART, + RESPONSE_REBOOT, + RESPONSE_CLOSE +}; + +struct GdmThemedGreeterPrivate +{ +}; + +enum { + PROP_0, +}; + +static void gdm_themed_greeter_class_init (GdmThemedGreeterClass *klass); +static void gdm_themed_greeter_init (GdmThemedGreeter *themed_greeter); +static void gdm_themed_greeter_finalize (GObject *object); + +G_DEFINE_TYPE (GdmThemedGreeter, gdm_themed_greeter, GDM_TYPE_GREETER) + +void +greeter_ignore_buttons (gboolean val) +{ + ignore_buttons = val; +} + +static GtkWidget * +hig_dialog_new (GtkWindow *parent, + GtkDialogFlags flags, + GtkMessageType type, + GtkButtonsType buttons, + const gchar *primary_message, + const gchar *secondary_message) +{ + GtkWidget *dialog; + + dialog = gtk_message_dialog_new (GTK_WINDOW (parent), + GTK_DIALOG_DESTROY_WITH_PARENT, + type, + buttons, + "%s", primary_message); + + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + "%s", secondary_message); + + gtk_window_set_title (GTK_WINDOW (dialog), ""); + gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 14); + + return dialog; +} + +/* If in random theme mode then grab a random theme from those selected */ +static char * +get_random_theme () +{ + char **vec; + char *themes_list; + char *theme; + int size; + int i; + + theme = NULL; + + gdm_settings_client_get_string (GDM_KEY_GRAPHICAL_THEMES, &themes_list); + + if (ve_string_empty (themes_list)) { + goto out; + } + + vec = g_strsplit (themes_list, GDM_DELIMITER_THEMES, -1); + if (vec == NULL) { + goto out; + } + + /* Get Number of elements in vector */ + for (size = 0; vec[size] != NULL; size++) {} + + /* Get Random Theme from list */ + srand (time (NULL)); + i = rand () % size; + theme = g_strdup (vec[i]); + g_strfreev (vec); + + out: + g_free (themes_list); + + return theme; +} + +/* + * The buttons with these handlers never appear in the F10 menu, + * so they can make use of callback data. + */ +static void +greeter_ok_handler (GreeterItemInfo *info, + gpointer user_data) +{ + if (ignore_buttons == FALSE) { + GreeterItemInfo *entry_info = greeter_lookup_id ("user-pw-entry"); + if (entry_info && entry_info->item && + GNOME_IS_CANVAS_WIDGET (entry_info->item) && + GTK_IS_ENTRY (GNOME_CANVAS_WIDGET (entry_info->item)->widget)) + { + GtkWidget *entry; + entry = GNOME_CANVAS_WIDGET (entry_info->item)->widget; + greeter_ignore_buttons (TRUE); + greeter_item_pam_login (GTK_ENTRY (entry), entry_info); + } + } +} + +static void +greeter_cancel_handler (GreeterItemInfo *info, + gpointer user_data) +{ + if (ignore_buttons == FALSE) { + greeter_item_ulist_unset_selected_user (); + greeter_item_ulist_disable (); + greeter_ignore_buttons (TRUE); +#if 0 + printf ("%c%c%c\n", STX, BEL, GDM_INTERRUPT_CANCEL); + fflush (stdout); +#endif + + } +} + +static void +greeter_language_handler (GreeterItemInfo *info, + gpointer user_data) +{ + gdm_lang_handler (user_data); +} + +static void +greeter_setup_items (GdmThemedGreeter *greeter) +{ + greeter_item_clock_setup (); + greeter_item_pam_setup (GDM_GREETER (greeter)); + +#if 0 + /* This will query the daemon for pictures through stdin/stdout! */ + greeter_item_ulist_setup (); +#endif + + greeter_item_capslock_setup (window); + greeter_item_timed_setup (); + greeter_item_register_action_callback ("ok_button", + greeter_ok_handler, + (gpointer) window); + greeter_item_register_action_callback ("cancel_button", + greeter_cancel_handler, + (gpointer) window); + greeter_item_register_action_callback ("language_button", + greeter_language_handler, + NULL); + greeter_item_register_action_callback ("disconnect_button", + (ActionFunc)gtk_main_quit, + NULL); + greeter_item_system_setup (); + greeter_item_session_setup (); + + /* Setup the custom widgets */ + greeter_item_customlist_setup (); +} + +static void +gdm_set_welcomemsg (GdmThemedGreeter *greeter) +{ + char *welcomemsg = gdm_common_get_welcomemsg (); + + if (welcome_string_info->data.text.orig_text != NULL) + g_free (welcome_string_info->data.text.orig_text); + + welcome_string_info->data.text.orig_text = welcomemsg; + greeter_item_update_text (welcome_string_info); +} + +static void +greeter_done (int sig) +{ + _exit (EXIT_SUCCESS); +} + +static char * +get_theme_greeter (const gchar *file, + const char *fallback) +{ + GKeyFile *config; + gchar *s; + + config = g_key_file_new (); + if (! g_key_file_load_from_file (config, file, 0, NULL)) { + return NULL; + } + + s = g_key_file_get_locale_string (config, "GdmGreeterTheme", "Greeter", NULL, NULL); + + if (s == NULL || s[0] == '\0') { + g_free (s); + s = g_strdup_printf ("%s.xml", fallback); + } + + g_key_file_free (config); + + return s; +} +static char * +get_theme_file (const char *in, char **theme_dir) +{ + char *file, *dir, *info, *s; + + if (in == NULL) + in = "circles"; + + *theme_dir = NULL; + + if (g_path_is_absolute (in)) { + dir = g_strdup (in); + } else { + char *graphical_theme_dir; + + gdm_settings_client_get_string (GDM_KEY_GRAPHICAL_THEME_DIR, &graphical_theme_dir); + dir = g_build_filename (graphical_theme_dir, in, NULL); + g_free (graphical_theme_dir); + } + + *theme_dir = dir; + + info = g_build_filename (dir, "GdmGreeterTheme.desktop", NULL); + if (g_access (info, F_OK) != 0) { + g_free (info); + info = g_build_filename (dir, "GdmGreeterTheme.info", NULL); + } + if (g_access (info, F_OK) != 0) { + char *base = g_path_get_basename (in); + /* just guess the name, we have no info about the theme at + * this point */ + g_free (info); + file = g_strdup_printf ("%s/%s.xml", dir, base); + g_free (base); + return file; + } + + s = get_theme_greeter (info, in); + file = g_build_filename (dir, s, NULL); + + g_free (info); + g_free (s); + + return file; +} + +/* The reaping stuff */ +static time_t last_reap_delay = 0; + +static gboolean +delay_reaping (GSignalInvocationHint *ihint, + guint n_param_values, + const GValue *param_values, + gpointer data) +{ + last_reap_delay = time (NULL); + return TRUE; +} + +static gboolean +reap_flexiserver (gpointer data) +{ + int reapminutes; + + gdm_settings_client_get_int (GDM_KEY_FLEXI_REAP_DELAY_MINUTES, &reapminutes); + + if (reapminutes > 0 && + ((time (NULL) - last_reap_delay) / 60) > reapminutes) { + _exit (DISPLAY_REMANAGE); + } + return TRUE; +} + +static gboolean +gdm_event (GSignalInvocationHint *ihint, + guint n_param_values, + const GValue *param_values, + gpointer data) +{ + GdkEvent *event; + + /* HAAAAAAAAAAAAAAAAACK */ + /* Since the user has not logged in yet and may have left/right + * mouse buttons switched, we just translate every right mouse click + * to a left mouse click */ + if (n_param_values != 2 || + !G_VALUE_HOLDS (¶m_values[1], GDK_TYPE_EVENT)) + return FALSE; + + event = g_value_get_boxed (¶m_values[1]); + if ((event->type == GDK_BUTTON_PRESS || + event->type == GDK_2BUTTON_PRESS || + event->type == GDK_3BUTTON_PRESS || + event->type == GDK_BUTTON_RELEASE) + && event->button.button == 3) + event->button.button = 1; + + /* Support Ctrl-U for blanking the username/password entry */ + if (event->type == GDK_KEY_PRESS && + (event->key.state & GDK_CONTROL_MASK) && + (event->key.keyval == GDK_u || + event->key.keyval == GDK_U)) { + + GreeterItemInfo *entry_info = greeter_lookup_id ("user-pw-entry"); + if (entry_info && entry_info->item && + GNOME_IS_CANVAS_WIDGET (entry_info->item) && + GTK_IS_ENTRY (GNOME_CANVAS_WIDGET (entry_info->item)->widget)) + { + GtkWidget *entry; + entry = GNOME_CANVAS_WIDGET (entry_info->item)->widget; + gtk_entry_set_text (GTK_ENTRY (entry), ""); + } + } + + return TRUE; +} + +static gboolean +gdm_themed_greeter_start (GdmGreeter *greeter) +{ + g_return_val_if_fail (GDM_IS_GREETER (greeter), FALSE); + + GDM_GREETER_CLASS (gdm_themed_greeter_parent_class)->start (greeter); + + return TRUE; +} + +static gboolean +gdm_themed_greeter_stop (GdmGreeter *greeter) +{ + g_return_val_if_fail (GDM_IS_GREETER (greeter), FALSE); + + GDM_GREETER_CLASS (gdm_themed_greeter_parent_class)->stop (greeter); + + return TRUE; +} + +static gboolean +gdm_themed_greeter_info (GdmGreeter *greeter, + const char *text) +{ + g_return_val_if_fail (GDM_IS_GREETER (greeter), FALSE); + + GDM_GREETER_CLASS (gdm_themed_greeter_parent_class)->info (greeter, text); + + g_debug ("THEMED GREETER: info: %s", text); + + greeter_item_pam_message (text); + + return TRUE; +} + +static gboolean +gdm_themed_greeter_problem (GdmGreeter *greeter, + const char *text) +{ + g_return_val_if_fail (GDM_IS_GREETER (greeter), FALSE); + + GDM_GREETER_CLASS (gdm_themed_greeter_parent_class)->problem (greeter, text); + + g_debug ("THEMED GREETER: problem: %s", text); + + greeter_item_pam_error (text); + + return TRUE; +} + +static gboolean +gdm_themed_greeter_info_query (GdmGreeter *greeter, + const char *text) +{ + g_return_val_if_fail (GDM_IS_GREETER (greeter), FALSE); + + GDM_GREETER_CLASS (gdm_themed_greeter_parent_class)->info_query (greeter, text); + + g_debug ("THEMED GREETER: info query: %s", text); + + if (text != NULL && strcmp (text, _("Username:")) == 0) { +#if 0 + gdm_common_login_sound (gdm_config_get_string (GDM_KEY_SOUND_PROGRAM), + gdm_config_get_string (GDM_KEY_SOUND_ON_LOGIN_FILE), + gdm_config_get_bool (GDM_KEY_SOUND_ON_LOGIN)); +#endif + greeter_probably_login_prompt = TRUE; + } + + if (gtk_ok_button != NULL) + gtk_widget_set_sensitive (GTK_WIDGET (gtk_ok_button), FALSE); + + if (gtk_start_again_button != NULL) + gtk_widget_set_sensitive (GTK_WIDGET (gtk_start_again_button), !first_prompt); + + first_prompt = FALSE; + + greeter_ignore_buttons (FALSE); + + greeter_item_pam_prompt (text, PW_ENTRY_SIZE, TRUE); + + return TRUE; +} + +static gboolean +gdm_themed_greeter_secret_info_query (GdmGreeter *greeter, + const char *text) +{ + g_return_val_if_fail (GDM_IS_GREETER (greeter), FALSE); + + GDM_GREETER_CLASS (gdm_themed_greeter_parent_class)->secret_info_query (greeter, text); + + g_debug ("THEMED GREETER: secret info query: %s", text); + + greeter_probably_login_prompt = FALSE; + + if (gtk_ok_button != NULL) + gtk_widget_set_sensitive (GTK_WIDGET (gtk_ok_button), FALSE); + + if (gtk_start_again_button != NULL) + gtk_widget_set_sensitive (GTK_WIDGET (gtk_start_again_button), !first_prompt); + + first_prompt = FALSE; + + greeter_ignore_buttons (FALSE); + greeter_item_pam_prompt (text, PW_ENTRY_SIZE, FALSE); + + return TRUE; +} + +static void +gdm_themed_greeter_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GdmThemedGreeter *self; + + self = GDM_THEMED_GREETER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdm_themed_greeter_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GdmThemedGreeter *self; + + self = GDM_THEMED_GREETER (object); + + switch (prop_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +create_greeter (GdmThemedGreeter *greeter) +{ + char *bg_color; + struct sigaction hup; + struct sigaction term; + sigset_t mask; + GError *error; + char *theme_file; + char *theme_dir; + char *gdm_graphical_theme; + char *gdm_gtk_theme; + guint sid; + int r; + gint i; + int delay; + gboolean rand_theme; + + gdm_common_setup_cursor (GDK_WATCH); + + { + char *gtkrc; + gdm_settings_client_get_string (GDM_KEY_GTKRC, >krc); + if (gtkrc != NULL) { + gtk_rc_parse (gtkrc); + } + g_free (gtkrc); + } + + gdm_gtk_theme = g_strdup (g_getenv ("GDM_GTK_THEME")); + if (ve_string_empty (gdm_gtk_theme)) { + gdm_settings_client_get_string (GDM_KEY_GTK_THEME, &gdm_gtk_theme); + } + + if ( ! ve_string_empty (gdm_gtk_theme)) { + gdm_set_theme (gdm_gtk_theme); + } + g_free (gdm_gtk_theme); + + { + int screen; + gdm_settings_client_get_int (GDM_KEY_XINERAMA_SCREEN, &screen); + gdm_wm_screen_init (screen); + } + + /* Load the background as early as possible so GDM does not leave */ + /* the background unfilled. The cursor should be a watch already */ + /* but just in case */ + bg_color = NULL; + gdm_settings_client_get_string (GDM_KEY_GRAPHICAL_THEMED_COLOR, &bg_color); + + /* If a graphical theme color does not exist fallback to the plain color */ + if (ve_string_empty (bg_color)) { + g_free (bg_color); + bg_color = NULL; + gdm_settings_client_get_string (GDM_KEY_BACKGROUND_COLOR, &bg_color); + } + gdm_common_setup_background_color (bg_color); + g_free (bg_color); + + greeter_session_init (); + + { + char *locale_file; + gdm_settings_client_get_string (GDM_KEY_LOCALE_FILE, &locale_file); + gdm_lang_initialize_model (locale_file); + g_free (locale_file); + } + + hup.sa_handler = ve_signal_notify; + hup.sa_flags = 0; + sigemptyset (&hup.sa_mask); + sigaddset (&hup.sa_mask, SIGCHLD); + + if (sigaction (SIGHUP, &hup, NULL) < 0) { + gdm_common_fail_greeter ("%s: Error setting up %s signal handler: %s", "main", + "HUP", strerror (errno)); + } + + term.sa_handler = greeter_done; + term.sa_flags = 0; + sigemptyset (&term.sa_mask); + sigaddset (&term.sa_mask, SIGCHLD); + + if G_UNLIKELY (sigaction (SIGINT, &term, NULL) < 0) { + gdm_common_fail_greeter ("%s: Error setting up %s signal handler: %s", "main", + "INT", strerror (errno)); + } + + if G_UNLIKELY (sigaction (SIGTERM, &term, NULL) < 0) { + gdm_common_fail_greeter ("%s: Error setting up %s signal handler: %s", "main", + "TERM", strerror (errno)); + } + + sigemptyset (&mask); + sigaddset (&mask, SIGTERM); + sigaddset (&mask, SIGHUP); + sigaddset (&mask, SIGINT); + + if G_UNLIKELY (sigprocmask (SIG_UNBLOCK, &mask, NULL) == -1) { + gdm_common_fail_greeter ("Could not set signal mask!"); + } + + /* ignore SIGCHLD */ + sigemptyset (&mask); + sigaddset (&mask, SIGCHLD); + + if G_UNLIKELY (sigprocmask (SIG_BLOCK, &mask, NULL) == -1) { + gdm_common_fail_greeter ("Could not set signal mask!"); + } + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + + canvas = gnome_canvas_new_aa (); + GTK_WIDGET_UNSET_FLAGS (canvas, GTK_CAN_FOCUS); + gnome_canvas_set_scroll_region (GNOME_CANVAS (canvas), + 0.0, 0.0, + (double) gdm_wm_screen.width, + (double) gdm_wm_screen.height); + gtk_window_set_decorated (GTK_WINDOW (window), FALSE); + gtk_window_set_default_size (GTK_WINDOW (window), + gdm_wm_screen.width, + gdm_wm_screen.height); + gtk_container_add (GTK_CONTAINER (window), canvas); + + /* + * Initialize the value with the default value so the first time it + * is displayed it doesn't show as 0. Also determine if the Halt, + * Reboot, Suspend and Configurator commands work. + */ + gdm_settings_client_get_int (GDM_KEY_TIMED_LOGIN_DELAY, &gdm_timed_delay); + + { + char *halt; + char *reboot; + char *suspend; + char *configurator; + + gdm_settings_client_get_string (GDM_KEY_HALT, &halt); + gdm_settings_client_get_string (GDM_KEY_REBOOT, &reboot); + gdm_settings_client_get_string (GDM_KEY_SUSPEND, &suspend); + gdm_settings_client_get_string (GDM_KEY_CONFIGURATOR, &configurator); + GdmHaltFound = gdm_working_command_exists (halt); + GdmRebootFound = gdm_working_command_exists (reboot); + GdmSuspendFound = gdm_working_command_exists (suspend); + GdmConfiguratorFound = gdm_working_command_exists (configurator); + + g_free (configurator); + g_free (suspend); + g_free (reboot); + g_free (halt); + } + + GdmCustomCmdsFound = g_new0 (gboolean, GDM_CUSTOM_COMMAND_MAX); + for (i = 0; i < GDM_CUSTOM_COMMAND_MAX; i++) { + char *key_string = NULL; + char *val; + + /* For each possible custom command */ + key_string = g_strdup_printf ("%s%d", GDM_KEY_CUSTOM_CMD_TEMPLATE, i); + + gdm_settings_client_get_string (key_string, &val); + GdmCustomCmdsFound[i] = gdm_working_command_exists (val); + if (GdmCustomCmdsFound[i]) + GdmAnyCustomCmdsFound = TRUE; + + g_free (val); + g_free (key_string); + } + + gdm_settings_client_get_boolean (GDM_KEY_GRAPHICAL_THEME_RAND, &rand_theme); + if (g_getenv ("GDM_THEME") != NULL) { + gdm_graphical_theme = g_strdup (g_getenv ("GDM_THEME")); + } else if (rand_theme) { + gdm_graphical_theme = get_random_theme (); + } else { + gdm_settings_client_get_string (GDM_KEY_GRAPHICAL_THEME, &gdm_graphical_theme); + } + + theme_file = get_theme_file (gdm_graphical_theme, &theme_dir); + + error = NULL; + root = greeter_parse (theme_file, + theme_dir, + GNOME_CANVAS (canvas), + gdm_wm_screen.width, + gdm_wm_screen.height, + &error); + + if (root == NULL) { + GtkWidget *dialog; + char *s; + char *tmp; + + gdm_wm_init (0); + gdm_wm_focus_new_windows (TRUE); + + tmp = ve_filename_to_utf8 (ve_sure_string (gdm_graphical_theme)); + s = g_strdup_printf (_("There was an error loading the " + "theme %s"), tmp); + g_free (tmp); + dialog = hig_dialog_new (NULL /* parent */, + GTK_DIALOG_MODAL /* flags */, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + s, + (error && error->message) ? error->message : ""); + g_free (s); + + gtk_widget_show_all (dialog); + gdm_wm_center_window (GTK_WINDOW (dialog)); + + gdm_common_setup_cursor (GDK_LEFT_PTR); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + + } + + g_free (gdm_graphical_theme); + + if G_UNLIKELY (error) + g_clear_error (&error); + + /* Try circles.xml */ + if (root == NULL) { + g_free (theme_file); + g_free (theme_dir); + theme_file = get_theme_file ("circles", &theme_dir); + root = greeter_parse (theme_file, + theme_dir, + GNOME_CANVAS (canvas), + gdm_wm_screen.width, + gdm_wm_screen.height, + NULL); + } + + g_free (theme_file); + + if (root != NULL && greeter_lookup_id ("user-pw-entry") == NULL) { + GtkWidget *dialog; + + gdm_wm_init (0); + gdm_wm_focus_new_windows (TRUE); + + dialog = hig_dialog_new (NULL /* parent */, + GTK_DIALOG_MODAL /* flags */, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("The greeter theme is corrupt"), + _("The theme does not contain " + "definition for the username/password " + "entry element.")); + + gtk_widget_show_all (dialog); + gdm_wm_center_window (GTK_WINDOW (dialog)); + + gdm_common_setup_cursor (GDK_LEFT_PTR); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + + root = NULL; + } + + if (root == NULL) { + GtkWidget *dialog; + + gdm_wm_init (0); + gdm_wm_focus_new_windows (TRUE); + + dialog = hig_dialog_new (NULL /* parent */, + GTK_DIALOG_MODAL /* flags */, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("There was an error loading the " + "theme, and the default theme " + "could not be loaded. " + "Attempting to start the " + "standard greeter"), + ""); + + gtk_widget_show_all (dialog); + gdm_wm_center_window (GTK_WINDOW (dialog)); + + gdm_common_setup_cursor (GDK_LEFT_PTR); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + + execl (LIBEXECDIR "/gdmlogin", LIBEXECDIR "/gdmlogin", NULL); + execlp ("gdmlogin", "gdmlogin", NULL); + + dialog = hig_dialog_new (NULL /* parent */, + GTK_DIALOG_MODAL /* flags */, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("The GTK+ greeter could not be started. " + "This display will abort and you may " + "have to login another way and fix the " + "installation of GDM"), + ""); + + gtk_widget_show_all (dialog); + gdm_wm_center_window (GTK_WINDOW (dialog)); + + gdm_common_setup_cursor (GDK_LEFT_PTR); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + + _exit (DISPLAY_ABORT); + } + + greeter_layout (root, GNOME_CANVAS (canvas)); + + greeter_setup_items (greeter); + + + gdm_common_setup_blinking (); + + gtk_widget_show_all (window); + gtk_window_move (GTK_WINDOW (window), gdm_wm_screen.x, gdm_wm_screen.y); + gtk_widget_show_now (window); + + greeter_item_ulist_unset_selected_user (); + greeter_item_ulist_enable (); + greeter_item_ulist_check_show_userlist (); + + /* can it ever happen that it'd be NULL here ??? */ + if (window->window != NULL) { + gdm_wm_init (GDK_WINDOW_XWINDOW (window->window)); + + /* Run the focus, note that this will work no matter what + * since gdm_wm_init will set the display to the gdk one + * if it fails */ + gdm_wm_focus_window (GDK_WINDOW_XWINDOW (window->window)); + } + + if G_UNLIKELY (session_dir_whacked_out) { + GtkWidget *dialog; + + gdm_wm_focus_new_windows (TRUE); + + dialog = hig_dialog_new (NULL /* parent */, + GTK_DIALOG_MODAL /* flags */, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("Session directory is missing"), + _("Your session directory is missing or empty! " + "There are two available sessions you can use, but " + "you should log in and correct the gdm configuration.")); + gtk_widget_show_all (dialog); + gdm_wm_center_window (GTK_WINDOW (dialog)); + + gdm_common_setup_cursor (GDK_LEFT_PTR); + + gdm_wm_no_login_focus_push (); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + gdm_wm_no_login_focus_pop (); + } + + if G_UNLIKELY (g_getenv ("GDM_WHACKED_GREETER_CONFIG") != NULL) { + GtkWidget *dialog; + + gdm_wm_focus_new_windows (TRUE); + + dialog = hig_dialog_new (NULL /* parent */, + GTK_DIALOG_MODAL /* flags */, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("Configuration is not correct"), + _("The configuration file contains an invalid command " + "line for the login dialog, so running the " + "default command. Please fix your configuration.")); + + gtk_widget_show_all (dialog); + gdm_wm_center_window (GTK_WINDOW (dialog)); + + gdm_common_setup_cursor (GDK_LEFT_PTR); + + gdm_wm_no_login_focus_push (); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + gdm_wm_no_login_focus_pop (); + } + + /* if a flexiserver, reap self after some time */ + gdm_settings_client_get_int (GDM_KEY_FLEXI_REAP_DELAY_MINUTES, &delay); + if (delay > 0 && ! ve_string_empty (g_getenv ("GDM_FLEXI_SERVER")) && + /* but don't reap Xnest flexis */ + ve_string_empty (g_getenv ("GDM_PARENT_DISPLAY"))) { + sid = g_signal_lookup ("activate", + GTK_TYPE_MENU_ITEM); + g_signal_add_emission_hook (sid, + 0 /* detail */, + delay_reaping, + NULL /* data */, + NULL /* destroy_notify */); + + sid = g_signal_lookup ("key_press_event", + GTK_TYPE_WIDGET); + g_signal_add_emission_hook (sid, + 0 /* detail */, + delay_reaping, + NULL /* data */, + NULL /* destroy_notify */); + + sid = g_signal_lookup ("button_press_event", + GTK_TYPE_WIDGET); + g_signal_add_emission_hook (sid, + 0 /* detail */, + delay_reaping, + NULL /* data */, + NULL /* destroy_notify */); + + last_reap_delay = time (NULL); + g_timeout_add (60*1000, reap_flexiserver, NULL); + } + + sid = g_signal_lookup ("event", + GTK_TYPE_WIDGET); + g_signal_add_emission_hook (sid, + 0 /* detail */, + gdm_event, + NULL /* data */, + NULL /* destroy_notify */); + + gdm_wm_restore_wm_order (); + + { + char *msg_file; + char *msg_font; + + gdm_settings_client_get_string (GDM_KEY_INFO_MSG_FILE, &msg_file); + gdm_settings_client_get_string (GDM_KEY_INFO_MSG_FONT, &msg_font); + + gdm_wm_show_info_msg_dialog (msg_file, msg_font); + g_free (msg_font); + g_free (msg_file); + } + + gdm_common_setup_cursor (GDK_LEFT_PTR); + gdm_wm_center_cursor (); + gdm_common_pre_fetch_launch (); +} + +static GObject * +gdm_themed_greeter_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) +{ + GdmThemedGreeter *greeter; + GdmThemedGreeterClass *klass; + + klass = GDM_THEMED_GREETER_CLASS (g_type_class_peek (GDM_TYPE_THEMED_GREETER)); + + greeter = GDM_GREETER (G_OBJECT_CLASS (gdm_themed_greeter_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + create_greeter (greeter); + + return G_OBJECT (greeter); +} + +static void +gdm_themed_greeter_class_init (GdmThemedGreeterClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GdmGreeterClass *greeter_class = GDM_GREETER_CLASS (klass); + + object_class->get_property = gdm_themed_greeter_get_property; + object_class->set_property = gdm_themed_greeter_set_property; + object_class->constructor = gdm_themed_greeter_constructor; + object_class->finalize = gdm_themed_greeter_finalize; + + greeter_class->start = gdm_themed_greeter_start; + greeter_class->stop = gdm_themed_greeter_stop; + greeter_class->info = gdm_themed_greeter_info; + greeter_class->problem = gdm_themed_greeter_problem; + greeter_class->info_query = gdm_themed_greeter_info_query; + greeter_class->secret_info_query = gdm_themed_greeter_secret_info_query; + + g_type_class_add_private (klass, sizeof (GdmThemedGreeterPrivate)); +} + +static void +gdm_themed_greeter_init (GdmThemedGreeter *themed_greeter) +{ + + themed_greeter->priv = GDM_THEMED_GREETER_GET_PRIVATE (themed_greeter); + +} + +static void +gdm_themed_greeter_finalize (GObject *object) +{ + GdmThemedGreeter *themed_greeter; + + g_return_if_fail (object != NULL); + g_return_if_fail (GDM_IS_THEMED_GREETER (object)); + + themed_greeter = GDM_THEMED_GREETER (object); + + g_return_if_fail (themed_greeter->priv != NULL); + + G_OBJECT_CLASS (gdm_themed_greeter_parent_class)->finalize (object); +} + +GdmGreeter * +gdm_themed_greeter_new (void) +{ + GObject *object; + + object = g_object_new (GDM_TYPE_THEMED_GREETER, + NULL); + + return GDM_GREETER (object); +} diff --git a/gui/greeter/gdm-themed-greeter.h b/gui/greeter/gdm-themed-greeter.h new file mode 100644 index 00000000..0b49b26c --- /dev/null +++ b/gui/greeter/gdm-themed-greeter.h @@ -0,0 +1,58 @@ +/* -*- 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. + * + */ + + +#ifndef __GDM_THEMED_GREETER_H +#define __GDM_THEMED_GREETER_H + +#include <glib-object.h> + +#include "gdm-greeter.h" + +G_BEGIN_DECLS + +#define GDM_TYPE_THEMED_GREETER (gdm_themed_greeter_get_type ()) +#define GDM_THEMED_GREETER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_THEMED_GREETER, GdmThemedGreeter)) +#define GDM_THEMED_GREETER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_THEMED_GREETER, GdmThemedGreeterClass)) +#define GDM_IS_THEMED_GREETER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_THEMED_GREETER)) +#define GDM_IS_THEMED_GREETER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_THEMED_GREETER)) +#define GDM_THEMED_GREETER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_THEMED_GREETER, GdmThemedGreeterClass)) + +typedef struct GdmThemedGreeterPrivate GdmThemedGreeterPrivate; + +typedef struct +{ + GdmGreeter parent; + GdmThemedGreeterPrivate *priv; +} GdmThemedGreeter; + +typedef struct +{ + GdmGreeterClass parent_class; + +} GdmThemedGreeterClass; + +GType gdm_themed_greeter_get_type (void); +GdmGreeter * gdm_themed_greeter_new (void); + + +G_END_DECLS + +#endif /* __GDM_THEMED_GREETER_H */ diff --git a/gui/greeter/greeter.c b/gui/greeter/greeter.c index 63bc4c86..3a0ec4ff 100644 --- a/gui/greeter/greeter.c +++ b/gui/greeter/greeter.c @@ -20,6 +20,7 @@ #include "config.h" +#include <stdlib.h> #include <libintl.h> #include <locale.h> #include <string.h> @@ -36,985 +37,101 @@ #include <glib/gi18n.h> #include <gtk/gtk.h> -#include <gdk/gdkkeysyms.h> - -#include <libgnomecanvas/libgnomecanvas.h> +#define DBUS_API_SUBJECT_TO_CHANGE +#include <dbus/dbus-glib.h> +#include <dbus/dbus-glib-lowlevel.h> #include "gdm-common.h" -#include "gdm-socket-protocol.h" #include "gdm-settings-client.h" #include "gdm-settings-keys.h" -#include "gdm.h" -#include "gdmwm.h" -#include "gdmcommon.h" -#include "gdmsession.h" -#include "gdmlanguages.h" - -#include "greeter.h" -#include "greeter_configuration.h" -#include "greeter_parser.h" -#include "greeter_geometry.h" -#include "greeter_item_clock.h" -#include "greeter_item_pam.h" -#include "greeter_item_ulist.h" -#include "greeter_item_customlist.h" -#include "greeter_item_capslock.h" -#include "greeter_item_timed.h" -#include "greeter_events.h" -#include "greeter_session.h" -#include "greeter_system.h" - -gboolean DOING_GDM_DEVELOPMENT = FALSE; - -GtkWidget *window; -GtkWidget *canvas; - -gboolean GDM_IS_LOCAL = FALSE; -static gboolean ignore_buttons = FALSE; -gboolean GdmHaltFound = FALSE; -gboolean GdmRebootFound = FALSE; -gboolean *GdmCustomCmdsFound = NULL; -gboolean GdmAnyCustomCmdsFound = FALSE; -gboolean GdmSuspendFound = FALSE; -gboolean GdmConfiguratorFound = FALSE; - -/* FIXME: hack */ -GreeterItemInfo *welcome_string_info = NULL; -GreeterItemInfo *root = NULL; - -extern gboolean session_dir_whacked_out; -extern gboolean require_quarter; -extern gint gdm_timed_delay; -extern GtkButton *gtk_ok_button; -extern GtkButton *gtk_start_again_button; - -gboolean greeter_probably_login_prompt = FALSE; -static gboolean first_prompt = TRUE; - -static void process_operation (guchar opcode, const gchar *args); - -void -greeter_ignore_buttons (gboolean val) -{ - ignore_buttons = val; -} - -/* If in random theme mode then grab a random theme from those selected */ -static char * -get_random_theme () -{ - char **vec; - char *themes_list; - char *theme; - int size; - int i; - - theme = NULL; - - gdm_settings_client_get_string (GDM_KEY_GRAPHICAL_THEMES, &themes_list); - - if (ve_string_empty (themes_list)) { - goto out; - } - - vec = g_strsplit (themes_list, GDM_DELIMITER_THEMES, -1); - if (vec == NULL) { - goto out; - } - - /* Get Number of elements in vector */ - for (size = 0; vec[size] != NULL; size++) {} +#include "gdm-themed-greeter.h" - /* Get Random Theme from list */ - srand (time (NULL)); - i = rand () % size; - theme = g_strdup (vec[i]); - g_strfreev (vec); - - out: - g_free (themes_list); - - return theme; -} - -static gboolean -greeter_ctrl_handler (GIOChannel *source, - GIOCondition cond, - gint fd) -{ - gchar buf[PIPE_SIZE]; - gchar *p; - gsize len; - - /* If this is not incoming i/o then return */ - if (cond != G_IO_IN) - return TRUE; - - /* Read random garbage from i/o channel until first STX is found */ - do { - g_io_channel_read_chars (source, buf, 1, &len, NULL); - - if (len != 1) - return TRUE; - } while (buf[0] && buf[0] != STX); - - memset (buf, '\0', sizeof (buf)); - if (g_io_channel_read_chars (source, buf, sizeof (buf) - 1, &len, NULL) != - G_IO_STATUS_NORMAL) - return TRUE; - - p = memchr (buf, STX, len); - if (p != NULL) { - len = p - buf; - g_io_channel_seek_position (source, -((sizeof (buf) - 1) - len), G_SEEK_CUR, NULL); - memset (buf + len, '\0', (sizeof (buf) - 1) - len); - } - buf[len - 1] = '\0'; - - process_operation ((guchar) buf[0], buf + 1); - return TRUE; -} - -static GtkWidget * -hig_dialog_new (GtkWindow *parent, - GtkDialogFlags flags, - GtkMessageType type, - GtkButtonsType buttons, - const gchar *primary_message, - const gchar *secondary_message) -{ - GtkWidget *dialog; - - dialog = gtk_message_dialog_new (GTK_WINDOW (parent), - GTK_DIALOG_DESTROY_WITH_PARENT, - type, - buttons, - "%s", primary_message); - - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), - "%s", secondary_message); +#include "gdmcommon.h" - gtk_window_set_title (GTK_WINDOW (dialog), ""); - gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); - gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 14); +#define SERVER_DBUS_PATH "/org/gnome/DisplayManager/GreeterServer" +#define SERVER_DBUS_INTERFACE "org.gnome.DisplayManager.GreeterServer" - return dialog; -} +static DBusGProxy *settings_proxy = NULL; +static DBusGConnection *connection = NULL; +static GdmThemedGreeter *greeter = NULL; +static DBusGProxy *server_proxy = NULL; static void -process_operation (guchar op_code, - const gchar *args) +on_info (DBusGProxy *proxy, + const char *text, + gpointer data) { - GtkWidget *dlg; - char *tmp; - char *session; - GreeterItemInfo *conversation_info; - static GnomeCanvasItem *disabled_cover = NULL; - gint lookup_status = SESSION_LOOKUP_SUCCESS; - gchar *firstmsg = NULL; - gchar *secondmsg = NULL; - gint save_session = GTK_RESPONSE_NO; - - /* Parse opcode */ - switch (op_code) { - case GDM_SETLOGIN: - /* somebody is trying to fool us this is the user that - * wants to log in, and well, we are the gullible kind */ - - greeter_item_pam_set_user (args); - printf ("%c\n", STX); - fflush (stdout); - break; - - case GDM_PROMPT: - tmp = ve_locale_to_utf8 (args); - if (tmp != NULL && strcmp (tmp, _("Username:")) == 0) { - char *sound_prog; - char *sound_file; - gboolean sound_on_login; - - gdm_settings_client_get_string (GDM_KEY_SOUND_PROGRAM, &sound_prog); - gdm_settings_client_get_string (GDM_KEY_SOUND_ON_LOGIN_FILE, &sound_file); - gdm_settings_client_get_boolean (GDM_KEY_SOUND_ON_LOGIN, &sound_on_login); - - gdm_common_login_sound (sound_prog, sound_file, sound_on_login); - g_free (sound_file); - g_free (sound_prog); - - greeter_probably_login_prompt = TRUE; - } - if (gtk_ok_button != NULL) - gtk_widget_set_sensitive (GTK_WIDGET (gtk_ok_button), FALSE); - - if (gtk_start_again_button != NULL) - gtk_widget_set_sensitive (GTK_WIDGET (gtk_start_again_button), !first_prompt); - - first_prompt = FALSE; - - greeter_ignore_buttons (FALSE); - - greeter_item_pam_prompt (tmp, PW_ENTRY_SIZE, TRUE); - g_free (tmp); - break; - - case GDM_NOECHO: - tmp = ve_locale_to_utf8 (args); - - greeter_probably_login_prompt = FALSE; - - if (gtk_ok_button != NULL) - gtk_widget_set_sensitive (GTK_WIDGET (gtk_ok_button), FALSE); - - if (gtk_start_again_button != NULL) - gtk_widget_set_sensitive (GTK_WIDGET (gtk_start_again_button), !first_prompt); - - first_prompt = FALSE; - - greeter_ignore_buttons (FALSE); - greeter_item_pam_prompt (tmp, PW_ENTRY_SIZE, FALSE); - g_free (tmp); - - break; - - case GDM_MSG: - tmp = ve_locale_to_utf8 (args); - greeter_item_pam_message (tmp); - g_free (tmp); - printf ("%c\n", STX); - fflush (stdout); - break; - - case GDM_ERRBOX: - tmp = ve_locale_to_utf8 (args); - greeter_item_pam_error (tmp); - g_free (tmp); - - printf ("%c\n", STX); - fflush (stdout); - break; - - case GDM_ERRDLG: - /* we should be now fine for focusing new windows */ - gdm_wm_focus_new_windows (TRUE); - - tmp = ve_locale_to_utf8 (args); - dlg = hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - tmp, - ""); - g_free (tmp); - - gdm_wm_center_window (GTK_WINDOW (dlg)); - - gdm_wm_no_login_focus_push (); - gtk_dialog_run (GTK_DIALOG (dlg)); - gtk_widget_destroy (dlg); - gdm_wm_no_login_focus_pop (); - - printf ("%c\n", STX); - fflush (stdout); - break; - - case GDM_SESS: - tmp = ve_locale_to_utf8 (args); - session = gdm_session_lookup (tmp, &lookup_status); - if (lookup_status != SESSION_LOOKUP_SUCCESS) { - switch (lookup_status) { - case SESSION_LOOKUP_PREFERRED_MISSING: - firstmsg = g_strdup_printf (_("Do you wish to make %s the default for " - "future sessions?"), - gdm_session_name (tmp)); - secondmsg = g_strdup_printf (_("Your preferred session type %s is not " - "installed on this computer."), - gdm_session_name (gdm_get_default_session ())); - save_session = gdm_wm_query_dialog (firstmsg, secondmsg, - _("Make _Default"), _("Just _Log In"), TRUE); - - g_free (firstmsg); - g_free (secondmsg); - gdm_set_save_session (save_session); - break; - - case SESSION_LOOKUP_DEFAULT_MISMATCH: - firstmsg = g_strdup_printf (_("Do you wish to make %s the default for " - "future sessions?"), - gdm_session_name (session)); - secondmsg = g_strdup_printf (_("You have chosen %s for this " - "session, but your default " - "setting is %s."), - gdm_session_name (session), - gdm_session_name (tmp)); - save_session = gdm_wm_query_dialog (firstmsg, secondmsg, - _("Make _Default"), _("Just For _This Session"), TRUE); - - g_free (firstmsg); - g_free (secondmsg); - gdm_set_save_session (save_session); - break; - case SESSION_LOOKUP_USE_SWITCHDESK: - firstmsg = g_strdup_printf (_("You have chosen %s for this " - "session"), - gdm_session_name (session)); - secondmsg = g_strdup_printf (_("If you wish to make %s " - "the default for future sessions, " - "run the 'switchdesk' utility " - "(System->Desktop Switching Tool from " - "the panel menu)."), - gdm_session_name (session)); - gdm_wm_message_dialog (firstmsg, secondmsg); - g_free (firstmsg); - g_free (secondmsg); - break; - - default: - break; - } - } - g_free (tmp); - if (gdm_get_save_session () == GTK_RESPONSE_CANCEL) { - printf ("%c%s\n", STX, GDM_RESPONSE_CANCEL); - } else { - tmp = ve_locale_from_utf8 (session); - printf ("%c%s\n", STX, tmp); - g_free (tmp); - } - fflush (stdout); - g_free (session); - break; - - case GDM_LANG: - gdm_lang_op_lang (args); - break; - - case GDM_SSESS: - if (gdm_get_save_session () == GTK_RESPONSE_YES) - printf ("%cY\n", STX); - else - printf ("%c\n", STX); - fflush (stdout); - - break; - - case GDM_SLANG: - gdm_lang_op_slang (args); - break; - - case GDM_SETLANG: - gdm_lang_op_setlang (args); - break; - - case GDM_ALWAYS_RESTART: - gdm_lang_op_always_restart (args); - break; - - case GDM_RESET: - /* fall thru to reset */ - - case GDM_RESETOK: - - if (gtk_ok_button != NULL) - gtk_widget_set_sensitive (GTK_WIDGET (gtk_ok_button), FALSE); - if (gtk_start_again_button != NULL) - gtk_widget_set_sensitive (GTK_WIDGET (gtk_start_again_button), FALSE); - - first_prompt = TRUE; - - conversation_info = greeter_lookup_id ("pam-conversation"); - - if (conversation_info) { - tmp = ve_locale_to_utf8 (args); - g_object_set (G_OBJECT (conversation_info->item), - "text", tmp, - NULL); - g_free (tmp); - } + g_debug ("GREETER INFO: %s", text); - printf ("%c\n", STX); - fflush (stdout); - greeter_ignore_buttons (FALSE); - greeter_item_ulist_enable (); - - break; - - case GDM_QUIT: - greeter_item_timed_stop (); - - if (require_quarter) { - /* we should be now fine for focusing new windows */ - gdm_wm_focus_new_windows (TRUE); - - dlg = hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_INFO, - GTK_BUTTONS_OK, - /* translators: This is a nice and evil eggie text, translate - * to your favourite currency */ - _("Please insert 25 cents " - "to log in."), - ""); - gdm_wm_center_window (GTK_WINDOW (dlg)); - - gdm_wm_no_login_focus_push (); - gtk_dialog_run (GTK_DIALOG (dlg)); - gtk_widget_destroy (dlg); - gdm_wm_no_login_focus_pop (); - } - - greeter_item_pam_leftover_messages (); - - gdk_flush (); - - if (greeter_show_only_background (root)) { - GdkPixbuf *background; - int width, height; - - gtk_window_get_size (GTK_WINDOW (window), &width, &height); - background = gdk_pixbuf_get_from_drawable (NULL, gtk_widget_get_root_window(window), NULL, 0, 0, 0, 0 ,width, height); - if (background) { - gdm_common_set_root_background (background); - g_object_unref (background); - } - } - - printf ("%c\n", STX); - fflush (stdout); - - /* screw gtk_main_quit, we want to make sure we definately die */ - _exit (EXIT_SUCCESS); - break; - - case GDM_STARTTIMER: - greeter_item_timed_start (); - - printf ("%c\n", STX); - fflush (stdout); - break; - - case GDM_STOPTIMER: - greeter_item_timed_stop (); - - printf ("%c\n", STX); - fflush (stdout); - break; - - case GDM_DISABLE: - gtk_widget_set_sensitive (window, FALSE); - - if (disabled_cover == NULL) - { - disabled_cover = gnome_canvas_item_new - (gnome_canvas_root (GNOME_CANVAS (canvas)), - GNOME_TYPE_CANVAS_RECT, - "x1", 0.0, - "y1", 0.0, - "x2", (double)canvas->allocation.width, - "y2", (double)canvas->allocation.height, - "fill_color_rgba", (guint)0x00000088, - NULL); - } - - printf ("%c\n", STX); - fflush (stdout); - break; - - case GDM_ENABLE: - gtk_widget_set_sensitive (window, TRUE); - - if (disabled_cover != NULL) - { - gtk_object_destroy (GTK_OBJECT (disabled_cover)); - disabled_cover = NULL; - } - - printf ("%c\n", STX); - fflush (stdout); - break; - - /* These are handled separately so ignore them here and send - * back a NULL response so that the daemon quits sending them */ - case GDM_NEEDPIC: - case GDM_READPIC: - printf ("%c\n", STX); - fflush (stdout); - break; - - case GDM_NOFOCUS: - gdm_wm_no_login_focus_push (); - - printf ("%c\n", STX); - fflush (stdout); - break; - - case GDM_FOCUS: - gdm_wm_no_login_focus_pop (); - - printf ("%c\n", STX); - fflush (stdout); - break; - - case GDM_SAVEDIE: - /* Set busy cursor */ - gdm_common_setup_cursor (GDK_WATCH); - - gdm_wm_save_wm_order (); - - gdk_flush (); - - _exit (EXIT_SUCCESS); - - case GDM_QUERY_CAPSLOCK: - if (greeter_is_capslock_on ()) - printf ("%cY\n", STX); - else - printf ("%c\n", STX); - fflush (stdout); - - break; - - default: - gdm_common_fail_greeter ("Unexpected greeter command received: '%c'", op_code); - break; - } -} - -static gboolean -key_press_event (GtkWidget *widget, GdkEventKey *key, gpointer data) -{ - if (DOING_GDM_DEVELOPMENT && (key->keyval == GDK_Escape)) { - process_operation (GDM_QUIT, NULL); - - return TRUE; - } - - return FALSE; -} - -/* - * The buttons with these handlers never appear in the F10 menu, - * so they can make use of callback data. - */ -static void -greeter_ok_handler (GreeterItemInfo *info, - gpointer user_data) -{ - if (ignore_buttons == FALSE) { - GreeterItemInfo *entry_info = greeter_lookup_id ("user-pw-entry"); - if (entry_info && entry_info->item && - GNOME_IS_CANVAS_WIDGET (entry_info->item) && - GTK_IS_ENTRY (GNOME_CANVAS_WIDGET (entry_info->item)->widget)) - { - GtkWidget *entry; - entry = GNOME_CANVAS_WIDGET (entry_info->item)->widget; - greeter_ignore_buttons (TRUE); - greeter_item_pam_login (GTK_ENTRY (entry), entry_info); - } - } + gdm_greeter_info (GDM_GREETER (greeter), text); } static void -greeter_cancel_handler (GreeterItemInfo *info, - gpointer user_data) +on_problem (DBusGProxy *proxy, + const char *text, + gpointer data) { - if (ignore_buttons == FALSE) { - greeter_item_ulist_unset_selected_user (); - greeter_item_ulist_disable (); - greeter_ignore_buttons (TRUE); - printf ("%c%c%c\n", STX, BEL, GDM_INTERRUPT_CANCEL); - fflush (stdout); - } -} + g_debug ("GREETER PROBLEM: %s", text); -static void -greeter_language_handler (GreeterItemInfo *info, - gpointer user_data) -{ - gdm_lang_handler (user_data); + gdm_greeter_problem (GDM_GREETER (greeter), text); } static void -greeter_setup_items (void) +on_info_query (DBusGProxy *proxy, + const char *text, + gpointer data) { - greeter_item_clock_setup (); - greeter_item_pam_setup (); - - /* This will query the daemon for pictures through stdin/stdout! */ - greeter_item_ulist_setup (); - - greeter_item_capslock_setup (window); - greeter_item_timed_setup (); - greeter_item_register_action_callback ("ok_button", - greeter_ok_handler, - (gpointer) window); - greeter_item_register_action_callback ("cancel_button", - greeter_cancel_handler, - (gpointer) window); - greeter_item_register_action_callback ("language_button", - greeter_language_handler, - NULL); - greeter_item_register_action_callback ("disconnect_button", - (ActionFunc)gtk_main_quit, - NULL); - greeter_item_system_setup (); - greeter_item_session_setup (); + g_debug ("GREETER Info query: %s", text); - /* Setup the custom widgets */ - greeter_item_customlist_setup (); -} - -enum { - RESPONSE_RESTART, - RESPONSE_REBOOT, - RESPONSE_CLOSE -}; - -static int -verify_gdm_version (void) -{ - const char *gdm_version; - const char *gdm_protocol_version; - - g_debug ("Checking GDM version"); - - gdm_version = g_getenv ("GDM_VERSION"); - gdm_protocol_version = g_getenv ("GDM_GREETER_PROTOCOL_VERSION"); - - if (! DOING_GDM_DEVELOPMENT && - ((gdm_protocol_version != NULL && - strcmp (gdm_protocol_version, GDM_GREETER_PROTOCOL_VERSION) != 0) || - (gdm_protocol_version == NULL && - (gdm_version == NULL || - strcmp (gdm_version, VERSION) != 0))) && - (g_getenv ("GDM_IS_LOCAL") != NULL)) { - GtkWidget *dialog; - gchar *msg; - - gdm_wm_init (0); - gdm_wm_focus_new_windows (TRUE); - - msg = g_strdup_printf (_("The greeter version (%s) does not match the daemon " - "version. " - "You have probably just upgraded GDM. " - "Please restart the GDM daemon or the computer."), - VERSION); - - dialog = hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("Cannot start the greeter"), - msg); - g_free (msg); - - gtk_widget_show_all (dialog); - gdm_wm_center_window (GTK_WINDOW (dialog)); - - gdm_common_setup_cursor (GDK_LEFT_PTR); - - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - return EXIT_SUCCESS; - } - - if (! DOING_GDM_DEVELOPMENT && - gdm_protocol_version == NULL && - gdm_version == NULL) { - GtkWidget *dialog; - gchar *msg; - - gdm_wm_init (0); - gdm_wm_focus_new_windows (TRUE); - - msg = g_strdup_printf (_("The greeter version (%s) does not match the daemon " - "version. " - "You have probably just upgraded GDM. " - "Please restart the GDM daemon or the computer."), - VERSION); - - dialog = hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_WARNING, - GTK_BUTTONS_NONE, - _("Cannot start the greeter"), - msg); - g_free (msg); - - gtk_dialog_add_buttons (GTK_DIALOG (dialog), - _("Restart Machine"), - RESPONSE_REBOOT, - GTK_STOCK_CLOSE, - RESPONSE_CLOSE, - NULL); - - gtk_widget_show_all (dialog); - gdm_wm_center_window (GTK_WINDOW (dialog)); - - gdm_common_setup_cursor (GDK_LEFT_PTR); - - switch (gtk_dialog_run (GTK_DIALOG (dialog))) { - case RESPONSE_REBOOT: - gtk_widget_destroy (dialog); - return DISPLAY_REBOOT; - default: - gtk_widget_destroy (dialog); - return DISPLAY_ABORT; - } - } - - if (! DOING_GDM_DEVELOPMENT && - ((gdm_protocol_version != NULL && - strcmp (gdm_protocol_version, GDM_GREETER_PROTOCOL_VERSION) != 0) || - (gdm_protocol_version == NULL && - strcmp (gdm_version, VERSION) != 0))) { - GtkWidget *dialog; - gchar *msg; - - gdm_wm_init (0); - gdm_wm_focus_new_windows (TRUE); - - msg = g_strdup_printf (_("The greeter version (%s) does not match the daemon " - "version (%s). " - "You have probably just upgraded GDM. " - "Please restart the GDM daemon or the computer."), - VERSION, gdm_version); - - dialog = hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_WARNING, - GTK_BUTTONS_NONE, - _("Cannot start the greeter"), - msg); - g_free (msg); - - gtk_dialog_add_buttons (GTK_DIALOG (dialog), - _("Restart GDM"), - RESPONSE_RESTART, - _("Restart Machine"), - RESPONSE_REBOOT, - GTK_STOCK_CLOSE, - RESPONSE_CLOSE, - NULL); - - gtk_widget_show_all (dialog); - gdm_wm_center_window (GTK_WINDOW (dialog)); - - gtk_dialog_set_default_response (GTK_DIALOG (dialog), RESPONSE_RESTART); - - gdm_common_setup_cursor (GDK_LEFT_PTR); - - switch (gtk_dialog_run (GTK_DIALOG (dialog))) { - case RESPONSE_RESTART: - gtk_widget_destroy (dialog); - return DISPLAY_RESTARTGDM; - case RESPONSE_REBOOT: - gtk_widget_destroy (dialog); - return DISPLAY_REBOOT; - default: - gtk_widget_destroy (dialog); - return DISPLAY_ABORT; - } - } - - return 0; + gdm_greeter_info_query (GDM_GREETER (greeter), text); } static void -gdm_set_welcomemsg (void) +on_secret_info_query (DBusGProxy *proxy, + const char *text, + gpointer data) { - char *welcomemsg = gdm_common_get_welcomemsg (); + g_debug ("GREETER Secret info query: %s", text); - if (welcome_string_info->data.text.orig_text != NULL) - g_free (welcome_string_info->data.text.orig_text); - - welcome_string_info->data.text.orig_text = welcomemsg; - greeter_item_update_text (welcome_string_info); + gdm_greeter_secret_info_query (GDM_GREETER (greeter), text); } static void -greeter_done (int sig) -{ - _exit (EXIT_SUCCESS); -} - -static char * -get_theme_greeter (const gchar *file, - const char *fallback) -{ - GKeyFile *config; - gchar *s; - - config = g_key_file_new (); - if (! g_key_file_load_from_file (config, file, 0, NULL)) { - return NULL; - } - - s = g_key_file_get_locale_string (config, "GdmGreeterTheme", "Greeter", NULL, NULL); - - if (s == NULL || s[0] == '\0') { - g_free (s); - s = g_strdup_printf ("%s.xml", fallback); - } - - g_key_file_free (config); - - return s; -} -static char * -get_theme_file (const char *in, char **theme_dir) +on_query_answer (GdmGreeter *greeter, + const char *text, + gpointer data) { - char *file, *dir, *info, *s; - - if (in == NULL) - in = "circles"; + gboolean res; + GError *error; - *theme_dir = NULL; - - if (g_path_is_absolute (in)) { - dir = g_strdup (in); - } else { - dir = NULL; - if (DOING_GDM_DEVELOPMENT) { - if (g_access (in, F_OK) == 0) { - dir = g_strdup (in); - } else { - dir = g_build_filename ("themes", in, NULL); - if (g_access (dir, F_OK) != 0) { - g_free (dir); - dir = NULL; - } - } - } + g_debug ("GREETER answer: %s", text); - if (dir == NULL) { - char *graphical_theme_dir; - - gdm_settings_client_get_string (GDM_KEY_GRAPHICAL_THEME_DIR, &graphical_theme_dir); - dir = g_build_filename (graphical_theme_dir, in, NULL); - g_free (graphical_theme_dir); - } - } - - *theme_dir = dir; - - info = g_build_filename (dir, "GdmGreeterTheme.desktop", NULL); - if (g_access (info, F_OK) != 0) { - g_free (info); - info = g_build_filename (dir, "GdmGreeterTheme.info", NULL); - } - if (g_access (info, F_OK) != 0) { - char *base = g_path_get_basename (in); - /* just guess the name, we have no info about the theme at - * this point */ - g_free (info); - file = g_strdup_printf ("%s/%s.xml", dir, base); - g_free (base); - return file; - } - - s = get_theme_greeter (info, in); - file = g_build_filename (dir, s, NULL); - - g_free (info); - g_free (s); - - return file; -} - -/* The reaping stuff */ -static time_t last_reap_delay = 0; - -static gboolean -delay_reaping (GSignalInvocationHint *ihint, - guint n_param_values, - const GValue *param_values, - gpointer data) -{ - last_reap_delay = time (NULL); - return TRUE; -} - -static gboolean -reap_flexiserver (gpointer data) -{ - int reapminutes; - - gdm_settings_client_get_int (GDM_KEY_FLEXI_REAP_DELAY_MINUTES, &reapminutes); - - if (reapminutes > 0 && - ((time (NULL) - last_reap_delay) / 60) > reapminutes) { - _exit (DISPLAY_REMANAGE); + error = NULL; + res = dbus_g_proxy_call (server_proxy, + "AnswerQuery", + &error, + G_TYPE_STRING, text, + G_TYPE_INVALID, + G_TYPE_INVALID); + if (! res) { + g_warning ("Unable to send AnswerQuery: %s", error->message); + g_error_free (error); } - return TRUE; } -static gboolean -gdm_event (GSignalInvocationHint *ihint, - guint n_param_values, - const GValue *param_values, - gpointer data) +static void +proxy_destroyed (GObject *object, + gpointer data) { - GdkEvent *event; - - /* HAAAAAAAAAAAAAAAAACK */ - /* Since the user has not logged in yet and may have left/right - * mouse buttons switched, we just translate every right mouse click - * to a left mouse click */ - if (n_param_values != 2 || - !G_VALUE_HOLDS (¶m_values[1], GDK_TYPE_EVENT)) - return FALSE; - - event = g_value_get_boxed (¶m_values[1]); - if ((event->type == GDK_BUTTON_PRESS || - event->type == GDK_2BUTTON_PRESS || - event->type == GDK_3BUTTON_PRESS || - event->type == GDK_BUTTON_RELEASE) - && event->button.button == 3) - event->button.button = 1; - - /* Support Ctrl-U for blanking the username/password entry */ - if (event->type == GDK_KEY_PRESS && - (event->key.state & GDK_CONTROL_MASK) && - (event->key.keyval == GDK_u || - event->key.keyval == GDK_U)) { - - GreeterItemInfo *entry_info = greeter_lookup_id ("user-pw-entry"); - if (entry_info && entry_info->item && - GNOME_IS_CANVAS_WIDGET (entry_info->item) && - GTK_IS_ENTRY (GNOME_CANVAS_WIDGET (entry_info->item)->widget)) - { - GtkWidget *entry; - entry = GNOME_CANVAS_WIDGET (entry_info->item)->widget; - gtk_entry_set_text (GTK_ENTRY (entry), ""); - } - } - - return TRUE; + g_debug ("GREETER Proxy disconnected"); } int main (int argc, char *argv[]) { - char *bg_color; - struct sigaction hup; - struct sigaction term; - sigset_t mask; - GIOChannel *ctrlch; - GError *error; - char *theme_file; - char *theme_dir; - char *gdm_graphical_theme; - char *gdm_gtk_theme; - guint sid; - int r; - gint i; - int delay; - gboolean rand_theme; - - if (g_getenv ("DOING_GDM_DEVELOPMENT") != NULL) - DOING_GDM_DEVELOPMENT = TRUE; + GError *error; + const char *address; bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); @@ -1022,11 +139,6 @@ main (int argc, char *argv[]) setlocale (LC_ALL, ""); - if (ve_string_empty (g_getenv ("GDM_IS_LOCAL"))) - GDM_IS_LOCAL = FALSE; - else - GDM_IS_LOCAL = TRUE; - g_type_init (); if (! gdm_settings_client_init (GDMCONFDIR "/gdm.schemas", "/")) { @@ -1039,477 +151,82 @@ main (int argc, char *argv[]) * because the atk-bridge will crash. */ gdk_init (&argc, &argv); - if (! DOING_GDM_DEVELOPMENT) { - gdm_common_atspi_launch (); - } - + gdm_common_atspi_launch (); gtk_init (&argc, &argv); - gdm_common_setup_cursor (GDK_WATCH); - gdm_common_log_init (); /*gdm_common_log_set_debug (gdm_settings_client_get_bool (GDM_KEY_DEBUG));*/ gdm_common_log_set_debug (TRUE); - { - char *gtkrc; - gdm_settings_client_get_string (GDM_KEY_GTKRC, >krc); - if (gtkrc != NULL) { - gtk_rc_parse (gtkrc); - } - g_free (gtkrc); - } - - gdm_gtk_theme = g_strdup (g_getenv ("GDM_GTK_THEME")); - if (ve_string_empty (gdm_gtk_theme)) { - gdm_settings_client_get_string (GDM_KEY_GTK_THEME, &gdm_gtk_theme); - } - - if ( ! ve_string_empty (gdm_gtk_theme)) { - gdm_set_theme (gdm_gtk_theme); - } - g_free (gdm_gtk_theme); - - { - int screen; - gdm_settings_client_get_int (GDM_KEY_XINERAMA_SCREEN, &screen); - gdm_wm_screen_init (screen); - } - - r = verify_gdm_version (); - if (r != 0) - return r; - - /* Load the background as early as possible so GDM does not leave */ - /* the background unfilled. The cursor should be a watch already */ - /* but just in case */ - bg_color = NULL; - gdm_settings_client_get_string (GDM_KEY_GRAPHICAL_THEMED_COLOR, &bg_color); - - /* If a graphical theme color does not exist fallback to the plain color */ - if (ve_string_empty (bg_color)) { - g_free (bg_color); - bg_color = NULL; - gdm_settings_client_get_string (GDM_KEY_BACKGROUND_COLOR, &bg_color); - } - gdm_common_setup_background_color (bg_color); - g_free (bg_color); - - greeter_session_init (); - - { - char *locale_file; - gdm_settings_client_get_string (GDM_KEY_LOCALE_FILE, &locale_file); - gdm_lang_initialize_model (locale_file); - g_free (locale_file); - } - - hup.sa_handler = ve_signal_notify; - hup.sa_flags = 0; - sigemptyset (&hup.sa_mask); - sigaddset (&hup.sa_mask, SIGCHLD); - - if (sigaction (SIGHUP, &hup, NULL) < 0) { - gdm_common_fail_greeter ("%s: Error setting up %s signal handler: %s", "main", - "HUP", strerror (errno)); - } - - term.sa_handler = greeter_done; - term.sa_flags = 0; - sigemptyset (&term.sa_mask); - sigaddset (&term.sa_mask, SIGCHLD); - - if G_UNLIKELY (sigaction (SIGINT, &term, NULL) < 0) { - gdm_common_fail_greeter ("%s: Error setting up %s signal handler: %s", "main", - "INT", strerror (errno)); - } - - if G_UNLIKELY (sigaction (SIGTERM, &term, NULL) < 0) { - gdm_common_fail_greeter ("%s: Error setting up %s signal handler: %s", "main", - "TERM", strerror (errno)); - } - - sigemptyset (&mask); - sigaddset (&mask, SIGTERM); - sigaddset (&mask, SIGHUP); - sigaddset (&mask, SIGINT); - - if G_UNLIKELY (sigprocmask (SIG_UNBLOCK, &mask, NULL) == -1) { - gdm_common_fail_greeter ("Could not set signal mask!"); - } - - /* ignore SIGCHLD */ - sigemptyset (&mask); - sigaddset (&mask, SIGCHLD); - - if G_UNLIKELY (sigprocmask (SIG_BLOCK, &mask, NULL) == -1) { - gdm_common_fail_greeter ("Could not set signal mask!"); - } - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - - if G_UNLIKELY (DOING_GDM_DEVELOPMENT) { - g_signal_connect (G_OBJECT (window), "key_press_event", - G_CALLBACK (key_press_event), NULL); - } - - canvas = gnome_canvas_new_aa (); - GTK_WIDGET_UNSET_FLAGS (canvas, GTK_CAN_FOCUS); - gnome_canvas_set_scroll_region (GNOME_CANVAS (canvas), - 0.0, 0.0, - (double) gdm_wm_screen.width, - (double) gdm_wm_screen.height); - gtk_window_set_decorated (GTK_WINDOW (window), FALSE); - gtk_window_set_default_size (GTK_WINDOW (window), - gdm_wm_screen.width, - gdm_wm_screen.height); - gtk_container_add (GTK_CONTAINER (window), canvas); - - /* - * Initialize the value with the default value so the first time it - * is displayed it doesn't show as 0. Also determine if the Halt, - * Reboot, Suspend and Configurator commands work. - */ - gdm_settings_client_get_int (GDM_KEY_TIMED_LOGIN_DELAY, &gdm_timed_delay); - - { - char *halt; - char *reboot; - char *suspend; - char *configurator; - - gdm_settings_client_get_string (GDM_KEY_HALT, &halt); - gdm_settings_client_get_string (GDM_KEY_REBOOT, &reboot); - gdm_settings_client_get_string (GDM_KEY_SUSPEND, &suspend); - gdm_settings_client_get_string (GDM_KEY_CONFIGURATOR, &configurator); - GdmHaltFound = gdm_working_command_exists (halt); - GdmRebootFound = gdm_working_command_exists (reboot); - GdmSuspendFound = gdm_working_command_exists (suspend); - GdmConfiguratorFound = gdm_working_command_exists (configurator); - - g_free (configurator); - g_free (suspend); - g_free (reboot); - g_free (halt); - } - - GdmCustomCmdsFound = g_new0 (gboolean, GDM_CUSTOM_COMMAND_MAX); - for (i = 0; i < GDM_CUSTOM_COMMAND_MAX; i++) { - char *key_string = NULL; - char *val; - - /* For each possible custom command */ - key_string = g_strdup_printf ("%s%d", GDM_KEY_CUSTOM_CMD_TEMPLATE, i); - - gdm_settings_client_get_string (key_string, &val); - GdmCustomCmdsFound[i] = gdm_working_command_exists (val); - if (GdmCustomCmdsFound[i]) - GdmAnyCustomCmdsFound = TRUE; - - g_free (val); - g_free (key_string); - } - - gdm_settings_client_get_boolean (GDM_KEY_GRAPHICAL_THEME_RAND, &rand_theme); - if (g_getenv ("GDM_THEME") != NULL) { - gdm_graphical_theme = g_strdup (g_getenv ("GDM_THEME")); - } else if (rand_theme) { - gdm_graphical_theme = get_random_theme (); - } else { - gdm_settings_client_get_string (GDM_KEY_GRAPHICAL_THEME, &gdm_graphical_theme); + address = g_getenv ("GDM_GREETER_DBUS_ADDRESS"); + if (address == NULL) { + g_warning ("GDM_GREETER_DBUS_ADDRESS not set"); + exit (1); } - theme_file = get_theme_file (gdm_graphical_theme, &theme_dir); - - error = NULL; - root = greeter_parse (theme_file, - theme_dir, - GNOME_CANVAS (canvas), - gdm_wm_screen.width, - gdm_wm_screen.height, - &error); - - if G_UNLIKELY (root == NULL) { - GtkWidget *dialog; - char *s; - char *tmp; - - gdm_wm_init (0); - gdm_wm_focus_new_windows (TRUE); - - tmp = ve_filename_to_utf8 (ve_sure_string (gdm_graphical_theme)); - s = g_strdup_printf (_("There was an error loading the " - "theme %s"), tmp); - g_free (tmp); - dialog = hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - s, - (error && error->message) ? error->message : ""); - g_free (s); - - gtk_widget_show_all (dialog); - gdm_wm_center_window (GTK_WINDOW (dialog)); - - gdm_common_setup_cursor (GDK_LEFT_PTR); + g_debug ("GREETER connecting to address: %s", address); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - if (DOING_GDM_DEVELOPMENT) { - exit (1); + error = NULL; + connection = dbus_g_connection_open (address, &error); + if (connection == NULL) { + if (error != NULL) { + g_warning ("error opening connection: %s", error->message); + g_error_free (error); + } else { + g_warning ("Unable to open connection"); } - } - - g_free (gdm_graphical_theme); - - if G_UNLIKELY (error) - g_clear_error (&error); - - /* Try circles.xml */ - if G_UNLIKELY (root == NULL) { - g_free (theme_file); - g_free (theme_dir); - theme_file = get_theme_file ("circles", &theme_dir); - root = greeter_parse (theme_file, - theme_dir, - GNOME_CANVAS (canvas), - gdm_wm_screen.width, - gdm_wm_screen.height, - NULL); - } - - g_free (theme_file); - - if G_UNLIKELY (root != NULL && greeter_lookup_id ("user-pw-entry") == NULL) { - GtkWidget *dialog; - - gdm_wm_init (0); - gdm_wm_focus_new_windows (TRUE); - - dialog = hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("The greeter theme is corrupt"), - _("The theme does not contain " - "definition for the username/password " - "entry element.")); - - gtk_widget_show_all (dialog); - gdm_wm_center_window (GTK_WINDOW (dialog)); - - gdm_common_setup_cursor (GDK_LEFT_PTR); - - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - root = NULL; - } - - /* FIXME: beter information should be printed */ - if G_UNLIKELY (DOING_GDM_DEVELOPMENT && root == NULL) { - g_warning ("No theme could be loaded"); exit (1); - } - - if G_UNLIKELY (root == NULL) { - GtkWidget *dialog; - - gdm_wm_init (0); - gdm_wm_focus_new_windows (TRUE); - - dialog = hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("There was an error loading the " - "theme, and the default theme " - "could not be loaded. " - "Attempting to start the " - "standard greeter"), - ""); - - gtk_widget_show_all (dialog); - gdm_wm_center_window (GTK_WINDOW (dialog)); - - gdm_common_setup_cursor (GDK_LEFT_PTR); - - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - execl (LIBEXECDIR "/gdmlogin", LIBEXECDIR "/gdmlogin", NULL); - execlp ("gdmlogin", "gdmlogin", NULL); - - dialog = hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("The GTK+ greeter could not be started. " - "This display will abort and you may " - "have to login another way and fix the " - "installation of GDM"), - ""); - - gtk_widget_show_all (dialog); - gdm_wm_center_window (GTK_WINDOW (dialog)); - - gdm_common_setup_cursor (GDK_LEFT_PTR); - - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - - _exit (DISPLAY_ABORT); - } - - greeter_layout (root, GNOME_CANVAS (canvas)); - - greeter_setup_items (); - - if G_LIKELY (! DOING_GDM_DEVELOPMENT) { - ctrlch = g_io_channel_unix_new (STDIN_FILENO); - g_io_channel_set_encoding (ctrlch, NULL, NULL); - g_io_channel_set_buffered (ctrlch, TRUE); - g_io_channel_set_flags (ctrlch, - g_io_channel_get_flags (ctrlch) | G_IO_FLAG_NONBLOCK, - NULL); - g_io_add_watch (ctrlch, - G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP | G_IO_NVAL, - (GIOFunc) greeter_ctrl_handler, - NULL); - g_io_channel_unref (ctrlch); - } - - gdm_common_setup_blinking (); - - gtk_widget_show_all (window); - gtk_window_move (GTK_WINDOW (window), gdm_wm_screen.x, gdm_wm_screen.y); - gtk_widget_show_now (window); - - greeter_item_ulist_unset_selected_user (); - greeter_item_ulist_enable (); - greeter_item_ulist_check_show_userlist (); - - /* can it ever happen that it'd be NULL here ??? */ - if G_UNLIKELY (window->window != NULL) { - gdm_wm_init (GDK_WINDOW_XWINDOW (window->window)); - - /* Run the focus, note that this will work no matter what - * since gdm_wm_init will set the display to the gdk one - * if it fails */ - gdm_wm_focus_window (GDK_WINDOW_XWINDOW (window->window)); - } - - if G_UNLIKELY (session_dir_whacked_out) { - GtkWidget *dialog; - - gdm_wm_focus_new_windows (TRUE); - - dialog = hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("Session directory is missing"), - _("Your session directory is missing or empty! " - "There are two available sessions you can use, but " - "you should log in and correct the gdm configuration.")); - gtk_widget_show_all (dialog); - gdm_wm_center_window (GTK_WINDOW (dialog)); - - gdm_common_setup_cursor (GDK_LEFT_PTR); - - gdm_wm_no_login_focus_push (); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - gdm_wm_no_login_focus_pop (); - } - - if G_UNLIKELY (g_getenv ("GDM_WHACKED_GREETER_CONFIG") != NULL) { - GtkWidget *dialog; - - gdm_wm_focus_new_windows (TRUE); - - dialog = hig_dialog_new (NULL /* parent */, - GTK_DIALOG_MODAL /* flags */, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_OK, - _("Configuration is not correct"), - _("The configuration file contains an invalid command " - "line for the login dialog, so running the " - "default command. Please fix your configuration.")); - - gtk_widget_show_all (dialog); - gdm_wm_center_window (GTK_WINDOW (dialog)); - - gdm_common_setup_cursor (GDK_LEFT_PTR); - - gdm_wm_no_login_focus_push (); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); - gdm_wm_no_login_focus_pop (); - } - - /* if a flexiserver, reap self after some time */ - gdm_settings_client_get_int (GDM_KEY_FLEXI_REAP_DELAY_MINUTES, &delay); - if (delay > 0 && ! ve_string_empty (g_getenv ("GDM_FLEXI_SERVER")) && - /* but don't reap Xnest flexis */ - ve_string_empty (g_getenv ("GDM_PARENT_DISPLAY"))) { - sid = g_signal_lookup ("activate", - GTK_TYPE_MENU_ITEM); - g_signal_add_emission_hook (sid, - 0 /* detail */, - delay_reaping, - NULL /* data */, - NULL /* destroy_notify */); - - sid = g_signal_lookup ("key_press_event", - GTK_TYPE_WIDGET); - g_signal_add_emission_hook (sid, - 0 /* detail */, - delay_reaping, - NULL /* data */, - NULL /* destroy_notify */); - - sid = g_signal_lookup ("button_press_event", - GTK_TYPE_WIDGET); - g_signal_add_emission_hook (sid, - 0 /* detail */, - delay_reaping, - NULL /* data */, - NULL /* destroy_notify */); + } - last_reap_delay = time (NULL); - g_timeout_add (60*1000, reap_flexiserver, NULL); + g_debug ("GREETER creating proxy for peer: %s", SERVER_DBUS_PATH); + server_proxy = dbus_g_proxy_new_for_peer (connection, + SERVER_DBUS_PATH, + SERVER_DBUS_INTERFACE); + if (server_proxy == NULL) { + g_warning ("Unable to create proxy for peer"); + exit (1); } - sid = g_signal_lookup ("event", - GTK_TYPE_WIDGET); - g_signal_add_emission_hook (sid, - 0 /* detail */, - gdm_event, - NULL /* data */, - NULL /* destroy_notify */); - - gdm_wm_restore_wm_order (); - - { - char *msg_file; - char *msg_font; - - gdm_settings_client_get_string (GDM_KEY_INFO_MSG_FILE, &msg_file); - gdm_settings_client_get_string (GDM_KEY_INFO_MSG_FONT, &msg_font); + g_signal_connect (server_proxy, "destroy", G_CALLBACK (proxy_destroyed), NULL); + + /* FIXME: not sure why introspection isn't working */ + dbus_g_proxy_add_signal (server_proxy, "InfoQuery", G_TYPE_STRING, G_TYPE_INVALID); + dbus_g_proxy_add_signal (server_proxy, "SecretInfoQuery", G_TYPE_STRING, G_TYPE_INVALID); + dbus_g_proxy_add_signal (server_proxy, "Info", G_TYPE_STRING, G_TYPE_INVALID); + dbus_g_proxy_add_signal (server_proxy, "Problem", G_TYPE_STRING, G_TYPE_INVALID); + + dbus_g_proxy_connect_signal (server_proxy, + "InfoQuery", + G_CALLBACK (on_info_query), + NULL, + NULL); + dbus_g_proxy_connect_signal (server_proxy, + "SecretInfoQuery", + G_CALLBACK (on_secret_info_query), + NULL, + NULL); + dbus_g_proxy_connect_signal (server_proxy, + "Info", + G_CALLBACK (on_info), + NULL, + NULL); + dbus_g_proxy_connect_signal (server_proxy, + "Problem", + G_CALLBACK (on_problem), + NULL, + NULL); + + greeter = gdm_themed_greeter_new (); + g_signal_connect (greeter, + "query-answer", + G_CALLBACK (on_query_answer), + NULL); + gtk_main (); - gdm_wm_show_info_msg_dialog (msg_file, msg_font); - g_free (msg_font); - g_free (msg_file); + if (greeter != NULL) { + g_object_unref (greeter); } - gdm_common_setup_cursor (GDK_LEFT_PTR); - gdm_wm_center_cursor (); - gdm_common_pre_fetch_launch (); - gtk_main (); - return 0; } diff --git a/gui/greeter/greeter_item_customlist.c b/gui/greeter/greeter_item_customlist.c index b2713269..6db0dac5 100644 --- a/gui/greeter/greeter_item_customlist.c +++ b/gui/greeter/greeter_item_customlist.c @@ -33,7 +33,6 @@ #include "gdm-common.h" #include "gdm-settings-client.h" #include "gdm-settings-keys.h" -#include "gdm-socket-protocol.h" #include "greeter_item.h" #include "greeter_configuration.h" @@ -467,9 +466,6 @@ combo_selected (GtkComboBox *combo, GreeterItemInfo *item) } else { char *authdir; - if (DOING_GDM_DEVELOPMENT) - return; - id = gtk_combo_box_get_active_text (combo); gdm_settings_client_get_string (GDM_KEY_SERV_AUTHDIR, &authdir); @@ -546,9 +542,6 @@ list_selected (GtkTreeSelection *selection, GreeterItemInfo *item) } else { char *authdir; - if (DOING_GDM_DEVELOPMENT) - return; - gdm_settings_client_get_string (GDM_KEY_SERV_AUTHDIR, &authdir); file = g_strdup_printf ("%s/%s.GreeterInfo", ve_sure_string (authdir), diff --git a/gui/greeter/greeter_item_pam.c b/gui/greeter/greeter_item_pam.c index d3b9a11d..08d3df78 100644 --- a/gui/greeter/greeter_item_pam.c +++ b/gui/greeter/greeter_item_pam.c @@ -24,7 +24,7 @@ #include <gdk/gdkkeysyms.h> #include "gdm-common.h" -#include "gdm-socket-protocol.h" +#include "gdm-greeter.h" #include "greeter.h" #include "greeter_item.h" @@ -38,6 +38,7 @@ #include "gdmwm.h" #include "gdmcommon.h" +static GdmGreeter *greeter_object = NULL; static gboolean messages_to_give = FALSE; static gboolean replace_msg = TRUE; static guint err_box_clear_handler = 0; @@ -141,6 +142,7 @@ greeter_item_pam_login (GtkEntry *entry, GreeterItemInfo *info) return; } +#if 0 if (greeter_probably_login_prompt && ve_string_empty (str) && greeter_item_timed_is_timed ()) @@ -150,6 +152,7 @@ greeter_item_pam_login (GtkEntry *entry, GreeterItemInfo *info) fflush (stdout); return; } +#endif gtk_widget_set_sensitive (GTK_WIDGET (entry), FALSE); @@ -165,10 +168,15 @@ greeter_item_pam_login (GtkEntry *entry, GreeterItemInfo *info) set_text (error_info, ""); } +#if 0 tmp = ve_locale_from_utf8 (str); printf ("%c%s\n", STX, tmp); fflush (stdout); g_free (tmp); +#endif + + gdm_greeter_answer_query (greeter_object, str); + } static gboolean @@ -208,10 +216,12 @@ pam_key_release_event (GtkWidget *entry, GdkEventKey *event, gpointer data) } gboolean -greeter_item_pam_setup (void) +greeter_item_pam_setup (GdmGreeter *greeter) { GreeterItemInfo *entry_info; + greeter_object = greeter; + greeter_item_pam_error_set (FALSE); entry_info = greeter_lookup_id ("user-pw-entry"); @@ -222,8 +232,7 @@ greeter_item_pam_setup (void) GtkWidget *entry = GNOME_CANVAS_WIDGET (entry_info->item)->widget; gtk_widget_grab_focus (entry); - if ( ! DOING_GDM_DEVELOPMENT) - { + { /* hack. For some reason if we leave it blank, * we'll get a little bit of activity on first keystroke, * this way we get rid of it, it will be cleared for the diff --git a/gui/greeter/greeter_item_pam.h b/gui/greeter/greeter_item_pam.h index 0d1d3a6e..325329a4 100644 --- a/gui/greeter/greeter_item_pam.h +++ b/gui/greeter/greeter_item_pam.h @@ -20,8 +20,9 @@ #define GREETER_ITEM_PAM_H #include "greeter_item.h" +#include "gdm-greeter.h" -gboolean greeter_item_pam_setup (void); +gboolean greeter_item_pam_setup (GdmGreeter *greeter); void greeter_item_pam_prompt (const char *message, int entry_len, gboolean entry_visible); diff --git a/gui/greeter/greeter_item_timed.c b/gui/greeter/greeter_item_timed.c index c5b99693..3aa39d79 100644 --- a/gui/greeter/greeter_item_timed.c +++ b/gui/greeter/greeter_item_timed.c @@ -26,7 +26,6 @@ #include "gdm.h" #include "gdm-common.h" -#include "gdm-socket-protocol.h" #include "gdm-settings-client.h" #include "gdm-settings-keys.h" @@ -60,8 +59,10 @@ gdm_timer (gpointer data) gdm_timed_delay--; if (gdm_timed_delay <= 0) { /* timed interruption */ +#if 0 printf ("%c%c%c\n", STX, BEL, GDM_INTERRUPT_TIMED_LOGIN); fflush (stdout); +#endif } return TRUE; } diff --git a/gui/greeter/greeter_item_ulist.c b/gui/greeter/greeter_item_ulist.c index 40b309c0..1217eb61 100644 --- a/gui/greeter/greeter_item_ulist.c +++ b/gui/greeter/greeter_item_ulist.c @@ -38,7 +38,6 @@ #include "gdmuser.h" #include "gdm-common.h" -#include "gdm-socket-protocol.h" #include "gdm-settings-client.h" #include "gdm-settings-keys.h" @@ -151,8 +150,8 @@ gdm_greeter_users_init (void) NULL, defface, &size_of_users, - GDM_IS_LOCAL, - !DOING_GDM_DEVELOPMENT); + TRUE, + TRUE); } static void @@ -204,10 +203,12 @@ greeter_populate_user_list (GtkTreeModel *tm) void greeter_item_ulist_select_user (gchar *login) { +#if 0 printf ("%c%c%c%s\n", STX, BEL, GDM_INTERRUPT_SELECT_USER, login); fflush (stdout); +#endif } static void diff --git a/gui/greeter/greeter_system.c b/gui/greeter/greeter_system.c index 7785508d..2cd4c31f 100644 --- a/gui/greeter/greeter_system.c +++ b/gui/greeter/greeter_system.c @@ -37,7 +37,6 @@ #include "misc.h" #include "gdm-common.h" -#include "gdm-socket-protocol.h" #include "gdm-settings-client.h" #include "gdm-settings-keys.h" @@ -102,8 +101,10 @@ query_greeter_custom_cmd_handler (GtkWidget *widget, gpointer data) gdm_settings_client_get_string (key_string, &val); if (gdm_wm_warn_dialog (val, "", GTK_STOCK_OK, NULL, TRUE) == GTK_RESPONSE_YES) { +#if 0 printf ("%c%c%c%d\n", STX, BEL, GDM_INTERRUPT_CUSTOM_CMD, *cmd_id); fflush (stdout); +#endif } g_free (val); g_free (key_string); @@ -125,8 +126,10 @@ query_greeter_suspend_handler (void) if (gdm_wm_warn_dialog (_("Are you sure you want to suspend the computer?"), "", _("_Suspend"), NULL, TRUE) == GTK_RESPONSE_YES) { /* suspend interruption */ +#if 0 printf ("%c%c%c\n", STX, BEL, GDM_INTERRUPT_SUSPEND); fflush (stdout); +#endif } } @@ -139,8 +142,10 @@ greeter_restart_handler (void) static void greeter_custom_cmd_handler (gint cmd_id) { +#if 0 printf ("%c%c%c%d\n", STX, BEL, GDM_INTERRUPT_CUSTOM_CMD, cmd_id); fflush (stdout); +#endif } static void @@ -152,8 +157,10 @@ greeter_halt_handler (void) static void greeter_suspend_handler (void) { +#if 0 printf ("%c%c%c\n", STX, BEL, GDM_INTERRUPT_SUSPEND); fflush (stdout); +#endif } static void @@ -167,9 +174,11 @@ greeter_config_handler (void) /* we should be now fine for focusing new windows */ gdm_wm_focus_new_windows (TRUE); +#if 0 /* configure interruption */ printf ("%c%c%c\n", STX, BEL, GDM_INTERRUPT_CONFIGURE); fflush (stdout); +#endif } static void diff --git a/utils/Makefile.am b/utils/Makefile.am index 22fa8b56..35f31f77 100644 --- a/utils/Makefile.am +++ b/utils/Makefile.am @@ -47,7 +47,6 @@ libexec_SCRIPTS = \ @GDMSSHSESSION@ libexec_PROGRAMS = \ - @GDMASKPASS@ \ @GDMOPEN@ \ @GDMPREFETCH@ \ gdmtranslate @@ -57,10 +56,7 @@ bin_PROGRAMS = gdm-dmx-reconnect-proxy endif EXTRA_SCRIPTS = gdm-ssh-session -EXTRA_PROGRAMS = gdmaskpass gdmopen gdmprefetch - -gdmaskpass_SOURCES = \ - gdmaskpass.c +EXTRA_PROGRAMS = gdmopen gdmprefetch gdmtranslate_SOURCES = \ gdmtranslate.c @@ -71,11 +67,6 @@ gdmopen_SOURCES = \ gdmprefetch_SOURCES = \ gdmprefetch.c -gdmaskpass_LDADD = \ - $(INTLLIBS) \ - -lpam \ - $(EXTRA_GDMASKPASS_LIBS) - gdmopen_LDADD = \ $(INTLLIBS) diff --git a/utils/gdmaskpass.c b/utils/gdmaskpass.c deleted file mode 100644 index 206b9eda..00000000 --- a/utils/gdmaskpass.c +++ /dev/null @@ -1,58 +0,0 @@ -/* Simple pam thingie to ask the root password, for use in XKeepsCrashing - * script. */ -#include "config.h" -#include <glib/gi18n.h> -#include <stdio.h> -#include <locale.h> -#include <unistd.h> -#include <security/pam_appl.h> -#include <security/pam_misc.h> - -static struct pam_conv conv = { - misc_conv, - NULL -}; - -int -main (int argc, char *argv[]) -{ - pam_handle_t *pamh; - const char *username = "root"; - int retval; - int tries = 3; - - if (getuid () != geteuid () || - getuid () != 0) { - fprintf (stderr, _("gdmaskpass only runs as root\n")); - return 1; - } - - if (argc >= 2) { - username = argv[1]; - } - - setlocale (LC_ALL, ""); - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - textdomain (GETTEXT_PACKAGE); - - for (tries = 3; tries > 0; tries --) { - if ((retval = pam_start ("gdm", username, &conv, &pamh)) != PAM_SUCCESS) { - pam_end (pamh, retval); - pamh = NULL; - printf (_("Authentication failure!\n")); - continue; - } - if ((retval = pam_authenticate (pamh, 0)) != PAM_SUCCESS) { - pam_end (pamh, retval); - pamh = NULL; - printf (_("Authentication failure!\n")); - continue; - } - break; - } - - if (pamh != NULL) - pam_end (pamh, retval); - - return (retval == PAM_SUCCESS) ? 0 : 1; -} |