summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtem Kachitchkine <artem.kachitchkin@sun.com>2006-09-02 17:52:11 -0700
committerArtem Kachitchkine <artem.kachitchkin@sun.com>2006-09-02 17:52:11 -0700
commitf4b7988a1ebccee442e48f442adb9988e8b5ed73 (patch)
tree1cb53869b1fdff7cb4926c1d8fc50911b5a674ba
parent275f3346f334b62181ece389d7118c7dc1422c83 (diff)
CloseTray() method (eject -t)
Add CloseTray() method to org.freedesktop.Hal.Device.Storage interface. Also add Eject() to that interface. Update HAL spec with definitions of the Storage and Volume interfaces.
-rw-r--r--doc/spec/hal-spec-examples.xml73
-rw-r--r--fdi/policy/10osvendor/20-storage-methods.fdi15
-rw-r--r--tools/Makefile.am4
-rw-r--r--tools/hal-storage-closetray.c177
-rw-r--r--tools/hal-storage-eject.c232
-rw-r--r--tools/hal-storage-shared.c73
-rw-r--r--tools/hal-storage-shared.h8
7 files changed, 422 insertions, 160 deletions
diff --git a/doc/spec/hal-spec-examples.xml b/doc/spec/hal-spec-examples.xml
index 4849fba5..4157a64e 100644
--- a/doc/spec/hal-spec-examples.xml
+++ b/doc/spec/hal-spec-examples.xml
@@ -348,6 +348,79 @@ void Condition(string condition, ...)
signals for only a subset of the devices available.
</para>
</sect2>
+
+ <sect2>
+ <title>Interface org.freedesktop.Hal.Device.Volume</title>
+ <para>
+ The org.freedesktop.Hal.Device.Volume interface is used on objects
+ with the "volume" capability. This interface has the following methods.
+ </para>
+ <programlisting>
+# Mount volume
+#
+# @param mountpoint Desired mount point. If NULL, will be generated based on label.
+# @param fstype Filesystem type
+# @param options Mount options
+# @raises org.freedesktop.Hal.Device.Volume.NoSuchDevice
+# org.freedesktop.Hal.Device.Volume.PermissionDenied
+# org.freedesktop.Hal.Device.Volume.AlreadyMounted
+# org.freedesktop.Hal.Device.Volume.InvalidMountOption
+# org.freedesktop.Hal.Device.Volume.UnknownFilesystemType
+# org.freedesktop.Hal.Device.Volume.InvalidMountpoint
+# org.freedesktop.Hal.Device.Volume.MountPointNotAvailable
+# org.freedesktop.Hal.Device.Volume.PermissionDeniedByPolicy
+#
+void Mount(string mountpoint, string fstype, array{string} options)
+# Unmount volume
+#
+# @param options Unmount options
+# @raises org.freedesktop.Hal.Device.Volume.NoSuchDevice
+# org.freedesktop.Hal.Device.Volume.PermissionDenied
+# org.freedesktop.Hal.Device.Volume.InvalidUnmountOption
+# org.freedesktop.Hal.Device.Volume.InvalidMountpoint
+# org.freedesktop.Hal.Device.Volume.MountPointNotAvailable
+# org.freedesktop.Hal.Device.Volume.PermissionDeniedByPolicy
+#
+void Unmount(array{string} options)
+# Eject volume
+#
+# @param ejectoptions Eject options
+# @raises org.freedesktop.Hal.Device.Volume.NoSuchDevice
+# org.freedesktop.Hal.Device.Volume.PermissionDenied
+# org.freedesktop.Hal.Device.Volume.InvalidEjectOption
+# org.freedesktop.Hal.Device.Volume.PermissionDeniedByPolicy
+#
+void Eject(array{string} options)
+ </programlisting>
+ </sect2>
+
+ <sect2>
+ <title>Interface org.freedesktop.Hal.Device.Storage</title>
+ <para>
+ The org.freedesktop.Hal.Device.Storage interface is used on objects
+ with the "storage" capability. This interface has the following methods.
+ </para>
+ <programlisting>
+# Eject media
+#
+# @param ejectoptions Eject options
+# @raises org.freedesktop.Hal.Device.Storage.NoSuchDevice
+# org.freedesktop.Hal.Device.Storage.PermissionDenied
+# org.freedesktop.Hal.Device.Storage.InvalidEjectOption
+# org.freedesktop.Hal.Device.Storage.PermissionDeniedByPolicy
+#
+void Eject(array{string} options)
+# Close media tray
+#
+# @param closetrayoptions Close tray options
+# @raises org.freedesktop.Hal.Device.Storage.NoSuchDevice
+# org.freedesktop.Hal.Device.Storage.PermissionDenied
+# org.freedesktop.Hal.Device.Storage.InvalidCloseTrayOption
+# org.freedesktop.Hal.Device.Storage.PermissionDeniedByPolicy
+#
+void CloseTray(array{string} options)
+ </programlisting>
+ </sect2>
</sect1>
<sect1 id="enforcing-policy">
diff --git a/fdi/policy/10osvendor/20-storage-methods.fdi b/fdi/policy/10osvendor/20-storage-methods.fdi
index f67c7b05..9b3f3a57 100644
--- a/fdi/policy/10osvendor/20-storage-methods.fdi
+++ b/fdi/policy/10osvendor/20-storage-methods.fdi
@@ -184,5 +184,20 @@
<append key="volume.unmount.valid_options" type="strlist">lazy</append>
</match>
+
+ <match key="storage.requires_eject" bool="true">
+ <!-- storage Eject causes eject on each volume on this storage -->
+ <append key="info.interfaces" type="strlist">org.freedesktop.Hal.Device.Storage</append>
+ <append key="org.freedesktop.Hal.Device.Storage.method_names" type="strlist">Eject</append>
+ <append key="org.freedesktop.Hal.Device.Storage.method_signatures" type="strlist">as</append>
+ <append key="org.freedesktop.Hal.Device.Storage.method_argnames" type="strlist">extra_options</append>
+ <append key="org.freedesktop.Hal.Device.Storage.method_execpaths" type="strlist">hal-storage-eject</append>
+
+ <append key="info.interfaces" type="strlist">org.freedesktop.Hal.Device.Storage</append>
+ <append key="org.freedesktop.Hal.Device.Storage.method_names" type="strlist">CloseTray</append>
+ <append key="org.freedesktop.Hal.Device.Storage.method_signatures" type="strlist">as</append>
+ <append key="org.freedesktop.Hal.Device.Storage.method_argnames" type="strlist">extra_options</append>
+ <append key="org.freedesktop.Hal.Device.Storage.method_execpaths" type="strlist">hal-storage-closetray</append>
+ </match>
</device>
</deviceinfo>
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 7d842382..d820cc8c 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -53,6 +53,7 @@ libexec_PROGRAMS = \
hal-storage-mount \
hal-storage-unmount \
hal-storage-eject \
+ hal-storage-closetray \
hal-storage-cleanup-mountpoint \
hal-storage-cleanup-all-mountpoints \
hal-system-power-pmu
@@ -66,6 +67,9 @@ hal_storage_unmount_LDADD = @GLIB_LIBS@ @POLKIT_LIBS@ @DBUS_LIBS@ $(top_builddir
hal_storage_eject_SOURCES = hal-storage-eject.c hal-storage-shared.c hal-storage-shared.h
hal_storage_eject_LDADD = @GLIB_LIBS@ @POLKIT_LIBS@ @DBUS_LIBS@ $(top_builddir)/libhal/libhal.la $(top_builddir)/libhal-storage/libhal-storage.la
+hal_storage_closetray_SOURCES = hal-storage-closetray.c hal-storage-shared.c hal-storage-shared.h
+hal_storage_closetray_LDADD = @GLIB_LIBS@ @POLKIT_LIBS@ @DBUS_LIBS@ $(top_builddir)/libhal/libhal.la $(top_builddir)/libhal-storage/libhal-storage.la
+
hal_storage_cleanup_mountpoint_SOURCES = hal-storage-cleanup-mountpoint.c hal-storage-shared.c hal-storage-shared.h
hal_storage_cleanup_mountpoint_LDADD = @GLIB_LIBS@ @POLKIT_LIBS@ @DBUS_LIBS@ $(top_builddir)/libhal/libhal.la $(top_builddir)/libhal-storage/libhal-storage.la
diff --git a/tools/hal-storage-closetray.c b/tools/hal-storage-closetray.c
new file mode 100644
index 00000000..755ccd16
--- /dev/null
+++ b/tools/hal-storage-closetray.c
@@ -0,0 +1,177 @@
+/***************************************************************************
+ *
+ * hal-storage-closetray.c : CloseTray method handler
+ *
+ * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
+ * Copyright (C) 2006 Sun Microsystems, Inc.
+ *
+ * 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 of the License, 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <libhal.h>
+#include <libhal-storage.h>
+#ifdef HAVE_POLKIT
+#include <libpolkit.h>
+#endif
+
+#include "hal-storage-shared.h"
+
+
+static void
+usage (void)
+{
+ fprintf (stderr, "This program should only be started by hald.\n");
+ exit (1);
+}
+
+
+void static
+unknown_closetray_error (const char *detail)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Storage.UnknownFailure\n");
+ fprintf (stderr, "%s\n", detail);
+ exit (1);
+}
+
+
+static void
+invalid_closetray_option (const char *option, const char *uid)
+{
+ fprintf (stderr, "org.freedesktop.Hal.Device.Storage.InvalidCloseTrayOption\n");
+ fprintf (stderr, "The option '%s' is not allowed for uid=%s\n", option, uid);
+ exit (1);
+}
+
+#ifdef __FreeBSD__
+#error Need FreeBSD specific changes here
+#endif
+
+
+int
+main (int argc, char *argv[])
+{
+ char *udi;
+ char *device;
+ LibHalDrive *drive;
+ DBusError error;
+ LibHalContext *hal_ctx = NULL;
+ DBusConnection *system_bus = NULL;
+#ifdef HAVE_POLKIT
+ LibPolKitContext *pol_ctx = NULL;
+#endif
+ char *invoked_by_uid;
+ char *invoked_by_syscon_name;
+ int i;
+ char closetray_options[1024];
+ char **given_options;
+ const char *end;
+
+ device = getenv ("HAL_PROP_BLOCK_DEVICE");
+ if (device == NULL)
+ usage ();
+
+ udi = getenv ("HAL_PROP_INFO_UDI");
+ if (udi == NULL)
+ usage ();
+
+ invoked_by_uid = getenv ("HAL_METHOD_INVOKED_BY_UID");
+
+ invoked_by_syscon_name = getenv ("HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME");
+
+ dbus_error_init (&error);
+ if ((hal_ctx = libhal_ctx_init_direct (&error)) == NULL) {
+ printf ("Cannot connect to hald\n");
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ usage ();
+ }
+
+ dbus_error_init (&error);
+ system_bus = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (system_bus == NULL) {
+ printf ("Cannot connect to the system bus\n");
+ LIBHAL_FREE_DBUS_ERROR (&error);
+ usage ();
+ }
+#ifdef HAVE_POLKIT
+ pol_ctx = libpolkit_new_context (system_bus);
+ if (pol_ctx == NULL) {
+ printf ("Cannot get libpolkit context\n");
+ unknown_closetray_error ("Cannot get libpolkit context");
+ }
+#endif
+
+ /* read from stdin */
+ if (strlen (fgets (closetray_options, sizeof (closetray_options), stdin)) > 0)
+ closetray_options [strlen (closetray_options) - 1] = '\0';
+ /* validate that input from stdin is UTF-8 */
+ if (!g_utf8_validate (closetray_options, -1, &end))
+ unknown_closetray_error ("Error validating closetray_options as UTF-8");
+#ifdef DEBUG
+ printf ("closetray_options = '%s'\n", closetray_options);
+#endif
+
+ /* delete any trailing whitespace options from splitting the string */
+ given_options = g_strsplit (closetray_options, "\t", 0);
+ for (i = g_strv_length (given_options) - 1; i >= 0; --i) {
+ if (strlen (given_options[i]) > 0)
+ break;
+ given_options[i] = NULL;
+ }
+
+ /* check options */
+ for (i = 0; given_options[i] != NULL; i++) {
+ char *given = given_options[i];
+
+ /* none supported right now */
+
+ invalid_closetray_option (given, invoked_by_uid);
+ }
+ g_strfreev (given_options);
+
+ /* should be storage */
+ if ((drive = libhal_drive_from_udi (hal_ctx, udi)) == NULL) {
+ unknown_closetray_error ("Cannot get drive");
+ }
+
+ /* use handle_eject() with the closetray option */
+ handle_eject (hal_ctx,
+#ifdef HAVE_POLKIT
+ pol_ctx,
+#endif
+ libhal_drive_get_udi (drive),
+ drive,
+ libhal_drive_get_device_file (drive),
+ invoked_by_uid,
+ invoked_by_syscon_name,
+ TRUE /* closetray option */);
+
+ return 0;
+}
+
+
diff --git a/tools/hal-storage-eject.c b/tools/hal-storage-eject.c
index 516d078e..65248f39 100644
--- a/tools/hal-storage-eject.c
+++ b/tools/hal-storage-eject.c
@@ -1,7 +1,6 @@
/***************************************************************************
- * CVSID: $Id: hal-storage-mount.c,v 1.7 2006/06/21 00:44:03 david Exp $
*
- * hal-storage-mount.c : Mount wrapper
+ * hal-storage-eject.c : Eject method handler
*
* Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
*
@@ -42,6 +41,10 @@
#include "hal-storage-shared.h"
+/* possible values: "Volume", "Storage" */
+static char *devtype = "Volume";
+
+
static void
usage (void)
{
@@ -50,84 +53,21 @@ usage (void)
}
-static void
-invalid_eject_option (const char *option, const char *uid)
+void static
+unknown_eject_error (const char *detail)
{
- fprintf (stderr, "org.freedesktop.Hal.Device.Volume.InvalidEjectOption\n");
- fprintf (stderr, "The option '%s' is not allowed for uid=%s\n", option, uid);
+ fprintf (stderr, "org.freedesktop.Hal.Device.%s.UnknownFailure\n", devtype);
+ fprintf (stderr, "%s\n", detail);
exit (1);
}
-#ifdef __FreeBSD__
-#error Need FreeBSD specific changes here
-#endif
-
-#define EJECT "/usr/bin/eject"
static void
-handle_eject (LibHalContext *hal_ctx,
-#ifdef HAVE_POLKIT
- LibPolKitContext *pol_ctx,
-#endif
- const char *udi,
- LibHalDrive *drive, const char *device,
- const char *invoked_by_uid, const char *invoked_by_syscon_name)
+invalid_eject_option (const char *option, const char *uid)
{
- GError *err = NULL;
- char *sout = NULL;
- char *serr = NULL;
- int exit_status;
- char *args[10];
- int na;
-
- /* TODO: should we require privileges here? */
-
-#ifdef DEBUG
- printf ("device = %s\n", device);
- printf ("invoked by uid = %s\n", invoked_by_uid);
- printf ("invoked by system bus connection = %s\n", invoked_by_syscon_name);
-#endif
-
- /* construct arguments to EJECT (e.g. /usr/bin/eject) */
- na = 0;
- args[na++] = EJECT;
- args[na++] = (char *) device;
- args[na++] = NULL;
-
-#ifdef DEBUG
- printf ("will eject %s\n", device);
-#endif
-
- /* invoke /bin/umount */
- if (!g_spawn_sync ("/",
- args,
- NULL,
- 0,
- NULL,
- NULL,
- &sout,
- &serr,
- &exit_status,
- &err)) {
- printf ("Cannot execute %s\n", EJECT);
- unknown_error ("Cannot spawn " EJECT);
- }
-
- /* check if eject was succesful */
- if (exit_status != 0) {
- printf ("%s error %d, stdout='%s', stderr='%s'\n", EJECT, exit_status, sout, serr);
-
- unknown_error (serr);
- }
-
- /* eject was succesful... */
-
-#ifdef DEBUG
- printf ("done ejecting\n");
-#endif
-
- g_free (sout);
- g_free (serr);
+ fprintf (stderr, "org.freedesktop.Hal.Device.Volume.InvalidEjectOption\n");
+ fprintf (stderr, "The option '%s' is not allowed for uid=%s\n", option, uid);
+ exit (1);
}
@@ -136,6 +76,8 @@ main (int argc, char *argv[])
{
char *udi;
char *device;
+ const char *drive_udi;
+ LibHalDrive *drive;
LibHalVolume *volume;
DBusError error;
LibHalContext *hal_ctx = NULL;
@@ -182,7 +124,7 @@ main (int argc, char *argv[])
pol_ctx = libpolkit_new_context (system_bus);
if (pol_ctx == NULL) {
printf ("Cannot get libpolkit context\n");
- unknown_error ("Cannot get libpolkit context");
+ unknown_eject_error ("Cannot get libpolkit context");
}
#endif
@@ -191,7 +133,7 @@ main (int argc, char *argv[])
eject_options [strlen (eject_options) - 1] = '\0';
/* validate that input from stdin is UTF-8 */
if (!g_utf8_validate (eject_options, -1, &end))
- unknown_error ("Error validating eject_options as UTF-8");
+ unknown_eject_error ("Error validating eject_options as UTF-8");
#ifdef DEBUG
printf ("eject_options = '%s'\n", eject_options);
#endif
@@ -214,109 +156,79 @@ main (int argc, char *argv[])
}
g_strfreev (given_options);
-
- volume = libhal_volume_from_udi (hal_ctx, udi);
- if (volume == NULL) {
- LibHalDrive *drive;
-
-#ifdef DEBUG
- printf ("eject called on drive %s\n", udi);
-#endif
-
- drive = libhal_drive_from_udi (hal_ctx, udi);
- if (drive == NULL) {
- usage ();
- } else {
-
- /* TODO: should try to unmount? */
-
- /* attempt the eject */
- handle_eject (hal_ctx,
-#ifdef HAVE_POLKIT
- pol_ctx,
-#endif
- libhal_drive_get_udi (drive),
- drive,
- libhal_drive_get_device_file (drive),
- invoked_by_uid,
- invoked_by_syscon_name);
- }
-
+ /* should be either volume or storage */
+ if ((volume = libhal_volume_from_udi (hal_ctx, udi)) != NULL) {
+ drive_udi = libhal_volume_get_storage_device_udi (volume);
} else {
- const char *drive_udi;
- LibHalDrive *drive;
+ drive_udi = g_strdup (udi);
+ devtype = "Storage";
+ }
+ if (drive_udi == NULL) {
+ unknown_eject_error ("Cannot get drive udi");
+ }
+ if ((drive = libhal_drive_from_udi (hal_ctx, drive_udi)) == NULL) {
+ unknown_eject_error ("Cannot get drive from udi");
+ }
- /* first, unmount all volumes */
+ /* first, unmount all volumes */
+ volume_udis = libhal_drive_find_all_volumes (hal_ctx, drive, &num_volumes);
+ if (volume_udis == NULL)
+ unknown_eject_error ("Cannot get all enclosed volumes");
+ for (i = 0; i < num_volumes; i++) {
+ char *volume_udi;
+ LibHalVolume *volume_to_unmount;
- drive_udi = libhal_volume_get_storage_device_udi (volume);
-
- if (drive_udi == NULL)
- unknown_error ("Cannot get drive_udi from volume");
- drive = libhal_drive_from_udi (hal_ctx, drive_udi);
- if (drive == NULL)
- unknown_error ("Cannot get drive from hal");
-
-
- volume_udis = libhal_drive_find_all_volumes (hal_ctx, drive, &num_volumes);
- if (volume_udis == NULL)
- unknown_error ("Cannot get all enclosed volumes");
- for (i = 0; i < num_volumes; i++) {
- char *volume_udi;
- LibHalVolume *volume_to_unmount;
-
- volume_udi = volume_udis[i];
+ volume_udi = volume_udis[i];
#ifdef DEBUG
- printf ("processing drive's volume %s (%d of %d)\n", volume_udi, i + 1, num_volumes);
+ printf ("processing drive's volume %s (%d of %d)\n", volume_udi, i + 1, num_volumes);
#endif
- volume_to_unmount = libhal_volume_from_udi (hal_ctx, volume_udi);
- if (volume_to_unmount == NULL) {
- unknown_error ("Cannot get volume object");
- }
+ volume_to_unmount = libhal_volume_from_udi (hal_ctx, volume_udi);
+ if (volume_to_unmount == NULL) {
+ unknown_eject_error ("Cannot get volume object");
+ }
- if (libhal_volume_is_mounted (volume_to_unmount)) {
+ if (libhal_volume_is_mounted (volume_to_unmount)) {
#ifdef DEBUG
- printf (" unmounting\n");
+ printf (" unmounting\n");
#endif
- /* only lock around unmount call because hald's /proc/mounts handler
- * will also want to lock the /media/.hal-mtab-lock file for peeking
- */
- if (!lock_hal_mtab ()) {
- unknown_error ("Cannot obtain lock on /media/.hal-mtab");
- }
- handle_unmount (hal_ctx,
+ /* only lock around unmount call because hald's /proc/mounts handler
+ * will also want to lock the /media/.hal-mtab-lock file for peeking
+ */
+ if (!lock_hal_mtab ()) {
+ unknown_eject_error ("Cannot obtain lock on /media/.hal-mtab");
+ }
+ handle_unmount (hal_ctx,
#ifdef HAVE_POLKIT
- pol_ctx,
+ pol_ctx,
#endif
- udi, volume_to_unmount, drive,
- libhal_volume_get_device_file (volume_to_unmount),
- invoked_by_uid, invoked_by_syscon_name,
- FALSE, FALSE); /* use neither lazy nor force */
- unlock_hal_mtab ();
- } else {
+ udi, volume_to_unmount, drive,
+ libhal_volume_get_device_file (volume_to_unmount),
+ invoked_by_uid, invoked_by_syscon_name,
+ FALSE, FALSE); /* use neither lazy nor force */
+ unlock_hal_mtab ();
+ } else {
#ifdef DEBUG
- printf (" not mounted\n");
+ printf (" not mounted\n");
#endif
- }
-
- libhal_volume_free (volume_to_unmount);
-
}
- libhal_free_string_array (volume_udis);
- /* now attempt the eject */
- handle_eject (hal_ctx,
-#ifdef HAVE_POLKIT
- pol_ctx,
-#endif
- libhal_drive_get_udi (drive),
- drive,
- libhal_drive_get_device_file (drive),
- invoked_by_uid,
- invoked_by_syscon_name);
+ libhal_volume_free (volume_to_unmount);
}
+ libhal_free_string_array (volume_udis);
+ /* now attempt the eject */
+ handle_eject (hal_ctx,
+#ifdef HAVE_POLKIT
+ pol_ctx,
+#endif
+ libhal_drive_get_udi (drive),
+ drive,
+ libhal_drive_get_device_file (drive),
+ invoked_by_uid,
+ invoked_by_syscon_name,
+ FALSE);
return 0;
}
diff --git a/tools/hal-storage-shared.c b/tools/hal-storage-shared.c
index dced6639..f8af3a9c 100644
--- a/tools/hal-storage-shared.c
+++ b/tools/hal-storage-shared.c
@@ -468,6 +468,79 @@ line_found:
g_free (mount_point_to_unmount);
}
+#define EJECT "/usr/bin/eject"
+
+void
+handle_eject (LibHalContext *hal_ctx,
+#ifdef HAVE_POLKIT
+ LibPolKitContext *pol_ctx,
+#endif
+ const char *udi,
+ LibHalDrive *drive, const char *device,
+ const char *invoked_by_uid, const char *invoked_by_syscon_name,
+ gboolean closetray)
+{
+ GError *err = NULL;
+ char *sout = NULL;
+ char *serr = NULL;
+ int exit_status;
+ char *args[10];
+ int na;
+
+ /* TODO: should we require privileges here? */
+
+#ifdef DEBUG
+ printf ("device = %s\n", device);
+ printf ("invoked by uid = %s\n", invoked_by_uid);
+ printf ("invoked by system bus connection = %s\n", invoked_by_syscon_name);
+#endif
+
+ /* construct arguments to EJECT (e.g. /usr/bin/eject) */
+ na = 0;
+ args[na++] = EJECT;
+ if (closetray) {
+ args[na++] = "-t";
+ }
+ args[na++] = (char *) device;
+ args[na++] = NULL;
+
+#ifdef DEBUG
+ printf ("will eject %s\n", device);
+#endif
+
+ /* invoke eject command */
+ if (!g_spawn_sync ("/",
+ args,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ &sout,
+ &serr,
+ &exit_status,
+ &err)) {
+ printf ("Cannot execute %s\n", EJECT);
+ unknown_error ("Cannot spawn " EJECT);
+ }
+
+ /* check if eject was succesful */
+ if (exit_status != 0) {
+ printf ("%s error %d, stdout='%s', stderr='%s'\n", EJECT, exit_status, sout, serr);
+
+ unknown_error (serr);
+ }
+
+ /* eject was succesful... */
+
+#ifdef DEBUG
+ printf ("done ejecting\n");
+#endif
+
+ g_free (sout);
+ g_free (serr);
+}
+
+
static int lock_mtab_fd = -1;
gboolean
diff --git a/tools/hal-storage-shared.h b/tools/hal-storage-shared.h
index f87d5d18..c1d7ebc5 100644
--- a/tools/hal-storage-shared.h
+++ b/tools/hal-storage-shared.h
@@ -55,6 +55,14 @@ void handle_unmount (LibHalContext *hal_ctx,
const char *invoked_by_uid, const char *invoked_by_syscon_name,
gboolean option_lazy, gboolean option_force);
+void handle_eject (LibHalContext *hal_ctx,
+#ifdef HAVE_POLKIT
+ LibPolKitContext *pol_ctx,
+#endif
+ const char *udi,
+ LibHalDrive *drive, const char *device,
+ const char *invoked_by_uid, const char *invoked_by_syscon_name,
+ gboolean closetray);
#endif /* HAL_STORAGE_SHARED_H */