tray close
Artem Kachitchkine
Artem.Kachitchkin at Sun.COM
Wed Aug 16 21:23:43 PDT 2006
Here's the preliminary patch. If it looks okay, I'll test some more and
add documentation.
(diffs of hal-storage-eject.c look kinda weird, so I also attached the
file itself)
thanks,
-Artem.
-------------- next part --------------
diff --git a/fdi/policy/10osvendor/20-storage-methods.fdi b/fdi/policy/10osvendor/20-storage-methods.fdi
index f67c7b0..9b3f3a5 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 bcfbf59..c595c7e 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@
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 0000000..368ca39
--- /dev/null
+++ b/tools/hal-storage-closetray.c
@@ -0,0 +1,177 @@
+/***************************************************************************
+ *
+ * hal-storage-mount.c : CloseTray method handler
+ *
+ * Copyright (C) 2006 David Zeuthen, <david at 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 516d078..65248f3 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 at fubar.dk>
*
@@ -42,6 +41,10 @@ #endif
#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 @@ #ifdef HAVE_POLKIT
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 @@ #endif
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 @@ #endif
}
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 dced663..f8af3a9 100644
--- a/tools/hal-storage-shared.c
+++ b/tools/hal-storage-shared.c
@@ -468,6 +468,79 @@ #endif
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 f87d5d1..c1d7ebc 100644
--- a/tools/hal-storage-shared.h
+++ b/tools/hal-storage-shared.h
@@ -55,6 +55,14 @@ #endif
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 */
-------------- next part --------------
/***************************************************************************
*
* hal-storage-eject.c : Eject method handler
*
* Copyright (C) 2006 David Zeuthen, <david at fubar.dk>
*
* 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"
/* possible values: "Volume", "Storage" */
static char *devtype = "Volume";
static void
usage (void)
{
fprintf (stderr, "This program should only be started by hald.\n");
exit (1);
}
void static
unknown_eject_error (const char *detail)
{
fprintf (stderr, "org.freedesktop.Hal.Device.%s.UnknownFailure\n", devtype);
fprintf (stderr, "%s\n", detail);
exit (1);
}
static void
invalid_eject_option (const char *option, const char *uid)
{
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);
}
int
main (int argc, char *argv[])
{
char *udi;
char *device;
const char *drive_udi;
LibHalDrive *drive;
LibHalVolume *volume;
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;
char **volume_udis;
int num_volumes;
int i;
char eject_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_eject_error ("Cannot get libpolkit context");
}
#endif
/* read from stdin */
if (strlen (fgets (eject_options, sizeof (eject_options), stdin)) > 0)
eject_options [strlen (eject_options) - 1] = '\0';
/* validate that input from stdin is UTF-8 */
if (!g_utf8_validate (eject_options, -1, &end))
unknown_eject_error ("Error validating eject_options as UTF-8");
#ifdef DEBUG
printf ("eject_options = '%s'\n", eject_options);
#endif
/* delete any trailing whitespace options from splitting the string */
given_options = g_strsplit (eject_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 eject options */
for (i = 0; given_options[i] != NULL; i++) {
char *given = given_options[i];
/* none supported right now */
invalid_eject_option (given, invoked_by_uid);
}
g_strfreev (given_options);
/* 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 {
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 */
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;
volume_udi = volume_udis[i];
#ifdef DEBUG
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_eject_error ("Cannot get volume object");
}
if (libhal_volume_is_mounted (volume_to_unmount)) {
#ifdef DEBUG
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_eject_error ("Cannot obtain lock on /media/.hal-mtab");
}
handle_unmount (hal_ctx,
#ifdef HAVE_POLKIT
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 {
#ifdef DEBUG
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,
FALSE);
return 0;
}
More information about the hal
mailing list