[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