summaryrefslogtreecommitdiff
path: root/libnautilus-extensions/nautilus-volume-monitor.c
diff options
context:
space:
mode:
Diffstat (limited to 'libnautilus-extensions/nautilus-volume-monitor.c')
-rw-r--r--libnautilus-extensions/nautilus-volume-monitor.c150
1 files changed, 143 insertions, 7 deletions
diff --git a/libnautilus-extensions/nautilus-volume-monitor.c b/libnautilus-extensions/nautilus-volume-monitor.c
index 4aaa0871a..c144b5ddf 100644
--- a/libnautilus-extensions/nautilus-volume-monitor.c
+++ b/libnautilus-extensions/nautilus-volume-monitor.c
@@ -31,6 +31,7 @@
#include "nautilus-gtk-extensions.h"
#include "nautilus-gtk-macros.h"
#include "nautilus-iso9660.h"
+#include "nautilus-stock-dialogs.h"
#include "nautilus-string.h"
#include "nautilus-string-list.h"
#include "nautilus-volume-monitor.h"
@@ -42,6 +43,7 @@
#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-exec.h>
#include <libgnome/gnome-i18n.h>
+#include <libgnome/gnome-util.h>
#include <libgnomevfs/gnome-vfs.h>
#include <stdio.h>
#include <stdlib.h>
@@ -935,15 +937,141 @@ nautilus_volume_monitor_volume_is_mounted (NautilusVolumeMonitor *monitor,
return FALSE;
}
+static const char *mount_known_locations [] = {
+ "/sbin/mount", "/bin/mount",
+ "/usr/sbin/mount", "/usr/bin/mount",
+ NULL
+};
+
+static const char *umount_known_locations [] = {
+ "/sbin/umount", "/bin/umount",
+ "/usr/sbin/umount", "/usr/bin/umount",
+ NULL
+};
+
+
+/* Returns the full path to the queried command */
+static const char *
+find_command (const char **known_locations)
+{
+ int i;
+
+ for (i = 0; known_locations [i]; i++){
+ if (g_file_exists (known_locations [i]))
+ return known_locations [i];
+ }
+ return NULL;
+}
+
+/* Pipes are guaranteed to be able to hold at least 4096 bytes */
+/* More than that would be unportable */
+#define MAX_PIPE_SIZE 4096
+
+static int error_pipe[2]; /* File descriptors of error pipe */
+static int old_error; /* File descriptor of old standard error */
+
+/* Creates a pipe to hold standard error for a later analysis. */
+static void
+open_error_pipe (void)
+{
+ pipe (error_pipe);
+
+ old_error = dup (2);
+ if (old_error < 0 || close(2) || dup (error_pipe[1]) != 2) {
+ close (error_pipe[0]);
+ close (error_pipe[1]);
+ }
+
+ close (error_pipe[1]);
+}
+
+static void
+close_error_pipe (gboolean mount, const char *mount_path)
+{
+ char *title, *message;
+ char detailed_msg[MAX_PIPE_SIZE];
+ int len = 0;
+ gboolean is_floppy;
+
+ if (mount) {
+ title = _("Mount Error");
+ } else {
+ title = _("Unmount Error");
+ }
+
+ if (old_error >= 0) {
+ close (2);
+ dup (old_error);
+ close (old_error);
+ len = read (error_pipe[0], detailed_msg, MAX_PIPE_SIZE);
+
+ if (len >= 0) {
+ detailed_msg[len] = 0;
+ }
+
+ close (error_pipe[0]);
+ }
+
+ /* No output to show */
+ if (len == 0) {
+ return;
+ }
+
+ is_floppy = strstr (mount_path, "floppy") != NULL;
+
+ /* Determine a user readable message from the obscure pipe error */
+ /* Attention localizers: The strings being examined by strstr need to be identical
+ to the errors returned to the terminal by mount */
+ if (mount) {
+ if (strstr (detailed_msg, _("is not a valid block device")) != NULL) {
+ /* No media in drive */
+ if (is_floppy) {
+ /* Handle floppy case */
+ message = g_strdup_printf (_("Nautilus was unable to mount the floppy drive. "
+ "There is probably no floppy in the drive."));
+ } else {
+ /* All others */
+ message = g_strdup_printf (_("Nautilus was unable to mount the volume. "
+ "There is probably no media in the device."));
+ }
+ } else if (strstr (detailed_msg, _("wrong fs type, bad option, bad superblock on")) != NULL) {
+ /* Unknown filesystem */
+ if (is_floppy) {
+ message = g_strdup_printf (_("Nautilus was unable to mount the floppy drive. "
+ "The floppy is probably in a format that cannot be mounted."));
+ } else {
+ message = g_strdup_printf (_("Nautilus was unable to mount the selected volume. "
+ "The volume is probably in a format that cannot be mounted."));
+ }
+ } else {
+ if (is_floppy) {
+ message = g_strdup (_("Nautilus was unable to mount the selected floppy drive."));
+ } else {
+ message = g_strdup (_("Nautilus was unable to mount the selected volume."));
+ }
+ }
+ } else {
+ message = _("Nautilus was unable to unmount the selected volume.");
+ }
+
+ nautilus_error_dialog_with_details (message, title, detailed_msg, NULL);
+
+ g_free (message);
+}
+
void
nautilus_volume_monitor_mount_unmount_removable (NautilusVolumeMonitor *monitor,
const char *mount_point,
gboolean should_mount)
{
- char *argv[3];
+ const char *command;
GList *p;
NautilusVolume *volume;
+ char *command_string;
+ FILE *file;
+
+ volume = NULL;
/* Check and see if volume exists in mounts already */
for (p = monitor->details->mounts; p != NULL; p = p->next) {
@@ -952,15 +1080,23 @@ nautilus_volume_monitor_mount_unmount_removable (NautilusVolumeMonitor *monitor,
return;
}
}
-
- /* Decide to mount/unmount the volume */
- argv[0] = should_mount ? "/bin/mount" : "/bin/umount";
- argv[1] = (char *) mount_point;
- argv[2] = NULL;
+
+ if (should_mount) {
+ command = find_command (mount_known_locations);
+ } else {
+ command = find_command (umount_known_locations);
+ }
- gnome_execute_async (g_get_home_dir(), 2, argv);
+ if (command != NULL) {
+ command_string = g_strconcat (command, " ", mount_point, NULL);
+ open_error_pipe ();
+ file = popen (command_string, "r");
+ close_error_pipe (should_mount, mount_point);
+ pclose (file);
+ }
}
+
static NautilusVolume *
copy_volume (NautilusVolume *volume)
{