--- gnome-mount-0.4/src/gnome-mount.c 2006-02-24 00:14:23.000000000 -0500
+++ gnome-mount-0.4.new/src/gnome-mount.c 2006-06-18 19:40:03.000000000 -0400
@@ -238,7 +238,8 @@
/* #define MOUNT_ERROR_DIALOG_RESPONSE_INSTALL_DRIVER 10 see below */
static void
-show_error_dialog_mount (LibHalVolume *volume, const char *error_name, const char *error_detail,
+show_error_dialog_mount (LibHalVolume *volume, LibHalDrive *drive,
+ const char *error_name, const char *error_detail,
const char *fstype_requested)
{
GtkWidget *w;
@@ -266,7 +267,10 @@
0,
_("Cannot mount volume"));
- volume_name = libhal_volume_get_label (volume);
+ if (volume != NULL)
+ volume_name = libhal_volume_get_label (volume);
+ else
+ volume_name = NULL;
if (strcmp (error_name, "org.freedesktop.Hal.Device.Volume.PermissionDenied") == 0) {
gtk_message_dialog_format_secondary_text (
@@ -289,8 +293,8 @@
volume_name != NULL ?
_("The volume '%s' uses the %s file system which is not supported by your system.") :
_("The volume uses the %s file system which is not supported by your system."),
- volume_name != NULL ? volume_name : fstype_requested,
- volume_name != NULL ? fstype_requested : "");
+ volume_name != NULL ? volume_name : (fstype_requested != NULL ? fstype_requested : ""),
+ volume_name != NULL ? (fstype_requested != NULL ? fstype_requested : "") : "");
/* some day.. :-)
gtk_dialog_add_buttons (GTK_DIALOG (w),
@@ -463,9 +467,9 @@
notify_parent (FALSE);
- show_error_dialog_mount (volume, error.name, error.message,
+ show_error_dialog_mount (volume, drive, error.name, error.message,
(fstype != NULL && strlen (fstype) > 0) ?
- fstype : libhal_volume_get_fstype (volume));
+ fstype : (volume != NULL ? libhal_volume_get_fstype (volume) : NULL));
dbus_error_free (&error);
goto out;
@@ -573,6 +577,226 @@
return flags;
}
+
+static gboolean
+fstab_open (gpointer *handle)
+{
+#ifdef __FreeBSD__
+ return setfsent () == 1;
+#else
+ *handle = fopen ("/etc/fstab", "r");
+ return *handle != NULL;
+#endif
+}
+
+static char *
+fstab_next (gpointer handle, char **mount_point)
+{
+#ifdef __FreeBSD__
+ struct fstab *fstab;
+
+ fstab = getfsent ();
+
+ /* TODO: fill out mount_point */
+ if (mount_point != NULL && fstab != NULL) {
+ *mount_point = fstab->fs_file;
+ }
+
+ return fstab ? fstab->fs_spec : NULL;
+#else
+ struct mntent *mnt;
+
+ mnt = getmntent (handle);
+
+ if (mount_point != NULL && mnt != NULL) {
+ *mount_point = mnt->mnt_dir;
+ }
+
+ return mnt ? mnt->mnt_fsname : NULL;
+#endif
+}
+
+
+static void
+fstab_close (gpointer handle)
+{
+#ifdef __FreeBSD__
+ endfsent ();
+#else
+ fclose (handle);
+#endif
+}
+
+
+/* borrowed from gtk/gtkfilesystemunix.c in GTK+ on 02/23/2006 */
+static void
+canonicalize_filename (gchar *filename)
+{
+ gchar *p, *q;
+ gboolean last_was_slash = FALSE;
+
+ p = filename;
+ q = filename;
+
+ while (*p)
+ {
+ if (*p == G_DIR_SEPARATOR)
+ {
+ if (!last_was_slash)
+ *q++ = G_DIR_SEPARATOR;
+
+ last_was_slash = TRUE;
+ }
+ else
+ {
+ if (last_was_slash && *p == '.')
+ {
+ if (*(p + 1) == G_DIR_SEPARATOR ||
+ *(p + 1) == '\0')
+ {
+ if (*(p + 1) == '\0')
+ break;
+
+ p += 1;
+ }
+ else if (*(p + 1) == '.' &&
+ (*(p + 2) == G_DIR_SEPARATOR ||
+ *(p + 2) == '\0'))
+ {
+ if (q > filename + 1)
+ {
+ q--;
+ while (q > filename + 1 &&
+ *(q - 1) != G_DIR_SEPARATOR)
+ q--;
+ }
+
+ if (*(p + 2) == '\0')
+ break;
+
+ p += 2;
+ }
+ else
+ {
+ *q++ = *p;
+ last_was_slash = FALSE;
+ }
+ }
+ else
+ {
+ *q++ = *p;
+ last_was_slash = FALSE;
+ }
+ }
+
+ p++;
+ }
+
+ if (q > filename + 1 && *(q - 1) == G_DIR_SEPARATOR)
+ q--;
+
+ *q = '\0';
+}
+
+static char *
+resolve_symlink (const char *file)
+{
+ GError *error;
+ char *dir;
+ char *link;
+ char *f;
+ char *f1;
+
+ f = g_strdup (file);
+
+ while (g_file_test (f, G_FILE_TEST_IS_SYMLINK)) {
+ link = g_file_read_link (f, &error);
+ if (link == NULL) {
+ g_warning ("Cannot resolve symlink %s: %s", f, error->message);
+ g_error_free (error);
+ g_free (f);
+ f = NULL;
+ goto out;
+ }
+
+ dir = g_path_get_dirname (f);
+ f1 = g_strdup_printf ("%s/%s", dir, link);
+ g_free (dir);
+ g_free (link);
+ g_free (f);
+ f = f1;
+ }
+
+out:
+ if (f != NULL)
+ canonicalize_filename (f);
+ return f;
+}
+
+static gboolean
+is_in_fstab (const char *device_file, const char *label, const char *uuid, char **mount_point)
+{
+ gboolean ret;
+ gpointer handle;
+ char *entry;
+ char *_mount_point;
+
+ ret = FALSE;
+
+ /* check if /etc/fstab mentions this device... (with symlinks etc) */
+ if (!fstab_open (&handle)) {
+ handle = NULL;
+ goto out;
+ }
+
+ while ((entry = fstab_next (handle, &_mount_point)) != NULL) {
+ char *resolved;
+
+ if (label != NULL && g_str_has_prefix (entry, "LABEL=")) {
+ if (strcmp (entry + 6, label) == 0) {
+ ret = TRUE;
+ if (mount_point != NULL)
+ *mount_point = g_strdup (_mount_point);
+ goto out;
+ }
+ }
+
+ if (uuid != NULL && g_str_has_prefix (entry, "UUID=")) {
+ if (strcmp (entry + 5, uuid) == 0) {
+ ret = TRUE;
+ if (mount_point != NULL)
+ *mount_point = g_strdup (_mount_point);
+ goto out;
+ }
+ }
+
+ resolved = resolve_symlink (entry);
+ if (strcmp (device_file, resolved) == 0) {
+ ret = TRUE;
+ g_free (resolved);
+ if (mount_point != NULL)
+ *mount_point = g_strdup (_mount_point);
+ goto out;
+ }
+
+ g_free (resolved);
+ }
+
+out:
+ if (handle != NULL)
+ fstab_close (handle);
+
+ return ret;
+}
+
+#ifdef __FreeBSD__
+#define MOUNT "/sbin/mount"
+#define UMOUNT "/sbin/umount"
+#else
+#define MOUNT "/bin/mount"
+#define UMOUNT "/bin/umount"
+#endif
+
static gboolean
volume_mount (const char *udi, LibHalVolume *volume, LibHalDrive *drive)
{
@@ -587,9 +811,89 @@
char *key;
gboolean ret;
const char *fstype;
+ const char *device_file;
+ const char *label;
+ const char *uuid;
ret = FALSE;
+ g_debug ("Mounting %s", udi);
+
+ /* check if it's in /etc/fstab */
+ label = NULL;
+ uuid = NULL;
+ device_file = NULL;
+ if (volume != NULL) {
+ label = libhal_volume_get_label (volume);
+ uuid = libhal_volume_get_uuid (volume);
+ device_file = libhal_volume_get_device_file (volume);
+ } else if (drive != NULL) {
+ device_file = libhal_drive_get_device_file (drive);
+ }
+ if (device_file != NULL) {
+ char *mount_point = NULL;
+
+ if (is_in_fstab (device_file, label, uuid, &mount_point)) {
+ GError *err = NULL;
+ char *sout = NULL;
+ char *serr = NULL;
+ int exit_status;
+ char *args[3] = {MOUNT, NULL, NULL};
+ char **envp = {NULL};
+
+ g_print (_("Device %s is in /etc/fstab with mount point \"%s\"\n"),
+ device_file, mount_point);
+ args[1] = mount_point;
+ if (!g_spawn_sync ("/",
+ args,
+ envp,
+ 0,
+ NULL,
+ NULL,
+ &sout,
+ &serr,
+ &exit_status,
+ &err)) {
+ g_warning ("Cannot execute %s\n", MOUNT);
+ g_free (mount_point);
+ goto out;
+ }
+
+ if (exit_status != 0) {
+ char errstr[] = "mount: unknown filesystem type";
+
+ g_warning ("%s said error %d, stdout='%s', stderr='%s'\n",
+ MOUNT, exit_status, sout, serr);
+
+ if (strstr (serr, "unknown filesystem type") != NULL) {
+ show_error_dialog_mount (volume, drive, "org.freedesktop.Hal.Device.Volume.UnknownFilesystemType", serr, NULL);
+ } else if (strstr (serr, "already mounted") != NULL) {
+ show_error_dialog_mount (volume, drive, "org.freedesktop.Hal.Device.Volume.AlreadyMounted", serr, NULL);
+ } else if (strstr (serr, "only root") != NULL) {
+ show_error_dialog_mount (volume, drive, "org.freedesktop.Hal.Device.Volume.PermissionDenied", serr, NULL);
+ } else if (strstr (serr, "bad option") != NULL) {
+ show_error_dialog_mount (volume, drive, "org.freedesktop.Hal.Device.Volume.InvalidMountOption", serr, NULL);
+ } else {
+ show_error_dialog_mount (volume, drive, "org.freedesktop.Hal.Device.Volume.UnknownFailure", serr, NULL);
+ }
+
+ g_free (mount_point);
+ goto out;
+
+ }
+
+ g_print (_("Mounted %s at \"%s\" (using /etc/fstab)\n"), device_file, mount_point);
+
+ g_free (mount_point);
+ ret = TRUE;
+ goto out;
+
+ }
+ g_free (mount_point);
+ }
+
+
+
if (volume != NULL) {
fstype = libhal_volume_get_fstype (volume);
} else {
@@ -690,6 +994,7 @@
g_free (mount_point);
+out:
return ret;
}
@@ -697,15 +1002,89 @@
static gboolean
volume_unmount (const char *udi, LibHalVolume *volume, LibHalDrive *drive)
{
- gboolean ret = FALSE;
+ gboolean ret;
DBusMessage *msg = NULL;
DBusMessage *reply = NULL;
DBusError error;
char **options = NULL;
unsigned int num_options = 0;
+ const char *fstype;
+ const char *device_file;
+ const char *label;
+ const char *uuid;
+
+ ret = FALSE;
g_debug ("Unmounting %s", udi);
+ /* check if it's in /etc/fstab */
+ label = NULL;
+ uuid = NULL;
+ device_file = NULL;
+ if (volume != NULL) {
+ label = libhal_volume_get_label (volume);
+ uuid = libhal_volume_get_uuid (volume);
+ device_file = libhal_volume_get_device_file (volume);
+ } else if (drive != NULL) {
+ device_file = libhal_drive_get_device_file (drive);
+ }
+ if (device_file != NULL) {
+ char *mount_point = NULL;
+
+ if (is_in_fstab (device_file, label, uuid, &mount_point)) {
+ GError *err = NULL;
+ char *sout = NULL;
+ char *serr = NULL;
+ int exit_status;
+ char *args[3] = {UMOUNT, NULL, NULL};
+ char **envp = {NULL};
+
+ g_print (_("Device %s is in /etc/fstab with mount point \"%s\"\n"),
+ device_file, mount_point);
+ args[1] = mount_point;
+ if (!g_spawn_sync ("/",
+ args,
+ envp,
+ 0,
+ NULL,
+ NULL,
+ &sout,
+ &serr,
+ &exit_status,
+ &err)) {
+ g_warning ("Cannot execute %s\n", UMOUNT);
+ g_free (mount_point);
+ goto out;
+ }
+
+ if (exit_status != 0) {
+ g_warning ("%s said error %d, stdout='%s', stderr='%s'\n",
+ UMOUNT, exit_status, sout, serr);
+ g_free (mount_point);
+
+ if (strstr (serr, "is busy") != NULL) {
+ show_error_dialog_unmount (udi, volume, drive, "org.freedesktop.Hal.Device.Volume.Busy", serr);
+ } else if (strstr (serr, "not mounted") != NULL) {
+ show_error_dialog_unmount (udi, volume, drive, "org.freedesktop.Hal.Device.Volume.NotMounted", serr);
+ } else if (strstr (serr, "only root") != NULL) {
+ show_error_dialog_unmount (udi, volume, drive, "org.freedesktop.Hal.Device.Volume.PermissionDenied", serr);
+ } else {
+ show_error_dialog_unmount (udi, volume, drive, "org.freedesktop.Hal.Device.Volume.UnknownFailure", serr);
+ }
+
+ goto out;
+ }
+
+ g_print (_("Unmounted %s (using /etc/fstab).\n"), device_file);
+
+ g_free (mount_point);
+ ret = TRUE;
+ goto out;
+
+ }
+ g_free (mount_point);
+ }
+
msg = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
"org.freedesktop.Hal.Device.Volume",
"Unmount");
@@ -752,8 +1131,82 @@
DBusError error;
char **options = NULL;
unsigned int num_options = 0;
+ const char *fstype;
+ const char *device_file;
+ const char *label;
+ const char *uuid;
+
+ ret = FALSE;
g_debug ("Ejecting %s", udi);
+
+ /* check if it's in /etc/fstab */
+ label = NULL;
+ uuid = NULL;
+ device_file = NULL;
+ if (volume != NULL) {
+ label = libhal_volume_get_label (volume);
+ uuid = libhal_volume_get_uuid (volume);
+ device_file = libhal_volume_get_device_file (volume);
+ } else if (drive != NULL) {
+ device_file = libhal_drive_get_device_file (drive);
+ }
+ if (device_file != NULL) {
+ char *mount_point = NULL;
+
+ if (is_in_fstab (device_file, label, uuid, &mount_point)) {
+ GError *err = NULL;
+ char *sout = NULL;
+ char *serr = NULL;
+ int exit_status;
+ char *args[3] = {"eject", NULL, NULL};
+ char **envp = {NULL};
+
+ g_print (_("Device %s is in /etc/fstab with mount point \"%s\"\n"),
+ device_file, mount_point);
+ args[1] = mount_point;
+ if (!g_spawn_sync ("/",
+ args,
+ envp,
+ G_SPAWN_SEARCH_PATH,
+ NULL,
+ NULL,
+ &sout,
+ &serr,
+ &exit_status,
+ &err)) {
+ g_warning ("Cannot execute %s\n", "eject");
+ g_free (mount_point);
+ goto out;
+ }
+
+ if (exit_status != 0) {
+ g_warning ("%s said error %d, stdout='%s', stderr='%s'\n",
+ "eject", exit_status, sout, serr);
+ g_free (mount_point);
+
+ if (strstr (serr, "is busy") != NULL) {
+ show_error_dialog_eject (udi, volume, drive, "org.freedesktop.Hal.Device.Volume.Busy", serr);
+ } else if (strstr (serr, "only root") != NULL) {
+ show_error_dialog_eject (udi, volume, drive, "org.freedesktop.Hal.Device.Volume.PermissionDenied", serr);
+ } else if (strstr (serr, "unable to open") != NULL) {
+ show_error_dialog_eject (udi, volume, drive, "org.freedesktop.Hal.Device.Volume.PermissionDenied", serr);
+ } else {
+ show_error_dialog_eject (udi, volume, drive, "org.freedesktop.Hal.Device.Volume.UnknownFailure", serr);
+ }
+
+ goto out;
+ }
+
+ g_print (_("Ejected %s (using /etc/fstab).\n"), device_file);
+
+ g_free (mount_point);
+ ret = TRUE;
+ goto out;
+
+ }
+ g_free (mount_point);
+ }
msg = dbus_message_new_method_call ("org.freedesktop.Hal", udi,
"org.freedesktop.Hal.Device.Volume",
@@ -1255,112 +1708,6 @@
{
}
-
-/* borrowed from gtk/gtkfilesystemunix.c in GTK+ on 02/23/2006 */
-static void
-canonicalize_filename (gchar *filename)
-{
- gchar *p, *q;
- gboolean last_was_slash = FALSE;
-
- p = filename;
- q = filename;
-
- while (*p)
- {
- if (*p == G_DIR_SEPARATOR)
- {
- if (!last_was_slash)
- *q++ = G_DIR_SEPARATOR;
-
- last_was_slash = TRUE;
- }
- else
- {
- if (last_was_slash && *p == '.')
- {
- if (*(p + 1) == G_DIR_SEPARATOR ||
- *(p + 1) == '\0')
- {
- if (*(p + 1) == '\0')
- break;
-
- p += 1;
- }
- else if (*(p + 1) == '.' &&
- (*(p + 2) == G_DIR_SEPARATOR ||
- *(p + 2) == '\0'))
- {
- if (q > filename + 1)
- {
- q--;
- while (q > filename + 1 &&
- *(q - 1) != G_DIR_SEPARATOR)
- q--;
- }
-
- if (*(p + 2) == '\0')
- break;
-
- p += 2;
- }
- else
- {
- *q++ = *p;
- last_was_slash = FALSE;
- }
- }
- else
- {
- *q++ = *p;
- last_was_slash = FALSE;
- }
- }
-
- p++;
- }
-
- if (q > filename + 1 && *(q - 1) == G_DIR_SEPARATOR)
- q--;
-
- *q = '\0';
-}
-
-static char *
-resolve_symlink (const char *file)
-{
- GError *error;
- char *dir;
- char *link;
- char *f;
- char *f1;
-
- f = g_strdup (file);
-
- while (g_file_test (f, G_FILE_TEST_IS_SYMLINK)) {
- link = g_file_read_link (f, &error);
- if (link == NULL) {
- g_warning ("Cannot resolve symlink %s: %s", f, error->message);
- g_error_free (error);
- g_free (f);
- f = NULL;
- goto out;
- }
-
- dir = g_path_get_dirname (f);
- f1 = g_strdup_printf ("%s/%s", dir, link);
- g_free (dir);
- g_free (link);
- g_free (f);
- f = f1;
- }
-
-out:
- if (f != NULL)
- canonicalize_filename (f);
- return f;
-}
-
int
main (int argc, char *argv[])
{
@@ -1689,7 +2036,8 @@
goto out;
- } else if (fsusage == LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM) {
+ } else if (fsusage == LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM ||
+ fsusage == LIBHAL_VOLUME_USAGE_UNKNOWN) {
if (volume_mount (udi, volume, drive))
rc = 0;
}
@@ -1700,7 +2048,7 @@
out:
if (drive != NULL)
- libhal_volume_free (volume);
+ libhal_drive_free (drive);
if (volume != NULL)
libhal_volume_free (volume);