Author: benny
Date: 2006-09-08 23:39:43 +0000 (Fri, 08 Sep 2006)
New Revision: 23113

Removed:
   xfce4-session/trunk/xfce4-session/xfsm-shutdown-helper-hal.c
   xfce4-session/trunk/xfce4-session/xfsm-shutdown-helper-none.c
   xfce4-session/trunk/xfce4-session/xfsm-shutdown-helper-redhat.c
   xfce4-session/trunk/xfce4-session/xfsm-shutdown-helper-sudo.c
Modified:
   xfce4-session/trunk/ChangeLog
   xfce4-session/trunk/README
   xfce4-session/trunk/configure.in.in
   xfce4-session/trunk/xfce4-session/Makefile.am
   xfce4-session/trunk/xfce4-session/xfsm-shutdown-helper.c
Log:
2006-09-09      Benedikt Meurer <[EMAIL PROTECTED]>

        * README, configure.in.in, xfce4-session/: Merge the sudo and the HAL
          shutdown helpers into a single shutdown helper, which tries to use
          HAL first, and falls back to sudo.




Modified: xfce4-session/trunk/ChangeLog
===================================================================
--- xfce4-session/trunk/ChangeLog       2006-09-08 23:11:30 UTC (rev 23112)
+++ xfce4-session/trunk/ChangeLog       2006-09-08 23:39:43 UTC (rev 23113)
@@ -1,3 +1,9 @@
+2006-09-09     Benedikt Meurer <[EMAIL PROTECTED]>
+
+       * README, configure.in.in, xfce4-session/: Merge the sudo and the HAL
+         shutdown helpers into a single shutdown helper, which tries to use
+         HAL first, and falls back to sudo.
+
 2006-09-02     Benedikt Meurer <[EMAIL PROTECTED]>
 
        * configure.in.in: Post-release version bump.

Modified: xfce4-session/trunk/README
===================================================================
--- xfce4-session/trunk/README  2006-09-08 23:11:30 UTC (rev 23112)
+++ xfce4-session/trunk/README  2006-09-08 23:39:43 UTC (rev 23113)
@@ -17,12 +17,11 @@
 
   myuser       myhost=/usr/local/libexec/xfsm-shutdown-helper
 
-Starting with xfce4-session 4.3.90.3 it is also possible to use HAL to
-shutdown/reboot the computer. Therefore pass --with-shutdown-style=hal
-to configure/autogen.sh and be sure to have D-BUS 0.34 or above (including
-the development files) installed and hald running. You will also need to
-allow users to shutdown the computer using HAL (see your system documentation
-for details here).
+Starting with xfce4-session 4.3.99.2 xfce4-session will first try to use
+HAL (if built with D-Bus support) and fallback to the sudo method described
+above. So if you have HAL installed on your system, and your account is
+allowed to shutdown/reboot the computer using HAL, you don't need to setup
+sudo at all.
 
 
 Legacy session management:

Modified: xfce4-session/trunk/configure.in.in
===================================================================
--- xfce4-session/trunk/configure.in.in 2006-09-08 23:11:30 UTC (rev 23112)
+++ xfce4-session/trunk/configure.in.in 2006-09-08 23:39:43 UTC (rev 23113)
@@ -75,6 +75,10 @@
 dnl Configure the MCS plugins
 XDT_XFCE_MCS_PLUGIN([XFCE_MCS_MANAGER], [4.3.99.1])
 
+dnl Check for D-Bus support (for HAL shutdown support)
+XDT_CHECK_OPTIONAL_PACKAGE([DBUS], [dbus-1], [0.34], [dbus],
+                           [Hal shutdown support], [yes])
+
 dnl Check for gnome support
 XDT_CHECK_OPTIONAL_PACKAGE([GNOME], [gconf-2.0], [2.4.0], [gnome],
                            [Assistive technologies support], [no])
@@ -121,58 +125,6 @@
   AC_MSG_RESULT([yes])
 fi
 
-dnl Check for shutdown method
-AC_ARG_WITH([shutdown-style],
-AC_HELP_STRING([--with-shutdown-style=auto/none/hal/sudo], [Shutdown style]),
-  [with_shutdown=$withval], [with_shutdown=auto])
-AC_MSG_CHECKING([what shutdown style should be used])
-if test x"$with_shutdown" != x"sudo" -a x"$with_shutdown" != x"hal" -a 
x"$with_shutdown" != x"none"; then
-  with_shutdown="sudo"
-fi
-AC_DEFINE_UNQUOTED([XFSM_SHUTDOWN_HELPER_IMPL_C],
-                   [<xfce4-session/xfsm-shutdown-helper-$with_shutdown.c>],
-                   [Shutdown helper implementation])
-AC_MSG_RESULT([$with_shutdown])
-
-dnl Check for dbus for hal support
-if test x"$with_shutdown" = x"hal"; then
-  XDT_CHECK_PACKAGE([DBUS], [dbus-1], [0.34])
-fi
-
-dnl
-dnl arguments to set shutdown commands
-dnl
-
-dnl AC_MSG_CHECKING([for custom 'poweroff' command])
-dnl AC_ARG_WITH([poweroff],
-dnl   AC_HELP_STRING([--with-poweroff=cmd], [command used to power down (full 
path with arguments)]),
-dnl   [with_poweroff="$withval"],
-dnl   [with_poweroff="no"])
-dnl if test "x$with_poweroff" != "xno"; then
-dnl   AC_DEFINE_UNQUOTED(POWEROFF_CMD, "$with_poweroff", [poweroff command])
-dnl fi
-dnl AC_MSG_RESULT([$with_poweroff])
-dnl 
-dnl AC_MSG_CHECKING([for custom 'halt' command])
-dnl AC_ARG_WITH([halt],
-dnl   AC_HELP_STRING([--with-halt=cmd], [command used to halt (full path with 
arguments)]),
-dnl   [with_halt="$withval"],
-dnl   [with_halt="no"])
-dnl if test "x$with_halt" != "xno"; then
-dnl   AC_DEFINE_UNQUOTED(HALT_CMD, "$with_halt", [halt command])
-dnl fi
-dnl AC_MSG_RESULT([$with_halt])
-dnl 
-dnl AC_MSG_CHECKING([for custom 'reboot' command])
-dnl AC_ARG_WITH([reboot],
-dnl   AC_HELP_STRING([--with-reboot=cmd], [command used to reboot (full path 
with arguments)]),
-dnl   [with_reboot="$withval"],
-dnl   [with_reboot="no"])
-dnl if test "x$with_reboot" != "xno"; then
-dnl   AC_DEFINE_UNQUOTED(REBOOT_CMD, "$with_reboot", [reboot command])
-dnl fi
-dnl AC_MSG_RESULT([$with_reboot])
-
 AC_OUTPUT([
 Makefile
 xfce4-session.spec

Modified: xfce4-session/trunk/xfce4-session/Makefile.am
===================================================================
--- xfce4-session/trunk/xfce4-session/Makefile.am       2006-09-08 23:11:30 UTC 
(rev 23112)
+++ xfce4-session/trunk/xfce4-session/Makefile.am       2006-09-08 23:39:43 UTC 
(rev 23113)
@@ -1,4 +1,7 @@
+# $Id$
+
 INCLUDES =                                                             \
+       -I$(top_builddir)                                               \
        -I$(top_srcdir)
 
 man_MANS = xfce4-session.1
@@ -42,12 +45,12 @@
        xfsm-startup.h
 
 xfce4_session_CFLAGS =                                                 \
-       @GNOME_CFLAGS@                                                  \
-       @LIBSM_CFLAGS@                                                  \
-       @LIBX11_CFLAGS@                                                 \
-       @LIBXFCE4MCS_CLIENT_CFLAGS@                                     \
-       @LIBXFCEGUI4_CFLAGS@                                            \
-       @DBUS_CFLAGS@                                                   \
+       $(GNOME_CFLAGS)                                                 \
+       $(LIBSM_CFLAGS)                                                 \
+       $(LIBX11_CFLAGS)                                                \
+       $(LIBXFCE4MCS_CLIENT_CFLAGS)                                    \
+       $(LIBXFCEGUI4_CFLAGS)                                           \
+       $(DBUS_CFLAGS)                                                  \
        -DDBUS_API_SUBJECT_TO_CHANGE                                    \
        -DLIBDIR=\"$(libdir)\"                                          \
        -DPACKAGE_LOCALE_DIR=\"$(localedir)\"                           \
@@ -56,14 +59,14 @@
 
 xfce4_session_LDADD =                                                  \
        $(top_builddir)/libxfsm/libxfsm-4.2.la                          \
-       @LIBSM_LDFLAGS@                                                 \
-       @LIBSM_LIBS@                                                    \
-       @LIBX11_LDFLAGS@                                                \
-       @LIBX11_LIBS@                                                   \
-       @LIBXFCE4MCS_CLIENT_LIBS@                                       \
-       @LIBXFCEGUI4_LIBS@                                              \
-       @DBUS_LIBS@                                                     \
-       @GNOME_LIBS@
+       $(LIBSM_LDFLAGS)                                                \
+       $(LIBSM_LIBS)                                                   \
+       $(LIBX11_LDFLAGS)                                               \
+       $(LIBX11_LIBS)                                                  \
+       $(LIBXFCE4MCS_CLIENT_LIBS)                                      \
+       $(LIBXFCEGUI4_LIBS)                                             \
+       $(DBUS_LIBS)                                                    \
+       $(GNOME_LIBS)
 
 xfce4_session_DEPENDENCIES =                                           \
        $(top_builddir)/libxfsm/libxfsm-4.2.la
@@ -75,9 +78,5 @@
 
 EXTRA_DIST =                                                           \
        $(man_MANS)                                                     \
-       chooser-icon.png                                                \
-       xfsm-shutdown-helper-none.c                                     \
-       xfsm-shutdown-helper-redhat.c                                   \
-       xfsm-shutdown-helper-hal.c                                      \
-       xfsm-shutdown-helper-sudo.c
+       chooser-icon.png
 

Deleted: xfce4-session/trunk/xfce4-session/xfsm-shutdown-helper-hal.c

Deleted: xfce4-session/trunk/xfce4-session/xfsm-shutdown-helper-none.c

Deleted: xfce4-session/trunk/xfce4-session/xfsm-shutdown-helper-redhat.c

Deleted: xfce4-session/trunk/xfce4-session/xfsm-shutdown-helper-sudo.c

Modified: xfce4-session/trunk/xfce4-session/xfsm-shutdown-helper.c
===================================================================
--- xfce4-session/trunk/xfce4-session/xfsm-shutdown-helper.c    2006-09-08 
23:11:30 UTC (rev 23112)
+++ xfce4-session/trunk/xfce4-session/xfsm-shutdown-helper.c    2006-09-08 
23:39:43 UTC (rev 23113)
@@ -1,6 +1,6 @@
 /* $Id$ */
 /*-
- * Copyright (c) 2003-2004 Benedikt Meurer <[EMAIL PROTECTED]>
+ * Copyright (c) 2003-2006 Benedikt Meurer <[EMAIL PROTECTED]>
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
@@ -17,15 +17,456 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  * 02111-1307, USA.
- *
- * The permission check was taken from gnome-session/logout.c, originally
- * written by Owen Taylor <[EMAIL PROTECTED]>.
  */
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
 
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
 
-#include XFSM_SHUTDOWN_HELPER_IMPL_C
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
 
+#ifdef HAVE_DBUS
+#include <dbus/dbus.h>
+#endif
+
+#include <libxfce4util/libxfce4util.h>
+
+#include <xfce4-session/xfsm-shutdown-helper.h>
+
+
+
+struct _XfsmShutdownHelper
+{
+  gchar   *sudo;
+  pid_t    pid;
+  FILE    *infile;
+  FILE    *outfile;
+  gboolean use_hal;
+  gboolean need_password;
+};
+
+
+
+static gboolean
+xfsm_shutdown_helper_hal_check (XfsmShutdownHelper *helper)
+{
+#ifdef HAVE_DBUS
+  DBusConnection *connection;
+  DBusMessage    *message;
+  DBusMessage    *result;
+  DBusError       error;
+
+  /* initialize the error */
+  dbus_error_init (&error);
+
+  /* connect to the system message bus */
+  connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
+  if (G_UNLIKELY (connection == NULL))
+    {
+      g_warning (G_STRLOC ": Failed to connect to the system message bus: %s", 
error.message);
+      dbus_error_free (&error);
+      return FALSE;
+    }
+
+  /* this is a simple trick to check whether we are allowed to
+   * 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");
+  result = dbus_connection_send_with_reply_and_block (connection, message, 
2000, &error);
+  dbus_message_unref (message);
+
+  /* translate error results appropriately */
+  if (result != NULL && dbus_set_error_from_message (&error, result))
+    {
+      /* release and reset the result */
+      dbus_message_unref (result);
+      result = NULL;
+    }
+  else if (G_UNLIKELY (result != NULL))
+    {
+      /* we received a valid message return?! HAL 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.
+   */
+  if (strcmp (error.name, "org.freedesktop.DBus.Error.UnknownMethod") == 0)
+    {
+      dbus_error_free (&error);
+      return TRUE;
+    }
+
+  /* otherwise, we failed for some reason */
+  g_warning (G_STRLOC ": Failed to contact HAL: %s", error.message);
+  dbus_error_free (&error);
+#endif
+
+  return FALSE;
+}
+
+
+
+static gboolean
+xfsm_shutdown_helper_hal_send (XfsmShutdownHelper *helper,
+                               XfsmShutdownCommand command)
+{
+#ifdef HAVE_DBUS
+  DBusConnection *connection;
+  DBusMessage    *message;
+  DBusMessage    *result;
+  DBusError       error;
+
+  /* initialize the error */
+  dbus_error_init (&error);
+
+  /* connect to the system message bus */
+  connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
+  if (G_UNLIKELY (connection == NULL))
+    {
+      g_warning (G_STRLOC ": Failed to connect to the system message bus: %s", 
error.message);
+      dbus_error_free (&error);
+      return FALSE;
+    }
+
+  /* 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",
+                                          (command == XFSM_SHUTDOWN_REBOOT) ? 
"Reboot" : "Shutdown");
+  result = dbus_connection_send_with_reply_and_block (connection, message, 
2000, &error);
+  dbus_message_unref (message);
+
+  /* check if we received a result */
+  if (G_UNLIKELY (result == NULL))
+    {
+      g_warning (G_STRLOC ": Failed to contact HAL: %s", error.message);
+      dbus_error_free (&error);
+      return FALSE;
+    }
+
+  /* pretend that we succeed */
+  dbus_message_unref (result);
+  return TRUE;
+#else
+  return FALSE;
+#endif
+}
+
+
+
+XfsmShutdownHelper*
+xfsm_shutdown_helper_spawn (void)
+{
+  XfsmShutdownHelper *helper;
+  struct              rlimit rlp;
+  gchar               buf[15];
+  gint                parent_pipe[2];
+  gint                child_pipe[2];
+  gint                result;
+  gint                n;
+
+  /* allocate a new helper */
+  helper = g_new0 (XfsmShutdownHelper, 1);
+
+  /* check if we can use HAL to shutdown the computer */
+  if (xfsm_shutdown_helper_hal_check (helper))
+    {
+      /* well that's it then */
+      g_message (G_STRLOC ": Using HAL to shutdown/reboot the computer.");
+      helper->use_hal = TRUE;
+      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.");
+
+  /* make sure sudo is installed, and in $PATH */
+  helper->sudo = g_find_program_in_path ("sudo");
+  if (G_UNLIKELY (helper->sudo == NULL))
+    {
+      g_warning ("sudo was not found. You will not be able to shutdown your 
system from within Xfce.");
+      g_free (helper);
+      return NULL;
+    }
+
+  result = pipe (parent_pipe);
+  if (result < 0)
+    goto error0;
+
+  result = pipe (child_pipe);
+  if (result < 0)
+    goto error1;
+
+  helper->pid = fork ();
+  if (helper->pid < 0)
+    {
+      goto error2;
+    }
+  else if (helper->pid == 0)
+    {
+      /* setup signals */
+      signal (SIGPIPE, SIG_IGN);
+
+      /* setup environment */
+      xfce_setenv ("LC_ALL", "C", TRUE);
+      xfce_setenv ("LANG", "C", TRUE);
+      xfce_setenv ("LANGUAGE", "C", TRUE);
+
+      /* setup the 3 standard file handles */
+      dup2 (child_pipe[0], STDIN_FILENO);
+      dup2 (parent_pipe[1], STDOUT_FILENO);
+      dup2 (parent_pipe[1], STDERR_FILENO);
+
+      /* Close all other file handles */
+      getrlimit (RLIMIT_NOFILE, &rlp);
+      for (n = 0; n < (gint) rlp.rlim_cur; ++n)
+        {
+          if (n != STDIN_FILENO && n != STDOUT_FILENO && n != STDERR_FILENO)
+            close (n);
+        }
+
+      /* execute sudo with the helper */
+      execl (helper->sudo, "sudo", "-H", "-S", "-p",
+             "XFSM_SUDO_PASS ", "--", XFSM_SHUTDOWN_HELPER, NULL);
+      _exit (127);
+    }
+
+  close (parent_pipe[1]);
+
+  /* read sudo/helper answer */
+  n = read (parent_pipe[0], buf, 15);
+  if (n < 15)
+    goto error2;
+
+  helper->infile = fdopen (parent_pipe[0], "r");
+  if (helper->infile == NULL)
+    goto error2;
+
+  helper->outfile = fdopen (child_pipe[1], "w");
+  if (helper->outfile == NULL)
+    goto error3;
+
+  if (memcmp (buf, "XFSM_SUDO_PASS ", 15) == 0)
+    {
+      helper->need_password = TRUE;
+    }
+  else if (memcmp (buf, "XFSM_SUDO_DONE ", 15) == 0)
+    {
+      helper->need_password = FALSE;
+    }
+  else
+    goto error3;
+
+  close (parent_pipe[1]);
+  close (child_pipe[0]);
+
+  return helper;
+
+error3:
+  if (helper->infile != NULL)
+    fclose (helper->infile);
+  if (helper->outfile != NULL)
+    fclose (helper->outfile);
+
+error2:
+  close (child_pipe[0]);
+  close (child_pipe[1]);
+
+error1:
+  close (parent_pipe[0]);
+  close (parent_pipe[1]);
+
+error0:
+  g_free (helper);
+  return NULL;
+}
+
+
+
+gboolean
+xfsm_shutdown_helper_need_password (const XfsmShutdownHelper *helper)
+{
+  return helper->need_password;
+}
+
+
+
+gboolean
+xfsm_shutdown_helper_send_password (XfsmShutdownHelper *helper,
+                                    const gchar        *password)
+{
+  gssize result;
+  gchar  buffer[1024];
+  gsize  failed;
+  gsize  length;
+  gsize  bytes;
+  gint   fd;
+
+  g_return_val_if_fail (helper != NULL, FALSE);
+  g_return_val_if_fail (password != NULL, FALSE);
+  g_return_val_if_fail (!helper->use_hal, FALSE);
+  g_return_val_if_fail (helper->need_password, FALSE);
+
+  g_snprintf (buffer, 1024, "%s\n", password);
+  length = strlen (buffer);
+  bytes = fwrite (buffer, 1, length, helper->outfile);
+  fflush (helper->outfile);
+  bzero (buffer, length);
+
+  if (bytes != length)
+    {
+      fprintf (stderr, "Failed to write password (bytes=%u, length=%u)\n", 
bytes, length);
+      return FALSE;
+    }
+
+  if (ferror (helper->outfile))
+    {
+      fprintf (stderr, "Pipe error\n");
+      return FALSE;
+    }
+
+  fd = fileno (helper->infile);
+
+  for (failed = length = 0;;)
+    {
+      result = read (fd, buffer + length, 256 - length);
+
+      if (result < 0)
+        {
+          perror ("read");
+          return FALSE;
+        }
+      else if (result == 0)
+        {
+          if (++failed > 20)
+            return FALSE;
+          continue;
+        }
+      else if (result + length >= 1024)
+        {
+          fprintf (stderr, "Too much output from sudo!\n");
+          return FALSE;
+        }
+
+      length += result;
+      buffer[length] = 0;
+
+      if (length >= 15)
+        {
+          if (strncmp (buffer + (length - 15), "XFSM_SUDO_PASS ", 15) == 0)
+            {
+              return FALSE;
+            }
+          else if (strncmp (buffer + (length - 15), "XFSM_SUDO_DONE ", 15) == 
0)
+            {
+              helper->need_password = FALSE;
+              break;
+            }
+        } 
+    }
+
+  return TRUE;
+}
+
+
+
+gboolean
+xfsm_shutdown_helper_send_command (XfsmShutdownHelper *helper,
+                                   XfsmShutdownCommand command)
+{
+  static gchar *command_table[] = { "POWEROFF", "REBOOT" };
+  gchar         response[256];
+
+  g_return_val_if_fail (helper != NULL, FALSE);
+  g_return_val_if_fail (!helper->need_password, FALSE);
+
+  /* check if we can use HAL to perform the requested action */
+  if (G_LIKELY (helper->use_hal))
+    {
+      /* well, send the command to HAL then */
+      return xfsm_shutdown_helper_hal_send (helper, command);
+    }
+  else
+    {
+      /* send it to our associated sudo'ed process */
+      fprintf (helper->outfile, "%s\n", command_table[command]);
+      fflush (helper->outfile);
+
+      if (ferror (helper->outfile))
+        {
+          fprintf (stderr, "Error sending command to helper\n");
+          return FALSE;
+        }
+
+      if (fgets (response, 256, helper->infile) == NULL)
+        {
+          fprintf (stderr, "No response from helper\n");
+          return FALSE;
+        }
+
+      if (strncmp (response, "SUCCEED", 7) != 0)
+        {
+          fprintf (stderr, "Command failed\n");
+          return FALSE;
+        }
+    }
+
+  return TRUE;
+}
+
+
+
+void
+xfsm_shutdown_helper_destroy (XfsmShutdownHelper *helper)
+{
+  gint status;
+
+  g_return_if_fail (helper != NULL);
+
+  if (helper->infile != NULL)
+    fclose (helper->infile);
+  if (helper->outfile != NULL)
+    fclose (helper->outfile);
+
+  if (helper->pid > 0)
+    waitpid (helper->pid, &status, 0);
+
+  g_free (helper->sudo);
+  g_free (helper);
+}
+
+

_______________________________________________
Xfce4-commits mailing list
Xfce4-commits@xfce.org
http://foo-projects.org/mailman/listinfo/xfce4-commits

Reply via email to