[Xfce4-commits] <xfce4-session:console-kit> WIP
Brian J. Tarricone
noreply at xfce.org
Fri Jan 29 07:08:02 CET 2010
Updating branch refs/heads/console-kit
to e6993a82aac7a11e5fd997ac35f1cd374ba5c80f (commit)
from cfaeaeeb62f354e0060c1c036d8a04b41f4349bb (commit)
commit e6993a82aac7a11e5fd997ac35f1cd374ba5c80f
Author: Brian J. Tarricone <brian at tarricone.org>
Date: Sat Jul 25 15:22:15 2009 -0700
WIP
xfce4-session/xfsm-shutdown-helper.c | 355 +++++++++++++++++++--------------
1 files changed, 204 insertions(+), 151 deletions(-)
diff --git a/xfce4-session/xfsm-shutdown-helper.c b/xfce4-session/xfsm-shutdown-helper.c
index ce319e2..e018c67 100644
--- a/xfce4-session/xfsm-shutdown-helper.c
+++ b/xfce4-session/xfsm-shutdown-helper.c
@@ -67,10 +67,19 @@
typedef enum
{
- XFSM_SHUTDOWN_SUDO = 0,
+ XFSM_SHUTDOWN_NONE = 0,
+ XFSM_SHUTDOWN_SUDO,
+ XFSM_SHUTDOWN_CONSOLEKIT,
XFSM_SHUTDOWN_HAL,
XFSM_SHUTDOWN_POWER_MANAGER,
-} XfsmShutdownBackend;
+} XfsmShutdownBackend
+
+typedef enum
+{
+ XFSM_SUSPEND_NONE = 0,
+ XFSM_SUSPEND_HAL,
+ XFSM_SUSPEND_POWER_MANAGER,
+} XfsmSuspendBackend;
static struct
@@ -87,7 +96,8 @@ static struct
struct _XfsmShutdownHelper
{
- XfsmShutdownBackend backend;
+ XfsmShutdownBackend shut_backend;
+ XfsmSuspendBackend susp_backend
gchar *sudo;
pid_t pid;
@@ -172,68 +182,86 @@ xfsm_shutdown_helper_pm_check (XfsmShutdownHelper *helper)
static gboolean
-xfsm_shutdown_helper_pm_send (XfsmShutdownHelper *helper,
- XfsmShutdownType command,
- GError **error)
+xfsm_shutdown_helper_dbus_send_noreply (XfsmShutdownHelper *helper,
+ DBusBusType bus_type,
+ const gchar *bus_name,
+ const gchar *bus_object,
+ const gchar *bus_interface,
+ const gchar *bus_method,
+ GError **error)
{
DBusConnection *connection;
- const char *methodname;
DBusMessage *message;
DBusMessage *result;
DBusError derror;
- guint i;
+ dbus_int32_t wakeup = 0;
- for (i = 0; i < G_N_ELEMENTS (command_name_map); i++)
- {
- if (command_name_map[i].command == command)
- {
- methodname = command_name_map[i].name;
- break;
- }
- }
+ connection = xfsm_shutdown_helper_dbus_connect (bus_type, error);
+ if(!connection)
+ return FALSE;
- if (!methodname)
- {
- if (error)
- {
- g_set_error (error, DBUS_GERROR, DBUS_GERROR_INVALID_ARGS,
- "%s", _("Invalid shutdown type"));
- }
- return FALSE;
- }
+ /* initialize the error */
+ dbus_error_init (&derror);
- connection = xfsm_shutdown_helper_dbus_connect (DBUS_BUS_SESSION, error);
- if (G_UNLIKELY (!connection))
- return FALSE;
+ /* send the appropriate message to HAL, telling it to shutdown or reboot the system */
+ message = dbus_message_new_method_call (bus_name, bus_object,
+ bus_interface, bus_method);
- message = dbus_message_new_method_call ("org.freedesktop.PowerManagement",
- "/org/freedesktop/PowerManagement",
- "org.freedesktop.PowerManagement",
- methodname);
+ /* hack: HAL's suspend requires additional arguements */
+ if (helper->susp_backend == XFSM_SUSPEND_HAL && !strcmp (bus_method, "Suspend"))
+ dbus_message_append_args (message, DBUS_TYPE_INT32, &wakeup, DBUS_TYPE_INVALID);
- dbus_error_init (&derror);
result = dbus_connection_send_with_reply_and_block (connection, message, -1, &derror);
dbus_message_unref (message);
- if (!result)
+ /* check if we received a result */
+ if (G_UNLIKELY (result == NULL))
{
+ g_warning (G_STRLOC ": Failed to contact %s: %s", bus_name, derror.message);
if (error)
dbus_set_g_error (error, &derror);
dbus_error_free (&derror);
return FALSE;
}
- else if (dbus_set_error_from_message (&derror, result))
+
+ /* pretend that we succeed */
+ dbus_message_unref (result);
+ return TRUE;
+}
+
+
+static gboolean
+xfsm_shutdown_helper_pm_send (XfsmShutdownHelper *helper,
+ XfsmShutdownType command,
+ GError **error)
+{
+ const char *methodname = NULL;
+ guint i;
+
+ for (i = 0; i < G_N_ELEMENTS (command_name_map); i++)
+ {
+ if (command_name_map[i].command == command)
+ {
+ methodname = command_name_map[i].name;
+ break;
+ }
+ }
+
+ if (!methodname)
{
- dbus_message_unref (result);
if (error)
{
- dbus_set_g_error (error, &derror);
+ g_set_error (error, DBUS_GERROR, DBUS_GERROR_INVALID_ARGS,
+ "%s", _("Invalid shutdown type"));
}
- dbus_error_free (&derror);
return FALSE;
}
- return TRUE;
+ return xfsm_shutdown_helper_dbus_send_noreply (helper, DBUS_BUS_SESSION,
+ "org.freedesktop.PowerManagement",
+ "/org/freedesktop/PowerManagement",
+ "org.freedesktop.PowerManagement",
+ methodname);
}
@@ -295,7 +323,10 @@ xfsm_shutdown_helper_check_pm_cap (const char *capability)
static gboolean
-xfsm_shutdown_helper_hal_check (XfsmShutdownHelper *helper)
+xfsm_shutdown_helper_iface_check (XfsmShutdownHelper *helper,
+ const char *bus_name,
+ const char *bus_object,
+ const char *bus_interface)
{
DBusConnection *connection;
DBusMessage *message;
@@ -315,10 +346,8 @@ xfsm_shutdown_helper_hal_check (XfsmShutdownHelper *helper)
* use the org.freedesktop.Hal.Device.SystemPowerManagement
* interface without shutting down/rebooting now.
*/
- message = dbus_message_new_method_call ("org.freedesktop.Hal",
- "/org/freedesktop/Hal/devices/computer",
- "org.freedesktop.Hal.Device.SystemPowerManagement",
- "ThisMethodMustNotExistInHal");
+ message = dbus_message_new_method_call (bus_name, bus_object, bus_interface,
+ "ThisMethodMustNotExistInAnything");
result = dbus_connection_send_with_reply_and_block (connection, message, 2000, &derror);
dbus_message_unref (message);
@@ -331,13 +360,15 @@ xfsm_shutdown_helper_hal_check (XfsmShutdownHelper *helper)
}
else if (G_UNLIKELY (result != NULL))
{
- /* we received a valid message return?! HAL must be on crack! */
+ /* we received a valid message return?! the service must be on crack! */
dbus_message_unref (result);
return FALSE;
}
/* if we receive org.freedesktop.DBus.Error.UnknownMethod, then
- * we are allowed to shutdown/reboot the computer via HAL.
+ * we are allowed to send messages to this interface.
+ * FIXME: however, PolicyKit may still deny the action, and this check
+ * won't catch that case
*/
if (strcmp (derror.name, "org.freedesktop.DBus.Error.UnknownMethod") == 0)
{
@@ -346,7 +377,7 @@ xfsm_shutdown_helper_hal_check (XfsmShutdownHelper *helper)
}
/* otherwise, we failed for some reason */
- g_warning (G_STRLOC ": Failed to contact HAL: %s", derror.message);
+ g_warning (G_STRLOC ": Failed to contact %s: %s", bus_name, derror.message);
dbus_error_free (&derror);
return FALSE;
@@ -355,17 +386,23 @@ xfsm_shutdown_helper_hal_check (XfsmShutdownHelper *helper)
static gboolean
+xfsm_shutdown_helper_hal_check (XfsmShutdownHelper *helper)
+{
+ return xfsm_shutdown_helper_iface_check (helper,
+ "org.freedesktop.Hal",
+ "/org/freedesktop/Hal/devices/computer",
+ "org.freedesktop.Hal.Device.SystemPowerManagement");
+}
+
+
+
+static gboolean
xfsm_shutdown_helper_hal_send (XfsmShutdownHelper *helper,
XfsmShutdownType command,
GError **error)
{
- DBusConnection *connection;
- DBusMessage *message;
- DBusMessage *result;
- DBusError derror;
- const gchar *methodname = NULL;
- dbus_int32_t wakeup = 0;
- guint i;
+ const gchar *methodname = NULL;
+ guint i;
for (i = 0; i < G_N_ELEMENTS (command_name_map); i++)
{
@@ -386,39 +423,11 @@ xfsm_shutdown_helper_hal_send (XfsmShutdownHelper *helper,
return FALSE;
}
- connection = xfsm_shutdown_helper_dbus_connect (DBUS_BUS_SYSTEM, error);
- if(!connection)
- return FALSE;
-
- /* initialize the error */
- dbus_error_init (&derror);
-
- /* send the appropriate message to HAL, telling it to shutdown or reboot the system */
- message = dbus_message_new_method_call ("org.freedesktop.Hal",
- "/org/freedesktop/Hal/devices/computer",
- "org.freedesktop.Hal.Device.SystemPowerManagement",
- methodname);
-
- /* suspend requires additional arguements */
- if (command == XFSM_SHUTDOWN_SUSPEND)
- dbus_message_append_args (message, DBUS_TYPE_INT32, &wakeup, DBUS_TYPE_INVALID);
-
- result = dbus_connection_send_with_reply_and_block (connection, message, -1, &derror);
- dbus_message_unref (message);
-
- /* check if we received a result */
- if (G_UNLIKELY (result == NULL))
- {
- g_warning (G_STRLOC ": Failed to contact HAL: %s", derror.message);
- if (error)
- dbus_set_g_error (error, &derror);
- dbus_error_free (&derror);
- return FALSE;
- }
-
- /* pretend that we succeed */
- dbus_message_unref (result);
- return TRUE;
+ return xfsm_shutdown_helper_dbus_send_noreply (helper, DBUS_BUS_SYSTEM,
+ "org.freedesktop.Hal",
+ "/org/freedesktop/Hal/devices/computer",
+ "org.freedesktop.Hal.Device.SystemPowerManagement",
+ methodname);
}
@@ -502,21 +511,34 @@ xfsm_shutdown_helper_spawn (GError **error)
if (xfsm_shutdown_helper_pm_check (helper))
{
g_message (G_STRLOC ": Using PM to shutdown/reboot the computer.");
- helper->backend = XFSM_SHUTDOWN_POWER_MANAGER;
+ helper->shut_backend = XFSM_SHUTDOWN_POWER_MANAGER;
+ g_message (G_STRLOC ": Using PM to suspend/hibernate the computer.");
+ helper->susp_backend = XFSM_SUSPEND_POWER_MANAGER;
return helper;
}
- /* check if we can use HAL to shutdown the computer */
+ /* next we try ConsoleKit for shutdown backend */
+ if (xfsm_shutdown_helper_ck_check (helper))
+ {
+ g_message (G_STRLOC ": Using CK to shutdown/reboot the computer.");
+ helper->shut_backend = XFSM_SHUTDOWN_CONSOLEKIT;
+ }
+
+ /* at this point, we at most have CK for shutdown/reboot, but we
+ * don't have a way to suspend/hibernate yet. */
if (xfsm_shutdown_helper_hal_check (helper))
{
- /* well that's it then */
- g_message (G_STRLOC ": Using HAL to shutdown/reboot the computer.");
- helper->backend = XFSM_SHUTDOWN_HAL;
+ if (helper->shut_backend == XFSM_SHUTDOWN_NONE)
+ {
+ g_message (G_STRLOC ": Using HAL to shutdown/reboot the computer.");
+ helper->shut_backend = XFSM_SHUTDOWN_HAL;
+ }
+ g_message (G_STRLOC ": Using HAL to suspend/hibernate the computer.");
+ helper->susp_backend = XFSM_SUSPEND_HAL;
return helper;
}
- /* no HAL, but maybe sudo will do */
- g_message (G_STRLOC ": HAL not available or does not permit to shutdown/reboot the computer, trying sudo fallback instead.");
+ /* if we get here, we'll have to fall back to sudo, if we can find it */
/* make sure sudo is installed, and in $PATH */
helper->sudo = g_find_program_in_path ("sudo");
@@ -650,6 +672,10 @@ xfsm_shutdown_helper_spawn (GError **error)
close (parent_pipe[1]);
close (child_pipe[0]);
+ g_message (G_STRLOC ": Using sudo to shutdown/reboot the computer.");
+ g_message (G_STRLOC ": Suspend/hibernate not available.");
+ helper->shut_backend = XFSM_SHUTDOWN_SUDO;
+
return helper;
error3:
@@ -771,78 +797,105 @@ xfsm_shutdown_helper_send_command (XfsmShutdownHelper *helper,
g_return_val_if_fail (helper != NULL, FALSE);
g_return_val_if_fail (!helper->need_password, FALSE);
g_return_val_if_fail (!error || !*error, FALSE);
- g_return_val_if_fail (command != XFSM_SHUTDOWN_ASK, FALSE);
+ g_return_val_if_fail (command != XFSM_SHUTDOWN_ASK
+ && command != XFSM_SHUTDOWN_LOGOUT, FALSE);
- if (helper->backend == XFSM_SHUTDOWN_POWER_MANAGER)
- {
- return xfsm_shutdown_helper_pm_send (helper, command, error);
- }
- else if (helper->backend == XFSM_SHUTDOWN_HAL)
- {
- /* well, send the command to HAL then */
- return xfsm_shutdown_helper_hal_send (helper, command, error);
- }
- else
- {
- /* we don't support hibernate or suspend without HAL */
- switch (command)
+ switch (command) {
+ case XFSM_SHUTDOWN_HALT:
+ case XFSM_SHUTDOWN_REBOOT:
+ if (helper->shut_backend == XFSM_SHUTDOWN_POWER_MANAGER)
+ {
+ return xfsm_shutdown_helper_pm_send (helper, command, error);
+ }
+ else if (helper->shut_backend == XFSM_SHUTDOWN_CONSOLEKIT)
+ {
+ return xfsm_shutdown_helper_ck_send (helper, command, error);
+ }
+ else if (helper->shut_backend == XFSM_SHUTDOWN_HAL)
{
- case XFSM_SHUTDOWN_HALT:
- command_str = "POWEROFF";
- break;
+ return xfsm_shutdown_helper_hal_send (helper, command, error);
+ }
+ else if (helper->shut_backend == XFSM_SHUTDOWN_SUDO)
+ {
+ /* we don't support hibernate or suspend without HAL */
+ switch (command)
+ {
+ case XFSM_SHUTDOWN_HALT:
+ command_str = "POWEROFF";
+ break;
- case XFSM_SHUTDOWN_REBOOT:
- command_str = "REBOOT";
- break;
+ case XFSM_SHUTDOWN_REBOOT:
+ command_str = "REBOOT";
+ break;
- case XFSM_SHUTDOWN_SUSPEND:
- case XFSM_SHUTDOWN_HIBERNATE:
- if (error)
- {
- g_set_error (error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN,
- _("Suspend and Hibernate are only supported through HAL, which is unavailable"));
- }
- /* fall through */
- default:
- return FALSE;
- }
+ case XFSM_SHUTDOWN_SUSPEND:
+ case XFSM_SHUTDOWN_HIBERNATE:
+ if (error)
+ {
+ g_set_error (error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN,
+ _("Suspend and Hibernate are only supported through HAL, which is unavailable"));
+ }
+ /* fall through */
+ default:
+ return FALSE;
+ }
- /* send it to our associated sudo'ed process */
- fprintf (helper->outfile, "%s\n", command_str);
- fflush (helper->outfile);
+ /* send it to our associated sudo'ed process */
+ fprintf (helper->outfile, "%s\n", command_str);
+ fflush (helper->outfile);
- if (ferror (helper->outfile))
- {
- if (error && errno != EINTR)
+ if (ferror (helper->outfile))
{
- g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
- _("Error sending command to shutdown helper: %s"),
- strerror (errno));
+ if (error && errno != EINTR)
+ {
+ g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+ _("Error sending command to shutdown helper: %s"),
+ strerror (errno));
+ }
+ return FALSE;
}
- return FALSE;
- }
- if (fgets (response, 256, helper->infile) == NULL)
- {
- if (error && errno != EINTR)
+ if (fgets (response, 256, helper->infile) == NULL)
{
- g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
- _("Error receiving response from shutdown helper: %s"),
- strerror (errno));
+ if (error && errno != EINTR)
+ {
+ g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+ _("Error receiving response from shutdown helper: %s"),
+ strerror (errno));
+ }
+ return FALSE;
}
- return FALSE;
- }
- if (strncmp (response, "SUCCEED", 7) != 0)
- {
- if (error)
+ if (strncmp (response, "SUCCEED", 7) != 0)
{
- g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
- _("Shutdown command failed"));
+ if (error)
+ {
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ _("Shutdown command failed"));
+ }
+ return FALSE;
}
- return FALSE;
}
- }
+ else
+ return FALSE;
+
+ break;
+
+ case XFSM_SHUTDOWN_SUSPEND:
+ case XFSM_SHUTDOWN_HIBERNATE:
+ if (helper->susp_backend == XFSM_SHUTDOWN_POWER_MANAGER)
+ {
+ return xfsm_shutdown_helper_pm_send (helper, command, error);
+ }
+ else if (helper->shusp_backend == XFSM_SHUTDOWN_CONSOLEKIT)
+ {
+ return xfsm_shutdown_helper_ck_send (helper, command, error);
+ }
+ else
+ return FALSE;
+
+ break;
+ }
return TRUE;
}
More information about the Xfce4-commits
mailing list