diff options
author | Sascha Silbe <silbe@activitycentral.com> | 2011-07-30 07:24:25 (GMT) |
---|---|---|
committer | Sascha Silbe <silbe@activitycentral.com> | 2011-12-20 13:24:01 (GMT) |
commit | 6f769f059e3503f2c6ca4d30c3c61ba48ca53aa8 (patch) | |
tree | c04b43ee281f7dc8666925e58178288d56339a5c | |
parent | f766da335c7d4f43c76ec063362a97ef9b56d504 (diff) |
Remove bundled copy of gnome-sessiongnome-session
Since sugar now uses upstream gnome-session directly, we don't need to ship a
copy of it in sugar-toolkit. We retain the client-side code that's being used
by activities to interface with the session manager, however.
-rw-r--r-- | po/POTFILES.skip | 1 | ||||
-rw-r--r-- | src/sugar/Makefile.am | 10 | ||||
-rw-r--r-- | src/sugar/_sugarext.defs | 74 | ||||
-rw-r--r-- | src/sugar/_sugarext.override | 2 | ||||
-rw-r--r-- | src/sugar/gsm-app.c | 396 | ||||
-rw-r--r-- | src/sugar/gsm-app.h | 70 | ||||
-rw-r--r-- | src/sugar/gsm-client-xsmp.c | 828 | ||||
-rw-r--r-- | src/sugar/gsm-client-xsmp.h | 70 | ||||
-rw-r--r-- | src/sugar/gsm-client.c | 251 | ||||
-rw-r--r-- | src/sugar/gsm-client.h | 111 | ||||
-rw-r--r-- | src/sugar/gsm-session.c | 509 | ||||
-rw-r--r-- | src/sugar/gsm-session.h | 97 | ||||
-rw-r--r-- | src/sugar/gsm-xsmp.c | 535 | ||||
-rw-r--r-- | src/sugar/gsm-xsmp.h | 29 |
14 files changed, 0 insertions, 2983 deletions
diff --git a/po/POTFILES.skip b/po/POTFILES.skip index a656b5a..8fbd868 100644 --- a/po/POTFILES.skip +++ b/po/POTFILES.skip @@ -3,4 +3,3 @@ # versions of these files. src/sugar/eggdesktopfile.c src/sugar/eggsmclient.c -src/sugar/gsm-xsmp.c diff --git a/src/sugar/Makefile.am b/src/sugar/Makefile.am index c1ff933..950bb11 100644 --- a/src/sugar/Makefile.am +++ b/src/sugar/Makefile.am @@ -29,16 +29,6 @@ _sugarext_la_SOURCES = \ acme-volume.c \ acme-volume-alsa.h \ acme-volume-alsa.c \ - gsm-app.h \ - gsm-app.c \ - gsm-client.h \ - gsm-client.c \ - gsm-client-xsmp.h \ - gsm-client-xsmp.c \ - gsm-xsmp.h \ - gsm-xsmp.c \ - gsm-session.h \ - gsm-session.c \ eggaccelerators.c \ eggaccelerators.h \ eggdesktopfile.h \ diff --git a/src/sugar/_sugarext.defs b/src/sugar/_sugarext.defs index 070fb5b..c2d6f36 100644 --- a/src/sugar/_sugarext.defs +++ b/src/sugar/_sugarext.defs @@ -36,13 +36,6 @@ (gtype-id "EGG_TYPE_SM_CLIENT") ) -(define-object Session - (in-module "Gsm") - (parent "GObject") - (c-name "GsmSession") - (gtype-id "GSM_TYPE_SESSION") -) - (define-object Volume (in-module "Acme") (parent "GObject") @@ -216,73 +209,6 @@ ) ) -;; From xsmp.h - -(define-function xsmp_init - (c-name "gsm_xsmp_init") - (return-type "char*") -) - -(define-function xsmp_run - (c-name "gsm_xsmp_run") - (return-type "none") -) - -(define-function xsmp_shutdown - (c-name "gsm_xsmp_shutdown") - (return-type "none") -) - -;; From session.h - -(define-method set_name - (of-object "GsmSession") - (c-name "gsm_session_set_name") - (return-type "none") - (parameters - '("const-char*" "name") - ) -) - -(define-method start - (of-object "GsmSession") - (c-name "gsm_session_start") - (return-type "none") -) - -(define-method get_phase - (of-object "GsmSession") - (c-name "gsm_session_get_phase") - (return-type "GsmSessionPhase") -) - -(define-method initiate_shutdown - (of-object "GsmSession") - (c-name "gsm_session_initiate_shutdown") - (return-type "none") -) - -(define-method cancel_shutdown - (of-object "GsmSession") - (c-name "gsm_session_cancel_shutdown") - (return-type "none") -) - -(define-method register_client - (of-object "GsmSession") - (c-name "gsm_session_register_client") - (return-type "char*") - (parameters - '("GsmClient*" "client") - '("const-char*" "previous_id") - ) -) - -(define-function session_create_global - (c-name "gsm_session_create_global") - (return-type "GsmSession*") -) - ;; From acme-volume.h (define-function acme_volume_get_type diff --git a/src/sugar/_sugarext.override b/src/sugar/_sugarext.override index def0927..5a7cfce 100644 --- a/src/sugar/_sugarext.override +++ b/src/sugar/_sugarext.override @@ -7,8 +7,6 @@ headers #include "sugar-grid.h" #include "sugar-key-grabber.h" #include "sugar-menu.h" -#include "gsm-session.h" -#include "gsm-xsmp.h" #include "acme-volume-alsa.h" #include "eggsmclient.h" diff --git a/src/sugar/gsm-app.c b/src/sugar/gsm-app.c deleted file mode 100644 index 96b65ce..0000000 --- a/src/sugar/gsm-app.c +++ /dev/null @@ -1,396 +0,0 @@ -/* app.c - * Copyright (C) 2007 Novell, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by 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 - * Lesser 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <glib.h> -#include <string.h> -#include <sys/wait.h> - -#include "gsm-app.h" - -enum { - EXITED, - REGISTERED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -enum { - PROP_0, - - PROP_DESKTOP_FILE, - PROP_CLIENT_ID, - - LAST_PROP -}; - -static void set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec); -static void get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec); -static void dispose (GObject *object); - -static const char *get_basename (GsmApp *app); -static pid_t launch (GsmApp *app, GError **err); - -G_DEFINE_TYPE (GsmApp, gsm_app, G_TYPE_OBJECT) - -static void -gsm_app_init (GsmApp *app) -{ - app->pid = -1; -} - -static void -gsm_app_class_init (GsmAppClass *app_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (app_class); - - object_class->set_property = set_property; - object_class->get_property = get_property; - object_class->dispose = dispose; - - app_class->get_basename = get_basename; - app_class->launch = launch; - - g_object_class_install_property (object_class, - PROP_DESKTOP_FILE, - g_param_spec_string ("desktop-file", - "Desktop file", - "Freedesktop .desktop file", - NULL, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, - PROP_CLIENT_ID, - g_param_spec_string ("client-id", - "Client ID", - "Session management client ID", - NULL, - G_PARAM_READWRITE)); - - signals[EXITED] = - g_signal_new ("exited", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GsmAppClass, exited), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - - signals[REGISTERED] = - g_signal_new ("registered", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GsmAppClass, registered), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); -} - -static void -set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - GsmApp *app = GSM_APP (object); - const char *desktop_file; - char *phase; - GError *error = NULL; - - switch (prop_id) - { - case PROP_DESKTOP_FILE: - if (app->desktop_file) - egg_desktop_file_free (app->desktop_file); - desktop_file = g_value_get_string (value); - if (!desktop_file) - { - app->desktop_file = NULL; - break; - } - - app->desktop_file = egg_desktop_file_new (desktop_file, &error); - if (!app->desktop_file) - { - g_warning ("Could not parse desktop file %s: %s", - desktop_file, error->message); - g_error_free (error); - break; - } - - phase = egg_desktop_file_get_string (app->desktop_file, - "X-GNOME-Autostart-Phase", NULL); - if (phase) - { - if (!strcmp (phase, "Initialization")) - app->phase = GSM_SESSION_PHASE_INITIALIZATION; - else if (!strcmp (phase, "WindowManager")) - app->phase = GSM_SESSION_PHASE_WINDOW_MANAGER; - else if (!strcmp (phase, "Panel")) - app->phase = GSM_SESSION_PHASE_PANEL; - else if (!strcmp (phase, "Desktop")) - app->phase = GSM_SESSION_PHASE_DESKTOP; - else - app->phase = GSM_SESSION_PHASE_APPLICATION; - - g_free (phase); - } - else - app->phase = GSM_SESSION_PHASE_APPLICATION; - break; - - case PROP_CLIENT_ID: - g_free (app->client_id); - app->client_id = g_value_dup_string (value); - break; - - default: - break; - } -} - -static void -get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - GsmApp *app = GSM_APP (object); - - switch (prop_id) - { - case PROP_DESKTOP_FILE: - if (app->desktop_file) - g_value_set_string (value, egg_desktop_file_get_source (app->desktop_file)); - else - g_value_set_string (value, NULL); - break; - - case PROP_CLIENT_ID: - g_value_set_string (value, app->client_id); - break; - - default: - break; - } -} - -static void -dispose(GObject *object) -{ - GsmApp *app = GSM_APP (object); - - if (app->desktop_file) - { - egg_desktop_file_free (app->desktop_file); - app->desktop_file = NULL; - } - - if (app->startup_id) - { - g_free (app->startup_id); - app->startup_id = NULL; - } - - if (app->client_id) - { - g_free (app->client_id); - app->client_id = NULL; - } -} - -/** - * gsm_app_get_basename: - * @app: a %GsmApp - * - * Returns an identifying name for @app, e.g. the basename of the path to - * @app's desktop file (if any). - * - * Return value: an identifying name for @app, or %NULL. - **/ -const char * -gsm_app_get_basename (GsmApp *app) -{ - return GSM_APP_GET_CLASS (app)->get_basename (app); -} - -static const char * -get_basename (GsmApp *app) -{ - const char *location, *slash; - - if (!app->desktop_file) - return NULL; - - location = egg_desktop_file_get_source (app->desktop_file); - - slash = strrchr (location, '/'); - if (slash) - return slash + 1; - else - return location; -} - -/** - * gsm_app_get_phase: - * @app: a %GsmApp - * - * Returns @app's startup phase. - * - * Return value: @app's startup phase - **/ -GsmSessionPhase -gsm_app_get_phase (GsmApp *app) -{ - g_return_val_if_fail (GSM_IS_APP (app), GSM_SESSION_PHASE_APPLICATION); - - return app->phase; -} - -/** - * gsm_app_is_disabled: - * @app: a %GsmApp - * - * Tests if @app is disabled - * - * Return value: whether or not @app is disabled - **/ -gboolean -gsm_app_is_disabled (GsmApp *app) -{ - g_return_val_if_fail (GSM_IS_APP (app), FALSE); - - if (GSM_APP_GET_CLASS (app)->is_disabled) - return GSM_APP_GET_CLASS (app)->is_disabled (app); - else - return FALSE; -} - -gboolean -gsm_app_provides (GsmApp *app, const char *service) -{ - char **provides; - gsize len, i; - - g_return_val_if_fail (GSM_IS_APP (app), FALSE); - - if (!app->desktop_file) - return FALSE; - - provides = egg_desktop_file_get_string_list (app->desktop_file, - "X-GNOME-Provides", - &len, NULL); - if (!provides) - return FALSE; - - for (i = 0; i < len; i++) - { - if (!strcmp (provides[i], service)) - { - g_strfreev (provides); - return TRUE; - } - } - - g_strfreev (provides); - return FALSE; -} - -static void -app_exited (GPid pid, gint status, gpointer data) -{ - if (WIFEXITED (status)) - g_signal_emit (GSM_APP (data), signals[EXITED], 0); -} - -static pid_t -launch (GsmApp *app, - GError **err) -{ - char *env[2] = { NULL, NULL }; - gboolean success; - - g_return_val_if_fail (app->desktop_file != NULL, (pid_t)-1); - - if (egg_desktop_file_get_boolean (app->desktop_file, - "X-GNOME-Autostart-Notify", NULL) || - egg_desktop_file_get_boolean (app->desktop_file, - "AutostartNotify", NULL)) - env[0] = g_strdup_printf ("DESKTOP_AUTOSTART_ID=%s", app->client_id); - -#if 0 - g_debug ("launching %s with client_id %s\n", - gsm_app_get_basename (app), app->client_id); -#endif - - success = - egg_desktop_file_launch (app->desktop_file, NULL, err, - EGG_DESKTOP_FILE_LAUNCH_PUTENV, env, - EGG_DESKTOP_FILE_LAUNCH_FLAGS, G_SPAWN_DO_NOT_REAP_CHILD, - EGG_DESKTOP_FILE_LAUNCH_RETURN_PID, &app->pid, - EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID, &app->startup_id, - NULL); - - g_free (env[0]); - - if (success) - { - /* In case the app belongs to Initialization phase, we monitor - * if it exits to emit proper "exited" signal to session. */ - if (app->phase == GSM_SESSION_PHASE_INITIALIZATION) - g_child_watch_add ((GPid) app->pid, app_exited, app); - - return app->pid; - } - else - return (pid_t) -1; -} - -/** - * gsm_app_launch: - * @app: a %GsmApp - * @err: an error pointer - * - * Launches @app - * - * Return value: the pid of the new process, or -1 on error - **/ -pid_t -gsm_app_launch (GsmApp *app, GError **err) -{ - return GSM_APP_GET_CLASS (app)->launch (app, err); -} - -/** - * gsm_app_registered: - * @app: a %GsmApp - * - * Emits "registered" signal in @app - **/ -void -gsm_app_registered (GsmApp *app) -{ - g_return_if_fail (GSM_IS_APP (app)); - - g_signal_emit (app, signals[REGISTERED], 0); -} - diff --git a/src/sugar/gsm-app.h b/src/sugar/gsm-app.h deleted file mode 100644 index 038caee..0000000 --- a/src/sugar/gsm-app.h +++ /dev/null @@ -1,70 +0,0 @@ -/* gsmapp.h - * Copyright (C) 2006 Novell, Inc. - * - */ - -#ifndef __GSM_APP_H__ -#define __GSM_APP_H__ - -#include <glib-object.h> -#include <sys/types.h> - -#include "eggdesktopfile.h" -#include "gsm-session.h" - -G_BEGIN_DECLS - -#define GSM_TYPE_APP (gsm_app_get_type ()) -#define GSM_APP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSM_TYPE_APP, GsmApp)) -#define GSM_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSM_TYPE_APP, GsmAppClass)) -#define GSM_IS_APP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSM_TYPE_APP)) -#define GSM_IS_APP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSM_TYPE_APP)) -#define GSM_APP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSM_TYPE_APP, GsmAppClass)) - -typedef struct _GsmApp GsmApp; -typedef struct _GsmAppClass GsmAppClass; -typedef struct _GsmAppPrivate GsmAppPrivate; - -struct _GsmApp -{ - GObject parent; - - EggDesktopFile *desktop_file; - GsmSessionPhase phase; - - pid_t pid; - char *startup_id, *client_id; -}; - -struct _GsmAppClass -{ - GObjectClass parent_class; - - /* signals */ - void (*exited) (GsmApp *app, int status); - void (*registered) (GsmApp *app); - - /* virtual methods */ - const char *(*get_basename) (GsmApp *app); - gboolean (*is_disabled) (GsmApp *app); - pid_t (*launch) (GsmApp *app, GError **err); - void (*set_client) (GsmApp *app, GsmClient *client); -}; - -GType gsm_app_get_type (void) G_GNUC_CONST; - -const char *gsm_app_get_basename (GsmApp *app); -GsmSessionPhase gsm_app_get_phase (GsmApp *app); -gboolean gsm_app_provides (GsmApp *app, - const char *service); -gboolean gsm_app_is_disabled (GsmApp *app); -pid_t gsm_app_launch (GsmApp *app, - GError **err); -void gsm_app_set_client (GsmApp *app, - GsmClient *client); - -void gsm_app_registered (GsmApp *app); - -G_END_DECLS - -#endif /* __GSM_APP_H__ */ diff --git a/src/sugar/gsm-client-xsmp.c b/src/sugar/gsm-client-xsmp.c deleted file mode 100644 index 632dec9..0000000 --- a/src/sugar/gsm-client-xsmp.c +++ /dev/null @@ -1,828 +0,0 @@ -/* client-xsmp.c - * Copyright (C) 2007 Novell, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by 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 - * Lesser 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> - -#include "gsm-client-xsmp.h" -#include "gsm-session.h" - -/* FIXME */ -#define GsmDesktopFile "_Gsm_DesktopFile" - -static gboolean client_iochannel_watch (GIOChannel *channel, - GIOCondition condition, - gpointer data); -static gboolean client_protocol_timeout (gpointer data); - -static void set_description (GsmClientXSMP *xsmp); - -static const char *xsmp_get_client_id (GsmClient *client); -static pid_t xsmp_get_pid (GsmClient *client); -static char *xsmp_get_desktop_file (GsmClient *client); -static char *xsmp_get_restart_command (GsmClient *client); -static char *xsmp_get_discard_command (GsmClient *client); -static gboolean xsmp_get_autorestart (GsmClient *client); - -static void xsmp_finalize (GObject *object); -static void xsmp_restart (GsmClient *client, - GError **error); -static void xsmp_save_yourself (GsmClient *client, - gboolean save_state); -static void xsmp_save_yourself_phase2 (GsmClient *client); -static void xsmp_interact (GsmClient *client); -static void xsmp_shutdown_cancelled (GsmClient *client); -static void xsmp_die (GsmClient *client); - -G_DEFINE_TYPE (GsmClientXSMP, gsm_client_xsmp, GSM_TYPE_CLIENT) - -static void -gsm_client_xsmp_init (GsmClientXSMP *xsmp) -{ - ; -} - -static void -gsm_client_xsmp_class_init (GsmClientXSMPClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - GsmClientClass *client_class = GSM_CLIENT_CLASS (klass); - - object_class->finalize = xsmp_finalize; - - client_class->get_client_id = xsmp_get_client_id; - client_class->get_pid = xsmp_get_pid; - client_class->get_desktop_file = xsmp_get_desktop_file; - client_class->get_restart_command = xsmp_get_restart_command; - client_class->get_discard_command = xsmp_get_discard_command; - client_class->get_autorestart = xsmp_get_autorestart; - - client_class->restart = xsmp_restart; - client_class->save_yourself = xsmp_save_yourself; - client_class->save_yourself_phase2 = xsmp_save_yourself_phase2; - client_class->interact = xsmp_interact; - client_class->shutdown_cancelled = xsmp_shutdown_cancelled; - client_class->die = xsmp_die; -} - -GsmClientXSMP * -gsm_client_xsmp_new (IceConn ice_conn) -{ - GsmClientXSMP *xsmp; - GIOChannel *channel; - int fd; - - xsmp = g_object_new (GSM_TYPE_CLIENT_XSMP, NULL); - xsmp->props = g_ptr_array_new (); - - xsmp->ice_conn = ice_conn; - xsmp->current_save_yourself = -1; - xsmp->next_save_yourself = -1; - - fd = IceConnectionNumber (ice_conn); - fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC); - - channel = g_io_channel_unix_new (fd); - xsmp->watch_id = g_io_add_watch (channel, G_IO_IN | G_IO_ERR, - client_iochannel_watch, xsmp); - g_io_channel_unref (channel); - - xsmp->protocol_timeout = g_timeout_add_seconds (5, client_protocol_timeout, xsmp); - - set_description (xsmp); - g_debug ("New client '%s'", xsmp->description); - - return xsmp; -} - -static void -xsmp_finalize (GObject *object) -{ - GsmClientXSMP *xsmp = (GsmClientXSMP *) object; - - g_debug ("xsmp_finalize (%s)", xsmp->description); - - if (xsmp->watch_id) - g_source_remove (xsmp->watch_id); - - if (xsmp->conn) - SmsCleanUp (xsmp->conn); - else - IceCloseConnection (xsmp->ice_conn); - - if (xsmp->protocol_timeout) - g_source_remove (xsmp->protocol_timeout); - - G_OBJECT_CLASS (gsm_client_xsmp_parent_class)->finalize (object); -} - -static gboolean -client_iochannel_watch (GIOChannel *channel, - GIOCondition condition, - gpointer data) -{ - GsmClient *client = data; - GsmClientXSMP *xsmp = data; - - switch (IceProcessMessages (xsmp->ice_conn, NULL, NULL)) - { - case IceProcessMessagesSuccess: - return TRUE; - - case IceProcessMessagesIOError: - g_debug ("IceProcessMessagesIOError on '%s'", xsmp->description); - gsm_client_disconnected (client); - return FALSE; - - case IceProcessMessagesConnectionClosed: - g_debug ("IceProcessMessagesConnectionClosed on '%s'", - xsmp->description); - return FALSE; - - default: - g_assert_not_reached (); - } -} - -/* Called if too much time passes between the initial connection and - * the XSMP protocol setup. - */ -static gboolean -client_protocol_timeout (gpointer data) -{ - GsmClient *client = data; - GsmClientXSMP *xsmp = data; - - g_debug ("client_protocol_timeout for client '%s' in ICE status %d", - xsmp->description, IceConnectionStatus (xsmp->ice_conn)); - gsm_client_disconnected (client); - - return FALSE; -} - -static Status -register_client_callback (SmsConn conn, - SmPointer manager_data, - char *previous_id) -{ - GsmClient *client = manager_data; - GsmClientXSMP *xsmp = manager_data; - char *id; - - g_debug ("Client '%s' received RegisterClient(%s)", - xsmp->description, - previous_id ? previous_id : "NULL"); - - id = gsm_session_register_client (global_session, client, previous_id); - - if (id == NULL) - { - g_debug (" rejected: invalid previous_id"); - free (previous_id); - return FALSE; - } - - xsmp->id = id; - - set_description (xsmp); - - g_debug ("Sending RegisterClientReply to '%s'", xsmp->description); - - SmsRegisterClientReply (conn, xsmp->id); - - if (!previous_id) - { - /* Send the initial SaveYourself. */ - g_debug ("Sending initial SaveYourself"); - SmsSaveYourself (conn, SmSaveLocal, False, SmInteractStyleNone, False); - xsmp->current_save_yourself = SmSaveLocal; - - free (previous_id); - } - - return TRUE; -} - -static void -do_save_yourself (GsmClientXSMP *xsmp, int save_type) -{ - if (xsmp->next_save_yourself != -1) - { - /* Either we're currently doing a shutdown and there's a checkpoint - * queued after it, or vice versa. Either way, the new SaveYourself - * is redundant. - */ - g_debug (" skipping redundant SaveYourself for '%s'", - xsmp->description); - } - else if (xsmp->current_save_yourself != -1) - { - g_debug (" queuing new SaveYourself for '%s'", - xsmp->description); - xsmp->next_save_yourself = save_type; - } - else - { - xsmp->current_save_yourself = save_type; - - switch (save_type) - { - case SmSaveLocal: - /* Save state */ - SmsSaveYourself (xsmp->conn, SmSaveLocal, FALSE, - SmInteractStyleNone, FALSE); - break; - - default: - /* Logout */ - SmsSaveYourself (xsmp->conn, save_type, TRUE, - SmInteractStyleAny, FALSE); - break; - } - } -} - -static void -save_yourself_request_callback (SmsConn conn, - SmPointer manager_data, - int save_type, - Bool shutdown, - int interact_style, - Bool fast, - Bool global) -{ - GsmClientXSMP *xsmp = manager_data; - - g_debug ("Client '%s' received SaveYourselfRequest(%s, %s, %s, %s, %s)", - xsmp->description, - save_type == SmSaveLocal ? "SmSaveLocal" : - save_type == SmSaveGlobal ? "SmSaveGlobal" : "SmSaveBoth", - shutdown ? "Shutdown" : "!Shutdown", - interact_style == SmInteractStyleAny ? "SmInteractStyleAny" : - interact_style == SmInteractStyleErrors ? "SmInteractStyleErrors" : - "SmInteractStyleNone", fast ? "Fast" : "!Fast", - global ? "Global" : "!Global"); - - /* Examining the g_debug above, you can see that there are a total - * of 72 different combinations of options that this could have been - * called with. However, most of them are stupid. - * - * If @shutdown and @global are both TRUE, that means the caller is - * requesting that a logout message be sent to all clients, so we do - * that. We use @fast to decide whether or not to show a - * confirmation dialog. (This isn't really what @fast is for, but - * the old gnome-session and ksmserver both interpret it that way, - * so we do too.) We ignore @save_type because we pick the correct - * save_type ourselves later based on user prefs, dialog choices, - * etc, and we ignore @interact_style, because clients have not used - * it correctly consistently enough to make it worth honoring. - * - * If @shutdown is TRUE and @global is FALSE, the caller is - * confused, so we ignore the request. - * - * If @shutdown is FALSE and @save_type is SmSaveGlobal or - * SmSaveBoth, then the client wants us to ask some or all open - * applications to save open files to disk, but NOT quit. This is - * silly and so we ignore the request. - * - * If @shutdown is FALSE and @save_type is SmSaveLocal, then the - * client wants us to ask some or all open applications to update - * their current saved state, but not log out. At the moment, the - * code only supports this for the !global case (ie, a client - * requesting that it be allowed to update *its own* saved state, - * but not having everyone else update their saved state). - */ - - if (shutdown && global) - { - g_debug (" initiating shutdown"); -/* gsm_session_initiate_shutdown (global_session, - !fast, - GSM_SESSION_LOGOUT_TYPE_LOGOUT); -*/ - } - else if (!shutdown && !global) - { - g_debug (" initiating checkpoint"); - do_save_yourself (xsmp, SmSaveLocal); - } - else - g_debug (" ignoring"); -} - -static void -xsmp_restart (GsmClient *client, GError **error) -{ - char *restart_cmd = gsm_client_get_restart_command (client); - - g_spawn_command_line_async (restart_cmd, error); - - g_free (restart_cmd); -} - -static void -xsmp_save_yourself (GsmClient *client, gboolean save_state) -{ - GsmClientXSMP *xsmp = (GsmClientXSMP *)client; - - g_debug ("xsmp_save_yourself ('%s', %s)", xsmp->description, - save_state ? "True" : "False"); - - do_save_yourself (xsmp, save_state ? SmSaveBoth : SmSaveGlobal); -} - -static void -save_yourself_phase2_request_callback (SmsConn conn, - SmPointer manager_data) -{ - GsmClient *client = manager_data; - GsmClientXSMP *xsmp = manager_data; - - g_debug ("Client '%s' received SaveYourselfPhase2Request", - xsmp->description); - - if (xsmp->current_save_yourself == SmSaveLocal) - { - /* WTF? Anyway, if it's checkpointing, it doesn't have to wait - * for anyone else. - */ - SmsSaveYourselfPhase2 (xsmp->conn); - } - else - gsm_client_request_phase2 (client); -} - -static void -xsmp_save_yourself_phase2 (GsmClient *client) -{ - GsmClientXSMP *xsmp = (GsmClientXSMP *)client; - - g_debug ("xsmp_save_yourself_phase2 ('%s')", xsmp->description); - - SmsSaveYourselfPhase2 (xsmp->conn); -} - -static void -interact_request_callback (SmsConn conn, - SmPointer manager_data, - int dialog_type) -{ - GsmClient *client = manager_data; - GsmClientXSMP *xsmp = manager_data; - - g_debug ("Client '%s' received InteractRequest(%s)", xsmp->description, - dialog_type == SmInteractStyleAny ? "Any" : "Errors"); - - gsm_client_request_interaction (client); -} - -static void -xsmp_interact (GsmClient *client) -{ - GsmClientXSMP *xsmp = (GsmClientXSMP *) client; - - g_debug ("xsmp_interact ('%s')", xsmp->description); - - SmsInteract (xsmp->conn); -} - -static void -interact_done_callback (SmsConn conn, - SmPointer manager_data, - Bool cancel_shutdown) -{ - GsmClient *client = manager_data; - GsmClientXSMP *xsmp = manager_data; - - g_debug ("Client '%s' received InteractDone(cancel_shutdown = %s)", - xsmp->description, cancel_shutdown ? "True" : "False"); - - gsm_client_interaction_done (client, cancel_shutdown); -} - -static void -xsmp_shutdown_cancelled (GsmClient *client) -{ - GsmClientXSMP *xsmp = (GsmClientXSMP *) client; - - g_debug ("xsmp_shutdown_cancelled ('%s')", xsmp->description); - - SmsShutdownCancelled (xsmp->conn); -} - -static void -xsmp_die (GsmClient *client) -{ - GsmClientXSMP *xsmp = (GsmClientXSMP *) client; - - g_debug ("xsmp_die ('%s')", xsmp->description); - - SmsDie (xsmp->conn); -} - -static void -save_yourself_done_callback (SmsConn conn, - SmPointer manager_data, - Bool success) -{ - GsmClient *client = manager_data; - GsmClientXSMP *xsmp = manager_data; - - g_debug ("Client '%s' received SaveYourselfDone(success = %s)", - xsmp->description, success ? "True" : "False"); - - if (xsmp->current_save_yourself == SmSaveLocal) - { - xsmp->current_save_yourself = -1; - SmsSaveComplete (xsmp->conn); - gsm_client_saved_state (client); - } - else - { - xsmp->current_save_yourself = -1; - gsm_client_save_yourself_done (client); - } - - if (xsmp->next_save_yourself) - { - int save_type = xsmp->next_save_yourself; - - xsmp->next_save_yourself = -1; - do_save_yourself (xsmp, save_type); - } -} - -static void -close_connection_callback (SmsConn conn, - SmPointer manager_data, - int count, - char **reason_msgs) -{ - GsmClient *client = manager_data; - GsmClientXSMP *xsmp = manager_data; - int i; - - g_debug ("Client '%s' received CloseConnection", xsmp->description); - for (i = 0; i < count; i++) - g_debug (" close reason: '%s'", reason_msgs[i]); - SmFreeReasons (count, reason_msgs); - - gsm_client_disconnected (client); -} - -static void -debug_print_property (SmProp *prop) -{ - GString *tmp; - int i; - - switch (prop->type[0]) - { - case 'C': /* CARD8 */ - g_debug (" %s = %d", prop->name, *(unsigned char *)prop->vals[0].value); - break; - - case 'A': /* ARRAY8 */ - g_debug (" %s = '%s'", prop->name, (char *)prop->vals[0].value); - break; - - case 'L': /* LISTofARRAY8 */ - tmp = g_string_new (NULL); - for (i = 0; i < prop->num_vals; i++) - { - g_string_append_printf (tmp, "'%.*s' ", prop->vals[i].length, - (char *)prop->vals[i].value); - } - g_debug (" %s = %s", prop->name, tmp->str); - g_string_free (tmp, TRUE); - break; - - default: - g_debug (" %s = ??? (%s)", prop->name, prop->type); - break; - } -} - -static SmProp * -find_property (GsmClientXSMP *client, const char *name, int *index) -{ - SmProp *prop; - int i; - - for (i = 0; i < client->props->len; i++) - { - prop = client->props->pdata[i]; - - if (!strcmp (prop->name, name)) - { - if (index) - *index = i; - return prop; - } - } - - return NULL; -} - -static void -delete_property (GsmClientXSMP *client, const char *name) -{ - int index; - SmProp *prop; - - prop = find_property (client, name, &index); - if (!prop) - return; - -#if 0 - /* This is wrong anyway; we can't unconditionally run the current - * discard command; if this client corresponds to a GsmAppResumed, - * and the current discard command is identical to the app's - * discard_command, then we don't run the discard command now, - * because that would delete a saved state we may want to resume - * again later. - */ - if (!strcmp (name, SmDiscardCommand)) - gsm_client_run_discard (client); -#endif - - g_ptr_array_remove_index_fast (client->props, index); - SmFreeProperty (prop); -} - -static void -set_properties_callback (SmsConn conn, - SmPointer manager_data, - int num_props, - SmProp **props) -{ - GsmClientXSMP *client = manager_data; - int i; - - g_debug ("Set properties from client '%s'", client->description); - - for (i = 0; i < num_props; i++) - { - delete_property (client, props[i]->name); - g_ptr_array_add (client->props, props[i]); - - debug_print_property (props[i]); - - if (!strcmp (props[i]->name, SmProgram)) - set_description (client); - } - - free (props); - -} - -static void -delete_properties_callback (SmsConn conn, - SmPointer manager_data, - int num_props, - char **prop_names) -{ - GsmClientXSMP *client = manager_data; - int i; - - g_debug ("Delete properties from '%s'", client->description); - - for (i = 0; i < num_props; i++) - { - delete_property (client, prop_names[i]); - - g_debug (" %s", prop_names[i]); - } - - free (prop_names); -} - -static void -get_properties_callback (SmsConn conn, - SmPointer manager_data) -{ - GsmClientXSMP *client = manager_data; - - g_debug ("Get properties request from '%s'", client->description); - - SmsReturnProperties (conn, client->props->len, - (SmProp **)client->props->pdata); -} - -static const char * -xsmp_get_client_id (GsmClient *client) -{ - GsmClientXSMP *xsmp = (GsmClientXSMP *) client; - - return xsmp->id; -} - -static pid_t -xsmp_get_pid (GsmClient *client) -{ - GsmClientXSMP *xsmp = (GsmClientXSMP *) client; - SmProp *prop = find_property (xsmp, SmProcessID, NULL); - char buf[32]; - - if (!prop || strcmp (prop->type, SmARRAY8) != 0) - return (pid_t)-1; - - /* prop->vals[0].value might not be '\0'-terminated... */ - g_strlcpy (buf, prop->vals[0].value, MIN (prop->vals[0].length, sizeof (buf))); - return (pid_t)strtoul (buf, NULL, 10); -} - -static char * -xsmp_get_desktop_file (GsmClient *client) -{ - GsmClientXSMP *xsmp = (GsmClientXSMP *) client; - SmProp *prop = find_property (xsmp, GsmDesktopFile, NULL); - - if (!prop || strcmp (prop->type, SmARRAY8) != 0) - return NULL; - - return g_strndup (prop->vals[0].value, prop->vals[0].length); -} - -static char * -prop_to_command (SmProp *prop) -{ - GString *str; - int i, j; - gboolean need_quotes; - - str = g_string_new (NULL); - for (i = 0; i < prop->num_vals; i++) - { - char *val = prop->vals[i].value; - - need_quotes = FALSE; - for (j = 0; j < prop->vals[i].length; j++) - { - if (!g_ascii_isalnum (val[j]) && !strchr ("-_=:./", val[j])) - { - need_quotes = TRUE; - break; - } - } - - if (i > 0) - g_string_append_c (str, ' '); - - if (!need_quotes) - { - g_string_append_printf (str, "%.*s", prop->vals[i].length, - (char *)prop->vals[i].value); - } - else - { - g_string_append_c (str, '\''); - while (val < (char *)prop->vals[i].value + prop->vals[i].length) - { - if (*val == '\'') - g_string_append (str, "'\''"); - else - g_string_append_c (str, *val); - val++; - } - g_string_append_c (str, '\''); - } - } - - return g_string_free (str, FALSE); -} - -static char * -xsmp_get_restart_command (GsmClient *client) -{ - GsmClientXSMP *xsmp = (GsmClientXSMP *) client; - SmProp *prop = find_property (xsmp, SmRestartCommand, NULL); - - if (!prop || strcmp (prop->type, SmLISTofARRAY8) != 0) - return NULL; - - return prop_to_command (prop); -} - -static char * -xsmp_get_discard_command (GsmClient *client) -{ - GsmClientXSMP *xsmp = (GsmClientXSMP *) client; - SmProp *prop = find_property (xsmp, SmDiscardCommand, NULL); - - if (!prop || strcmp (prop->type, SmLISTofARRAY8) != 0) - return NULL; - - return prop_to_command (prop); -} - -static gboolean -xsmp_get_autorestart (GsmClient *client) -{ - GsmClientXSMP *xsmp = (GsmClientXSMP *) client; - SmProp *prop = find_property (xsmp, SmRestartStyleHint, NULL); - - if (!prop || strcmp (prop->type, SmCARD8) != 0) - return FALSE; - - return ((unsigned char *)prop->vals[0].value)[0] == SmRestartImmediately; -} - -static void -set_description (GsmClientXSMP *client) -{ - SmProp *prop = find_property (client, SmProgram, NULL); - - g_free (client->description); - if (prop) - { - client->description = g_strdup_printf ("%p [%.*s %s]", client, - prop->vals[0].length, - (char *)prop->vals[0].value, - client->id); - } - else if (client->id) - client->description = g_strdup_printf ("%p [%s]", client, client->id); - else - client->description = g_strdup_printf ("%p", client); -} - -void -gsm_client_xsmp_connect (GsmClientXSMP *client, SmsConn conn, - unsigned long *mask_ret, SmsCallbacks *callbacks_ret) -{ - client->conn = conn; - - if (client->protocol_timeout) - { - g_source_remove (client->protocol_timeout); - client->protocol_timeout = 0; - } - - g_debug ("Initializing client %s", client->description); - - *mask_ret = 0; - - *mask_ret |= SmsRegisterClientProcMask; - callbacks_ret->register_client.callback = register_client_callback; - callbacks_ret->register_client.manager_data = client; - - *mask_ret |= SmsInteractRequestProcMask; - callbacks_ret->interact_request.callback = interact_request_callback; - callbacks_ret->interact_request.manager_data = client; - - *mask_ret |= SmsInteractDoneProcMask; - callbacks_ret->interact_done.callback = interact_done_callback; - callbacks_ret->interact_done.manager_data = client; - - *mask_ret |= SmsSaveYourselfRequestProcMask; - callbacks_ret->save_yourself_request.callback = save_yourself_request_callback; - callbacks_ret->save_yourself_request.manager_data = client; - - *mask_ret |= SmsSaveYourselfP2RequestProcMask; - callbacks_ret->save_yourself_phase2_request.callback = save_yourself_phase2_request_callback; - callbacks_ret->save_yourself_phase2_request.manager_data = client; - - *mask_ret |= SmsSaveYourselfDoneProcMask; - callbacks_ret->save_yourself_done.callback = save_yourself_done_callback; - callbacks_ret->save_yourself_done.manager_data = client; - - *mask_ret |= SmsCloseConnectionProcMask; - callbacks_ret->close_connection.callback = close_connection_callback; - callbacks_ret->close_connection.manager_data = client; - - *mask_ret |= SmsSetPropertiesProcMask; - callbacks_ret->set_properties.callback = set_properties_callback; - callbacks_ret->set_properties.manager_data = client; - - *mask_ret |= SmsDeletePropertiesProcMask; - callbacks_ret->delete_properties.callback = delete_properties_callback; - callbacks_ret->delete_properties.manager_data = client; - - *mask_ret |= SmsGetPropertiesProcMask; - callbacks_ret->get_properties.callback = get_properties_callback; - callbacks_ret->get_properties.manager_data = client; -} diff --git a/src/sugar/gsm-client-xsmp.h b/src/sugar/gsm-client-xsmp.h deleted file mode 100644 index 46e34a5..0000000 --- a/src/sugar/gsm-client-xsmp.h +++ /dev/null @@ -1,70 +0,0 @@ -/* client-xsmp.h - * Copyright (C) 2007 Novell, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by 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 - * Lesser 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 __GSM_CLIENT_XSMP_H__ -#define __GSM_CLIENT_XSMP_H__ - -#include "gsm-client.h" - -#include <X11/SM/SMlib.h> - -G_BEGIN_DECLS - -#define GSM_TYPE_CLIENT_XSMP (gsm_client_xsmp_get_type ()) -#define GSM_CLIENT_XSMP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSM_TYPE_CLIENT_XSMP, GsmClientXSMP)) -#define GSM_CLIENT_XSMP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSM_TYPE_CLIENT_XSMP, GsmClientXSMPClass)) -#define GSM_IS_CLIENT_XSMP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSM_TYPE_CLIENT_XSMP)) -#define GSM_IS_CLIENT_XSMP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSM_TYPE_CLIENT_XSMP)) -#define GSM_CLIENT_XSMP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSM_TYPE_CLIENT_XSMP, GsmClientXSMPClass)) - -typedef struct _GsmClientXSMP GsmClientXSMP; -typedef struct _GsmClientXSMPClass GsmClientXSMPClass; - -struct _GsmClientXSMP -{ - GsmClient parent; - - SmsConn conn; - IceConn ice_conn; - - guint watch_id, protocol_timeout; - - int current_save_yourself, next_save_yourself; - char *id, *description; - GPtrArray *props; -}; - -struct _GsmClientXSMPClass -{ - GsmClientClass parent_class; - -}; - -GType gsm_client_xsmp_get_type (void) G_GNUC_CONST; - -GsmClientXSMP *gsm_client_xsmp_new (IceConn ice_conn); - -void gsm_client_xsmp_connect (GsmClientXSMP *client, - SmsConn conn, - unsigned long *mask_ret, - SmsCallbacks *callbacks_ret); - -G_END_DECLS - -#endif /* __GSM_CLIENT_XSMP_H__ */ diff --git a/src/sugar/gsm-client.c b/src/sugar/gsm-client.c deleted file mode 100644 index 31554d4..0000000 --- a/src/sugar/gsm-client.c +++ /dev/null @@ -1,251 +0,0 @@ -/* client.c - * Copyright (C) 2007 Novell, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by 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 - * Lesser 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "gsm-client.h" - -enum { - SAVED_STATE, - REQUEST_PHASE2, - REQUEST_INTERACTION, - INTERACTION_DONE, - SAVE_YOURSELF_DONE, - DISCONNECTED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE (GsmClient, gsm_client, G_TYPE_OBJECT) - -static void -gsm_client_init (GsmClient *client) -{ - ; -} - -static void -gsm_client_class_init (GsmClientClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - signals[SAVED_STATE] = - g_signal_new ("saved_state", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GsmClientClass, saved_state), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - - signals[REQUEST_PHASE2] = - g_signal_new ("request_phase2", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GsmClientClass, request_phase2), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - - signals[REQUEST_INTERACTION] = - g_signal_new ("request_interaction", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GsmClientClass, request_interaction), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - - signals[INTERACTION_DONE] = - g_signal_new ("interaction_done", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GsmClientClass, interaction_done), - NULL, NULL, - g_cclosure_marshal_VOID__BOOLEAN, - G_TYPE_NONE, - 1, G_TYPE_BOOLEAN); - - signals[SAVE_YOURSELF_DONE] = - g_signal_new ("save_yourself_done", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GsmClientClass, save_yourself_done), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - - signals[DISCONNECTED] = - g_signal_new ("disconnected", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GsmClientClass, disconnected), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); - -} - -const char * -gsm_client_get_client_id (GsmClient *client) -{ - g_return_val_if_fail (GSM_IS_CLIENT (client), NULL); - - return GSM_CLIENT_GET_CLASS (client)->get_client_id (client); -} - -pid_t -gsm_client_get_pid (GsmClient *client) -{ - g_return_val_if_fail (GSM_IS_CLIENT (client), -1); - - return GSM_CLIENT_GET_CLASS (client)->get_pid (client); -} - -char * -gsm_client_get_desktop_file (GsmClient *client) -{ - g_return_val_if_fail (GSM_IS_CLIENT (client), NULL); - - return GSM_CLIENT_GET_CLASS (client)->get_desktop_file (client); -} - -char * -gsm_client_get_restart_command (GsmClient *client) -{ - g_return_val_if_fail (GSM_IS_CLIENT (client), NULL); - - return GSM_CLIENT_GET_CLASS (client)->get_restart_command (client); -} - -char * -gsm_client_get_discard_command (GsmClient *client) -{ - g_return_val_if_fail (GSM_IS_CLIENT (client), NULL); - - return GSM_CLIENT_GET_CLASS (client)->get_discard_command (client); -} - -gboolean -gsm_client_get_autorestart (GsmClient *client) -{ - g_return_val_if_fail (GSM_IS_CLIENT (client), FALSE); - - return GSM_CLIENT_GET_CLASS (client)->get_autorestart (client); -} - -void -gsm_client_save_state (GsmClient *client) -{ - g_return_if_fail (GSM_IS_CLIENT (client)); -} - -void -gsm_client_restart (GsmClient *client, GError **error) -{ - g_return_if_fail (GSM_IS_CLIENT (client)); - - GSM_CLIENT_GET_CLASS (client)->restart (client, error); -} - -void -gsm_client_save_yourself (GsmClient *client, - gboolean save_state) -{ - g_return_if_fail (GSM_IS_CLIENT (client)); - - GSM_CLIENT_GET_CLASS (client)->save_yourself (client, save_state); -} - -void -gsm_client_save_yourself_phase2 (GsmClient *client) -{ - g_return_if_fail (GSM_IS_CLIENT (client)); - - GSM_CLIENT_GET_CLASS (client)->save_yourself_phase2 (client); -} - -void -gsm_client_interact (GsmClient *client) -{ - g_return_if_fail (GSM_IS_CLIENT (client)); - - GSM_CLIENT_GET_CLASS (client)->interact (client); -} - -void -gsm_client_shutdown_cancelled (GsmClient *client) -{ - g_return_if_fail (GSM_IS_CLIENT (client)); - - GSM_CLIENT_GET_CLASS (client)->shutdown_cancelled (client); -} - -void -gsm_client_die (GsmClient *client) -{ - g_return_if_fail (GSM_IS_CLIENT (client)); - - GSM_CLIENT_GET_CLASS (client)->die (client); -} - -void -gsm_client_saved_state (GsmClient *client) -{ - g_signal_emit (client, signals[SAVED_STATE], 0); -} - -void -gsm_client_request_phase2 (GsmClient *client) -{ - g_signal_emit (client, signals[REQUEST_PHASE2], 0); -} - -void -gsm_client_request_interaction (GsmClient *client) -{ - g_signal_emit (client, signals[REQUEST_INTERACTION], 0); -} - -void -gsm_client_interaction_done (GsmClient *client, gboolean cancel_shutdown) -{ - g_signal_emit (client, signals[INTERACTION_DONE], 0, cancel_shutdown); -} - -void -gsm_client_save_yourself_done (GsmClient *client) -{ - g_signal_emit (client, signals[SAVE_YOURSELF_DONE], 0); -} - -void -gsm_client_disconnected (GsmClient *client) -{ - g_signal_emit (client, signals[DISCONNECTED], 0); -} - diff --git a/src/sugar/gsm-client.h b/src/sugar/gsm-client.h deleted file mode 100644 index 4cfd7ed..0000000 --- a/src/sugar/gsm-client.h +++ /dev/null @@ -1,111 +0,0 @@ -/* client.h - * Copyright (C) 2007 Novell, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by 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 - * Lesser 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 __GSM_CLIENT_H__ -#define __GSM_CLIENT_H__ - -#include <glib-object.h> -#include <sys/types.h> - -G_BEGIN_DECLS - -#define GSM_TYPE_CLIENT (gsm_client_get_type ()) -#define GSM_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSM_TYPE_CLIENT, GsmClient)) -#define GSM_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSM_TYPE_CLIENT, GsmClientClass)) -#define GSM_IS_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSM_TYPE_CLIENT)) -#define GSM_IS_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSM_TYPE_CLIENT)) -#define GSM_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSM_TYPE_CLIENT, GsmClientClass)) - -typedef struct _GsmClient GsmClient; -typedef struct _GsmClientClass GsmClientClass; - -struct _GsmClient -{ - GObject parent; - -}; - -struct _GsmClientClass -{ - GObjectClass parent_class; - - /* signals */ - void (*saved_state) (GsmClient *client); - - void (*request_phase2) (GsmClient *client); - - void (*request_interaction) (GsmClient *client); - void (*interaction_done) (GsmClient *client, - gboolean cancel_shutdown); - - void (*save_yourself_done) (GsmClient *client); - - void (*disconnected) (GsmClient *client); - - /* virtual methods */ - const char * (*get_client_id) (GsmClient *client); - pid_t (*get_pid) (GsmClient *client); - char * (*get_desktop_file) (GsmClient *client); - char * (*get_restart_command) (GsmClient *client); - char * (*get_discard_command) (GsmClient *client); - gboolean (*get_autorestart) (GsmClient *client); - - void (*restart) (GsmClient *client, - GError **error); - void (*save_yourself) (GsmClient *client, - gboolean save_state); - void (*save_yourself_phase2) (GsmClient *client); - void (*interact) (GsmClient *client); - void (*shutdown_cancelled) (GsmClient *client); - void (*die) (GsmClient *client); -}; - -GType gsm_client_get_type (void) G_GNUC_CONST; - -const char *gsm_client_get_client_id (GsmClient *client); - -pid_t gsm_client_get_pid (GsmClient *client); -char *gsm_client_get_desktop_file (GsmClient *client); -char *gsm_client_get_restart_command (GsmClient *client); -char *gsm_client_get_discard_command (GsmClient *client); -gboolean gsm_client_get_autorestart (GsmClient *client); - -void gsm_client_save_state (GsmClient *client); - -void gsm_client_restart (GsmClient *client, - GError **error); -void gsm_client_save_yourself (GsmClient *client, - gboolean save_state); -void gsm_client_save_yourself_phase2 (GsmClient *client); -void gsm_client_interact (GsmClient *client); -void gsm_client_shutdown_cancelled (GsmClient *client); -void gsm_client_die (GsmClient *client); - -/* protected */ -void gsm_client_saved_state (GsmClient *client); -void gsm_client_request_phase2 (GsmClient *client); -void gsm_client_request_interaction (GsmClient *client); -void gsm_client_interaction_done (GsmClient *client, - gboolean cancel_shutdown); -void gsm_client_save_yourself_done (GsmClient *client); -void gsm_client_disconnected (GsmClient *client); - -G_END_DECLS - -#endif /* __GSM_CLIENT_H__ */ diff --git a/src/sugar/gsm-session.c b/src/sugar/gsm-session.c deleted file mode 100644 index 6430a94..0000000 --- a/src/sugar/gsm-session.c +++ /dev/null @@ -1,509 +0,0 @@ -/* session.c - * Copyright (C) 2007 Novell, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by 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 - * Lesser 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 <string.h> - -#include "gsm-session.h" -#include "gsm-app.h" -#include "gsm-xsmp.h" - -GsmSession *global_session; - -static void initiate_shutdown (GsmSession *session); - -static void session_shutdown (GsmSession *session); - -static void client_saved_state (GsmClient *client, - gpointer data); -static void client_request_phase2 (GsmClient *client, - gpointer data); -static void client_request_interaction (GsmClient *client, - gpointer data); -static void client_interaction_done (GsmClient *client, - gboolean cancel_shutdown, - gpointer data); -static void client_save_yourself_done (GsmClient *client, - gpointer data); -static void client_disconnected (GsmClient *client, - gpointer data); - -struct _GsmSession { - GObject parent; - - char *name; - - /* Current status */ - GsmSessionPhase phase; - guint timeout; - GSList *pending_apps; - - /* SM clients */ - GSList *clients; - - /* When shutdown starts, all clients are put into shutdown_clients. - * If they request phase2, they are moved from shutdown_clients to - * phase2_clients. If they request interaction, they are appended - * to interact_clients (the first client in interact_clients is - * the one currently interacting). If they report that they're done, - * they're removed from shutdown_clients/phase2_clients. - * - * Once shutdown_clients is empty, phase2 starts. Once phase2_clients - * is empty, shutdown is complete. - */ - GSList *shutdown_clients; - GSList *interact_clients; - GSList *phase2_clients; - - /* List of clients which were disconnected due to disabled condition - * and shouldn't be automatically restarted */ - GSList *condition_clients; -}; - -struct _GsmSessionClass -{ - GObjectClass parent_class; - - void (* shutdown_completed) (GsmSession *client); -}; - -enum { - SHUTDOWN_COMPLETED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE (GsmSession, gsm_session, G_TYPE_OBJECT) - -#define GSM_SESSION_PHASE_TIMEOUT 10 /* seconds */ - -void -gsm_session_init (GsmSession *session) -{ - session->name = NULL; - session->clients = NULL; - session->condition_clients = NULL; -} - -static void -gsm_session_class_init (GsmSessionClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - signals[SHUTDOWN_COMPLETED] = - g_signal_new ("shutdown_completed", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GsmSessionClass, shutdown_completed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, - 0); -} - - -/** - * gsm_session_set_name: - * @session: session instance - * @name: name of the session - * - * Sets the name of a running session. - **/ -void -gsm_session_set_name (GsmSession *session, const char *name) -{ - if (session->name) - g_free (session->name); - - session->name = g_strdup (name); -} - -static void start_phase (GsmSession *session); - -static void -end_phase (GsmSession *session) -{ - g_slist_free (session->pending_apps); - session->pending_apps = NULL; - - g_debug ("ending phase %d\n", session->phase); - - session->phase++; - - if (session->phase < GSM_SESSION_PHASE_RUNNING) - start_phase (session); -} - -static void -app_registered (GsmApp *app, gpointer data) -{ - GsmSession *session = data; - - session->pending_apps = g_slist_remove (session->pending_apps, app); - g_signal_handlers_disconnect_by_func (app, app_registered, session); - - if (!session->pending_apps) - { - if (session->timeout > 0) - { - g_source_remove (session->timeout); - session->timeout = 0; - } - - end_phase (session); - } -} - -static gboolean -phase_timeout (gpointer data) -{ - GsmSession *session = data; - GSList *a; - - session->timeout = 0; - - for (a = session->pending_apps; a; a = a->next) - { - g_warning ("Application '%s' failed to register before timeout", - gsm_app_get_basename (a->data)); - g_signal_handlers_disconnect_by_func (a->data, app_registered, session); - - /* FIXME: what if the app was filling in a required slot? */ - } - - end_phase (session); - return FALSE; -} - -static void -start_phase (GsmSession *session) -{ - g_debug ("starting phase %d\n", session->phase); - - g_slist_free (session->pending_apps); - session->pending_apps = NULL; - - if (session->pending_apps) - { - if (session->phase < GSM_SESSION_PHASE_APPLICATION) - { - session->timeout = g_timeout_add_seconds (GSM_SESSION_PHASE_TIMEOUT, - phase_timeout, session); - } - } - else - end_phase (session); -} - -void -gsm_session_start (GsmSession *session) -{ - session->phase = GSM_SESSION_PHASE_INITIALIZATION; - - start_phase (session); -} - -GsmSessionPhase -gsm_session_get_phase (GsmSession *session) -{ - return session->phase; -} - -char * -gsm_session_register_client (GsmSession *session, - GsmClient *client, - const char *id) -{ - GSList *a; - char *client_id = NULL; - - /* If we're shutting down, we don't accept any new session - clients. */ - if (session->phase == GSM_SESSION_PHASE_SHUTDOWN) - return FALSE; - - if (id == NULL) - client_id = gsm_xsmp_generate_client_id (); - else - { - for (a = session->clients; a; a = a->next) - { - GsmClient *client = GSM_CLIENT (a->data); - - /* We can't have two clients with the same id. */ - if (!strcmp (id, gsm_client_get_client_id (client))) - { - return NULL; - } - } - - client_id = g_strdup (id); - } - - g_debug ("Adding new client %s to session", id); - - g_signal_connect (client, "saved_state", - G_CALLBACK (client_saved_state), session); - g_signal_connect (client, "request_phase2", - G_CALLBACK (client_request_phase2), session); - g_signal_connect (client, "request_interaction", - G_CALLBACK (client_request_interaction), session); - g_signal_connect (client, "interaction_done", - G_CALLBACK (client_interaction_done), session); - g_signal_connect (client, "save_yourself_done", - G_CALLBACK (client_save_yourself_done), session); - g_signal_connect (client, "disconnected", - G_CALLBACK (client_disconnected), session); - - session->clients = g_slist_prepend (session->clients, client); - - /* If it's a brand new client id, we just accept the client*/ - if (id == NULL) - return client_id; - - /* If we're starting up the session, try to match the new client - * with one pending apps for the current phase. If not, try to match - * with any of the autostarted apps. */ - if (session->phase < GSM_SESSION_PHASE_APPLICATION) - a = session->pending_apps; - - for (; a; a = a->next) - { - GsmApp *app = GSM_APP (a->data); - - if (!strcmp (client_id, app->client_id)) - { - gsm_app_registered (app); - return client_id; - } - } - - g_free (client_id); - - return NULL; -} - -static void -client_saved_state (GsmClient *client, gpointer data) -{ - /* FIXME */ -} - -void -gsm_session_initiate_shutdown (GsmSession *session) -{ - if (session->phase == GSM_SESSION_PHASE_SHUTDOWN) - { - /* Already shutting down, nothing more to do */ - return; - } - - initiate_shutdown (session); -} - -static void -session_shutdown_phase2 (GsmSession *session) -{ - GSList *cl; - - for (cl = session->phase2_clients; cl; cl = cl->next) - gsm_client_save_yourself_phase2 (cl->data); -} - -static void -session_cancel_shutdown (GsmSession *session) -{ - GSList *cl; - - session->phase = GSM_SESSION_PHASE_RUNNING; - - g_slist_free (session->shutdown_clients); - session->shutdown_clients = NULL; - g_slist_free (session->interact_clients); - session->interact_clients = NULL; - g_slist_free (session->phase2_clients); - session->phase2_clients = NULL; - - for (cl = session->clients; cl; cl = cl->next) - gsm_client_shutdown_cancelled (cl->data); -} - -void -gsm_session_cancel_shutdown (GsmSession *session) -{ - if (session == NULL || session->phase != GSM_SESSION_PHASE_SHUTDOWN) - { - g_warning ("Session is not in shutdown mode"); - return; - } - - session_cancel_shutdown (session); -} - -static void -initiate_shutdown (GsmSession *session) -{ - GSList *cl; - - session->phase = GSM_SESSION_PHASE_SHUTDOWN; - - if (session->clients == NULL) - session_shutdown (session); - - for (cl = session->clients; cl; cl = cl->next) - { - GsmClient *client = GSM_CLIENT (cl->data); - - session->shutdown_clients = - g_slist_prepend (session->shutdown_clients, client); - - gsm_client_save_yourself (client, FALSE); - } -} - -static void -session_shutdown (GsmSession *session) -{ - GSList *cl; - - /* FIXME: do this in reverse phase order */ - for (cl = session->clients; cl; cl = cl->next) - gsm_client_die (cl->data); - - g_signal_emit (session, signals[SHUTDOWN_COMPLETED], 0); -} - -static void -client_request_phase2 (GsmClient *client, gpointer data) -{ - GsmSession *session = data; - - /* Move the client from shutdown_clients to phase2_clients */ - - session->shutdown_clients = - g_slist_remove (session->shutdown_clients, client); - session->phase2_clients = - g_slist_prepend (session->phase2_clients, client); -} - -static void -client_request_interaction (GsmClient *client, gpointer data) -{ - GsmSession *session = data; - - session->interact_clients = - g_slist_append (session->interact_clients, client); - - if (!session->interact_clients->next) - gsm_client_interact (client); -} - -static void -client_interaction_done (GsmClient *client, gboolean cancel_shutdown, - gpointer data) -{ - GsmSession *session = data; - - g_return_if_fail (session->interact_clients && - (GsmClient *)session->interact_clients->data == client); - - if (cancel_shutdown) - { - session_cancel_shutdown (session); - return; - } - - /* Remove this client from interact_clients, and if there's another - * client waiting to interact, let it interact now. - */ - session->interact_clients = - g_slist_remove (session->interact_clients, client); - if (session->interact_clients) - gsm_client_interact (session->interact_clients->data); -} - -static void -client_save_yourself_done (GsmClient *client, gpointer data) -{ - GsmSession *session = data; - - session->shutdown_clients = - g_slist_remove (session->shutdown_clients, client); - session->interact_clients = - g_slist_remove (session->interact_clients, client); - session->phase2_clients = - g_slist_remove (session->phase2_clients, client); - - if (session->phase == GSM_SESSION_PHASE_SHUTDOWN && - !session->shutdown_clients) - { - if (session->phase2_clients) - session_shutdown_phase2 (session); - else - session_shutdown (session); - } -} - -static void -client_disconnected (GsmClient *client, gpointer data) -{ - GsmSession *session = data; - gboolean is_condition_client = FALSE; - - session->clients = - g_slist_remove (session->clients, client); - session->shutdown_clients = - g_slist_remove (session->shutdown_clients, client); - session->interact_clients = - g_slist_remove (session->interact_clients, client); - session->phase2_clients = - g_slist_remove (session->phase2_clients, client); - - if (g_slist_find (session->condition_clients, client)) - { - session->condition_clients = - g_slist_remove (session->condition_clients, client); - - is_condition_client = TRUE; - } - - if (session->phase != GSM_SESSION_PHASE_SHUTDOWN && - gsm_client_get_autorestart (client) && - !is_condition_client) - { - GError *error = NULL; - - gsm_client_restart (client, &error); - - if (error) - { - g_warning ("Error on restarting session client: %s", error->message); - g_clear_error (&error); - } - } - - g_object_unref (client); -} - -GsmSession * -gsm_session_create_global (void) -{ - global_session = GSM_SESSION(g_object_new (GSM_TYPE_SESSION, NULL)); - return global_session; -} diff --git a/src/sugar/gsm-session.h b/src/sugar/gsm-session.h deleted file mode 100644 index 31d2762..0000000 --- a/src/sugar/gsm-session.h +++ /dev/null @@ -1,97 +0,0 @@ -/* session.h - * Copyright (C) 2007 Novell, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by 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 - * Lesser 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 __GSM_SESSION_H__ -#define __GSM_SESSION_H__ - -#include <glib.h> -#include "gsm-client.h" - -G_BEGIN_DECLS - -#define GSM_TYPE_SESSION (gsm_session_get_type ()) -#define GSM_SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSM_TYPE_SESSION, GsmSession)) -#define GSM_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GSM_TYPE_SESSION, GsmSessionClass)) -#define GSM_IS_SESSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSM_TYPE_SESSION)) -#define GSM_IS_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GSM_TYPE_SESSION)) -#define GSM_SESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GSM_TYPE_SESSION, GsmSessionClass)) - -typedef struct _GsmSession GsmSession; -typedef struct _GsmSessionClass GsmSessionClass; -extern GsmSession *global_session; - -typedef enum { - /* gsm's own startup/initialization phase */ - GSM_SESSION_PHASE_STARTUP, - - /* xrandr setup, gnome-settings-daemon, etc */ - GSM_SESSION_PHASE_INITIALIZATION, - - /* window/compositing managers */ - GSM_SESSION_PHASE_WINDOW_MANAGER, - - /* apps that will create _NET_WM_WINDOW_TYPE_PANEL windows */ - GSM_SESSION_PHASE_PANEL, - - /* apps that will create _NET_WM_WINDOW_TYPE_DESKTOP windows */ - GSM_SESSION_PHASE_DESKTOP, - - /* everything else */ - GSM_SESSION_PHASE_APPLICATION, - - /* done launching */ - GSM_SESSION_PHASE_RUNNING, - - /* shutting down */ - GSM_SESSION_PHASE_SHUTDOWN -} GsmSessionPhase; - -typedef enum { - GSM_SESSION_LOGOUT_TYPE_LOGOUT, - GSM_SESSION_LOGOUT_TYPE_SHUTDOWN -} GsmSessionLogoutType; - -typedef enum { - GSM_SESSION_LOGOUT_MODE_NORMAL, - GSM_SESSION_LOGOUT_MODE_NO_CONFIRMATION, - GSM_SESSION_LOGOUT_MODE_FORCE -} GsmSessionLogoutMode; - -GType gsm_session_get_type (void) G_GNUC_CONST; - -void gsm_session_set_name (GsmSession *session, - const char *name); - -void gsm_session_start (GsmSession *session); - -GsmSessionPhase gsm_session_get_phase (GsmSession *session); - -void gsm_session_initiate_shutdown (GsmSession *session); - -void gsm_session_cancel_shutdown (GsmSession *session); - -char *gsm_session_register_client (GsmSession *session, - GsmClient *client, - const char *previous_id); - -GsmSession *gsm_session_create_global (void); - -G_END_DECLS - -#endif /* __GSM_SESSION_H__ */ diff --git a/src/sugar/gsm-xsmp.c b/src/sugar/gsm-xsmp.c deleted file mode 100644 index aa9dff1..0000000 --- a/src/sugar/gsm-xsmp.c +++ /dev/null @@ -1,535 +0,0 @@ -/* xsmp.c - * Copyright (C) 2007 Novell, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by 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 - * Lesser 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. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <fcntl.h> -#include <stdlib.h> -#include <string.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/types.h> -#include <unistd.h> - -#include <glib.h> -#include <glib/gi18n.h> - -#include "gsm-client-xsmp.h" -#include "gsm-xsmp.h" - -#include <X11/ICE/ICElib.h> -#include <X11/ICE/ICEutil.h> -#include <X11/ICE/ICEconn.h> -#include <X11/SM/SMlib.h> - -#ifdef HAVE_X11_XTRANS_XTRANS_H -/* Get the proto for _IceTransNoListen */ -#define ICE_t -#define TRANS_SERVER -#include <X11/Xtrans/Xtrans.h> -#undef ICE_t -#undef TRANS_SERVER -#endif /* HAVE_X11_XTRANS_XTRANS_H */ - -static IceListenObj *xsmp_sockets; -static int num_xsmp_sockets, num_local_xsmp_sockets; - -static gboolean update_iceauthority (gboolean adding); - -static gboolean accept_ice_connection (GIOChannel *source, - GIOCondition condition, - gpointer data); -static Status accept_xsmp_connection (SmsConn conn, - SmPointer manager_data, - unsigned long *mask_ret, - SmsCallbacks *callbacks_ret, - char **failure_reason_ret); - -static void ice_error_handler (IceConn conn, - Bool swap, - int offending_minor_opcode, - unsigned long offending_sequence_num, - int error_class, - int severity, - IcePointer values); -static void ice_io_error_handler (IceConn conn); -static void sms_error_handler (SmsConn sms_conn, - Bool swap, - int offending_minor_opcode, - unsigned long offending_sequence_num, - int error_class, - int severity, - IcePointer values); -/** - * gsm_xsmp_init: - * - * Initializes XSMP. Notably, it creates the XSMP listening socket and - * sets the SESSION_MANAGER environment variable to point to it. - **/ -char * -gsm_xsmp_init (void) -{ - char error[256]; - mode_t saved_umask; - char *network_id_list; - int i; - - /* Set up sane error handlers */ - IceSetErrorHandler (ice_error_handler); - IceSetIOErrorHandler (ice_io_error_handler); - SmsSetErrorHandler (sms_error_handler); - - /* Initialize libSM; we pass NULL for hostBasedAuthProc to disable - * host-based authentication. - */ - if (!SmsInitialize (PACKAGE, VERSION, accept_xsmp_connection, - NULL, NULL, sizeof (error), error)) - g_error("Could not initialize libSM: %s", error); - -#ifdef HAVE_X11_XTRANS_XTRANS_H - /* By default, IceListenForConnections will open one socket for each - * transport type known to X. We don't want connections from remote - * hosts, so for security reasons it would be best if ICE didn't - * even open any non-local sockets. So we use an internal ICElib - * method to disable them here. Unfortunately, there is no way to - * ask X what transport types it knows about, so we're forced to - * guess. - */ - _IceTransNoListen ("tcp"); -#endif - - /* Create the XSMP socket. Older versions of IceListenForConnections - * have a bug which causes the umask to be set to 0 on certain types - * of failures. Probably not an issue on any modern systems, but - * we'll play it safe. - */ - saved_umask = umask (0); - umask (saved_umask); - if (!IceListenForConnections (&num_xsmp_sockets, &xsmp_sockets, - sizeof (error), error)) - g_error ("Could not create ICE listening socket: %s", error); - umask (saved_umask); - - /* Find the local sockets in the returned socket list and move them - * to the start of the list. - */ - for (i = num_local_xsmp_sockets = 0; i < num_xsmp_sockets; i++) - { - char *id = IceGetListenConnectionString (xsmp_sockets[i]); - - if (!strncmp (id, "local/", sizeof ("local/") - 1) || - !strncmp (id, "unix/", sizeof ("unix/") - 1)) - { - if (i > num_local_xsmp_sockets) - { - IceListenObj tmp = xsmp_sockets[i]; - xsmp_sockets[i] = xsmp_sockets[num_local_xsmp_sockets]; - xsmp_sockets[num_local_xsmp_sockets] = tmp; - } - num_local_xsmp_sockets++; - } - free (id); - } - - if (num_local_xsmp_sockets == 0) - g_error ("IceListenForConnections did not return a local listener!"); - -#ifdef HAVE_X11_XTRANS_XTRANS_H - if (num_local_xsmp_sockets != num_xsmp_sockets) - { - /* Xtrans was apparently compiled with support for some - * non-local transport besides TCP (which we disabled above); we - * won't create IO watches on those extra sockets, so - * connections to them will never be noticed, but they're still - * there, which is inelegant. - * - * If the g_warning below is triggering for you and you want to - * stop it, the fix is to add additional _IceTransNoListen() - * calls above. - */ - network_id_list = - IceComposeNetworkIdList (num_xsmp_sockets - num_local_xsmp_sockets, - xsmp_sockets + num_local_xsmp_sockets); - g_warning ("IceListenForConnections returned %d non-local listeners: %s", - num_xsmp_sockets - num_local_xsmp_sockets, network_id_list); - free (network_id_list); - } -#endif - - /* Update .ICEauthority with new auth entries for our socket */ - if (!update_iceauthority (TRUE)) - { - /* FIXME: is this really fatal? Hm... */ - g_error ("Could not update ICEauthority file %s", - IceAuthFileName ()); - } - - network_id_list = IceComposeNetworkIdList (num_local_xsmp_sockets, - xsmp_sockets); - - return network_id_list; -} - -/** - * gsm_xsmp_run: - * - * Sets the XSMP server to start accepting connections. - **/ -void -gsm_xsmp_run (void) -{ - GIOChannel *channel; - int i; - - for (i = 0; i < num_local_xsmp_sockets; i++) - { - channel = g_io_channel_unix_new (IceGetListenConnectionNumber (xsmp_sockets[i])); - g_io_add_watch (channel, G_IO_IN | G_IO_HUP | G_IO_ERR, - accept_ice_connection, xsmp_sockets[i]); - g_io_channel_unref (channel); - } -} - -/** - * gsm_xsmp_shutdown: - * - * Shuts down the XSMP server and closes the ICE listening socket - **/ -void -gsm_xsmp_shutdown (void) -{ - update_iceauthority (FALSE); - - IceFreeListenObjs (num_xsmp_sockets, xsmp_sockets); - xsmp_sockets = NULL; -} - -/** - * gsm_xsmp_generate_client_id: - * - * Generates a new XSMP client ID. - * - * Return value: an XSMP client ID. - **/ -char * -gsm_xsmp_generate_client_id (void) -{ - static int sequence = -1; - static guint rand1 = 0, rand2 = 0; - static pid_t pid = 0; - struct timeval tv; - - /* The XSMP spec defines the ID as: - * - * Version: "1" - * Address type and address: - * "1" + an IPv4 address as 8 hex digits - * "2" + a DECNET address as 12 hex digits - * "6" + an IPv6 address as 32 hex digits - * Time stamp: milliseconds since UNIX epoch as 13 decimal digits - * Process-ID type and process-ID: - * "1" + POSIX PID as 10 decimal digits - * Sequence number as 4 decimal digits - * - * XSMP client IDs are supposed to be globally unique: if - * SmsGenerateClientID() is unable to determine a network - * address for the machine, it gives up and returns %NULL. - * GNOME and KDE have traditionally used a fourth address - * format in this case: - * "0" + 16 random hex digits - * - * We don't even bother trying SmsGenerateClientID(), since the - * user's IP address is probably "192.168.1.*" anyway, so a random - * number is actually more likely to be globally unique. - */ - - if (!rand1) - { - rand1 = g_random_int (); - rand2 = g_random_int (); - pid = getpid (); - } - - sequence = (sequence + 1) % 10000; - gettimeofday (&tv, NULL); - return g_strdup_printf ("10%.04x%.04x%.10lu%.3u%.10lu%.4d", - rand1, rand2, - (unsigned long) tv.tv_sec, - (unsigned) tv.tv_usec, - (unsigned long) pid, - sequence); -} - -/* This is called (by glib via xsmp->ice_connection_watch) when a - * connection is first received on the ICE listening socket. (We - * expect that the client will then initiate XSMP on the connection; - * if it does not, GsmClientXSMP will eventually time out and close - * the connection.) - * - * FIXME: it would probably make more sense to not create a - * GsmClientXSMP object until accept_xsmp_connection, below (and to do - * the timing-out here in xsmp.c). - */ -static gboolean -accept_ice_connection (GIOChannel *source, - GIOCondition condition, - gpointer data) -{ - IceListenObj listener = data; - IceConn ice_conn; - IceAcceptStatus status; - GsmClientXSMP *client; - - g_debug ("accept_ice_connection()"); - - ice_conn = IceAcceptConnection (listener, &status); - if (status != IceAcceptSuccess) - { - g_debug ("IceAcceptConnection returned %d", status); - return TRUE; - } - - client = gsm_client_xsmp_new (ice_conn); - ice_conn->context = client; - return TRUE; -} - -/* This is called (by libSM) when XSMP is initiated on an ICE - * connection that was already accepted by accept_ice_connection. - */ -static Status -accept_xsmp_connection (SmsConn sms_conn, SmPointer manager_data, - unsigned long *mask_ret, SmsCallbacks *callbacks_ret, - char **failure_reason_ret) -{ - IceConn ice_conn; - GsmClientXSMP *client; - - /* FIXME: what about during shutdown but before gsm_xsmp_shutdown? */ - if (!xsmp_sockets) - { - g_debug ("In shutdown, rejecting new client"); - - *failure_reason_ret = - strdup (_("Refusing new client connection because the session is currently being shut down\n")); - return FALSE; - } - - ice_conn = SmsGetIceConnection (sms_conn); - client = ice_conn->context; - - g_return_val_if_fail (client != NULL, TRUE); - - gsm_client_xsmp_connect (client, sms_conn, mask_ret, callbacks_ret); - return TRUE; -} - -/* ICEauthority stuff */ - -/* Various magic numbers stolen from iceauth.c */ -#define GSM_ICE_AUTH_RETRIES 10 -#define GSM_ICE_AUTH_INTERVAL 2 /* 2 seconds */ -#define GSM_ICE_AUTH_LOCK_TIMEOUT 600 /* 10 minutes */ - -#define GSM_ICE_MAGIC_COOKIE_AUTH_NAME "MIT-MAGIC-COOKIE-1" -#define GSM_ICE_MAGIC_COOKIE_LEN 16 - -static IceAuthFileEntry * -auth_entry_new (const char *protocol, const char *network_id) -{ - IceAuthFileEntry *file_entry; - IceAuthDataEntry data_entry; - - file_entry = malloc (sizeof (IceAuthFileEntry)); - - file_entry->protocol_name = strdup (protocol); - file_entry->protocol_data = NULL; - file_entry->protocol_data_length = 0; - file_entry->network_id = strdup (network_id); - file_entry->auth_name = strdup (GSM_ICE_MAGIC_COOKIE_AUTH_NAME); - file_entry->auth_data = IceGenerateMagicCookie (GSM_ICE_MAGIC_COOKIE_LEN); - file_entry->auth_data_length = GSM_ICE_MAGIC_COOKIE_LEN; - - /* Also create an in-memory copy, which is what the server will - * actually use for checking client auth. - */ - data_entry.protocol_name = file_entry->protocol_name; - data_entry.network_id = file_entry->network_id; - data_entry.auth_name = file_entry->auth_name; - data_entry.auth_data = file_entry->auth_data; - data_entry.auth_data_length = file_entry->auth_data_length; - IceSetPaAuthData (1, &data_entry); - - return file_entry; -} - -static gboolean -update_iceauthority (gboolean adding) -{ - char *filename = IceAuthFileName (); - char **our_network_ids; - FILE *fp; - IceAuthFileEntry *auth_entry; - GSList *entries, *e; - int i; - gboolean ok = FALSE; - - if (IceLockAuthFile (filename, GSM_ICE_AUTH_RETRIES, GSM_ICE_AUTH_INTERVAL, - GSM_ICE_AUTH_LOCK_TIMEOUT) != IceAuthLockSuccess) - return FALSE; - - our_network_ids = g_malloc (num_local_xsmp_sockets * sizeof (char *)); - for (i = 0; i < num_local_xsmp_sockets; i++) - our_network_ids[i] = IceGetListenConnectionString (xsmp_sockets[i]); - - entries = NULL; - - fp = fopen (filename, "r+"); - if (fp) - { - while ((auth_entry = IceReadAuthFileEntry (fp)) != NULL) - { - /* Skip/delete entries with no network ID (invalid), or with - * our network ID; if we're starting up, an entry with our - * ID must be a stale entry left behind by an old process, - * and if we're shutting down, it won't be valid in the - * future, so either way we want to remove it from the list. - */ - if (!auth_entry->network_id) - { - IceFreeAuthFileEntry (auth_entry); - continue; - } - - for (i = 0; i < num_local_xsmp_sockets; i++) - { - if (!strcmp (auth_entry->network_id, our_network_ids[i])) - { - IceFreeAuthFileEntry (auth_entry); - break; - } - } - if (i != num_local_xsmp_sockets) - continue; - - entries = g_slist_prepend (entries, auth_entry); - } - - rewind (fp); - } - else - { - int fd; - - if (g_file_test (filename, G_FILE_TEST_EXISTS)) - { - g_warning ("Unable to read ICE authority file: %s", filename); - goto cleanup; - } - - fd = open (filename, O_CREAT | O_WRONLY, 0600); - fp = fdopen (fd, "w"); - if (!fp) - { - g_warning ("Unable to write to ICE authority file: %s", filename); - if (fd != -1) - close (fd); - goto cleanup; - } - } - - if (adding) - { - for (i = 0; i < num_local_xsmp_sockets; i++) - { - entries = g_slist_append (entries, - auth_entry_new ("ICE", our_network_ids[i])); - entries = g_slist_prepend (entries, - auth_entry_new ("XSMP", our_network_ids[i])); - } - } - - for (e = entries; e; e = e->next) - { - IceAuthFileEntry *auth_entry = e->data; - IceWriteAuthFileEntry (fp, auth_entry); - IceFreeAuthFileEntry (auth_entry); - } - g_slist_free (entries); - - fclose (fp); - ok = TRUE; - - cleanup: - IceUnlockAuthFile (filename); - for (i = 0; i < num_local_xsmp_sockets; i++) - free (our_network_ids[i]); - g_free (our_network_ids); - - return ok; -} - -/* Error handlers */ - -static void -ice_error_handler (IceConn conn, Bool swap, int offending_minor_opcode, - unsigned long offending_sequence, int error_class, - int severity, IcePointer values) -{ - g_debug ("ice_error_handler (%p, %s, %d, %lx, %d, %d)", - conn, swap ? "TRUE" : "FALSE", offending_minor_opcode, - offending_sequence, error_class, severity); - - if (severity == IceCanContinue) - return; - - /* FIXME: the ICElib docs are completely vague about what we're - * supposed to do in this case. Need to verify that calling - * IceCloseConnection() here is guaranteed to cause neither - * free-memory-reads nor leaks. - */ - IceCloseConnection (conn); -} - -static void -ice_io_error_handler (IceConn conn) -{ - g_debug ("ice_io_error_handler (%p)", conn); - - /* We don't need to do anything here; the next call to - * IceProcessMessages() for this connection will receive - * IceProcessMessagesIOError and we can handle the error there. - */ -} - -static void -sms_error_handler (SmsConn conn, Bool swap, int offending_minor_opcode, - unsigned long offending_sequence_num, int error_class, - int severity, IcePointer values) -{ - g_debug ("sms_error_handler (%p, %s, %d, %lx, %d, %d)", - conn, swap ? "TRUE" : "FALSE", offending_minor_opcode, - offending_sequence_num, error_class, severity); - - /* We don't need to do anything here; if the connection needs to be - * closed, libSM will do that itself. - */ -} diff --git a/src/sugar/gsm-xsmp.h b/src/sugar/gsm-xsmp.h deleted file mode 100644 index b4b535f..0000000 --- a/src/sugar/gsm-xsmp.h +++ /dev/null @@ -1,29 +0,0 @@ -/* xsmp.h - * Copyright (C) 2007 Novell, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by 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 - * Lesser 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 __GSM_XSMP_H__ -#define __GSM_XSMP_H__ - -char *gsm_xsmp_init (void); -void gsm_xsmp_run (void); -void gsm_xsmp_shutdown (void); - -char *gsm_xsmp_generate_client_id (void); - -#endif /* __GSM_XSMP_H__ */ |