gdm r5676 - in trunk: . daemon



Author: mccann
Date: Fri Feb  1 23:36:16 2008
New Revision: 5676
URL: http://svn.gnome.org/viewvc/gdm?rev=5676&view=rev

Log:
2008-02-01  William Jon McCann  <mccann jhu edu>

	* daemon/Makefile.am:
	* daemon/gdm-chooser-session.c: (gdm_chooser_session_set_property),
	(gdm_chooser_session_get_property),
	(gdm_chooser_session_class_init), (gdm_chooser_session_init),
	(gdm_chooser_session_finalize), (gdm_chooser_session_new):
	* daemon/gdm-chooser-session.h:
	* daemon/gdm-factory-slave.c: (run_greeter),
	(gdm_factory_slave_stop):
	* daemon/gdm-greeter-session.c: (gdm_greeter_session_set_property),
	(gdm_greeter_session_get_property),
	(gdm_greeter_session_class_init), (gdm_greeter_session_init),
	(gdm_greeter_session_finalize), (gdm_greeter_session_new):
	* daemon/gdm-greeter-session.h:
	* daemon/gdm-simple-slave.c: (start_session_timeout),
	(run_greeter), (gdm_simple_slave_stop):
	* daemon/gdm-welcome-session.c: (listify_hash),
	(open_welcome_session), (close_welcome_session),
	(get_welcome_environment), (welcome_session_child_watch),
	(spawn_child_setup), (spawn_command_line_sync_as_user),
	(spawn_command_line_async_as_user), (parse_value_as_integer),
	(parse_dbus_launch_output), (start_dbus_daemon),
	(stop_dbus_daemon), (gdm_welcome_session_spawn),
	(gdm_welcome_session_start), (wait_on_child),
	(welcome_session_died), (gdm_welcome_session_stop),
	(gdm_welcome_session_set_server_address),
	(_gdm_welcome_session_set_x11_display_name),
	(_gdm_welcome_session_set_x11_display_hostname),
	(_gdm_welcome_session_set_x11_display_device),
	(_gdm_welcome_session_set_x11_display_is_local),
	(_gdm_welcome_session_set_x11_authority_file),
	(_gdm_welcome_session_set_user_name),
	(_gdm_welcome_session_set_group_name),
	(_gdm_welcome_session_set_server_dbus_path),
	(_gdm_welcome_session_set_server_dbus_interface),
	(_gdm_welcome_session_set_command),
	(_gdm_welcome_session_set_server_env_var_name),
	(_gdm_welcome_session_set_register_ck_session),
	(gdm_welcome_session_set_property),
	(gdm_welcome_session_get_property),
	(gdm_welcome_session_constructor),
	(gdm_welcome_session_class_init), (gdm_welcome_session_init),
	(gdm_welcome_session_finalize):
	* daemon/gdm-welcome-session.h:
	* daemon/gdm-xdmcp-chooser-slave.c: (run_chooser),
	(gdm_xdmcp_chooser_slave_stop):
	Add a base class to share code between chooser and greeter sessions.



Added:
   trunk/daemon/gdm-welcome-session.c
   trunk/daemon/gdm-welcome-session.h
Modified:
   trunk/ChangeLog
   trunk/daemon/Makefile.am
   trunk/daemon/gdm-chooser-session.c
   trunk/daemon/gdm-chooser-session.h
   trunk/daemon/gdm-factory-slave.c
   trunk/daemon/gdm-greeter-session.c
   trunk/daemon/gdm-greeter-session.h
   trunk/daemon/gdm-simple-slave.c
   trunk/daemon/gdm-xdmcp-chooser-slave.c

Modified: trunk/daemon/Makefile.am
==============================================================================
--- trunk/daemon/Makefile.am	(original)
+++ trunk/daemon/Makefile.am	Fri Feb  1 23:36:16 2008
@@ -120,6 +120,8 @@
 	simple-slave-main.c 		\
 	gdm-greeter-server.c		\
 	gdm-greeter-server.h		\
+	gdm-welcome-session.c		\
+	gdm-welcome-session.h		\
 	gdm-greeter-session.c		\
 	gdm-greeter-session.h		\
 	ck-connector.h			\
@@ -156,6 +158,8 @@
 	factory-slave-main.c 		\
 	gdm-greeter-server.c		\
 	gdm-greeter-server.h		\
+	gdm-welcome-session.c		\
+	gdm-welcome-session.h		\
 	gdm-greeter-session.c		\
 	gdm-greeter-session.h		\
 	ck-connector.h			\
@@ -217,8 +221,12 @@
 
 gdm_xdmcp_chooser_slave_SOURCES = 		\
 	xdmcp-chooser-slave-main.c 		\
+	ck-connector.h				\
+	ck-connector.c				\
 	gdm-chooser-server.c			\
 	gdm-chooser-server.h			\
+	gdm-welcome-session.c			\
+	gdm-welcome-session.h			\
 	gdm-chooser-session.c			\
 	gdm-chooser-session.h			\
 	gdm-slave.c				\

Modified: trunk/daemon/gdm-chooser-session.c
==============================================================================
--- trunk/daemon/gdm-chooser-session.c	(original)
+++ trunk/daemon/gdm-chooser-session.c	Fri Feb  1 23:36:16 2008
@@ -36,665 +36,31 @@
 #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-common.h"
 
+#include "gdm-welcome-session.h"
 #include "gdm-chooser-session.h"
 
-#define DBUS_LAUNCH_COMMAND BINDIR "/dbus-launch --exit-with-session"
-
 #define GDM_CHOOSER_SERVER_DBUS_PATH      "/org/gnome/DisplayManager/ChooserServer"
 #define GDM_CHOOSER_SERVER_DBUS_INTERFACE "org.gnome.DisplayManager.ChooserServer"
 
-extern char **environ;
-
 #define GDM_CHOOSER_SESSION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_CHOOSER_SESSION, GdmChooserSessionPrivate))
 
 struct GdmChooserSessionPrivate
 {
-        char           *command;
-        GPid            pid;
-
-        char           *user_name;
-        char           *group_name;
-
-        char           *x11_display_name;
-        char           *x11_display_device;
-        char           *x11_display_hostname;
-        char           *x11_authority_file;
-
-        guint           child_watch_id;
-
-        GPid            dbus_pid;
-        char           *dbus_bus_address;
-
-        char           *server_address;
+        gpointer dummy;
 };
 
 enum {
         PROP_0,
-        PROP_X11_DISPLAY_NAME,
-        PROP_X11_DISPLAY_DEVICE,
-        PROP_X11_DISPLAY_HOSTNAME,
-        PROP_X11_AUTHORITY_FILE,
-        PROP_USER_NAME,
-        PROP_GROUP_NAME,
-        PROP_SERVER_ADDRESS,
 };
 
-enum {
-        STARTED,
-        STOPPED,
-        EXITED,
-        DIED,
-        LAST_SIGNAL
-};
-
-static guint signals [LAST_SIGNAL] = { 0, };
-
 static void     gdm_chooser_session_class_init    (GdmChooserSessionClass *klass);
 static void     gdm_chooser_session_init          (GdmChooserSession      *chooser_session);
 static void     gdm_chooser_session_finalize      (GObject                *object);
 
-G_DEFINE_TYPE (GdmChooserSession, gdm_chooser_session, G_TYPE_OBJECT)
-
-static void
-listify_hash (const char *key,
-              const char *value,
-              GPtrArray  *env)
-{
-        char *str;
-        str = g_strdup_printf ("%s=%s", key, value);
-        g_debug ("GdmChooserSession: chooser environment: %s", str);
-        g_ptr_array_add (env, str);
-}
-
-static GPtrArray *
-get_chooser_environment (GdmChooserSession *chooser_session)
-{
-        GPtrArray     *env;
-        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 (chooser_session->priv->dbus_bus_address != NULL) {
-                g_hash_table_insert (hash, g_strdup ("DBUS_SESSION_BUS_ADDRESS"), g_strdup (chooser_session->priv->dbus_bus_address));
-        }
-        if (chooser_session->priv->server_address != NULL) {
-                g_hash_table_insert (hash, g_strdup ("GDM_CHOOSER_DBUS_ADDRESS"), g_strdup (chooser_session->priv->server_address));
-        }
-
-        g_hash_table_insert (hash, g_strdup ("XAUTHORITY"), g_strdup (chooser_session->priv->x11_authority_file));
-        g_hash_table_insert (hash, g_strdup ("DISPLAY"), g_strdup (chooser_session->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 (chooser_session->priv->user_name));
-        g_hash_table_insert (hash, g_strdup ("USER"), g_strdup (chooser_session->priv->user_name));
-        g_hash_table_insert (hash, g_strdup ("USERNAME"), g_strdup (chooser_session->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 (chooser_session->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));
-        }
-
-
-        g_hash_table_insert (hash, g_strdup ("PATH"), g_strdup (g_getenv ("PATH")));
-
-        g_hash_table_insert (hash, g_strdup ("RUNNING_UNDER_GDM"), g_strdup ("true"));
-
-        g_hash_table_foreach (hash, (GHFunc)listify_hash, env);
-        g_hash_table_destroy (hash);
-
-        g_ptr_array_add (env, NULL);
-
-        return env;
-}
-
-static void
-chooser_session_child_watch (GPid               pid,
-                             int                status,
-                             GdmChooserSession *session)
-{
-        g_debug ("GdmChooserSession: child (pid:%d) done (%s:%d)",
-                 (int) pid,
-                 WIFEXITED (status) ? "status"
-                 : WIFSIGNALED (status) ? "signal"
-                 : "unknown",
-                 WIFEXITED (status) ? WEXITSTATUS (status)
-                 : WIFSIGNALED (status) ? WTERMSIG (status)
-                 : -1);
-
-        if (WIFEXITED (status)) {
-                int code = WEXITSTATUS (status);
-                g_signal_emit (session, signals [EXITED], 0, code);
-        } else if (WIFSIGNALED (status)) {
-                int num = WTERMSIG (status);
-                g_signal_emit (session, signals [DIED], 0, num);
-        }
-
-        g_spawn_close_pid (session->priv->pid);
-        session->priv->pid = -1;
-}
-
-typedef struct {
-        const char *user_name;
-        const char *group_name;
-} SpawnChildData;
-
-static void
-spawn_child_setup (SpawnChildData *data)
-{
-        struct passwd *pwent;
-        struct group  *grent;
-
-        if (data->user_name == NULL) {
-                return;
-        }
-
-        pwent = getpwnam (data->user_name);
-        if (pwent == NULL) {
-                g_warning (_("User %s doesn't exist"),
-                           data->user_name);
-                _exit (1);
-        }
-
-        grent = getgrnam (data->group_name);
-        if (grent == NULL) {
-                g_warning (_("Group %s doesn't exist"),
-                           data->group_name);
-                _exit (1);
-        }
-
-        g_debug ("GdmChooserSession: 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);
-        }
-
-        if (setsid () < 0) {
-                g_debug ("GdmChooserSession: could not set pid '%u' as leader of new session and process group - %s",
-                         (guint) getpid (), g_strerror (errno));
-                _exit (2);
-        }
-}
-
-static gboolean
-spawn_command_line_sync_as_user (const char *command_line,
-                                 const char *user_name,
-                                 const char *group_name,
-                                 char       **env,
-                                 char       **std_output,
-                                 char       **std_error,
-                                 int         *exit_status,
-                                 GError     **error)
-{
-        char           **argv;
-        GError          *local_error;
-        gboolean         ret;
-        gboolean         res;
-        SpawnChildData   data;
-
-        ret = FALSE;
-
-        argv = NULL;
-        local_error = NULL;
-        if (! g_shell_parse_argv (command_line, NULL, &argv, &local_error)) {
-                g_warning ("Could not parse command: %s", local_error->message);
-                g_propagate_error (error, local_error);
-                goto out;
-        }
-
-        data.user_name = user_name;
-        data.group_name = group_name;
-
-        local_error = NULL;
-        res = g_spawn_sync (NULL,
-                            argv,
-                            env,
-                            G_SPAWN_SEARCH_PATH,
-                            (GSpawnChildSetupFunc)spawn_child_setup,
-                            &data,
-                            std_output,
-                            std_error,
-                            exit_status,
-                            &local_error);
-
-        if (! res) {
-                g_warning ("Could not spawn command: %s", local_error->message);
-                g_propagate_error (error, local_error);
-                goto out;
-        }
-
-        ret = TRUE;
- out:
-        g_strfreev (argv);
-
-        return ret;
-}
-
-static gboolean
-spawn_command_line_async_as_user (const char *command_line,
-                                  const char *user_name,
-                                  const char *group_name,
-                                  char      **env,
-                                  GPid       *child_pid,
-                                  GError    **error)
-{
-        char           **argv;
-        GError          *local_error;
-        gboolean         ret;
-        gboolean         res;
-        SpawnChildData   data;
-
-        ret = FALSE;
-
-        argv = NULL;
-        local_error = NULL;
-        if (! g_shell_parse_argv (command_line, NULL, &argv, &local_error)) {
-                g_warning ("Could not parse command: %s", local_error->message);
-                g_propagate_error (error, local_error);
-                goto out;
-        }
-
-        data.user_name = user_name;
-        data.group_name = group_name;
-
-        local_error = NULL;
-        res = g_spawn_async (NULL,
-                             argv,
-                             env,
-                             G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
-                             (GSpawnChildSetupFunc)spawn_child_setup,
-                             &data,
-                             child_pid,
-                             &local_error);
-        if (! res) {
-                g_warning ("Could not spawn command: %s", local_error->message);
-                g_propagate_error (error, local_error);
-                goto out;
-        }
-
-        ret = TRUE;
- out:
-        g_strfreev (argv);
-
-        return ret;
-}
-
-static gboolean
-parse_value_as_integer (const char *value,
-                        int        *intval)
-{
-        char *end_of_valid_int;
-        glong long_value;
-        gint  int_value;
-
-        errno = 0;
-        long_value = strtol (value, &end_of_valid_int, 10);
-
-        if (*value == '\0' || *end_of_valid_int != '\0') {
-                return FALSE;
-        }
-
-        int_value = long_value;
-        if (int_value != long_value || errno == ERANGE) {
-                return FALSE;
-        }
-
-        *intval = int_value;
-
-        return TRUE;
-}
-
-static gboolean
-parse_dbus_launch_output (const char *output,
-                          char      **addressp,
-                          GPid       *pidp)
-{
-        GRegex     *re;
-        GMatchInfo *match_info;
-        gboolean    ret;
-        gboolean    res;
-        GError     *error;
-
-        ret = FALSE;
-
-        error = NULL;
-        re = g_regex_new ("DBUS_SESSION_BUS_ADDRESS=(.+)\nDBUS_SESSION_BUS_PID=([0-9]+)", 0, 0, &error);
-        if (re == NULL) {
-                g_critical (error->message);
-        }
-
-        g_regex_match (re, output, 0, &match_info);
-
-        res = g_match_info_matches (match_info);
-        if (! res) {
-                g_warning ("Unable to parse output: %s", output);
-                goto out;
-        }
-
-        if (addressp != NULL) {
-                *addressp = g_strdup (g_match_info_fetch (match_info, 1));
-        }
-
-        if (pidp != NULL) {
-                int      pid;
-                gboolean res;
-                res = parse_value_as_integer (g_match_info_fetch (match_info, 2), &pid);
-                if (res) {
-                        *pidp = pid;
-                } else {
-                        *pidp = 0;
-                }
-        }
-
-        ret = TRUE;
-
- out:
-        g_match_info_free (match_info);
-        g_regex_unref (re);
-
-        return ret;
-}
-
-static gboolean
-start_dbus_daemon (GdmChooserSession *chooser_session)
-{
-        gboolean   res;
-        char      *std_out;
-        char      *std_err;
-        int        exit_status;
-        GError    *error;
-        GPtrArray *env;
-
-        env = get_chooser_environment (chooser_session);
-
-        error = NULL;
-        res = spawn_command_line_sync_as_user (DBUS_LAUNCH_COMMAND,
-                                               chooser_session->priv->user_name,
-                                               chooser_session->priv->group_name,
-                                               (char **)env->pdata,
-                                               &std_out,
-                                               &std_err,
-                                               &exit_status,
-                                               &error);
-        g_ptr_array_foreach (env, (GFunc)g_free, NULL);
-        g_ptr_array_free (env, TRUE);
-
-        if (! res) {
-                g_warning ("Unable to launch D-Bus daemon: %s", error->message);
-                g_error_free (error);
-                goto out;
-        }
-
-        /* pull the address and pid from the output */
-        res = parse_dbus_launch_output (std_out,
-                                        &chooser_session->priv->dbus_bus_address,
-                                        &chooser_session->priv->dbus_pid);
-        if (! res) {
-                g_warning ("Unable to parse D-Bus launch output");
-        } else {
-                g_debug ("GdmChooserSession: Started D-Bus daemon on pid %d", chooser_session->priv->dbus_pid);
-        }
- out:
-        return res;
-}
-
-static gboolean
-stop_dbus_daemon (GdmChooserSession *chooser_session)
-{
-        if (chooser_session->priv->dbus_pid > 0) {
-                gdm_signal_pid (-1 * chooser_session->priv->dbus_pid, SIGTERM);
-                chooser_session->priv->dbus_pid = 0;
-        }
-        return TRUE;
-}
-
-static gboolean
-gdm_chooser_session_spawn (GdmChooserSession *chooser_session)
-{
-        GError          *error;
-        GPtrArray       *env;
-        gboolean         ret;
-        gboolean         res;
-
-        ret = FALSE;
-
-        g_debug ("GdmChooserSession: Running chooser_session process: %s", chooser_session->priv->command);
-
-        res = start_dbus_daemon (chooser_session);
-        if (! res) {
-                /* FIXME: */
-        }
-
-        env = get_chooser_environment (chooser_session);
-
-        error = NULL;
-
-        ret = spawn_command_line_async_as_user (chooser_session->priv->command,
-                                                chooser_session->priv->user_name,
-                                                chooser_session->priv->group_name,
-                                                (char **)env->pdata,
-                                                &chooser_session->priv->pid,
-                                                &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",
-                           chooser_session->priv->command,
-                           error->message);
-                g_error_free (error);
-                goto out;
-        } else {
-                g_debug ("GdmChooserSession: ChooserSession on pid %d", (int)chooser_session->priv->pid);
-        }
-
-        chooser_session->priv->child_watch_id = g_child_watch_add (chooser_session->priv->pid,
-                                                                   (GChildWatchFunc)chooser_session_child_watch,
-                                                                   chooser_session);
-
- out:
-
-        return ret;
-}
-
-/**
- * gdm_chooser_session_start:
- * @disp: Pointer to a GdmDisplay structure
- *
- * Starts a local X chooser_session. Handles retries and fatal errors properly.
- */
-gboolean
-gdm_chooser_session_start (GdmChooserSession *chooser_session)
-{
-        gboolean    res;
-
-        g_debug ("GdmChooserSession: Starting chooser...");
-
-        res = gdm_chooser_session_spawn (chooser_session);
-
-        if (res) {
-
-        }
-
-
-        return res;
-}
-
-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 ("GdmChooserSession: waitpid () should not fail");
-                }
-        }
-
-        return status;
-}
-
-static void
-chooser_session_died (GdmChooserSession *chooser_session)
-{
-        int exit_status;
-
-        g_debug ("GdmChooserSession: Waiting on process %d", chooser_session->priv->pid);
-        exit_status = wait_on_child (chooser_session->priv->pid);
-
-        if (WIFEXITED (exit_status) && (WEXITSTATUS (exit_status) != 0)) {
-                g_debug ("GdmChooserSession: Wait on child process failed");
-        } else {
-                /* exited normally */
-        }
-
-        g_spawn_close_pid (chooser_session->priv->pid);
-        chooser_session->priv->pid = -1;
-
-        g_debug ("GdmChooserSession: ChooserSession died");
-}
-
-gboolean
-gdm_chooser_session_stop (GdmChooserSession *chooser_session)
-{
-
-        if (chooser_session->priv->pid <= 1) {
-                return TRUE;
-        }
-
-        /* remove watch source before we can wait on child */
-        if (chooser_session->priv->child_watch_id > 0) {
-                g_source_remove (chooser_session->priv->child_watch_id);
-                chooser_session->priv->child_watch_id = 0;
-        }
-
-        g_debug ("GdmChooserSession: Stopping chooser_session");
-
-        gdm_signal_pid (-1 * chooser_session->priv->pid, SIGTERM);
-        chooser_session_died (chooser_session);
-
-        stop_dbus_daemon (chooser_session);
-
-        return TRUE;
-}
-
-void
-gdm_chooser_session_set_server_address (GdmChooserSession *chooser_session,
-                                        const char        *address)
-{
-        g_return_if_fail (GDM_IS_CHOOSER_SESSION (chooser_session));
-
-        g_free (chooser_session->priv->server_address);
-        chooser_session->priv->server_address = g_strdup (address);
-}
-
-static void
-_gdm_chooser_session_set_x11_display_name (GdmChooserSession *chooser_session,
-                                           const char        *name)
-{
-        g_free (chooser_session->priv->x11_display_name);
-        chooser_session->priv->x11_display_name = g_strdup (name);
-}
-
-static void
-_gdm_chooser_session_set_x11_display_hostname (GdmChooserSession *chooser_session,
-                                               const char        *name)
-{
-        g_free (chooser_session->priv->x11_display_hostname);
-        chooser_session->priv->x11_display_hostname = g_strdup (name);
-}
-
-static void
-_gdm_chooser_session_set_x11_display_device (GdmChooserSession *chooser_session,
-                                             const char        *name)
-{
-        g_free (chooser_session->priv->x11_display_device);
-        chooser_session->priv->x11_display_device = g_strdup (name);
-}
-
-static void
-_gdm_chooser_session_set_x11_authority_file (GdmChooserSession *chooser_session,
-                                             const char        *file)
-{
-        g_free (chooser_session->priv->x11_authority_file);
-        chooser_session->priv->x11_authority_file = g_strdup (file);
-}
-
-static void
-_gdm_chooser_session_set_user_name (GdmChooserSession *chooser_session,
-                                    const char        *name)
-{
-        g_free (chooser_session->priv->user_name);
-        chooser_session->priv->user_name = g_strdup (name);
-}
-
-static void
-_gdm_chooser_session_set_group_name (GdmChooserSession *chooser_session,
-                                     const char        *name)
-{
-        g_free (chooser_session->priv->group_name);
-        chooser_session->priv->group_name = g_strdup (name);
-}
+G_DEFINE_TYPE (GdmChooserSession, gdm_chooser_session, GDM_TYPE_WELCOME_SESSION)
 
 static void
 gdm_chooser_session_set_property (GObject      *object,
@@ -707,27 +73,6 @@
         self = GDM_CHOOSER_SESSION (object);
 
         switch (prop_id) {
-        case PROP_X11_DISPLAY_NAME:
-                _gdm_chooser_session_set_x11_display_name (self, g_value_get_string (value));
-                break;
-        case PROP_X11_DISPLAY_HOSTNAME:
-                _gdm_chooser_session_set_x11_display_hostname (self, g_value_get_string (value));
-                break;
-        case PROP_X11_DISPLAY_DEVICE:
-                _gdm_chooser_session_set_x11_display_device (self, g_value_get_string (value));
-                break;
-        case PROP_X11_AUTHORITY_FILE:
-                _gdm_chooser_session_set_x11_authority_file (self, g_value_get_string (value));
-                break;
-        case PROP_USER_NAME:
-                _gdm_chooser_session_set_user_name (self, g_value_get_string (value));
-                break;
-        case PROP_GROUP_NAME:
-                _gdm_chooser_session_set_group_name (self, g_value_get_string (value));
-                break;
-        case PROP_SERVER_ADDRESS:
-                gdm_chooser_session_set_server_address (self, g_value_get_string (value));
-                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -745,27 +90,6 @@
         self = GDM_CHOOSER_SESSION (object);
 
         switch (prop_id) {
-        case PROP_X11_DISPLAY_NAME:
-                g_value_set_string (value, self->priv->x11_display_name);
-                break;
-        case PROP_X11_DISPLAY_HOSTNAME:
-                g_value_set_string (value, self->priv->x11_display_hostname);
-                break;
-        case PROP_X11_DISPLAY_DEVICE:
-                g_value_set_string (value, self->priv->x11_display_device);
-                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;
-        case PROP_SERVER_ADDRESS:
-                g_value_set_string (value, self->priv->server_address);
-                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -800,98 +124,6 @@
         object_class->finalize = gdm_chooser_session_finalize;
 
         g_type_class_add_private (klass, sizeof (GdmChooserSessionPrivate));
-
-        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_DISPLAY_HOSTNAME,
-                                         g_param_spec_string ("x11-display-hostname",
-                                                              "hostname",
-                                                              "hostname",
-                                                              NULL,
-                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-        g_object_class_install_property (object_class,
-                                         PROP_X11_DISPLAY_DEVICE,
-                                         g_param_spec_string ("x11-display-device",
-                                                              "device",
-                                                              "device",
-                                                              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));
-        g_object_class_install_property (object_class,
-                                         PROP_SERVER_ADDRESS,
-                                         g_param_spec_string ("server-address",
-                                                              "server address",
-                                                              "server address",
-                                                              NULL,
-                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-        signals [STARTED] =
-                g_signal_new ("started",
-                              G_OBJECT_CLASS_TYPE (object_class),
-                              G_SIGNAL_RUN_FIRST,
-                              G_STRUCT_OFFSET (GdmChooserSessionClass, 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 (GdmChooserSessionClass, stopped),
-                              NULL,
-                              NULL,
-                              g_cclosure_marshal_VOID__VOID,
-                              G_TYPE_NONE,
-                              0);
-        signals [EXITED] =
-                g_signal_new ("exited",
-                              G_OBJECT_CLASS_TYPE (object_class),
-                              G_SIGNAL_RUN_FIRST,
-                              G_STRUCT_OFFSET (GdmChooserSessionClass, exited),
-                              NULL,
-                              NULL,
-                              g_cclosure_marshal_VOID__INT,
-                              G_TYPE_NONE,
-                              1,
-                              G_TYPE_INT);
-        signals [DIED] =
-                g_signal_new ("died",
-                              G_OBJECT_CLASS_TYPE (object_class),
-                              G_SIGNAL_RUN_FIRST,
-                              G_STRUCT_OFFSET (GdmChooserSessionClass, died),
-                              NULL,
-                              NULL,
-                              g_cclosure_marshal_VOID__INT,
-                              G_TYPE_NONE,
-                              1,
-                              G_TYPE_INT);
 }
 
 static void
@@ -899,10 +131,6 @@
 {
 
         chooser_session->priv = GDM_CHOOSER_SESSION_GET_PRIVATE (chooser_session);
-
-        chooser_session->priv->pid = -1;
-
-        chooser_session->priv->command = g_strdup (LIBEXECDIR "/gdm-simple-chooser");
 }
 
 static void
@@ -917,17 +145,6 @@
 
         g_return_if_fail (chooser_session->priv != NULL);
 
-        gdm_chooser_session_stop (chooser_session);
-
-        g_free (chooser_session->priv->command);
-        g_free (chooser_session->priv->user_name);
-        g_free (chooser_session->priv->group_name);
-        g_free (chooser_session->priv->x11_display_name);
-        g_free (chooser_session->priv->x11_display_device);
-        g_free (chooser_session->priv->x11_display_hostname);
-        g_free (chooser_session->priv->x11_authority_file);
-        g_free (chooser_session->priv->server_address);
-
         G_OBJECT_CLASS (gdm_chooser_session_parent_class)->finalize (object);
 }
 
@@ -939,6 +156,11 @@
         GObject *object;
 
         object = g_object_new (GDM_TYPE_CHOOSER_SESSION,
+                               "command", LIBEXECDIR "/gdm-simple-chooser",
+                               "server-dbus-path", GDM_CHOOSER_SERVER_DBUS_PATH,
+                               "server-dbus-interface", GDM_CHOOSER_SERVER_DBUS_INTERFACE,
+                               "server-env-var-name", "GDM_CHOOSER_DBUS_ADDRESS",
+                               "register-ck-session", FALSE,
                                "x11-display-name", display_name,
                                "x11-display-device", display_device,
                                "x11-display-hostname", display_hostname,

Modified: trunk/daemon/gdm-chooser-session.h
==============================================================================
--- trunk/daemon/gdm-chooser-session.h	(original)
+++ trunk/daemon/gdm-chooser-session.h	Fri Feb  1 23:36:16 2008
@@ -24,6 +24,8 @@
 
 #include <glib-object.h>
 
+#include "gdm-welcome-session.h"
+
 G_BEGIN_DECLS
 
 #define GDM_TYPE_CHOOSER_SESSION         (gdm_chooser_session_get_type ())
@@ -37,30 +39,19 @@
 
 typedef struct
 {
-        GObject                   parent;
+        GdmWelcomeSession         parent;
         GdmChooserSessionPrivate *priv;
 } GdmChooserSession;
 
 typedef struct
 {
-        GObjectClass   parent_class;
-
-        void (* started)           (GdmChooserSession  *chooser_session);
-        void (* stopped)           (GdmChooserSession  *chooser_session);
-        void (* exited)            (GdmChooserSession  *chooser_session,
-                                    int                 exit_code);
-        void (* died)              (GdmChooserSession  *chooser_session,
-                                    int                 signal_number);
+        GdmWelcomeSessionClass    parent_class;
 } GdmChooserSessionClass;
 
 GType                 gdm_chooser_session_get_type           (void);
 GdmChooserSession *   gdm_chooser_session_new                (const char        *display_name,
                                                               const char        *display_device,
                                                               const char        *display_hostname);
-void                  gdm_chooser_session_set_server_address (GdmChooserSession *chooser_session,
-                                                              const char        *server_address);
-gboolean              gdm_chooser_session_start              (GdmChooserSession *chooser_session);
-gboolean              gdm_chooser_session_stop               (GdmChooserSession *chooser_session);
 
 G_END_DECLS
 

Modified: trunk/daemon/gdm-factory-slave.c
==============================================================================
--- trunk/daemon/gdm-factory-slave.c	(original)
+++ trunk/daemon/gdm-factory-slave.c	Fri Feb  1 23:36:16 2008
@@ -515,8 +515,8 @@
         g_object_set (slave->priv->greeter,
                       "x11-authority-file", auth_file,
                       NULL);
-        gdm_greeter_session_set_server_address (slave->priv->greeter, address);
-        gdm_greeter_session_start (slave->priv->greeter);
+        gdm_welcome_session_set_server_address (GDM_WELCOME_SESSION (slave->priv->greeter), address);
+        gdm_welcome_session_start (GDM_WELCOME_SESSION (slave->priv->greeter));
 
         g_free (address);
 
@@ -728,7 +728,7 @@
         }
 
         if (GDM_FACTORY_SLAVE (slave)->priv->greeter != NULL) {
-                gdm_greeter_session_stop (GDM_FACTORY_SLAVE (slave)->priv->greeter);
+                gdm_welcome_session_stop (GDM_WELCOME_SESSION (GDM_FACTORY_SLAVE (slave)->priv->greeter));
                 g_object_unref (GDM_FACTORY_SLAVE (slave)->priv->greeter);
                 GDM_FACTORY_SLAVE (slave)->priv->greeter = NULL;
         }

Modified: trunk/daemon/gdm-greeter-session.c
==============================================================================
--- trunk/daemon/gdm-greeter-session.c	(original)
+++ trunk/daemon/gdm-greeter-session.c	Fri Feb  1 23:36:16 2008
@@ -36,813 +36,29 @@
 #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-common.h"
-#include "ck-connector.h"
 
+#include "gdm-welcome-session.h"
 #include "gdm-greeter-session.h"
 
-#define DBUS_LAUNCH_COMMAND BINDIR "/dbus-launch --exit-with-session"
-
 #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_SESSION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_GREETER_SESSION, GdmGreeterSessionPrivate))
 
 struct GdmGreeterSessionPrivate
 {
-        char           *command;
-        GPid            pid;
-
-        char           *user_name;
-        char           *group_name;
-
-        char           *x11_display_name;
-        char           *x11_display_device;
-        char           *x11_display_hostname;
-        char           *x11_authority_file;
-        gboolean        x11_display_is_local;
-
-        CkConnector    *ckc;
-
-        guint           child_watch_id;
-
-        GPid            dbus_pid;
-        char           *dbus_bus_address;
-
-        char           *server_address;
+        gpointer dummy;
 };
 
 enum {
         PROP_0,
-        PROP_X11_DISPLAY_NAME,
-        PROP_X11_DISPLAY_DEVICE,
-        PROP_X11_DISPLAY_HOSTNAME,
-        PROP_X11_DISPLAY_IS_LOCAL,
-        PROP_X11_AUTHORITY_FILE,
-        PROP_USER_NAME,
-        PROP_GROUP_NAME,
-        PROP_SERVER_ADDRESS,
 };
 
-enum {
-        STARTED,
-        STOPPED,
-        LAST_SIGNAL
-};
-
-static guint signals [LAST_SIGNAL] = { 0, };
-
 static void     gdm_greeter_session_class_init    (GdmGreeterSessionClass *klass);
 static void     gdm_greeter_session_init  (GdmGreeterSession      *greeter_session);
 static void     gdm_greeter_session_finalize      (GObject         *object);
 
-G_DEFINE_TYPE (GdmGreeterSession, gdm_greeter_session, G_TYPE_OBJECT)
-
-static void
-listify_hash (const char *key,
-              const char *value,
-              GPtrArray  *env)
-{
-        char *str;
-        str = g_strdup_printf ("%s=%s", key, value);
-        g_debug ("GdmGreeterSession: greeter environment: %s", str);
-        g_ptr_array_add (env, str);
-}
-
-static gboolean
-open_greeter_session (GdmGreeterSession *greeter_session)
-{
-        struct passwd *pwent;
-        const char    *session_type;
-        const char    *hostname;
-        const char    *x11_display_device;
-        int            res;
-        gboolean       ret;
-        DBusError      error;
-
-        ret = FALSE;
-
-        session_type = "LoginWindow";
-
-        pwent = getpwnam (greeter_session->priv->user_name);
-        if (pwent == NULL) {
-                /* FIXME: */
-                g_warning ("Couldn't look up uid");
-                goto out;
-        }
-
-        greeter_session->priv->ckc = ck_connector_new ();
-        if (greeter_session->priv->ckc == NULL) {
-                g_warning ("Couldn't create new ConsoleKit connector");
-                goto out;
-        }
-
-        if (greeter_session->priv->x11_display_hostname != NULL) {
-                hostname = greeter_session->priv->x11_display_hostname;
-        } else {
-                hostname = "";
-        }
-
-        if (greeter_session->priv->x11_display_device != NULL) {
-                x11_display_device = greeter_session->priv->x11_display_device;
-        } else {
-                x11_display_device = "";
-        }
-
-        g_debug ("GdmGreeterSession: Opening ConsoleKit session for user:%d x11-display:'%s' x11-display-device:'%s' remote-host-name:'%s' is-local:%d",
-                 pwent->pw_uid,
-                 greeter_session->priv->x11_display_name,
-                 x11_display_device,
-                 hostname,
-                 greeter_session->priv->x11_display_is_local);
-
-        dbus_error_init (&error);
-        res = ck_connector_open_session_with_parameters (greeter_session->priv->ckc,
-                                                         &error,
-                                                         "unix-user", &pwent->pw_uid,
-                                                         "session-type", &session_type,
-                                                         "x11-display", &greeter_session->priv->x11_display_name,
-                                                         "x11-display-device", &x11_display_device,
-                                                         "remote-host-name", &hostname,
-                                                         "is-local", &greeter_session->priv->x11_display_is_local,
-                                                         NULL);
-        if (! res) {
-                if (dbus_error_is_set (&error)) {
-                        g_warning ("%s\n", error.message);
-                        dbus_error_free (&error);
-                } else {
-                        g_warning ("cannot open CK session: OOM, D-Bus system bus not available,\n"
-                                   "ConsoleKit not available or insufficient privileges.\n");
-                }
-                goto out;
-        }
-
-        ret = TRUE;
-
- out:
-        return ret;
-}
-
-static gboolean
-close_greeter_session (GdmGreeterSession *greeter_session)
-{
-        int       res;
-        gboolean  ret;
-        DBusError error;
-
-        ret = FALSE;
-
-        if (greeter_session->priv->ckc == NULL) {
-                return FALSE;
-        }
-
-        dbus_error_init (&error);
-        res = ck_connector_close_session (greeter_session->priv->ckc, &error);
-        if (! res) {
-                if (dbus_error_is_set (&error)) {
-                        g_warning ("%s\n", error.message);
-                        dbus_error_free (&error);
-                } else {
-                        g_warning ("cannot open CK session: OOM, D-Bus system bus not available,\n"
-                                   "ConsoleKit not available or insufficient privileges.\n");
-                }
-                goto out;
-        }
-
-        ret = TRUE;
- out:
-
-        return ret;
-}
-
-static GPtrArray *
-get_greeter_environment (GdmGreeterSession *greeter_session)
-{
-        GPtrArray     *env;
-        GHashTable    *hash;
-        struct passwd *pwent;
-        static const char * const optional_environment[] = {
-            "LANG", "LANGUAGE", "LC_CTYPE", "LC_NUMERIC", "LC_TIME",
-            "LC_COLLATE", "LC_MONETARY", "LC_MESSAGES", "LC_PAPER",
-            "LC_NAME", "LC_ADDRESS", "LC_TELEPHONE", "LC_MEASUREMENT",
-            "LC_IDENTIFICATION", "LC_ALL",
-            NULL
-        };
-        int i;
-
-        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);
-
-        for (i = 0; optional_environment[i] != NULL; i++) {
-                if (g_getenv (optional_environment[i]) == NULL) {
-                        continue;
-                }
-
-                g_hash_table_insert (hash, g_strdup (optional_environment[i]),
-                                     g_strdup (g_getenv (optional_environment[i])));
-        }
-
-        if (greeter_session->priv->dbus_bus_address != NULL) {
-                g_hash_table_insert (hash, g_strdup ("DBUS_SESSION_BUS_ADDRESS"), g_strdup (greeter_session->priv->dbus_bus_address));
-        }
-        if (greeter_session->priv->server_address != NULL) {
-                g_hash_table_insert (hash, g_strdup ("GDM_GREETER_DBUS_ADDRESS"), g_strdup (greeter_session->priv->server_address));
-        }
-
-        g_hash_table_insert (hash, g_strdup ("XAUTHORITY"), g_strdup (greeter_session->priv->x11_authority_file));
-        g_hash_table_insert (hash, g_strdup ("DISPLAY"), g_strdup (greeter_session->priv->x11_display_name));
-
-#if 0
-        /* hackish ain't it */
-        set_xnest_parent_stuff ();
-#endif
-
-        if (greeter_session->priv->ckc != NULL) {
-                const char *cookie;
-                cookie = ck_connector_get_cookie (greeter_session->priv->ckc);
-                if (cookie != NULL) {
-                        g_hash_table_insert (hash, g_strdup ("XDG_SESSION_COOKIE"), g_strdup (cookie));
-                }
-        }
-
-        g_hash_table_insert (hash, g_strdup ("LOGNAME"), g_strdup (greeter_session->priv->user_name));
-        g_hash_table_insert (hash, g_strdup ("USER"), g_strdup (greeter_session->priv->user_name));
-        g_hash_table_insert (hash, g_strdup ("USERNAME"), g_strdup (greeter_session->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_session->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));
-        }
-
-
-        g_hash_table_insert (hash, g_strdup ("PATH"), g_strdup (g_getenv ("PATH")));
-
-        g_hash_table_insert (hash, g_strdup ("RUNNING_UNDER_GDM"), g_strdup ("true"));
-
-        g_hash_table_foreach (hash, (GHFunc)listify_hash, env);
-        g_hash_table_destroy (hash);
-
-        g_ptr_array_add (env, NULL);
-
-        return env;
-}
-
-static void
-greeter_session_child_watch (GPid               pid,
-                             int                status,
-                             GdmGreeterSession *greeter_session)
-{
-        g_debug ("GdmGreeterSession: 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_session->priv->pid);
-        greeter_session->priv->pid = -1;
-
-        if (greeter_session->priv->ckc != NULL) {
-                close_greeter_session (greeter_session);
-        }
-}
-
-typedef struct {
-        const char *user_name;
-        const char *group_name;
-} SpawnChildData;
-
-static void
-spawn_child_setup (SpawnChildData *data)
-{
-        struct passwd *pwent;
-        struct group  *grent;
-
-        if (data->user_name == NULL) {
-                return;
-        }
-
-        pwent = getpwnam (data->user_name);
-        if (pwent == NULL) {
-                g_warning (_("User %s doesn't exist"),
-                           data->user_name);
-                _exit (1);
-        }
-
-        grent = getgrnam (data->group_name);
-        if (grent == NULL) {
-                g_warning (_("Group %s doesn't exist"),
-                           data->group_name);
-                _exit (1);
-        }
-
-        g_debug ("GdmGreeterSession: 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);
-        }
-
-        if (setsid () < 0) {
-                g_debug ("GdmGreeterSession: could not set pid '%u' as leader of new session and process group - %s",
-                         (guint) getpid (), g_strerror (errno));
-                _exit (2);
-        }
-}
-
-static gboolean
-spawn_command_line_sync_as_user (const char *command_line,
-                                 const char *user_name,
-                                 const char *group_name,
-                                 char       **env,
-                                 char       **std_output,
-                                 char       **std_error,
-                                 int         *exit_status,
-                                 GError     **error)
-{
-        char           **argv;
-        GError          *local_error;
-        gboolean         ret;
-        gboolean         res;
-        SpawnChildData   data;
-
-        ret = FALSE;
-
-        argv = NULL;
-        local_error = NULL;
-        if (! g_shell_parse_argv (command_line, NULL, &argv, &local_error)) {
-                g_warning ("Could not parse command: %s", local_error->message);
-                g_propagate_error (error, local_error);
-                goto out;
-        }
-
-        data.user_name = user_name;
-        data.group_name = group_name;
-
-        local_error = NULL;
-        res = g_spawn_sync (NULL,
-                            argv,
-                            env,
-                            G_SPAWN_SEARCH_PATH,
-                            (GSpawnChildSetupFunc)spawn_child_setup,
-                            &data,
-                            std_output,
-                            std_error,
-                            exit_status,
-                            &local_error);
-
-        if (! res) {
-                g_warning ("Could not spawn command: %s", local_error->message);
-                g_propagate_error (error, local_error);
-                goto out;
-        }
-
-        ret = TRUE;
- out:
-        g_strfreev (argv);
-
-        return ret;
-}
-
-static gboolean
-spawn_command_line_async_as_user (const char *command_line,
-                                  const char *user_name,
-                                  const char *group_name,
-                                  char       **env,
-                                  GPid        *child_pid,
-                                  GError     **error)
-{
-        char           **argv;
-        GError          *local_error;
-        gboolean         ret;
-        gboolean         res;
-        SpawnChildData   data;
-
-        ret = FALSE;
-
-        argv = NULL;
-        local_error = NULL;
-        if (! g_shell_parse_argv (command_line, NULL, &argv, &local_error)) {
-                g_warning ("Could not parse command: %s", local_error->message);
-                g_propagate_error (error, local_error);
-                goto out;
-        }
-
-        data.user_name = user_name;
-        data.group_name = group_name;
-
-        local_error = NULL;
-        res = g_spawn_async (NULL,
-                             argv,
-                             env,
-                             G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
-                             (GSpawnChildSetupFunc)spawn_child_setup,
-                             &data,
-                             child_pid,
-                             &local_error);
-        if (! res) {
-                g_warning ("Could not spawn command: %s", local_error->message);
-                g_propagate_error (error, local_error);
-                goto out;
-        }
-
-        ret = TRUE;
- out:
-        g_strfreev (argv);
-
-        return ret;
-}
-
-static gboolean
-parse_value_as_integer (const char *value,
-                        int        *intval)
-{
-        char *end_of_valid_int;
-        glong long_value;
-        gint  int_value;
-
-        errno = 0;
-        long_value = strtol (value, &end_of_valid_int, 10);
-
-        if (*value == '\0' || *end_of_valid_int != '\0') {
-                return FALSE;
-        }
-
-        int_value = long_value;
-        if (int_value != long_value || errno == ERANGE) {
-                return FALSE;
-        }
-
-        *intval = int_value;
-
-        return TRUE;
-}
-
-static gboolean
-parse_dbus_launch_output (const char *output,
-                          char      **addressp,
-                          GPid       *pidp)
-{
-        GRegex     *re;
-        GMatchInfo *match_info;
-        gboolean    ret;
-        gboolean    res;
-        GError     *error;
-
-        ret = FALSE;
-
-        error = NULL;
-        re = g_regex_new ("DBUS_SESSION_BUS_ADDRESS=(.+)\nDBUS_SESSION_BUS_PID=([0-9]+)", 0, 0, &error);
-        if (re == NULL) {
-                g_critical (error->message);
-        }
-
-        g_regex_match (re, output, 0, &match_info);
-
-        res = g_match_info_matches (match_info);
-        if (! res) {
-                g_warning ("Unable to parse output: %s", output);
-                goto out;
-        }
-
-        if (addressp != NULL) {
-                *addressp = g_strdup (g_match_info_fetch (match_info, 1));
-        }
-
-        if (pidp != NULL) {
-                int      pid;
-                gboolean res;
-                res = parse_value_as_integer (g_match_info_fetch (match_info, 2), &pid);
-                if (res) {
-                        *pidp = pid;
-                } else {
-                        *pidp = 0;
-                }
-        }
-
-        ret = TRUE;
-
- out:
-        g_match_info_free (match_info);
-        g_regex_unref (re);
-
-        return ret;
-}
-
-static gboolean
-start_dbus_daemon (GdmGreeterSession *greeter_session)
-{
-        gboolean   res;
-        char      *std_out;
-        char      *std_err;
-        int        exit_status;
-        GError    *error;
-        GPtrArray *env;
-
-        env = get_greeter_environment (greeter_session);
-
-        error = NULL;
-        res = spawn_command_line_sync_as_user (DBUS_LAUNCH_COMMAND,
-                                               greeter_session->priv->user_name,
-                                               greeter_session->priv->group_name,
-                                               (char **)env->pdata,
-                                               &std_out,
-                                               &std_err,
-                                               &exit_status,
-                                               &error);
-        g_ptr_array_foreach (env, (GFunc)g_free, NULL);
-        g_ptr_array_free (env, TRUE);
-
-        if (! res) {
-                g_warning ("Unable to launch D-Bus daemon: %s", error->message);
-                g_error_free (error);
-                goto out;
-        }
-
-        /* pull the address and pid from the output */
-        res = parse_dbus_launch_output (std_out,
-                                        &greeter_session->priv->dbus_bus_address,
-                                        &greeter_session->priv->dbus_pid);
-        if (! res) {
-                g_warning ("Unable to parse D-Bus launch output");
-        } else {
-                g_debug ("GdmGreeterSession: Started D-Bus daemon on pid %d", greeter_session->priv->dbus_pid);
-        }
- out:
-        return res;
-}
-
-static gboolean
-stop_dbus_daemon (GdmGreeterSession *greeter_session)
-{
-        if (greeter_session->priv->dbus_pid > 0) {
-                gdm_signal_pid (-1 * greeter_session->priv->dbus_pid, SIGTERM);
-                greeter_session->priv->dbus_pid = 0;
-        }
-        return TRUE;
-}
-
-static gboolean
-gdm_greeter_session_spawn (GdmGreeterSession *greeter_session)
-{
-        GError          *error;
-        GPtrArray       *env;
-        gboolean         ret;
-        gboolean         res;
-
-        ret = FALSE;
-
-        res = start_dbus_daemon (greeter_session);
-        if (! res) {
-                /* FIXME: */
-        }
-
-#if 0
-        create_temp_auth_file (greeter_session);
-#endif
-
-        g_debug ("GdmGreeterSession: Running greeter_session process: %s", greeter_session->priv->command);
-
-        open_greeter_session (greeter_session);
-
-        env = get_greeter_environment (greeter_session);
-
-        error = NULL;
-
-        ret = spawn_command_line_async_as_user (greeter_session->priv->command,
-                                                greeter_session->priv->user_name,
-                                                greeter_session->priv->group_name,
-                                                (char **)env->pdata,
-                                                &greeter_session->priv->pid,
-                                                &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_session->priv->command,
-                           error->message);
-                g_error_free (error);
-                goto out;
-        } else {
-                g_debug ("GdmGreeterSession: GreeterSession on pid %d", (int)greeter_session->priv->pid);
-        }
-
-        greeter_session->priv->child_watch_id = g_child_watch_add (greeter_session->priv->pid,
-                                                                   (GChildWatchFunc)greeter_session_child_watch,
-                                                                   greeter_session);
-
- out:
-
-        return ret;
-}
-
-/**
- * gdm_greeter_session_start:
- * @disp: Pointer to a GdmDisplay structure
- *
- * Starts a local X greeter_session. Handles retries and fatal errors properly.
- */
-gboolean
-gdm_greeter_session_start (GdmGreeterSession *greeter_session)
-{
-        gboolean    res;
-
-        g_debug ("GdmGreeterSession: Starting greeter...");
-
-        res = gdm_greeter_session_spawn (greeter_session);
-
-        if (res) {
-
-        }
-
-
-        return res;
-}
-
-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 ("GdmGreeterSession: waitpid () should not fail");
-                }
-        }
-
-        return status;
-}
-
-static void
-greeter_session_died (GdmGreeterSession *greeter_session)
-{
-        int exit_status;
-
-        g_debug ("GdmGreeterSession: Waiting on process %d", greeter_session->priv->pid);
-        exit_status = wait_on_child (greeter_session->priv->pid);
-
-        if (WIFEXITED (exit_status) && (WEXITSTATUS (exit_status) != 0)) {
-                g_debug ("GdmGreeterSession: Wait on child process failed");
-        } else {
-                /* exited normally */
-        }
-
-        g_spawn_close_pid (greeter_session->priv->pid);
-        greeter_session->priv->pid = -1;
-
-        g_debug ("GdmGreeterSession: GreeterSession died");
-}
-
-gboolean
-gdm_greeter_session_stop (GdmGreeterSession *greeter_session)
-{
-
-        if (greeter_session->priv->pid <= 1) {
-                return TRUE;
-        }
-
-        /* remove watch source before we can wait on child */
-        if (greeter_session->priv->child_watch_id > 0) {
-                g_source_remove (greeter_session->priv->child_watch_id);
-                greeter_session->priv->child_watch_id = 0;
-        }
-
-        g_debug ("GdmGreeterSession: Stopping greeter_session");
-
-        gdm_signal_pid (-1 * greeter_session->priv->pid, SIGTERM);
-        greeter_session_died (greeter_session);
-
-        if (greeter_session->priv->ckc != NULL) {
-                close_greeter_session (greeter_session);
-        }
-
-        stop_dbus_daemon (greeter_session);
-
-        return TRUE;
-}
-
-void
-gdm_greeter_session_set_server_address (GdmGreeterSession *greeter_session,
-                                        const char        *address)
-{
-        g_return_if_fail (GDM_IS_GREETER_SESSION (greeter_session));
-
-        g_free (greeter_session->priv->server_address);
-        greeter_session->priv->server_address = g_strdup (address);
-}
-
-static void
-_gdm_greeter_session_set_x11_display_name (GdmGreeterSession *greeter_session,
-                                           const char        *name)
-{
-        g_free (greeter_session->priv->x11_display_name);
-        greeter_session->priv->x11_display_name = g_strdup (name);
-}
-
-static void
-_gdm_greeter_session_set_x11_display_hostname (GdmGreeterSession *greeter_session,
-                                               const char        *name)
-{
-        g_free (greeter_session->priv->x11_display_hostname);
-        greeter_session->priv->x11_display_hostname = g_strdup (name);
-}
-
-static void
-_gdm_greeter_session_set_x11_display_device (GdmGreeterSession *greeter_session,
-                                             const char        *name)
-{
-        g_free (greeter_session->priv->x11_display_device);
-        greeter_session->priv->x11_display_device = g_strdup (name);
-}
-
-static void
-_gdm_greeter_session_set_x11_display_is_local (GdmGreeterSession *greeter_session,
-                                               gboolean           is_local)
-{
-        greeter_session->priv->x11_display_is_local = is_local;
-}
-
-static void
-_gdm_greeter_session_set_x11_authority_file (GdmGreeterSession *greeter_session,
-                                             const char        *file)
-{
-        g_free (greeter_session->priv->x11_authority_file);
-        greeter_session->priv->x11_authority_file = g_strdup (file);
-}
-
-static void
-_gdm_greeter_session_set_user_name (GdmGreeterSession *greeter_session,
-                                    const char        *name)
-{
-        g_free (greeter_session->priv->user_name);
-        greeter_session->priv->user_name = g_strdup (name);
-}
-
-static void
-_gdm_greeter_session_set_group_name (GdmGreeterSession *greeter_session,
-                                     const char        *name)
-{
-        g_free (greeter_session->priv->group_name);
-        greeter_session->priv->group_name = g_strdup (name);
-}
+G_DEFINE_TYPE (GdmGreeterSession, gdm_greeter_session, GDM_TYPE_WELCOME_SESSION)
 
 static void
 gdm_greeter_session_set_property (GObject      *object,
@@ -855,30 +71,6 @@
         self = GDM_GREETER_SESSION (object);
 
         switch (prop_id) {
-        case PROP_X11_DISPLAY_NAME:
-                _gdm_greeter_session_set_x11_display_name (self, g_value_get_string (value));
-                break;
-        case PROP_X11_DISPLAY_HOSTNAME:
-                _gdm_greeter_session_set_x11_display_hostname (self, g_value_get_string (value));
-                break;
-        case PROP_X11_DISPLAY_DEVICE:
-                _gdm_greeter_session_set_x11_display_device (self, g_value_get_string (value));
-                break;
-        case PROP_X11_DISPLAY_IS_LOCAL:
-                _gdm_greeter_session_set_x11_display_is_local (self, g_value_get_boolean (value));
-                break;
-        case PROP_X11_AUTHORITY_FILE:
-                _gdm_greeter_session_set_x11_authority_file (self, g_value_get_string (value));
-                break;
-        case PROP_USER_NAME:
-                _gdm_greeter_session_set_user_name (self, g_value_get_string (value));
-                break;
-        case PROP_GROUP_NAME:
-                _gdm_greeter_session_set_group_name (self, g_value_get_string (value));
-                break;
-        case PROP_SERVER_ADDRESS:
-                gdm_greeter_session_set_server_address (self, g_value_get_string (value));
-                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -896,30 +88,6 @@
         self = GDM_GREETER_SESSION (object);
 
         switch (prop_id) {
-        case PROP_X11_DISPLAY_NAME:
-                g_value_set_string (value, self->priv->x11_display_name);
-                break;
-        case PROP_X11_DISPLAY_HOSTNAME:
-                g_value_set_string (value, self->priv->x11_display_hostname);
-                break;
-        case PROP_X11_DISPLAY_DEVICE:
-                g_value_set_string (value, self->priv->x11_display_device);
-                break;
-        case PROP_X11_DISPLAY_IS_LOCAL:
-                g_value_set_boolean (value, self->priv->x11_display_is_local);
-                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;
-        case PROP_SERVER_ADDRESS:
-                g_value_set_string (value, self->priv->server_address);
-                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -937,8 +105,8 @@
         klass = GDM_GREETER_SESSION_CLASS (g_type_class_peek (GDM_TYPE_GREETER_SESSION));
 
         greeter_session = GDM_GREETER_SESSION (G_OBJECT_CLASS (gdm_greeter_session_parent_class)->constructor (type,
-                                                                                                         n_construct_properties,
-                                                                                                         construct_properties));
+                                                                                                               n_construct_properties,
+                                                                                                               construct_properties));
 
         return G_OBJECT (greeter_session);
 }
@@ -954,83 +122,6 @@
         object_class->finalize = gdm_greeter_session_finalize;
 
         g_type_class_add_private (klass, sizeof (GdmGreeterSessionPrivate));
-
-        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_DISPLAY_HOSTNAME,
-                                         g_param_spec_string ("x11-display-hostname",
-                                                              "hostname",
-                                                              "hostname",
-                                                              NULL,
-                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-        g_object_class_install_property (object_class,
-                                         PROP_X11_DISPLAY_DEVICE,
-                                         g_param_spec_string ("x11-display-device",
-                                                              "device",
-                                                              "device",
-                                                              NULL,
-                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-        g_object_class_install_property (object_class,
-                                         PROP_X11_DISPLAY_IS_LOCAL,
-                                         g_param_spec_boolean ("x11-display-is-local",
-                                                               "is local",
-                                                               "is local",
-                                                               FALSE,
-                                                               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));
-        g_object_class_install_property (object_class,
-                                         PROP_SERVER_ADDRESS,
-                                         g_param_spec_string ("server-address",
-                                                              "server address",
-                                                              "server address",
-                                                              NULL,
-                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
-        signals [STARTED] =
-                g_signal_new ("started",
-                              G_OBJECT_CLASS_TYPE (object_class),
-                              G_SIGNAL_RUN_FIRST,
-                              G_STRUCT_OFFSET (GdmGreeterSessionClass, 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 (GdmGreeterSessionClass, stopped),
-                              NULL,
-                              NULL,
-                              g_cclosure_marshal_VOID__VOID,
-                              G_TYPE_NONE,
-                              0);
 }
 
 static void
@@ -1038,10 +129,6 @@
 {
 
         greeter_session->priv = GDM_GREETER_SESSION_GET_PRIVATE (greeter_session);
-
-        greeter_session->priv->pid = -1;
-
-        greeter_session->priv->command = g_strdup (LIBEXECDIR "/gdm-simple-greeter");
 }
 
 static void
@@ -1056,22 +143,6 @@
 
         g_return_if_fail (greeter_session->priv != NULL);
 
-        gdm_greeter_session_stop (greeter_session);
-
-        g_free (greeter_session->priv->command);
-        g_free (greeter_session->priv->user_name);
-        g_free (greeter_session->priv->group_name);
-        g_free (greeter_session->priv->x11_display_name);
-        g_free (greeter_session->priv->x11_display_device);
-        g_free (greeter_session->priv->x11_display_hostname);
-        g_free (greeter_session->priv->x11_authority_file);
-        g_free (greeter_session->priv->dbus_bus_address);
-        g_free (greeter_session->priv->server_address);
-
-        if (greeter_session->priv->ckc != NULL) {
-                ck_connector_unref (greeter_session->priv->ckc);
-        }
-
         G_OBJECT_CLASS (gdm_greeter_session_parent_class)->finalize (object);
 }
 
@@ -1084,6 +155,11 @@
         GObject *object;
 
         object = g_object_new (GDM_TYPE_GREETER_SESSION,
+                               "command", LIBEXECDIR "/gdm-simple-greeter",
+                               "server-dbus-path", GDM_GREETER_SERVER_DBUS_PATH,
+                               "server-dbus-interface", GDM_GREETER_SERVER_DBUS_INTERFACE,
+                               "server-env-var-name", "GDM_GREETER_DBUS_ADDRESS",
+                               "register-ck-session", FALSE,
                                "x11-display-name", display_name,
                                "x11-display-device", display_device,
                                "x11-display-hostname", display_hostname,

Modified: trunk/daemon/gdm-greeter-session.h
==============================================================================
--- trunk/daemon/gdm-greeter-session.h	(original)
+++ trunk/daemon/gdm-greeter-session.h	Fri Feb  1 23:36:16 2008
@@ -24,6 +24,8 @@
 
 #include <glib-object.h>
 
+#include "gdm-welcome-session.h"
+
 G_BEGIN_DECLS
 
 #define GDM_TYPE_GREETER_SESSION         (gdm_greeter_session_get_type ())
@@ -37,16 +39,13 @@
 
 typedef struct
 {
-        GObject                   parent;
+        GdmWelcomeSession         parent;
         GdmGreeterSessionPrivate *priv;
 } GdmGreeterSession;
 
 typedef struct
 {
-        GObjectClass   parent_class;
-
-        void (* started)           (GdmGreeterSession  *greeter_session);
-        void (* stopped)           (GdmGreeterSession  *greeter_session);
+        GdmWelcomeSessionClass    parent_class;
 } GdmGreeterSessionClass;
 
 GType                 gdm_greeter_session_get_type           (void);
@@ -54,10 +53,6 @@
                                                               const char        *display_device,
                                                               const char        *display_hostname,
                                                               gboolean           display_is_local);
-void                  gdm_greeter_session_set_server_address (GdmGreeterSession *greeter_session,
-                                                              const char        *server_address);
-gboolean              gdm_greeter_session_start              (GdmGreeterSession *greeter_session);
-gboolean              gdm_greeter_session_stop               (GdmGreeterSession *greeter_session);
 
 G_END_DECLS
 

Modified: trunk/daemon/gdm-simple-slave.c
==============================================================================
--- trunk/daemon/gdm-simple-slave.c	(original)
+++ trunk/daemon/gdm-simple-slave.c	Fri Feb  1 23:36:16 2008
@@ -256,7 +256,7 @@
                 goto out;
         }
 
-        gdm_greeter_session_stop (slave->priv->greeter);
+        gdm_welcome_session_stop (GDM_WELCOME_SESSION (slave->priv->greeter));
         gdm_greeter_server_stop (slave->priv->greeter_server);
 
         auth_file = NULL;
@@ -696,8 +696,8 @@
         g_object_set (slave->priv->greeter,
                       "x11-authority-file", auth_file,
                       NULL);
-        gdm_greeter_session_set_server_address (slave->priv->greeter, address);
-        gdm_greeter_session_start (slave->priv->greeter);
+        gdm_welcome_session_set_server_address (GDM_WELCOME_SESSION (slave->priv->greeter), address);
+        gdm_welcome_session_start (GDM_WELCOME_SESSION (slave->priv->greeter));
 
         g_free (display_id);
         g_free (display_name);
@@ -807,7 +807,7 @@
         res = GDM_SLAVE_CLASS (gdm_simple_slave_parent_class)->stop (slave);
 
         if (GDM_SIMPLE_SLAVE (slave)->priv->greeter != NULL) {
-                gdm_greeter_session_stop (GDM_SIMPLE_SLAVE (slave)->priv->greeter);
+                gdm_welcome_session_stop (GDM_WELCOME_SESSION (GDM_SIMPLE_SLAVE (slave)->priv->greeter));
                 g_object_unref (GDM_SIMPLE_SLAVE (slave)->priv->greeter);
                 GDM_SIMPLE_SLAVE (slave)->priv->greeter = NULL;
         }

Added: trunk/daemon/gdm-welcome-session.c
==============================================================================
--- (empty file)
+++ trunk/daemon/gdm-welcome-session.c	Fri Feb  1 23:36:16 2008
@@ -0,0 +1,1228 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 William Jon McCann <jmccann redhat com>
+ *
+ * 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>
+#include <signal.h>
+
+#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-common.h"
+#include "ck-connector.h"
+
+#include "gdm-welcome-session.h"
+
+#define DBUS_LAUNCH_COMMAND BINDIR "/dbus-launch --exit-with-session"
+
+extern char **environ;
+
+#define GDM_WELCOME_SESSION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_WELCOME_SESSION, GdmWelcomeSessionPrivate))
+
+struct GdmWelcomeSessionPrivate
+{
+        char           *command;
+        GPid            pid;
+
+        CkConnector    *ckc;
+
+        char           *user_name;
+        char           *group_name;
+
+        char           *x11_display_name;
+        char           *x11_display_device;
+        char           *x11_display_hostname;
+        char           *x11_authority_file;
+        gboolean        x11_display_is_local;
+
+        guint           child_watch_id;
+
+        GPid            dbus_pid;
+        char           *dbus_bus_address;
+        char           *server_dbus_path;
+        char           *server_dbus_interface;
+        char           *server_env_var_name;
+        gboolean        register_ck_session;
+
+        char           *server_address;
+};
+
+enum {
+        PROP_0,
+        PROP_X11_DISPLAY_NAME,
+        PROP_X11_DISPLAY_DEVICE,
+        PROP_X11_DISPLAY_HOSTNAME,
+        PROP_X11_AUTHORITY_FILE,
+        PROP_X11_DISPLAY_IS_LOCAL,
+        PROP_USER_NAME,
+        PROP_GROUP_NAME,
+        PROP_SERVER_ADDRESS,
+        PROP_COMMAND,
+        PROP_SERVER_DBUS_PATH,
+        PROP_SERVER_DBUS_INTERFACE,
+        PROP_SERVER_ENV_VAR_NAME,
+        PROP_REGISTER_CK_SESSION,
+};
+
+enum {
+        STARTED,
+        STOPPED,
+        EXITED,
+        DIED,
+        LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0, };
+
+static void     gdm_welcome_session_class_init    (GdmWelcomeSessionClass *klass);
+static void     gdm_welcome_session_init          (GdmWelcomeSession      *welcome_session);
+static void     gdm_welcome_session_finalize      (GObject                *object);
+
+G_DEFINE_ABSTRACT_TYPE (GdmWelcomeSession, gdm_welcome_session, G_TYPE_OBJECT)
+
+static void
+listify_hash (const char *key,
+              const char *value,
+              GPtrArray  *env)
+{
+        char *str;
+        str = g_strdup_printf ("%s=%s", key, value);
+        g_debug ("GdmWelcomeSession: welcome environment: %s", str);
+        g_ptr_array_add (env, str);
+}
+
+static gboolean
+open_welcome_session (GdmWelcomeSession *welcome_session)
+{
+        struct passwd *pwent;
+        const char    *session_type;
+        const char    *hostname;
+        const char    *x11_display_device;
+        int            res;
+        gboolean       ret;
+        DBusError      error;
+
+        ret = FALSE;
+
+        g_debug ("GdmWelcomeSession: Registering session with ConsoleKit");
+
+        session_type = "LoginWindow";
+
+        pwent = getpwnam (welcome_session->priv->user_name);
+        if (pwent == NULL) {
+                /* FIXME: */
+                g_warning ("Couldn't look up uid");
+                goto out;
+        }
+
+        welcome_session->priv->ckc = ck_connector_new ();
+        if (welcome_session->priv->ckc == NULL) {
+                g_warning ("Couldn't create new ConsoleKit connector");
+                goto out;
+        }
+
+        if (welcome_session->priv->x11_display_hostname != NULL) {
+                hostname = welcome_session->priv->x11_display_hostname;
+        } else {
+                hostname = "";
+        }
+
+        if (welcome_session->priv->x11_display_device != NULL) {
+                x11_display_device = welcome_session->priv->x11_display_device;
+        } else {
+                x11_display_device = "";
+        }
+
+        g_debug ("GdmWelcomeSession: Opening ConsoleKit session for user:%d x11-display:'%s' x11-display-device:'%s' remote-host-name:'%s' is-local:%d",
+                 pwent->pw_uid,
+                 welcome_session->priv->x11_display_name,
+                 x11_display_device,
+                 hostname,
+                 welcome_session->priv->x11_display_is_local);
+
+        dbus_error_init (&error);
+        res = ck_connector_open_session_with_parameters (welcome_session->priv->ckc,
+                                                         &error,
+                                                         "unix-user", &pwent->pw_uid,
+                                                         "session-type", &session_type,
+                                                         "x11-display", &welcome_session->priv->x11_display_name,
+                                                         "x11-display-device", &x11_display_device,
+                                                         "remote-host-name", &hostname,
+                                                         "is-local", &welcome_session->priv->x11_display_is_local,
+                                                         NULL);
+        if (! res) {
+                if (dbus_error_is_set (&error)) {
+                        g_warning ("%s\n", error.message);
+                        dbus_error_free (&error);
+                } else {
+                        g_warning ("cannot open CK session: OOM, D-Bus system bus not available,\n"
+                                   "ConsoleKit not available or insufficient privileges.\n");
+                }
+                goto out;
+        }
+
+        ret = TRUE;
+
+ out:
+        return ret;
+}
+
+static gboolean
+close_welcome_session (GdmWelcomeSession *welcome_session)
+{
+        int       res;
+        gboolean  ret;
+        DBusError error;
+
+        ret = FALSE;
+
+        if (welcome_session->priv->ckc == NULL) {
+                return FALSE;
+        }
+
+        g_debug ("GdmWelcomeSession: De-registering session from ConsoleKit");
+
+        dbus_error_init (&error);
+        res = ck_connector_close_session (welcome_session->priv->ckc, &error);
+        if (! res) {
+                if (dbus_error_is_set (&error)) {
+                        g_warning ("%s\n", error.message);
+                        dbus_error_free (&error);
+                } else {
+                        g_warning ("cannot open CK session: OOM, D-Bus system bus not available,\n"
+                                   "ConsoleKit not available or insufficient privileges.\n");
+                }
+                goto out;
+        }
+
+        ret = TRUE;
+ out:
+
+        return ret;
+}
+
+static GPtrArray *
+get_welcome_environment (GdmWelcomeSession *welcome_session)
+{
+        GPtrArray     *env;
+        GHashTable    *hash;
+        struct passwd *pwent;
+        static const char * const optional_environment[] = {
+                "LANG", "LANGUAGE", "LC_CTYPE", "LC_NUMERIC", "LC_TIME",
+                "LC_COLLATE", "LC_MONETARY", "LC_MESSAGES", "LC_PAPER",
+                "LC_NAME", "LC_ADDRESS", "LC_TELEPHONE", "LC_MEASUREMENT",
+                "LC_IDENTIFICATION", "LC_ALL",
+                NULL
+        };
+        int i;
+
+        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);
+
+        for (i = 0; optional_environment[i] != NULL; i++) {
+                if (g_getenv (optional_environment[i]) == NULL) {
+                        continue;
+                }
+
+                g_hash_table_insert (hash,
+                                     g_strdup (optional_environment[i]),
+                                     g_strdup (g_getenv (optional_environment[i])));
+        }
+
+        if (welcome_session->priv->dbus_bus_address != NULL) {
+                g_hash_table_insert (hash,
+                                     g_strdup ("DBUS_SESSION_BUS_ADDRESS"),
+                                     g_strdup (welcome_session->priv->dbus_bus_address));
+        }
+        if (welcome_session->priv->server_address != NULL) {
+                g_assert (welcome_session->priv->server_env_var_name != NULL);
+                g_hash_table_insert (hash,
+                                     g_strdup (welcome_session->priv->server_env_var_name),
+                                     g_strdup (welcome_session->priv->server_address));
+        }
+
+        g_hash_table_insert (hash, g_strdup ("XAUTHORITY"), g_strdup (welcome_session->priv->x11_authority_file));
+        g_hash_table_insert (hash, g_strdup ("DISPLAY"), g_strdup (welcome_session->priv->x11_display_name));
+
+#if 0
+        /* hackish ain't it */
+        set_xnest_parent_stuff ();
+#endif
+
+        if (welcome_session->priv->ckc != NULL) {
+                const char *cookie;
+                cookie = ck_connector_get_cookie (welcome_session->priv->ckc);
+                if (cookie != NULL) {
+                        g_hash_table_insert (hash, g_strdup ("XDG_SESSION_COOKIE"), g_strdup (cookie));
+                }
+        }
+
+        g_hash_table_insert (hash, g_strdup ("LOGNAME"), g_strdup (welcome_session->priv->user_name));
+        g_hash_table_insert (hash, g_strdup ("USER"), g_strdup (welcome_session->priv->user_name));
+        g_hash_table_insert (hash, g_strdup ("USERNAME"), g_strdup (welcome_session->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 (welcome_session->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));
+        }
+
+
+        g_hash_table_insert (hash, g_strdup ("PATH"), g_strdup (g_getenv ("PATH")));
+
+        g_hash_table_insert (hash, g_strdup ("RUNNING_UNDER_GDM"), g_strdup ("true"));
+
+        g_hash_table_foreach (hash, (GHFunc)listify_hash, env);
+        g_hash_table_destroy (hash);
+
+        g_ptr_array_add (env, NULL);
+
+        return env;
+}
+
+static void
+welcome_session_child_watch (GPid               pid,
+                             int                status,
+                             GdmWelcomeSession *session)
+{
+        g_debug ("GdmWelcomeSession: child (pid:%d) done (%s:%d)",
+                 (int) pid,
+                 WIFEXITED (status) ? "status"
+                 : WIFSIGNALED (status) ? "signal"
+                 : "unknown",
+                 WIFEXITED (status) ? WEXITSTATUS (status)
+                 : WIFSIGNALED (status) ? WTERMSIG (status)
+                 : -1);
+
+        if (WIFEXITED (status)) {
+                int code = WEXITSTATUS (status);
+                g_signal_emit (session, signals [EXITED], 0, code);
+        } else if (WIFSIGNALED (status)) {
+                int num = WTERMSIG (status);
+                g_signal_emit (session, signals [DIED], 0, num);
+        }
+
+        g_spawn_close_pid (session->priv->pid);
+        session->priv->pid = -1;
+
+        if (session->priv->ckc != NULL) {
+                close_welcome_session (session);
+        }
+}
+
+typedef struct {
+        const char *user_name;
+        const char *group_name;
+} SpawnChildData;
+
+static void
+spawn_child_setup (SpawnChildData *data)
+{
+        struct passwd *pwent;
+        struct group  *grent;
+
+        if (data->user_name == NULL) {
+                return;
+        }
+
+        pwent = getpwnam (data->user_name);
+        if (pwent == NULL) {
+                g_warning (_("User %s doesn't exist"),
+                           data->user_name);
+                _exit (1);
+        }
+
+        grent = getgrnam (data->group_name);
+        if (grent == NULL) {
+                g_warning (_("Group %s doesn't exist"),
+                           data->group_name);
+                _exit (1);
+        }
+
+        g_debug ("GdmWelcomeSession: 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);
+        }
+
+        if (setsid () < 0) {
+                g_debug ("GdmWelcomeSession: could not set pid '%u' as leader of new session and process group - %s",
+                         (guint) getpid (), g_strerror (errno));
+                _exit (2);
+        }
+}
+
+static gboolean
+spawn_command_line_sync_as_user (const char *command_line,
+                                 const char *user_name,
+                                 const char *group_name,
+                                 char       **env,
+                                 char       **std_output,
+                                 char       **std_error,
+                                 int         *exit_status,
+                                 GError     **error)
+{
+        char           **argv;
+        GError          *local_error;
+        gboolean         ret;
+        gboolean         res;
+        SpawnChildData   data;
+
+        ret = FALSE;
+
+        argv = NULL;
+        local_error = NULL;
+        if (! g_shell_parse_argv (command_line, NULL, &argv, &local_error)) {
+                g_warning ("Could not parse command: %s", local_error->message);
+                g_propagate_error (error, local_error);
+                goto out;
+        }
+
+        data.user_name = user_name;
+        data.group_name = group_name;
+
+        local_error = NULL;
+        res = g_spawn_sync (NULL,
+                            argv,
+                            env,
+                            G_SPAWN_SEARCH_PATH,
+                            (GSpawnChildSetupFunc)spawn_child_setup,
+                            &data,
+                            std_output,
+                            std_error,
+                            exit_status,
+                            &local_error);
+
+        if (! res) {
+                g_warning ("Could not spawn command: %s", local_error->message);
+                g_propagate_error (error, local_error);
+                goto out;
+        }
+
+        ret = TRUE;
+ out:
+        g_strfreev (argv);
+
+        return ret;
+}
+
+static gboolean
+spawn_command_line_async_as_user (const char *command_line,
+                                  const char *user_name,
+                                  const char *group_name,
+                                  char      **env,
+                                  GPid       *child_pid,
+                                  GError    **error)
+{
+        char           **argv;
+        GError          *local_error;
+        gboolean         ret;
+        gboolean         res;
+        SpawnChildData   data;
+
+        ret = FALSE;
+
+        argv = NULL;
+        local_error = NULL;
+        if (! g_shell_parse_argv (command_line, NULL, &argv, &local_error)) {
+                g_warning ("Could not parse command: %s", local_error->message);
+                g_propagate_error (error, local_error);
+                goto out;
+        }
+
+        data.user_name = user_name;
+        data.group_name = group_name;
+
+        local_error = NULL;
+        res = g_spawn_async (NULL,
+                             argv,
+                             env,
+                             G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
+                             (GSpawnChildSetupFunc)spawn_child_setup,
+                             &data,
+                             child_pid,
+                             &local_error);
+        if (! res) {
+                g_warning ("Could not spawn command: %s", local_error->message);
+                g_propagate_error (error, local_error);
+                goto out;
+        }
+
+        ret = TRUE;
+ out:
+        g_strfreev (argv);
+
+        return ret;
+}
+
+static gboolean
+parse_value_as_integer (const char *value,
+                        int        *intval)
+{
+        char *end_of_valid_int;
+        glong long_value;
+        gint  int_value;
+
+        errno = 0;
+        long_value = strtol (value, &end_of_valid_int, 10);
+
+        if (*value == '\0' || *end_of_valid_int != '\0') {
+                return FALSE;
+        }
+
+        int_value = long_value;
+        if (int_value != long_value || errno == ERANGE) {
+                return FALSE;
+        }
+
+        *intval = int_value;
+
+        return TRUE;
+}
+
+static gboolean
+parse_dbus_launch_output (const char *output,
+                          char      **addressp,
+                          GPid       *pidp)
+{
+        GRegex     *re;
+        GMatchInfo *match_info;
+        gboolean    ret;
+        gboolean    res;
+        GError     *error;
+
+        ret = FALSE;
+
+        error = NULL;
+        re = g_regex_new ("DBUS_SESSION_BUS_ADDRESS=(.+)\nDBUS_SESSION_BUS_PID=([0-9]+)", 0, 0, &error);
+        if (re == NULL) {
+                g_critical (error->message);
+        }
+
+        g_regex_match (re, output, 0, &match_info);
+
+        res = g_match_info_matches (match_info);
+        if (! res) {
+                g_warning ("Unable to parse output: %s", output);
+                goto out;
+        }
+
+        if (addressp != NULL) {
+                *addressp = g_strdup (g_match_info_fetch (match_info, 1));
+        }
+
+        if (pidp != NULL) {
+                int      pid;
+                gboolean res;
+                res = parse_value_as_integer (g_match_info_fetch (match_info, 2), &pid);
+                if (res) {
+                        *pidp = pid;
+                } else {
+                        *pidp = 0;
+                }
+        }
+
+        ret = TRUE;
+
+ out:
+        g_match_info_free (match_info);
+        g_regex_unref (re);
+
+        return ret;
+}
+
+static gboolean
+start_dbus_daemon (GdmWelcomeSession *welcome_session)
+{
+        gboolean   res;
+        char      *std_out;
+        char      *std_err;
+        int        exit_status;
+        GError    *error;
+        GPtrArray *env;
+
+
+        sleep(10);
+        g_debug ("GdmWelcomeSession: Starting D-Bus daemon");
+
+        env = get_welcome_environment (welcome_session);
+
+        error = NULL;
+        res = spawn_command_line_sync_as_user (DBUS_LAUNCH_COMMAND,
+                                               welcome_session->priv->user_name,
+                                               welcome_session->priv->group_name,
+                                               (char **)env->pdata,
+                                               &std_out,
+                                               &std_err,
+                                               &exit_status,
+                                               &error);
+        g_ptr_array_foreach (env, (GFunc)g_free, NULL);
+        g_ptr_array_free (env, TRUE);
+
+        if (! res) {
+                g_warning ("Unable to launch D-Bus daemon: %s", error->message);
+                g_error_free (error);
+                goto out;
+        }
+
+        /* pull the address and pid from the output */
+        res = parse_dbus_launch_output (std_out,
+                                        &welcome_session->priv->dbus_bus_address,
+                                        &welcome_session->priv->dbus_pid);
+        if (! res) {
+                g_warning ("Unable to parse D-Bus launch output");
+        } else {
+                g_debug ("GdmWelcomeSession: Started D-Bus daemon on pid %d", welcome_session->priv->dbus_pid);
+        }
+ out:
+        return res;
+}
+
+static gboolean
+stop_dbus_daemon (GdmWelcomeSession *welcome_session)
+{
+        if (welcome_session->priv->dbus_pid > 0) {
+                g_debug ("GdmWelcomeSession: Stopping D-Bus daemon");
+                gdm_signal_pid (-1 * welcome_session->priv->dbus_pid, SIGTERM);
+                welcome_session->priv->dbus_pid = 0;
+        }
+        return TRUE;
+}
+
+static gboolean
+gdm_welcome_session_spawn (GdmWelcomeSession *welcome_session)
+{
+        GError          *error;
+        GPtrArray       *env;
+        gboolean         ret;
+        gboolean         res;
+
+        ret = FALSE;
+
+        g_debug ("GdmWelcomeSession: Running welcome_session process: %s", welcome_session->priv->command);
+
+        res = start_dbus_daemon (welcome_session);
+        if (! res) {
+                /* FIXME: */
+        }
+
+        if (welcome_session->priv->register_ck_session) {
+                open_welcome_session (welcome_session);
+        }
+
+        env = get_welcome_environment (welcome_session);
+
+        error = NULL;
+
+        ret = spawn_command_line_async_as_user (welcome_session->priv->command,
+                                                welcome_session->priv->user_name,
+                                                welcome_session->priv->group_name,
+                                                (char **)env->pdata,
+                                                &welcome_session->priv->pid,
+                                                &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",
+                           welcome_session->priv->command,
+                           error->message);
+                g_error_free (error);
+                goto out;
+        } else {
+                g_debug ("GdmWelcomeSession: WelcomeSession on pid %d", (int)welcome_session->priv->pid);
+        }
+
+        welcome_session->priv->child_watch_id = g_child_watch_add (welcome_session->priv->pid,
+                                                                   (GChildWatchFunc)welcome_session_child_watch,
+                                                                   welcome_session);
+
+ out:
+
+        return ret;
+}
+
+/**
+ * gdm_welcome_session_start:
+ * @disp: Pointer to a GdmDisplay structure
+ *
+ * Starts a local X welcome_session. Handles retries and fatal errors properly.
+ */
+gboolean
+gdm_welcome_session_start (GdmWelcomeSession *welcome_session)
+{
+        gboolean    res;
+
+        g_debug ("GdmWelcomeSession: Starting welcome...");
+
+        res = gdm_welcome_session_spawn (welcome_session);
+
+        if (res) {
+
+        }
+
+
+        return res;
+}
+
+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 ("GdmWelcomeSession: waitpid () should not fail");
+                }
+        }
+
+        return status;
+}
+
+static void
+welcome_session_died (GdmWelcomeSession *welcome_session)
+{
+        int exit_status;
+
+        g_debug ("GdmWelcomeSession: Waiting on process %d", welcome_session->priv->pid);
+        exit_status = wait_on_child (welcome_session->priv->pid);
+
+        if (WIFEXITED (exit_status) && (WEXITSTATUS (exit_status) != 0)) {
+                g_debug ("GdmWelcomeSession: Wait on child process failed");
+        } else {
+                /* exited normally */
+        }
+
+        g_spawn_close_pid (welcome_session->priv->pid);
+        welcome_session->priv->pid = -1;
+
+        g_debug ("GdmWelcomeSession: WelcomeSession died");
+}
+
+gboolean
+gdm_welcome_session_stop (GdmWelcomeSession *welcome_session)
+{
+
+        if (welcome_session->priv->pid <= 1) {
+                return TRUE;
+        }
+
+        /* remove watch source before we can wait on child */
+        if (welcome_session->priv->child_watch_id > 0) {
+                g_source_remove (welcome_session->priv->child_watch_id);
+                welcome_session->priv->child_watch_id = 0;
+        }
+
+        g_debug ("GdmWelcomeSession: Stopping welcome_session");
+
+        gdm_signal_pid (-1 * welcome_session->priv->pid, SIGTERM);
+        welcome_session_died (welcome_session);
+
+        if (welcome_session->priv->ckc != NULL) {
+                close_welcome_session (welcome_session);
+        }
+
+        stop_dbus_daemon (welcome_session);
+
+        return TRUE;
+}
+
+void
+gdm_welcome_session_set_server_address (GdmWelcomeSession *welcome_session,
+                                        const char        *address)
+{
+        g_return_if_fail (GDM_IS_WELCOME_SESSION (welcome_session));
+
+        g_free (welcome_session->priv->server_address);
+        welcome_session->priv->server_address = g_strdup (address);
+}
+
+static void
+_gdm_welcome_session_set_x11_display_name (GdmWelcomeSession *welcome_session,
+                                           const char        *name)
+{
+        g_free (welcome_session->priv->x11_display_name);
+        welcome_session->priv->x11_display_name = g_strdup (name);
+}
+
+static void
+_gdm_welcome_session_set_x11_display_hostname (GdmWelcomeSession *welcome_session,
+                                               const char        *name)
+{
+        g_free (welcome_session->priv->x11_display_hostname);
+        welcome_session->priv->x11_display_hostname = g_strdup (name);
+}
+
+static void
+_gdm_welcome_session_set_x11_display_device (GdmWelcomeSession *welcome_session,
+                                             const char        *name)
+{
+        g_free (welcome_session->priv->x11_display_device);
+        welcome_session->priv->x11_display_device = g_strdup (name);
+}
+
+static void
+_gdm_welcome_session_set_x11_display_is_local (GdmWelcomeSession *welcome_session,
+                                               gboolean           is_local)
+{
+        welcome_session->priv->x11_display_is_local = is_local;
+}
+
+
+static void
+_gdm_welcome_session_set_x11_authority_file (GdmWelcomeSession *welcome_session,
+                                             const char        *file)
+{
+        g_free (welcome_session->priv->x11_authority_file);
+        welcome_session->priv->x11_authority_file = g_strdup (file);
+}
+
+static void
+_gdm_welcome_session_set_user_name (GdmWelcomeSession *welcome_session,
+                                    const char        *name)
+{
+        g_free (welcome_session->priv->user_name);
+        welcome_session->priv->user_name = g_strdup (name);
+}
+
+static void
+_gdm_welcome_session_set_group_name (GdmWelcomeSession *welcome_session,
+                                     const char        *name)
+{
+        g_free (welcome_session->priv->group_name);
+        welcome_session->priv->group_name = g_strdup (name);
+}
+
+static void
+_gdm_welcome_session_set_server_dbus_path (GdmWelcomeSession *welcome_session,
+                                           const char        *name)
+{
+        g_free (welcome_session->priv->server_dbus_path);
+        welcome_session->priv->server_dbus_path = g_strdup (name);
+}
+
+static void
+_gdm_welcome_session_set_server_dbus_interface (GdmWelcomeSession *welcome_session,
+                                                const char        *name)
+{
+        g_free (welcome_session->priv->server_dbus_interface);
+        welcome_session->priv->server_dbus_interface = g_strdup (name);
+}
+
+static void
+_gdm_welcome_session_set_command (GdmWelcomeSession *welcome_session,
+                                  const char        *name)
+{
+        g_free (welcome_session->priv->command);
+        welcome_session->priv->command = g_strdup (name);
+}
+
+static void
+_gdm_welcome_session_set_server_env_var_name (GdmWelcomeSession *welcome_session,
+                                              const char        *name)
+{
+        g_free (welcome_session->priv->server_env_var_name);
+        welcome_session->priv->server_env_var_name = g_strdup (name);
+}
+
+static void
+_gdm_welcome_session_set_register_ck_session (GdmWelcomeSession *welcome_session,
+                                              gboolean           val)
+{
+        welcome_session->priv->register_ck_session = val;
+}
+
+static void
+gdm_welcome_session_set_property (GObject      *object,
+                                  guint         prop_id,
+                                  const GValue *value,
+                                  GParamSpec   *pspec)
+{
+        GdmWelcomeSession *self;
+
+        self = GDM_WELCOME_SESSION (object);
+
+        switch (prop_id) {
+        case PROP_X11_DISPLAY_NAME:
+                _gdm_welcome_session_set_x11_display_name (self, g_value_get_string (value));
+                break;
+        case PROP_X11_DISPLAY_HOSTNAME:
+                _gdm_welcome_session_set_x11_display_hostname (self, g_value_get_string (value));
+                break;
+        case PROP_X11_DISPLAY_DEVICE:
+                _gdm_welcome_session_set_x11_display_device (self, g_value_get_string (value));
+                break;
+        case PROP_X11_DISPLAY_IS_LOCAL:
+                _gdm_welcome_session_set_x11_display_is_local (self, g_value_get_boolean (value));
+                break;
+        case PROP_X11_AUTHORITY_FILE:
+                _gdm_welcome_session_set_x11_authority_file (self, g_value_get_string (value));
+                break;
+        case PROP_USER_NAME:
+                _gdm_welcome_session_set_user_name (self, g_value_get_string (value));
+                break;
+        case PROP_GROUP_NAME:
+                _gdm_welcome_session_set_group_name (self, g_value_get_string (value));
+                break;
+        case PROP_SERVER_ADDRESS:
+                gdm_welcome_session_set_server_address (self, g_value_get_string (value));
+                break;
+        case PROP_SERVER_DBUS_PATH:
+                _gdm_welcome_session_set_server_dbus_path (self, g_value_get_string (value));
+                break;
+        case PROP_SERVER_DBUS_INTERFACE:
+                _gdm_welcome_session_set_server_dbus_interface (self, g_value_get_string (value));
+                break;
+        case PROP_REGISTER_CK_SESSION:
+                _gdm_welcome_session_set_register_ck_session (self, g_value_get_boolean (value));
+                break;
+        case PROP_SERVER_ENV_VAR_NAME:
+                _gdm_welcome_session_set_server_env_var_name (self, g_value_get_string (value));
+                break;
+        case PROP_COMMAND:
+                _gdm_welcome_session_set_command (self, g_value_get_string (value));
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static void
+gdm_welcome_session_get_property (GObject    *object,
+                                  guint       prop_id,
+                                  GValue     *value,
+                                  GParamSpec *pspec)
+{
+        GdmWelcomeSession *self;
+
+        self = GDM_WELCOME_SESSION (object);
+
+        switch (prop_id) {
+        case PROP_X11_DISPLAY_NAME:
+                g_value_set_string (value, self->priv->x11_display_name);
+                break;
+        case PROP_X11_DISPLAY_HOSTNAME:
+                g_value_set_string (value, self->priv->x11_display_hostname);
+                break;
+        case PROP_X11_DISPLAY_DEVICE:
+                g_value_set_string (value, self->priv->x11_display_device);
+                break;
+        case PROP_X11_DISPLAY_IS_LOCAL:
+                g_value_set_boolean (value, self->priv->x11_display_is_local);
+                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;
+        case PROP_SERVER_ADDRESS:
+                g_value_set_string (value, self->priv->server_address);
+                break;
+        case PROP_SERVER_DBUS_PATH:
+                g_value_set_string (value, self->priv->server_dbus_path);
+                break;
+        case PROP_SERVER_DBUS_INTERFACE:
+                g_value_set_string (value, self->priv->server_dbus_interface);
+                break;
+        case PROP_REGISTER_CK_SESSION:
+                g_value_set_boolean (value, self->priv->register_ck_session);
+                break;
+        case PROP_SERVER_ENV_VAR_NAME:
+                g_value_set_string (value, self->priv->server_env_var_name);
+                break;
+        case PROP_COMMAND:
+                g_value_set_string (value, self->priv->command);
+                break;
+        default:
+                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+                break;
+        }
+}
+
+static GObject *
+gdm_welcome_session_constructor (GType                  type,
+                                 guint                  n_construct_properties,
+                                 GObjectConstructParam *construct_properties)
+{
+        GdmWelcomeSession      *welcome_session;
+        GdmWelcomeSessionClass *klass;
+
+        klass = GDM_WELCOME_SESSION_CLASS (g_type_class_peek (GDM_TYPE_WELCOME_SESSION));
+
+        welcome_session = GDM_WELCOME_SESSION (G_OBJECT_CLASS (gdm_welcome_session_parent_class)->constructor (type,
+                                                                                                               n_construct_properties,
+                                                                                                               construct_properties));
+
+        return G_OBJECT (welcome_session);
+}
+
+static void
+gdm_welcome_session_class_init (GdmWelcomeSessionClass *klass)
+{
+        GObjectClass    *object_class = G_OBJECT_CLASS (klass);
+
+        object_class->get_property = gdm_welcome_session_get_property;
+        object_class->set_property = gdm_welcome_session_set_property;
+        object_class->constructor = gdm_welcome_session_constructor;
+        object_class->finalize = gdm_welcome_session_finalize;
+
+        g_type_class_add_private (klass, sizeof (GdmWelcomeSessionPrivate));
+
+        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_DISPLAY_HOSTNAME,
+                                         g_param_spec_string ("x11-display-hostname",
+                                                              "hostname",
+                                                              "hostname",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+        g_object_class_install_property (object_class,
+                                         PROP_X11_DISPLAY_DEVICE,
+                                         g_param_spec_string ("x11-display-device",
+                                                              "device",
+                                                              "device",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+        g_object_class_install_property (object_class,
+                                         PROP_X11_DISPLAY_IS_LOCAL,
+                                         g_param_spec_boolean ("x11-display-is-local",
+                                                               "is local",
+                                                               "is local",
+                                                               FALSE,
+                                                               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));
+        g_object_class_install_property (object_class,
+                                         PROP_SERVER_ADDRESS,
+                                         g_param_spec_string ("server-address",
+                                                              "server address",
+                                                              "server address",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+        g_object_class_install_property (object_class,
+                                         PROP_SERVER_DBUS_PATH,
+                                         g_param_spec_string ("server-dbus-path",
+                                                              "server dbus path",
+                                                              "server dbus path",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+        g_object_class_install_property (object_class,
+                                         PROP_SERVER_DBUS_INTERFACE,
+                                         g_param_spec_string ("server-dbus-interface",
+                                                              "server dbus interface",
+                                                              "server dbus interface",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+        g_object_class_install_property (object_class,
+                                         PROP_SERVER_ENV_VAR_NAME,
+                                         g_param_spec_string ("server-env-var-name",
+                                                              "server env var name",
+                                                              "server env var name",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+        g_object_class_install_property (object_class,
+                                         PROP_COMMAND,
+                                         g_param_spec_string ("command",
+                                                              "command",
+                                                              "command",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+        g_object_class_install_property (object_class,
+                                         PROP_REGISTER_CK_SESSION,
+                                         g_param_spec_boolean ("register-ck-session",
+                                                               NULL,
+                                                               NULL,
+                                                               FALSE,
+                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+        signals [STARTED] =
+                g_signal_new ("started",
+                              G_OBJECT_CLASS_TYPE (object_class),
+                              G_SIGNAL_RUN_FIRST,
+                              G_STRUCT_OFFSET (GdmWelcomeSessionClass, 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 (GdmWelcomeSessionClass, stopped),
+                              NULL,
+                              NULL,
+                              g_cclosure_marshal_VOID__VOID,
+                              G_TYPE_NONE,
+                              0);
+        signals [EXITED] =
+                g_signal_new ("exited",
+                              G_OBJECT_CLASS_TYPE (object_class),
+                              G_SIGNAL_RUN_FIRST,
+                              G_STRUCT_OFFSET (GdmWelcomeSessionClass, exited),
+                              NULL,
+                              NULL,
+                              g_cclosure_marshal_VOID__INT,
+                              G_TYPE_NONE,
+                              1,
+                              G_TYPE_INT);
+        signals [DIED] =
+                g_signal_new ("died",
+                              G_OBJECT_CLASS_TYPE (object_class),
+                              G_SIGNAL_RUN_FIRST,
+                              G_STRUCT_OFFSET (GdmWelcomeSessionClass, died),
+                              NULL,
+                              NULL,
+                              g_cclosure_marshal_VOID__INT,
+                              G_TYPE_NONE,
+                              1,
+                              G_TYPE_INT);
+}
+
+static void
+gdm_welcome_session_init (GdmWelcomeSession *welcome_session)
+{
+
+        welcome_session->priv = GDM_WELCOME_SESSION_GET_PRIVATE (welcome_session);
+
+        welcome_session->priv->pid = -1;
+
+        welcome_session->priv->command = NULL;
+}
+
+static void
+gdm_welcome_session_finalize (GObject *object)
+{
+        GdmWelcomeSession *welcome_session;
+
+        g_return_if_fail (object != NULL);
+        g_return_if_fail (GDM_IS_WELCOME_SESSION (object));
+
+        welcome_session = GDM_WELCOME_SESSION (object);
+
+        g_return_if_fail (welcome_session->priv != NULL);
+
+        gdm_welcome_session_stop (welcome_session);
+
+        g_free (welcome_session->priv->command);
+        g_free (welcome_session->priv->user_name);
+        g_free (welcome_session->priv->group_name);
+        g_free (welcome_session->priv->x11_display_name);
+        g_free (welcome_session->priv->x11_display_device);
+        g_free (welcome_session->priv->x11_display_hostname);
+        g_free (welcome_session->priv->x11_authority_file);
+        g_free (welcome_session->priv->server_address);
+        g_free (welcome_session->priv->server_dbus_path);
+        g_free (welcome_session->priv->server_dbus_interface);
+
+        G_OBJECT_CLASS (gdm_welcome_session_parent_class)->finalize (object);
+}

Added: trunk/daemon/gdm-welcome-session.h
==============================================================================
--- (empty file)
+++ trunk/daemon/gdm-welcome-session.h	Fri Feb  1 23:36:16 2008
@@ -0,0 +1,71 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 William Jon McCann <jmccann redhat com>
+ *
+ * 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_WELCOME_SESSION_H
+#define __GDM_WELCOME_SESSION_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GDM_TYPE_WELCOME_SESSION         (gdm_welcome_session_get_type ())
+#define GDM_WELCOME_SESSION(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_WELCOME_SESSION, GdmWelcomeSession))
+#define GDM_WELCOME_SESSION_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_WELCOME_SESSION, GdmWelcomeSessionClass))
+#define GDM_IS_WELCOME_SESSION(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_WELCOME_SESSION))
+#define GDM_IS_WELCOME_SESSION_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_WELCOME_SESSION))
+#define GDM_WELCOME_SESSION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_WELCOME_SESSION, GdmWelcomeSessionClass))
+
+typedef struct GdmWelcomeSessionPrivate GdmWelcomeSessionPrivate;
+
+typedef struct
+{
+        GObject                   parent;
+        GdmWelcomeSessionPrivate *priv;
+} GdmWelcomeSession;
+
+typedef struct
+{
+        GObjectClass   parent_class;
+
+        /* methods */
+        gboolean (*start)          (GdmWelcomeSession  *welcome_session);
+        gboolean (*stop)           (GdmWelcomeSession  *welcome_session);
+
+
+        /* signals */
+        void (* started)           (GdmWelcomeSession  *welcome_session);
+        void (* stopped)           (GdmWelcomeSession  *welcome_session);
+        void (* exited)            (GdmWelcomeSession  *welcome_session,
+                                    int                 exit_code);
+        void (* died)              (GdmWelcomeSession  *welcome_session,
+                                    int                 signal_number);
+} GdmWelcomeSessionClass;
+
+GType                 gdm_welcome_session_get_type           (void);
+
+void                  gdm_welcome_session_set_server_address (GdmWelcomeSession *welcome_session,
+                                                              const char        *server_address);
+gboolean              gdm_welcome_session_start              (GdmWelcomeSession *welcome_session);
+gboolean              gdm_welcome_session_stop               (GdmWelcomeSession *welcome_session);
+
+G_END_DECLS
+
+#endif /* __GDM_WELCOME_SESSION_H */

Modified: trunk/daemon/gdm-xdmcp-chooser-slave.c
==============================================================================
--- trunk/daemon/gdm-xdmcp-chooser-slave.c	(original)
+++ trunk/daemon/gdm-xdmcp-chooser-slave.c	Fri Feb  1 23:36:16 2008
@@ -232,8 +232,8 @@
         g_object_set (slave->priv->chooser,
                       "x11-authority-file", auth_file,
                       NULL);
-        gdm_chooser_session_set_server_address (slave->priv->chooser, address);
-        gdm_chooser_session_start (slave->priv->chooser);
+        gdm_welcome_session_set_server_address (GDM_WELCOME_SESSION (slave->priv->chooser), address);
+        gdm_welcome_session_start (GDM_WELCOME_SESSION (slave->priv->chooser));
 
         g_free (display_id);
         g_free (display_name);
@@ -306,7 +306,7 @@
         res = GDM_SLAVE_CLASS (gdm_xdmcp_chooser_slave_parent_class)->stop (slave);
 
         if (GDM_XDMCP_CHOOSER_SLAVE (slave)->priv->chooser != NULL) {
-                gdm_chooser_session_stop (GDM_XDMCP_CHOOSER_SLAVE (slave)->priv->chooser);
+                gdm_welcome_session_stop (GDM_WELCOME_SESSION (GDM_XDMCP_CHOOSER_SLAVE (slave)->priv->chooser));
                 g_object_unref (GDM_XDMCP_CHOOSER_SLAVE (slave)->priv->chooser);
                 GDM_XDMCP_CHOOSER_SLAVE (slave)->priv->chooser = NULL;
         }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]