summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--README11
-rw-r--r--configure.in.in56
-rw-r--r--xfce4-session/Makefile.am37
-rw-r--r--xfce4-session/xfsm-shutdown-helper-hal.c124
-rw-r--r--xfce4-session/xfsm-shutdown-helper-none.c71
-rw-r--r--xfce4-session/xfsm-shutdown-helper-redhat.c186
-rw-r--r--xfce4-session/xfsm-shutdown-helper-sudo.c326
-rw-r--r--xfce4-session/xfsm-shutdown-helper.c451
9 files changed, 479 insertions, 789 deletions
diff --git a/ChangeLog b/ChangeLog
index fbef160f..df865c32 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2006-09-09 Benedikt Meurer <benny@xfce.org>
+
+ * 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 <benny@xfce.org>
* configure.in.in: Post-release version bump.
diff --git a/README b/README
index 2df5d080..8e40f04a 100644
--- a/README
+++ b/README
@@ -17,12 +17,11 @@ that file):
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:
diff --git a/configure.in.in b/configure.in.in
index cc44cfca..af5381b4 100644
--- a/configure.in.in
+++ b/configure.in.in
@@ -75,6 +75,10 @@ XDT_CHECK_PACKAGE([LIBXFCEGUI4], [libxfcegui4-1.0], [4.3.99.1])
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 @@ else
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
diff --git a/xfce4-session/Makefile.am b/xfce4-session/Makefile.am
index 2cfe604f..bb4cee8e 100644
--- a/xfce4-session/Makefile.am
+++ b/xfce4-session/Makefile.am
@@ -1,4 +1,7 @@
+# $Id$
+
INCLUDES = \
+ -I$(top_builddir) \
-I$(top_srcdir)
man_MANS = xfce4-session.1
@@ -42,12 +45,12 @@ xfce4_session_SOURCES = \
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_CFLAGS = \
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 @@ chooser-icon.h: $(srcdir)/chooser-icon.png
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
diff --git a/xfce4-session/xfsm-shutdown-helper-hal.c b/xfce4-session/xfsm-shutdown-helper-hal.c
deleted file mode 100644
index e885a843..00000000
--- a/xfce4-session/xfsm-shutdown-helper-hal.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/* $Id$ */
-/*-
- * Copyright (c) 2006 Jani Monoses <jani@ubuntu.com>
- * All rights reserved.
- *
- * 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, 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 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
-
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-
-#include <dbus/dbus.h>
-
-#include <xfce4-session/xfsm-shutdown-helper.h>
-
-
-
-#define HAL_DBUS_SERVICE "org.freedesktop.Hal"
-#define HAL_ROOT_COMPUTER "/org/freedesktop/Hal/devices/computer"
-#define HAL_DBUS_INTERFACE_POWER "org.freedesktop.Hal.Device.SystemPowerManagement"
-
-
-
-struct _XfsmShutdownHelper
-{
- gint dummy;
-};
-
-
-XfsmShutdownHelper*
-xfsm_shutdown_helper_spawn (void)
-{
- return g_new0 (XfsmShutdownHelper, 1);
-}
-
-
-gboolean
-xfsm_shutdown_helper_need_password (const XfsmShutdownHelper *helper)
-{
- return FALSE;
-}
-
-
-gboolean
-xfsm_shutdown_helper_send_password (XfsmShutdownHelper *helper,
- const gchar *password)
-{
- return TRUE;
-}
-
-
-static gboolean
-hal_dbus_power_command(XfsmShutdownCommand command)
-{
- DBusConnection *connection;
- DBusMessage *method;
- DBusMessage *result;
- const gchar *methodname;
- DBusError derror;
-
- if (command == XFSM_SHUTDOWN_REBOOT)
- methodname = "Reboot";
- else
- methodname = "Shutdown";
-
- dbus_error_init (&derror);
- connection = dbus_bus_get (DBUS_BUS_SYSTEM, &derror);
- if (connection == NULL)
- {
- dbus_error_free (&derror);
- return FALSE;
- }
-
- method = dbus_message_new_method_call (HAL_DBUS_SERVICE,
- HAL_ROOT_COMPUTER,
- HAL_DBUS_INTERFACE_POWER,
- methodname);
- result = dbus_connection_send_with_reply_and_block (connection, method, 2000, &derror);
- dbus_message_unref (method);
-
- if (result == NULL)
- {
- dbus_error_free (&derror);
- return FALSE;
- }
-
- dbus_message_unref (result);
- return TRUE;
-}
-
-
-gboolean
-xfsm_shutdown_helper_send_command (XfsmShutdownHelper *helper,
- XfsmShutdownCommand command)
-{
- return hal_dbus_power_command (command);
-}
-
-
-void
-xfsm_shutdown_helper_destroy (XfsmShutdownHelper *helper)
-{
- g_free (helper);
-}
-
-
diff --git a/xfce4-session/xfsm-shutdown-helper-none.c b/xfce4-session/xfsm-shutdown-helper-none.c
deleted file mode 100644
index 1abbade2..00000000
--- a/xfce4-session/xfsm-shutdown-helper-none.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/* $Id$ */
-/*-
- * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
- * All rights reserved.
- *
- * 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, 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 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 <xfce4-session/xfsm-shutdown-helper.h>
-
-
-struct _XfmShutdownHelper
-{
- gint dummy;
-};
-
-
-XfsmShutdownHelper*
-xfsm_shutdown_helper_spawn (void)
-{
- return NULL;
-}
-
-
-gboolean
-xfsm_shutdown_helper_need_password (const XfsmShutdownHelper *helper)
-{
- return FALSE;
-}
-
-
-gboolean
-xfsm_shutdown_helper_send_password (XfsmShutdownHelper *helper,
- const gchar *password)
-{
- return TRUE;
-}
-
-
-gboolean
-xfsm_shutdown_helper_send_command (XfsmShutdownHelper *helper,
- XfsmShutdownCommand command)
-{
- return FALSE;
-}
-
-
-void
-xfsm_shutdown_helper_destroy (XfsmShutdownHelper *helper)
-{
-}
-
-
diff --git a/xfce4-session/xfsm-shutdown-helper-redhat.c b/xfce4-session/xfsm-shutdown-helper-redhat.c
deleted file mode 100644
index 212e55a8..00000000
--- a/xfce4-session/xfsm-shutdown-helper-redhat.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/* $Id$ */
-/*-
- * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
- * All rights reserved.
- *
- * 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, 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 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.
- *
- * The permission check was taken from gnome-session/logout.c, originally
- * written by Owen Taylor <otaylor@redhat.com>.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-#ifdef HAVE_SYS_RESOURCE_H
-#include <sys/resource.h>
-#endif
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include <xfce4-session/xfsm-shutdown-helper.h>
-
-
-struct _XfsmShutdownHelper
-{
- gint dummy;
-};
-
-
-static char *halt_command[] = { "/usr/bin/halt", "halt", NULL };
-static char *reboot_command[] = { "/usr/bin/reboot", "reboot", NULL };
-
-
-XfsmShutdownHelper*
-xfsm_shutdown_helper_spawn (void)
-{
- XfsmShutdownHelper *helper = NULL;
- gchar *s;
- gchar *t;
-
- s = g_build_filename ("/var/lock/console", g_get_user_name (), NULL);
- t = g_build_filename ("/var/run/console", g_get_user_name (), NULL);
-
- if (((geteuid () == 0)
- || g_file_test (s, G_FILE_TEST_EXISTS)
- || g_file_test (t, G_FILE_TEST_EXISTS))
- && access (halt_command[0], X_OK) == 0)
- {
- helper = g_new0 (XfsmShutdownHelper, 1);
- }
-
- g_free (s);
- g_free (t);
-
- return helper;
-}
-
-
-gboolean
-xfsm_shutdown_helper_need_password (const XfsmShutdownHelper *helper)
-{
- return FALSE;
-}
-
-
-gboolean
-xfsm_shutdown_helper_send_password (XfsmShutdownHelper *helper,
- const gchar *password)
-{
- return TRUE;
-}
-
-
-gboolean
-xfsm_shutdown_helper_send_command (XfsmShutdownHelper *helper,
- XfsmShutdownCommand command)
-{
-#ifdef HAVE_SIGPROCMASK
- sigset_t sigset;
-#endif
- struct rlimit rlp;
- int result;
- int status;
- int fd;
- char **argv;
- pid_t pid;
-
- if (command == XFSM_SHUTDOWN_POWEROFF)
- argv = halt_command;
- else
- argv = reboot_command;
-
- pid = fork ();
- if (pid < 0)
- {
- return FALSE;
- }
- else if (pid == 0)
- {
-#ifdef HAVE_SETSID
- setsid ();
-#endif
-
-#ifdef HAVE_SIGPROCMASK
- sigemptyset (&sigset);
- sigaddset (&sigset, SIGHUP);
- sigaddset (&sigset, SIGINT);
- sigaddset (&sigset, SIGPIPE);
- sigprocmask (SIG_BLOCK, &sigset, NULL);
-#endif
-
- /* setup the 3 standard file handles */
- fd = open ("/dev/null", O_RDWR, 0);
- if (fd >= 0)
- {
- dup2 (fd, STDIN_FILENO);
- dup2 (fd, STDOUT_FILENO);
- dup2 (fd, STDERR_FILENO);
- close (fd);
- }
-
- /* Close all other file handles */
- getrlimit (RLIMIT_NOFILE, &rlp);
- for (fd = 0; fd < (int) rlp.rlim_cur; ++fd)
- {
- if (fd != STDIN_FILENO && fd != STDOUT_FILENO && fd != STDERR_FILENO)
- close (fd);
- }
-
- execv (argv[0], argv + 1);
- _exit (127);
- }
-
- /* check if the shutdown command failed */
- result = waitpid (pid, &status, 0);
- if ((result == pid && status != 0) || (result < 0 && errno == ECHILD))
- return FALSE;
-
- return TRUE;
-}
-
-
-void
-xfsm_shutdown_helper_destroy (XfsmShutdownHelper *helper)
-{
- g_free (helper);
-}
-
-
diff --git a/xfce4-session/xfsm-shutdown-helper-sudo.c b/xfce4-session/xfsm-shutdown-helper-sudo.c
deleted file mode 100644
index 60a0f01c..00000000
--- a/xfce4-session/xfsm-shutdown-helper-sudo.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/* $Id$ */
-/*-
- * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
- * All rights reserved.
- *
- * 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, 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 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
-
-#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
-
-#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
-
-#include <libxfce4util/libxfce4util.h>
-
-#include <xfce4-session/xfsm-shutdown-helper.h>
-
-
-struct _XfsmShutdownHelper
-{
- gchar *sudo;
- pid_t pid;
- FILE *infile;
- FILE *outfile;
- gboolean need_password;
-};
-
-
-XfsmShutdownHelper*
-xfsm_shutdown_helper_spawn (void)
-{
- XfsmShutdownHelper *helper;
- struct rlimit rlp;
- char *sudo;
- char buf[15];
- int parent_pipe[2];
- int child_pipe[2];
- int result;
- int n;
-
- sudo = g_find_program_in_path ("sudo");
- if (G_UNLIKELY (sudo == NULL))
- {
- g_warning ("sudo was not found. You will not be able to shutdown your "
- "system from within Xfce.");
- return NULL;
- }
-
- helper = g_new0 (XfsmShutdownHelper, 1);
- helper->sudo = sudo;
-
- 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 < (int) 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)
-{
- char buffer[1024];
- ssize_t result;
- size_t failed;
- size_t length;
- size_t bytes;
- int fd;
-
- g_return_val_if_fail (helper != NULL, FALSE);
- g_return_val_if_fail (password != NULL, 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 char *command_table[] = { "POWEROFF", "REBOOT" };
- char response[256];
-
- g_return_val_if_fail (helper != NULL, FALSE);
- g_return_val_if_fail (!helper->need_password, FALSE);
-
- 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)
-{
- int 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);
-}
-
-
diff --git a/xfce4-session/xfsm-shutdown-helper.c b/xfce4-session/xfsm-shutdown-helper.c
index 1af9124f..b998ee24 100644
--- a/xfce4-session/xfsm-shutdown-helper.c
+++ b/xfce4-session/xfsm-shutdown-helper.c
@@ -1,6 +1,6 @@
/* $Id$ */
/*-
- * Copyright (c) 2003-2004 Benedikt Meurer <benny@xfce.org>
+ * Copyright (c) 2003-2006 Benedikt Meurer <benny@xfce.org>
* 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 <otaylor@redhat.com>.
*/
#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
+
+#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);
+}
-#include XFSM_SHUTDOWN_HELPER_IMPL_C