317 lines
8.9 KiB
Diff
317 lines
8.9 KiB
Diff
|
--- gnome-session-2.15.91/gnome-session/gdm-logout-action.c
|
||
|
+++ gnome-session-2.15.91/gnome-session/gdm-logout-action.c
|
||
|
@@ -56,6 +56,8 @@
|
||
|
#define GDM_ACTION_STR_REBOOT "REBOOT"
|
||
|
#define GDM_ACTION_STR_SUSPEND "SUSPEND"
|
||
|
|
||
|
+#define KDM_PROTOCOL_MSG_QUERY_ACTION "caps"
|
||
|
+
|
||
|
typedef struct {
|
||
|
int fd;
|
||
|
char *auth_cookie;
|
||
|
@@ -64,6 +66,8 @@
|
||
|
GdmLogoutAction current_actions;
|
||
|
|
||
|
time_t last_update;
|
||
|
+
|
||
|
+ guint is_kdm : 1;
|
||
|
} GdmProtocolData;
|
||
|
|
||
|
static GdmProtocolData gdm_protocol_data = {
|
||
|
@@ -71,11 +75,12 @@
|
||
|
NULL,
|
||
|
GDM_LOGOUT_ACTION_NONE,
|
||
|
GDM_LOGOUT_ACTION_NONE,
|
||
|
- 0
|
||
|
+ 0,
|
||
|
+ FALSE
|
||
|
};
|
||
|
|
||
|
static char *
|
||
|
-gdm_send_protocol_msg (GdmProtocolData *data,
|
||
|
+dm_send_protocol_msg (GdmProtocolData *data,
|
||
|
const char *msg)
|
||
|
{
|
||
|
GString *retval;
|
||
|
@@ -87,7 +92,7 @@
|
||
|
if (write (data->fd, p, strlen (p)) < 0) {
|
||
|
g_free (p);
|
||
|
|
||
|
- g_warning ("Failed to send message to GDM: %s",
|
||
|
+ g_warning ("Failed to send message to display manager: %s",
|
||
|
g_strerror (errno));
|
||
|
return NULL;
|
||
|
}
|
||
|
@@ -153,7 +158,7 @@
|
||
|
|
||
|
msg = g_strdup_printf (GDM_PROTOCOL_MSG_AUTHENTICATE " %s",
|
||
|
data->auth_cookie);
|
||
|
- response = gdm_send_protocol_msg (data, msg);
|
||
|
+ response = dm_send_protocol_msg (data, msg);
|
||
|
g_free (msg);
|
||
|
|
||
|
if (response && !strcmp (response, "OK")) {
|
||
|
@@ -195,7 +200,7 @@
|
||
|
XauDisposeAuth (xau);
|
||
|
|
||
|
msg = g_strdup_printf (GDM_PROTOCOL_MSG_AUTHENTICATE " %s", buffer);
|
||
|
- response = gdm_send_protocol_msg (data, msg);
|
||
|
+ response = dm_send_protocol_msg (data, msg);
|
||
|
g_free (msg);
|
||
|
|
||
|
if (response && !strcmp (response, "OK")) {
|
||
|
@@ -218,7 +223,7 @@
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
-gdm_shutdown_protocol_connection (GdmProtocolData *data)
|
||
|
+dm_shutdown_protocol_connection (GdmProtocolData *data)
|
||
|
{
|
||
|
if (data->fd)
|
||
|
close (data->fd);
|
||
|
@@ -237,7 +242,7 @@
|
||
|
if (data->fd < 0) {
|
||
|
g_warning ("Failed to create GDM socket: %s",
|
||
|
g_strerror (errno));
|
||
|
- gdm_shutdown_protocol_connection (data);
|
||
|
+ dm_shutdown_protocol_connection (data);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
@@ -247,29 +252,93 @@
|
||
|
if (connect (data->fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
|
||
|
g_warning ("Failed to establish a connection with GDM: %s",
|
||
|
g_strerror (errno));
|
||
|
- gdm_shutdown_protocol_connection (data);
|
||
|
+ dm_shutdown_protocol_connection (data);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
- response = gdm_send_protocol_msg (data, GDM_PROTOCOL_MSG_VERSION);
|
||
|
+ response = dm_send_protocol_msg (data, GDM_PROTOCOL_MSG_VERSION);
|
||
|
if (!response || strncmp (response, "GDM ", strlen ("GDM ") != 0)) {
|
||
|
g_free (response);
|
||
|
|
||
|
g_warning ("Failed to get protocol version from GDM");
|
||
|
- gdm_shutdown_protocol_connection (data);
|
||
|
+ dm_shutdown_protocol_connection (data);
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
if (!gdm_authenticate_connection (data)) {
|
||
|
g_warning ("Failed to authenticate with GDM");
|
||
|
- gdm_shutdown_protocol_connection (data);
|
||
|
+ dm_shutdown_protocol_connection (data);
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
+static gboolean
|
||
|
+kdm_init_protocol_connection (GdmProtocolData *data)
|
||
|
+{
|
||
|
+ struct sockaddr_un addr;
|
||
|
+ char *response;
|
||
|
+ char *dm_display;
|
||
|
+ char *dm_control;
|
||
|
+ char *p0 = NULL;
|
||
|
+
|
||
|
+ g_assert (data->fd <= 0);
|
||
|
+
|
||
|
+ data->fd = socket (AF_UNIX, SOCK_STREAM, 0);
|
||
|
+ if (data->fd < 0) {
|
||
|
+ g_warning ("Failed to create KDM socket: %s",
|
||
|
+ g_strerror (errno));
|
||
|
+ dm_shutdown_protocol_connection (data);
|
||
|
+ return FALSE;
|
||
|
+ }
|
||
|
+
|
||
|
+ dm_display = g_strdup (g_getenv ("DISPLAY"));
|
||
|
+ dm_control = g_strdup (g_getenv ("DM_CONTROL"));
|
||
|
+
|
||
|
+ if (dm_display && (p0 = strchr (dm_display, ':')))
|
||
|
+ p0 = strchr (p0, '.');
|
||
|
+
|
||
|
+ if (!dm_control || !strlen (dm_control) ||
|
||
|
+ !dm_display || !strlen (dm_display)) {
|
||
|
+ g_free (dm_control);
|
||
|
+ g_free (dm_display);
|
||
|
+
|
||
|
+ g_warning ("Could not locate KDM socket.");
|
||
|
+ dm_shutdown_protocol_connection (data);
|
||
|
+ return FALSE;
|
||
|
+ }
|
||
|
+
|
||
|
+ snprintf (addr.sun_path, sizeof (addr.sun_path), "%s/dmctl-%.*s/socket",
|
||
|
+ dm_control, p0 ? p0 - dm_display : 512, dm_display);
|
||
|
+ addr.sun_family = AF_UNIX;
|
||
|
+
|
||
|
+ g_free (dm_display);
|
||
|
+ g_free (dm_control);
|
||
|
+
|
||
|
+ if (connect (data->fd, (struct sockaddr *) &addr, sizeof (addr)) < 0) {
|
||
|
+ g_warning ("Failed to establish a connection with KDM: %s",
|
||
|
+ g_strerror (errno));
|
||
|
+ dm_shutdown_protocol_connection (data);
|
||
|
+ return FALSE;
|
||
|
+ }
|
||
|
+
|
||
|
+ return TRUE;
|
||
|
+}
|
||
|
+
|
||
|
+static gboolean
|
||
|
+dm_init_protocol_connection (GdmProtocolData *data)
|
||
|
+{
|
||
|
+ if (g_getenv ("DM_CONTROL") && !g_getenv ("GDMSESSION")) {
|
||
|
+ data->is_kdm = TRUE;
|
||
|
+ return kdm_init_protocol_connection (data);
|
||
|
+ }
|
||
|
+
|
||
|
+ data->is_kdm = FALSE;
|
||
|
+ return gdm_init_protocol_connection (data);
|
||
|
+}
|
||
|
+
|
||
|
static void
|
||
|
gdm_parse_query_response (GdmProtocolData *data,
|
||
|
const char *response)
|
||
|
@@ -317,7 +386,21 @@
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
-gdm_update_logout_actions (GdmProtocolData *data)
|
||
|
+kdm_parse_query_response (GdmProtocolData *data,
|
||
|
+ const char *response)
|
||
|
+{
|
||
|
+ data->available_actions = GDM_LOGOUT_ACTION_NONE;
|
||
|
+ data->current_actions = GDM_LOGOUT_ACTION_NONE;
|
||
|
+
|
||
|
+ if (!response)
|
||
|
+ return;
|
||
|
+
|
||
|
+ if (strstr (response, "\tshutdown"))
|
||
|
+ data->available_actions |= GDM_LOGOUT_ACTION_SHUTDOWN | GDM_LOGOUT_ACTION_REBOOT;
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+dm_update_logout_actions (GdmProtocolData *data)
|
||
|
{
|
||
|
time_t current_time;
|
||
|
char *response;
|
||
|
@@ -328,21 +411,30 @@
|
||
|
|
||
|
data->last_update = current_time;
|
||
|
|
||
|
- if (!gdm_init_protocol_connection (data))
|
||
|
+ if (!dm_init_protocol_connection (data))
|
||
|
return;
|
||
|
-
|
||
|
- if ((response = gdm_send_protocol_msg (data, GDM_PROTOCOL_MSG_QUERY_ACTION))) {
|
||
|
- gdm_parse_query_response (data, response);
|
||
|
- g_free (response);
|
||
|
- }
|
||
|
|
||
|
- gdm_shutdown_protocol_connection (data);
|
||
|
+ if (data->is_kdm) {
|
||
|
+ /* KDM */
|
||
|
+ if ((response = dm_send_protocol_msg (data, KDM_PROTOCOL_MSG_QUERY_ACTION))) {
|
||
|
+ kdm_parse_query_response (data, response);
|
||
|
+ g_free (response);
|
||
|
+ }
|
||
|
+ } else {
|
||
|
+ /* GDM */
|
||
|
+ if ((response = dm_send_protocol_msg (data, GDM_PROTOCOL_MSG_QUERY_ACTION))) {
|
||
|
+ gdm_parse_query_response (data, response);
|
||
|
+ g_free (response);
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ dm_shutdown_protocol_connection (data);
|
||
|
}
|
||
|
|
||
|
gboolean
|
||
|
gdm_supports_logout_action (GdmLogoutAction action)
|
||
|
{
|
||
|
- gdm_update_logout_actions (&gdm_protocol_data);
|
||
|
+ dm_update_logout_actions (&gdm_protocol_data);
|
||
|
|
||
|
return (gdm_protocol_data.available_actions & action) != 0;
|
||
|
}
|
||
|
@@ -350,20 +442,15 @@
|
||
|
GdmLogoutAction
|
||
|
gdm_get_logout_action (void)
|
||
|
{
|
||
|
- gdm_update_logout_actions (&gdm_protocol_data);
|
||
|
+ dm_update_logout_actions (&gdm_protocol_data);
|
||
|
|
||
|
return gdm_protocol_data.current_actions;
|
||
|
}
|
||
|
|
||
|
-void
|
||
|
-gdm_set_logout_action (GdmLogoutAction action)
|
||
|
+static char *
|
||
|
+gdm_logout_action_msg (GdmLogoutAction action)
|
||
|
{
|
||
|
char *action_str = NULL;
|
||
|
- char *msg;
|
||
|
- char *response;
|
||
|
-
|
||
|
- if (!gdm_init_protocol_connection (&gdm_protocol_data))
|
||
|
- return;
|
||
|
|
||
|
switch (action) {
|
||
|
case GDM_LOGOUT_ACTION_NONE:
|
||
|
@@ -380,14 +467,48 @@
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
- msg = g_strdup_printf (GDM_PROTOCOL_MSG_SET_ACTION " %s", action_str);
|
||
|
+ return g_strdup_printf (GDM_PROTOCOL_MSG_SET_ACTION " %s", action_str);
|
||
|
+}
|
||
|
+
|
||
|
+static char *
|
||
|
+kdm_logout_action_msg (GdmLogoutAction action)
|
||
|
+{
|
||
|
+ char *msg = NULL;
|
||
|
+
|
||
|
+ if (action == GDM_LOGOUT_ACTION_SHUTDOWN)
|
||
|
+ msg = g_strdup ("shutdown\thalt\task");
|
||
|
+ else if (action == GDM_LOGOUT_ACTION_REBOOT)
|
||
|
+ msg = g_strdup ("shutdown\treboot\task");
|
||
|
+
|
||
|
+ return msg;
|
||
|
+}
|
||
|
+
|
||
|
+void
|
||
|
+gdm_set_logout_action (GdmLogoutAction action)
|
||
|
+{
|
||
|
+ char *action_str = NULL;
|
||
|
+ char *msg;
|
||
|
+ char *response;
|
||
|
+
|
||
|
+ if (!dm_init_protocol_connection (&gdm_protocol_data))
|
||
|
+ return;
|
||
|
+
|
||
|
+ if (gdm_protocol_data.is_kdm)
|
||
|
+ msg = kdm_logout_action_msg (action);
|
||
|
+ else
|
||
|
+ msg = gdm_logout_action_msg (action);
|
||
|
+
|
||
|
+ if (!msg) {
|
||
|
+ dm_shutdown_protocol_connection (&gdm_protocol_data);
|
||
|
+ return;
|
||
|
+ }
|
||
|
|
||
|
- response = gdm_send_protocol_msg (&gdm_protocol_data, msg);
|
||
|
+ response = dm_send_protocol_msg (&gdm_protocol_data, msg);
|
||
|
|
||
|
g_free (msg);
|
||
|
g_free (response);
|
||
|
|
||
|
gdm_protocol_data.last_update = 0;
|
||
|
|
||
|
- gdm_shutdown_protocol_connection (&gdm_protocol_data);
|
||
|
+ dm_shutdown_protocol_connection (&gdm_protocol_data);
|
||
|
}
|