mirror of
https://gitlab.gnome.org/GNOME/nautilus
synced 2024-08-24 18:25:50 +00:00
Fixed bug 1866, Turn volume mounting code into an object.
2000-08-02 Gene Z. Ragan <gzr@eazel.com> Fixed bug 1866, Turn volume mounting code into an object. Monitor now emits a signal, volume_mounted, when a mount occurs. Removed the old fm-desktop-mounting files and added new nautilus-volume-monitor files. * libnautilus-extensions/Makefile.am: * src/file-manager/Makefile.am: Added new files and removed old ones. * libnautilus-extensions/nautilus-cdrom-extensions.h: New file * libnautilus-extensions/nautilus-iso9660.h: New file * libnautilus-extensions/nautilus-volume-monitor.c: New file (nautilus_volume_monitor_initialize), (nautilus_volume_monitor_initialize_class), (nautilus_volume_monitor_destroy), (nautilus_volume_monitor_get), (floppy_sort), (fm_desktop_get_removable_volume_list), (nautilus_volume_monitor_volume_is_mounted), (mount_device_is_mounted), (mount_device_cdrom_set_state), (mount_device_floppy_set_state), (mount_device_ext2_set_state), (mount_device_set_state), (device_set_state_empty), (mount_device_mount), (mount_device_activate_cdrom), (mount_device_activate_floppy), (mount_device_activate_ext2), (mount_device_activate), (eject_cdrom), (mount_device_deactivate), (mount_device_do_nothing), (mount_device_check_change), (mount_devices_update_is_mounted), (mount_devices_check_status), (check_permissions), (mount_device_floppy_add), (mount_device_ext2_add), (cdrom_ioctl_frenzy), (mount_device_iso9660_add), (mount_device_add_aliases), (add_mount_device), (mntent_is_removable_fs), (mntent_has_option), (nautilus_volume_monitor_find_mount_devices), (nautilus_volume_monitor_mount_unmount_removable), (remove_mount_link), (free_device_info), (get_iso9660_volume_name), (get_ext2_volume_name), (get_floppy_volume_name): * libnautilus-extensions/nautilus-volume-monitor.h: New file * src/file-manager/fm-cdrom-extensions.h: * src/file-manager/fm-desktop-icon-view.c: (fm_desktop_icon_view_destroy), (fm_desktop_icon_view_initialize), (fm_desktop_icon_view_create_background_context_menu_items), (fm_desktop_icon_view_trash_state_changed_callback), (mount_unmount_removable), (place_home_directory): * src/file-manager/fm-desktop-icon-view.h: * src/file-manager/fm-desktop-mounting.c: * src/file-manager/fm-desktop-mounting.h: * src/file-manager/iso9660.h: All old files that have been removed from build.
This commit is contained in:
parent
9bd742ccff
commit
1d671db24c
58
ChangeLog
58
ChangeLog
|
@ -1,3 +1,61 @@
|
|||
2000-08-02 Gene Z. Ragan <gzr@eazel.com>
|
||||
|
||||
Fixed bug 1866, Turn volume mounting code into an object.
|
||||
|
||||
Monitor now emits a signal, volume_mounted, when a mount occurs.
|
||||
|
||||
Removed the old fm-desktop-mounting files and added
|
||||
new nautilus-volume-monitor files.
|
||||
|
||||
* libnautilus-extensions/Makefile.am:
|
||||
* src/file-manager/Makefile.am:
|
||||
Added new files and removed old ones.
|
||||
|
||||
* libnautilus-extensions/nautilus-cdrom-extensions.h:
|
||||
New file
|
||||
|
||||
* libnautilus-extensions/nautilus-iso9660.h:
|
||||
New file
|
||||
|
||||
* libnautilus-extensions/nautilus-volume-monitor.c:
|
||||
New file
|
||||
(nautilus_volume_monitor_initialize),
|
||||
(nautilus_volume_monitor_initialize_class),
|
||||
(nautilus_volume_monitor_destroy), (nautilus_volume_monitor_get),
|
||||
(floppy_sort), (fm_desktop_get_removable_volume_list),
|
||||
(nautilus_volume_monitor_volume_is_mounted),
|
||||
(mount_device_is_mounted), (mount_device_cdrom_set_state),
|
||||
(mount_device_floppy_set_state), (mount_device_ext2_set_state),
|
||||
(mount_device_set_state), (device_set_state_empty),
|
||||
(mount_device_mount), (mount_device_activate_cdrom),
|
||||
(mount_device_activate_floppy), (mount_device_activate_ext2),
|
||||
(mount_device_activate), (eject_cdrom), (mount_device_deactivate),
|
||||
(mount_device_do_nothing), (mount_device_check_change),
|
||||
(mount_devices_update_is_mounted), (mount_devices_check_status),
|
||||
(check_permissions), (mount_device_floppy_add),
|
||||
(mount_device_ext2_add), (cdrom_ioctl_frenzy),
|
||||
(mount_device_iso9660_add), (mount_device_add_aliases),
|
||||
(add_mount_device), (mntent_is_removable_fs), (mntent_has_option),
|
||||
(nautilus_volume_monitor_find_mount_devices),
|
||||
(nautilus_volume_monitor_mount_unmount_removable),
|
||||
(remove_mount_link), (free_device_info), (get_iso9660_volume_name),
|
||||
(get_ext2_volume_name), (get_floppy_volume_name):
|
||||
|
||||
* libnautilus-extensions/nautilus-volume-monitor.h:
|
||||
New file
|
||||
|
||||
* src/file-manager/fm-cdrom-extensions.h:
|
||||
* src/file-manager/fm-desktop-icon-view.c:
|
||||
(fm_desktop_icon_view_destroy), (fm_desktop_icon_view_initialize),
|
||||
(fm_desktop_icon_view_create_background_context_menu_items),
|
||||
(fm_desktop_icon_view_trash_state_changed_callback),
|
||||
(mount_unmount_removable), (place_home_directory):
|
||||
* src/file-manager/fm-desktop-icon-view.h:
|
||||
* src/file-manager/fm-desktop-mounting.c:
|
||||
* src/file-manager/fm-desktop-mounting.h:
|
||||
* src/file-manager/iso9660.h:
|
||||
All old files that have been removed from build.
|
||||
|
||||
2000-08-02 Arlo Rose <arlo@eazel.com>
|
||||
|
||||
* icons/eazel/Back.png:
|
||||
|
|
|
@ -103,6 +103,7 @@ libnautilus_extensions_la_SOURCES = \
|
|||
nautilus-undo-signal-handlers.c \
|
||||
nautilus-user-level-manager.c \
|
||||
nautilus-view-identifier.c \
|
||||
nautilus-volume-monitor.c \
|
||||
nautilus-xml-extensions.c \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
|
||||
|
||||
/* fm-desktop-mounting.c - Desktop volume mounting routines.
|
||||
/* nautilus-volume-monitor.c - Desktop volume mounting routines.
|
||||
|
||||
Copyright (C) 2000 Eazel, Inc.
|
||||
|
||||
|
@ -23,12 +23,6 @@
|
|||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include "fm-desktop-mounting.h"
|
||||
|
||||
#include "fm-cdrom-extensions.h"
|
||||
#include "fm-desktop-icon-view.h"
|
||||
#include "fm-icon-view.h"
|
||||
#include "iso9660.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -38,16 +32,28 @@
|
|||
#include <libgnome/gnome-i18n.h>
|
||||
#include <libgnomevfs/gnome-vfs.h>
|
||||
#include <mntent.h>
|
||||
#include <libnautilus-extensions/nautilus-cdrom-extensions.h>
|
||||
#include <libnautilus-extensions/nautilus-directory-private.h>
|
||||
#include <libnautilus-extensions/nautilus-file-utilities.h>
|
||||
#include <libnautilus-extensions/nautilus-gtk-extensions.h>
|
||||
#include <libnautilus-extensions/nautilus-gtk-macros.h>
|
||||
#include <libnautilus-extensions/nautilus-iso9660.h>
|
||||
#include <libnautilus-extensions/nautilus-link.h>
|
||||
#include <libnautilus-extensions/nautilus-volume-monitor.h>
|
||||
|
||||
#include <parser.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <xmlmemory.h>
|
||||
|
||||
|
||||
/* FIXME: Remove messages when this code is done. */
|
||||
#define MESSAGE g_message
|
||||
|
||||
NautilusVolumeMonitor *global_volume_monitor = NULL;
|
||||
|
||||
const char * const state_names[] = {
|
||||
"ACTIVE",
|
||||
"INACTIVE",
|
||||
|
@ -61,21 +67,102 @@ const char * const type_names[] = {
|
|||
"OTHER"
|
||||
};
|
||||
|
||||
/* The NautilusVolumeMonitor signals. */
|
||||
enum {
|
||||
VOLUME_MOUNTED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
static void remove_mount_link (DeviceInfo *device);
|
||||
static void get_iso9660_volume_name (DeviceInfo *device);
|
||||
static void get_ext2_volume_name (DeviceInfo *device);
|
||||
static void get_floppy_volume_name (DeviceInfo *device);
|
||||
static void mount_device_mount (FMDesktopIconView *view,
|
||||
DeviceInfo *device);
|
||||
static gboolean mount_device_is_mounted (DeviceInfo *device);
|
||||
static void mount_device_activate (FMDesktopIconView *view,
|
||||
DeviceInfo *device);
|
||||
static void mount_device_deactivate (FMDesktopIconView *icon_view,
|
||||
DeviceInfo *device);
|
||||
static void mount_device_activate_floppy (FMDesktopIconView *view,
|
||||
DeviceInfo *device);
|
||||
static gboolean mntent_is_removable_fs (struct mntent *ent);
|
||||
static void nautilus_volume_monitor_initialize (NautilusVolumeMonitor *desktop_mounter);
|
||||
static void nautilus_volume_monitor_initialize_class (NautilusVolumeMonitorClass *klass);
|
||||
static void nautilus_volume_monitor_destroy (GtkObject *object);
|
||||
static void remove_mount_link (DeviceInfo *device);
|
||||
static void get_iso9660_volume_name (DeviceInfo *device);
|
||||
static void get_ext2_volume_name (DeviceInfo *device);
|
||||
static void get_floppy_volume_name (DeviceInfo *device);
|
||||
static void mount_device_mount (NautilusVolumeMonitor *view,
|
||||
DeviceInfo *device);
|
||||
static gboolean mount_device_is_mounted (DeviceInfo *device);
|
||||
static void mount_device_activate (NautilusVolumeMonitor *view,
|
||||
DeviceInfo *device);
|
||||
static void mount_device_deactivate (NautilusVolumeMonitor *monitor,
|
||||
DeviceInfo *device);
|
||||
static void mount_device_activate_floppy (NautilusVolumeMonitor *view,
|
||||
DeviceInfo *device);
|
||||
static gboolean mntent_is_removable_fs (struct mntent *ent);
|
||||
static void free_device_info (DeviceInfo *device,
|
||||
NautilusVolumeMonitor *monitor);
|
||||
|
||||
|
||||
NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusVolumeMonitor, nautilus_volume_monitor, GTK_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
nautilus_volume_monitor_initialize (NautilusVolumeMonitor *monitor)
|
||||
{
|
||||
/* Set up details */
|
||||
monitor->details = g_new0 (NautilusVolumeMonitorDetails, 1);
|
||||
monitor->details->devices_by_fsname = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
monitor->details->devices = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_volume_monitor_initialize_class (NautilusVolumeMonitorClass *klass)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
|
||||
object_class = GTK_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->destroy = nautilus_volume_monitor_destroy;
|
||||
|
||||
signals[VOLUME_MOUNTED]
|
||||
= gtk_signal_new ("volume_mounted",
|
||||
GTK_RUN_LAST,
|
||||
object_class->type,
|
||||
GTK_SIGNAL_OFFSET (NautilusVolumeMonitorClass,
|
||||
volume_mounted),
|
||||
nautilus_gtk_marshal_STRING__NONE,
|
||||
GTK_TYPE_STRING, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_volume_monitor_destroy (GtkObject *object)
|
||||
{
|
||||
NautilusVolumeMonitor *monitor;
|
||||
|
||||
monitor = NAUTILUS_VOLUME_MONITOR (object);
|
||||
|
||||
/* Remove timer function */
|
||||
gtk_timeout_remove (monitor->details->mount_device_timer_id);
|
||||
|
||||
/* Clean up other device info */
|
||||
g_list_foreach (monitor->details->devices, (GFunc)free_device_info, monitor);
|
||||
|
||||
/* Remove timer function */
|
||||
gtk_timeout_remove (monitor->details->mount_device_timer_id);
|
||||
|
||||
/* Clean up details */
|
||||
g_hash_table_destroy (monitor->details->devices_by_fsname);
|
||||
g_list_free (monitor->details->devices);
|
||||
g_free (monitor->details);
|
||||
|
||||
NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object));
|
||||
}
|
||||
|
||||
/* Return the global instance of the NautilusVolumeMonitor. Create one
|
||||
* if we have not done so already
|
||||
*/
|
||||
NautilusVolumeMonitor *
|
||||
nautilus_volume_monitor_get (void)
|
||||
{
|
||||
if (global_volume_monitor == NULL) {
|
||||
global_volume_monitor = NAUTILUS_VOLUME_MONITOR
|
||||
(gtk_object_new (nautilus_volume_monitor_get_type(),
|
||||
NULL));
|
||||
}
|
||||
|
||||
return global_volume_monitor;
|
||||
}
|
||||
|
||||
static int
|
||||
floppy_sort (const char *name_1, const char *name_2)
|
||||
|
@ -119,58 +206,8 @@ fm_desktop_get_removable_volume_list (void)
|
|||
return list;
|
||||
}
|
||||
|
||||
void
|
||||
fm_desktop_mount_unmount_removable (GtkCheckMenuItem *item, FMDesktopIconView *icon_view)
|
||||
{
|
||||
gboolean is_mounted, found_device;
|
||||
char *mount_point;
|
||||
char *argv[3];
|
||||
GList *element;
|
||||
DeviceInfo *device;
|
||||
int exec_err;
|
||||
|
||||
is_mounted = FALSE;
|
||||
found_device = FALSE;
|
||||
device = NULL;
|
||||
|
||||
/* Locate our mount point data */
|
||||
mount_point = gtk_object_get_data (GTK_OBJECT (item), "mount_point");
|
||||
if (mount_point != NULL) {
|
||||
/* Locate DeviceInfo for mount point */
|
||||
for (element = icon_view->details->devices; element != NULL; element = element->next) {
|
||||
device = element->data;
|
||||
if (strcmp (mount_point, device->mount_path) == 0) {
|
||||
found_device = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get mount state and then decide to mount/unmount the volume */
|
||||
if (found_device) {
|
||||
is_mounted = fm_desktop_volume_is_mounted (mount_point);
|
||||
argv[1] = mount_point;
|
||||
argv[2] = NULL;
|
||||
|
||||
if (is_mounted) {
|
||||
/* Unount */
|
||||
argv[0] = "/bin/umount";
|
||||
exec_err = gnome_execute_async (g_get_home_dir(), 2, argv);
|
||||
is_mounted = FALSE;
|
||||
} else {
|
||||
/* Mount */
|
||||
argv[0] = "/bin/mount";
|
||||
exec_err = gnome_execute_async (g_get_home_dir(), 2, argv);
|
||||
is_mounted = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the check state of menu item even thought the user may not see it */
|
||||
gtk_check_menu_item_set_active (item, is_mounted);
|
||||
}
|
||||
|
||||
gboolean
|
||||
fm_desktop_volume_is_mounted (const char *mount_point)
|
||||
nautilus_volume_monitor_volume_is_mounted (const char *mount_point)
|
||||
{
|
||||
FILE *fh;
|
||||
char line[PATH_MAX * 3];
|
||||
|
@ -201,7 +238,7 @@ mount_device_is_mounted (DeviceInfo *device)
|
|||
}
|
||||
|
||||
static void
|
||||
mount_device_cdrom_set_state (FMDesktopIconView *icon_view, DeviceInfo *device)
|
||||
mount_device_cdrom_set_state (NautilusVolumeMonitor *monitor, DeviceInfo *device)
|
||||
{
|
||||
if (device->device_fd < 0) {
|
||||
device->device_fd = open (device->fsname, O_RDONLY|O_NONBLOCK);
|
||||
|
@ -246,10 +283,10 @@ mount_device_cdrom_set_state (FMDesktopIconView *icon_view, DeviceInfo *device)
|
|||
|
||||
|
||||
static void
|
||||
mount_device_floppy_set_state (FMDesktopIconView *icon_view, DeviceInfo *device)
|
||||
mount_device_floppy_set_state (NautilusVolumeMonitor *monitor, DeviceInfo *device)
|
||||
{
|
||||
/* If the floppy is not in mtab, then we set it to empty */
|
||||
if (fm_desktop_volume_is_mounted (device->mount_path)) {
|
||||
if (nautilus_volume_monitor_volume_is_mounted (device->mount_path)) {
|
||||
device->state = STATE_ACTIVE;
|
||||
} else {
|
||||
device->state = STATE_EMPTY;
|
||||
|
@ -257,25 +294,25 @@ mount_device_floppy_set_state (FMDesktopIconView *icon_view, DeviceInfo *device)
|
|||
}
|
||||
|
||||
static void
|
||||
mount_device_ext2_set_state (FMDesktopIconView *icon_view, DeviceInfo *device)
|
||||
mount_device_ext2_set_state (NautilusVolumeMonitor *monitor, DeviceInfo *device)
|
||||
{
|
||||
device->state = STATE_ACTIVE;
|
||||
}
|
||||
|
||||
static void
|
||||
mount_device_set_state (DeviceInfo *device, FMDesktopIconView *icon_view)
|
||||
mount_device_set_state (DeviceInfo *device, NautilusVolumeMonitor *monitor)
|
||||
{
|
||||
switch (device->type) {
|
||||
case DEVICE_CDROM:
|
||||
mount_device_cdrom_set_state (icon_view, device);
|
||||
mount_device_cdrom_set_state (monitor, device);
|
||||
break;
|
||||
|
||||
case DEVICE_FLOPPY:
|
||||
mount_device_floppy_set_state (icon_view, device);
|
||||
mount_device_floppy_set_state (monitor, device);
|
||||
break;
|
||||
|
||||
case DEVICE_EXT2:
|
||||
mount_device_ext2_set_state (icon_view, device);
|
||||
mount_device_ext2_set_state (monitor, device);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -284,22 +321,19 @@ mount_device_set_state (DeviceInfo *device, FMDesktopIconView *icon_view)
|
|||
}
|
||||
|
||||
static void
|
||||
device_set_state_empty (DeviceInfo *device, FMDesktopIconView *icon_view)
|
||||
device_set_state_empty (DeviceInfo *device, NautilusVolumeMonitor *monitor)
|
||||
{
|
||||
device->state = STATE_EMPTY;
|
||||
}
|
||||
|
||||
static void
|
||||
mount_device_mount (FMDesktopIconView *view, DeviceInfo *device)
|
||||
mount_device_mount (NautilusVolumeMonitor *view, DeviceInfo *device)
|
||||
{
|
||||
char *target_uri, *desktop_path;
|
||||
const char *icon_name;
|
||||
NautilusIconContainer *container;
|
||||
gboolean result;
|
||||
int index;
|
||||
|
||||
container = NAUTILUS_ICON_CONTAINER (GTK_BIN (view)->child);
|
||||
|
||||
desktop_path = nautilus_get_desktop_directory ();
|
||||
target_uri = nautilus_get_uri_from_local_path (device->mount_path);
|
||||
|
||||
|
@ -354,7 +388,7 @@ mount_device_mount (FMDesktopIconView *view, DeviceInfo *device)
|
|||
}
|
||||
|
||||
static void
|
||||
mount_device_activate_cdrom (FMDesktopIconView *icon_view, DeviceInfo *device)
|
||||
mount_device_activate_cdrom (NautilusVolumeMonitor *monitor, DeviceInfo *device)
|
||||
{
|
||||
int disctype;
|
||||
|
||||
|
@ -375,7 +409,7 @@ mount_device_activate_cdrom (FMDesktopIconView *icon_view, DeviceInfo *device)
|
|||
case CDS_MIXED:
|
||||
/* Get volume name */
|
||||
get_iso9660_volume_name (device);
|
||||
mount_device_mount (icon_view, device);
|
||||
mount_device_mount (monitor, device);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -390,7 +424,7 @@ mount_device_activate_cdrom (FMDesktopIconView *icon_view, DeviceInfo *device)
|
|||
}
|
||||
|
||||
static void
|
||||
mount_device_activate_floppy (FMDesktopIconView *view, DeviceInfo *device)
|
||||
mount_device_activate_floppy (NautilusVolumeMonitor *view, DeviceInfo *device)
|
||||
{
|
||||
/* Get volume name */
|
||||
get_floppy_volume_name (device);
|
||||
|
@ -399,7 +433,7 @@ mount_device_activate_floppy (FMDesktopIconView *view, DeviceInfo *device)
|
|||
}
|
||||
|
||||
static void
|
||||
mount_device_activate_ext2 (FMDesktopIconView *view, DeviceInfo *device)
|
||||
mount_device_activate_ext2 (NautilusVolumeMonitor *view, DeviceInfo *device)
|
||||
{
|
||||
/* Get volume name */
|
||||
get_ext2_volume_name (device);
|
||||
|
@ -407,28 +441,32 @@ mount_device_activate_ext2 (FMDesktopIconView *view, DeviceInfo *device)
|
|||
mount_device_mount (view, device);
|
||||
}
|
||||
|
||||
typedef void (* ChangeDeviceInfoFunction) (FMDesktopIconView *view, DeviceInfo *device);
|
||||
typedef void (* ChangeDeviceInfoFunction) (NautilusVolumeMonitor *view, DeviceInfo *device);
|
||||
|
||||
static void
|
||||
mount_device_activate (FMDesktopIconView *view, DeviceInfo *device)
|
||||
mount_device_activate (NautilusVolumeMonitor *monitor, DeviceInfo *device)
|
||||
{
|
||||
switch (device->type) {
|
||||
case DEVICE_CDROM:
|
||||
mount_device_activate_cdrom (view, device);
|
||||
mount_device_activate_cdrom (monitor, device);
|
||||
break;
|
||||
|
||||
case DEVICE_FLOPPY:
|
||||
mount_device_activate_floppy (view, device);
|
||||
mount_device_activate_floppy (monitor, device);
|
||||
break;
|
||||
|
||||
case DEVICE_EXT2:
|
||||
mount_device_activate_ext2 (view, device);
|
||||
mount_device_activate_ext2 (monitor, device);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_signal_emit (GTK_OBJECT (monitor),
|
||||
signals[VOLUME_MOUNTED],
|
||||
&device->mount_path);
|
||||
}
|
||||
|
||||
|
||||
|
@ -453,7 +491,7 @@ eject_cdrom (DeviceInfo *device)
|
|||
}
|
||||
|
||||
static void
|
||||
mount_device_deactivate (FMDesktopIconView *icon_view, DeviceInfo *device)
|
||||
mount_device_deactivate (NautilusVolumeMonitor *monitor, DeviceInfo *device)
|
||||
{
|
||||
GList dummy_list;
|
||||
|
||||
|
@ -477,7 +515,7 @@ mount_device_deactivate (FMDesktopIconView *icon_view, DeviceInfo *device)
|
|||
}
|
||||
|
||||
static void
|
||||
mount_device_do_nothing (FMDesktopIconView *icon_view, DeviceInfo *device)
|
||||
mount_device_do_nothing (NautilusVolumeMonitor *monitor, DeviceInfo *device)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -494,18 +532,18 @@ mount_device_check_change (gpointer data, gpointer callback_data)
|
|||
};
|
||||
|
||||
DeviceInfo *device;
|
||||
FMDesktopIconView *icon_view;
|
||||
NautilusVolumeMonitor *monitor;
|
||||
DeviceState old_state;
|
||||
ChangeDeviceInfoFunction f;
|
||||
|
||||
g_assert (data != NULL);
|
||||
|
||||
device = data;
|
||||
icon_view = FM_DESKTOP_ICON_VIEW (callback_data);
|
||||
monitor = NAUTILUS_VOLUME_MONITOR (callback_data);
|
||||
|
||||
old_state = device->state;
|
||||
|
||||
mount_device_set_state (device, icon_view);
|
||||
mount_device_set_state (device, monitor);
|
||||
|
||||
if (old_state != device->state) {
|
||||
f = state_transitions[device->state][old_state];
|
||||
|
@ -513,12 +551,12 @@ mount_device_check_change (gpointer data, gpointer callback_data)
|
|||
MESSAGE ("State on %s changed from %s to %s, running %p",
|
||||
device->fsname, state_names[old_state], state_names[device->state], f);
|
||||
|
||||
(* f) (icon_view, device);
|
||||
(* f) (monitor, device);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mount_devices_update_is_mounted (FMDesktopIconView *icon_view)
|
||||
mount_devices_update_is_mounted (NautilusVolumeMonitor *monitor)
|
||||
{
|
||||
FILE *fh;
|
||||
char line[PATH_MAX * 3], mntpoint[PATH_MAX], devname[PATH_MAX];
|
||||
|
@ -526,7 +564,7 @@ mount_devices_update_is_mounted (FMDesktopIconView *icon_view)
|
|||
DeviceInfo *device;
|
||||
|
||||
/* Toggle mount state to off and then recheck in mtab. */
|
||||
for (element = icon_view->details->devices; element != NULL; element = element->next) {
|
||||
for (element = monitor->details->devices; element != NULL; element = element->next) {
|
||||
device = element->data;
|
||||
device->is_mounted = FALSE;
|
||||
}
|
||||
|
@ -539,7 +577,7 @@ mount_devices_update_is_mounted (FMDesktopIconView *icon_view)
|
|||
|
||||
while (fgets (line, sizeof(line), fh)) {
|
||||
sscanf(line, "%s %s", devname, mntpoint);
|
||||
device = g_hash_table_lookup (icon_view->details->devices_by_fsname, devname);
|
||||
device = g_hash_table_lookup (monitor->details->devices_by_fsname, devname);
|
||||
|
||||
if(device) {
|
||||
device->is_mounted = TRUE;
|
||||
|
@ -550,13 +588,13 @@ mount_devices_update_is_mounted (FMDesktopIconView *icon_view)
|
|||
}
|
||||
|
||||
static gint
|
||||
mount_devices_check_status (FMDesktopIconView *icon_view)
|
||||
mount_devices_check_status (NautilusVolumeMonitor *monitor)
|
||||
{
|
||||
mount_devices_update_is_mounted (icon_view);
|
||||
mount_devices_update_is_mounted (monitor);
|
||||
|
||||
g_list_foreach (icon_view->details->devices,
|
||||
g_list_foreach (monitor->details->devices,
|
||||
mount_device_check_change,
|
||||
icon_view);
|
||||
monitor);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -597,7 +635,7 @@ check_permissions (gchar *filename, int mode)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
mount_device_floppy_add (FMDesktopIconView *icon_view, DeviceInfo *device)
|
||||
mount_device_floppy_add (NautilusVolumeMonitor *monitor, DeviceInfo *device)
|
||||
{
|
||||
device->mount_type = g_strdup ("floppy");
|
||||
device->type = DEVICE_FLOPPY;
|
||||
|
@ -640,7 +678,7 @@ cdrom_ioctl_frenzy (int fd)
|
|||
|
||||
|
||||
static gboolean
|
||||
mount_device_iso9660_add (FMDesktopIconView *icon_view, DeviceInfo *device)
|
||||
mount_device_iso9660_add (NautilusVolumeMonitor *monitor, DeviceInfo *device)
|
||||
{
|
||||
device->device_fd = open (device->fsname, O_RDONLY|O_NONBLOCK);
|
||||
if(device->device_fd < 0) {
|
||||
|
@ -665,12 +703,12 @@ mount_device_iso9660_add (FMDesktopIconView *icon_view, DeviceInfo *device)
|
|||
|
||||
/* This is here because mtab lists devices by their symlink-followed names rather than what is listed in fstab. *sigh* */
|
||||
static void
|
||||
mount_device_add_aliases (FMDesktopIconView *icon_view, const char *alias, DeviceInfo *device)
|
||||
mount_device_add_aliases (NautilusVolumeMonitor *monitor, const char *alias, DeviceInfo *device)
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
int buflen;
|
||||
|
||||
g_hash_table_insert (icon_view->details->devices_by_fsname, (gpointer)alias, device);
|
||||
g_hash_table_insert (monitor->details->devices_by_fsname, (gpointer)alias, device);
|
||||
|
||||
buflen = readlink (alias, buf, sizeof(buf));
|
||||
if(buflen < 1) {
|
||||
|
@ -688,12 +726,12 @@ mount_device_add_aliases (FMDesktopIconView *icon_view, const char *alias, Devic
|
|||
strcpy(buf, buf2);
|
||||
}
|
||||
|
||||
mount_device_add_aliases (icon_view, g_strdup(buf), device);
|
||||
mount_device_add_aliases (monitor, g_strdup(buf), device);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
add_mount_device (FMDesktopIconView *icon_view, struct mntent *ent)
|
||||
add_mount_device (NautilusVolumeMonitor *monitor, struct mntent *ent)
|
||||
{
|
||||
DeviceInfo *newdev = NULL;
|
||||
gboolean mounted;
|
||||
|
@ -710,9 +748,9 @@ add_mount_device (FMDesktopIconView *icon_view, struct mntent *ent)
|
|||
mounted = FALSE;
|
||||
|
||||
if (strcmp (ent->mnt_type, MOUNT_TYPE_ISO9660) == 0) {
|
||||
mounted = mount_device_iso9660_add (icon_view, newdev);
|
||||
mounted = mount_device_iso9660_add (monitor, newdev);
|
||||
} else if (strncmp (ent->mnt_fsname, "/dev/fd", strlen("/dev/fd")) == 0) {
|
||||
mounted = mount_device_floppy_add (icon_view, newdev);
|
||||
mounted = mount_device_floppy_add (monitor, newdev);
|
||||
} else if (strcmp (ent->mnt_type, MOUNT_TYPE_EXT2) == 0) {
|
||||
mounted = mount_device_ext2_add (newdev);
|
||||
} else {
|
||||
|
@ -721,8 +759,8 @@ add_mount_device (FMDesktopIconView *icon_view, struct mntent *ent)
|
|||
}
|
||||
|
||||
if (mounted) {
|
||||
icon_view->details->devices = g_list_append (icon_view->details->devices, newdev);
|
||||
mount_device_add_aliases (icon_view, newdev->fsname, newdev);
|
||||
monitor->details->devices = g_list_append (monitor->details->devices, newdev);
|
||||
mount_device_add_aliases (monitor, newdev->fsname, newdev);
|
||||
MESSAGE ("Device %s came through (type %s)", newdev->fsname, type_names[newdev->type]);
|
||||
} else {
|
||||
close (newdev->device_fd);
|
||||
|
@ -770,12 +808,12 @@ mntent_has_option(const char *optlist, const char *option)
|
|||
#endif
|
||||
|
||||
void
|
||||
fm_desktop_find_mount_devices (FMDesktopIconView *icon_view, const char *fstab_path)
|
||||
nautilus_volume_monitor_find_mount_devices (NautilusVolumeMonitor *monitor)
|
||||
{
|
||||
FILE *mef;
|
||||
struct mntent *ent;
|
||||
|
||||
mef = setmntent (fstab_path, "r");
|
||||
mef = setmntent (_PATH_MNTTAB, "r");
|
||||
g_return_if_fail (mef);
|
||||
|
||||
while ((ent = getmntent (mef))) {
|
||||
|
@ -794,20 +832,65 @@ fm_desktop_find_mount_devices (FMDesktopIconView *icon_view, const char *fstab_p
|
|||
}
|
||||
#endif
|
||||
/* Add it to our list of mount points */
|
||||
add_mount_device (icon_view, ent);
|
||||
add_mount_device (monitor, ent);
|
||||
}
|
||||
|
||||
|
||||
endmntent (mef);
|
||||
|
||||
g_list_foreach (icon_view->details->devices, (GFunc) mount_device_set_state, icon_view);
|
||||
g_list_foreach (monitor->details->devices, (GFunc) mount_device_set_state, monitor);
|
||||
|
||||
/* Manually set state of all volumes to empty so we update */
|
||||
g_list_foreach (icon_view->details->devices, (GFunc) device_set_state_empty, icon_view);
|
||||
g_list_foreach (monitor->details->devices, (GFunc) device_set_state_empty, monitor);
|
||||
|
||||
/* Add a timer function to check for status change in mounted devices */
|
||||
icon_view->details->mount_device_timer_id =
|
||||
gtk_timeout_add (CHECK_INTERVAL, (GtkFunction) mount_devices_check_status, icon_view);
|
||||
monitor->details->mount_device_timer_id =
|
||||
gtk_timeout_add (CHECK_INTERVAL, (GtkFunction) mount_devices_check_status, monitor);
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
nautilus_volume_monitor_mount_unmount_removable (NautilusVolumeMonitor *monitor, const char *mount_point)
|
||||
{
|
||||
gboolean is_mounted, found_device;
|
||||
char *argv[3];
|
||||
GList *element;
|
||||
DeviceInfo *device;
|
||||
int exec_err;
|
||||
|
||||
is_mounted = FALSE;
|
||||
found_device = FALSE;
|
||||
device = NULL;
|
||||
|
||||
/* Locate DeviceInfo for mount point */
|
||||
for (element = monitor->details->devices; element != NULL; element = element->next) {
|
||||
device = element->data;
|
||||
if (strcmp (mount_point, device->mount_path) == 0) {
|
||||
found_device = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get mount state and then decide to mount/unmount the volume */
|
||||
if (found_device) {
|
||||
is_mounted = nautilus_volume_monitor_volume_is_mounted (mount_point);
|
||||
argv[1] = (char *)mount_point;
|
||||
argv[2] = NULL;
|
||||
|
||||
if (is_mounted) {
|
||||
/* Unount */
|
||||
argv[0] = "/bin/umount";
|
||||
exec_err = gnome_execute_async (g_get_home_dir(), 2, argv);
|
||||
is_mounted = FALSE;
|
||||
} else {
|
||||
/* Mount */
|
||||
argv[0] = "/bin/mount";
|
||||
exec_err = gnome_execute_async (g_get_home_dir(), 2, argv);
|
||||
is_mounted = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return is_mounted;
|
||||
}
|
||||
|
||||
|
||||
|
@ -827,16 +910,8 @@ remove_mount_link (DeviceInfo *device)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
fm_desktop_remove_mount_links (DeviceInfo *device, FMDesktopIconView *icon_view)
|
||||
{
|
||||
remove_mount_link (device);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
fm_desktop_free_device_info (DeviceInfo *device, FMDesktopIconView *icon_view)
|
||||
static void
|
||||
free_device_info (DeviceInfo *device, NautilusVolumeMonitor *monitor)
|
||||
{
|
||||
|
||||
if (device->device_fd != -1) {
|
||||
|
@ -900,39 +975,3 @@ get_floppy_volume_name (DeviceInfo *device)
|
|||
{
|
||||
device->volume_name = g_strdup ("Floppy");
|
||||
}
|
||||
|
||||
/* fm_dekstop_place_home_directory
|
||||
*
|
||||
* Add an icon representing the user's home directory on the desktop.
|
||||
* Create if necessary
|
||||
*/
|
||||
void
|
||||
fm_desktop_place_home_directory (FMDesktopIconView *icon_view)
|
||||
{
|
||||
char *desktop_path, *home_link_name, *home_link_path, *home_link_uri, *home_dir_uri;
|
||||
GnomeVFSResult result;
|
||||
GnomeVFSFileInfo info;
|
||||
|
||||
desktop_path = nautilus_get_desktop_directory ();
|
||||
home_link_name = g_strdup_printf ("%s's Home", g_get_user_name ());
|
||||
home_link_path = nautilus_make_path (desktop_path, home_link_name);
|
||||
home_link_uri = nautilus_get_uri_from_local_path (home_link_path);
|
||||
|
||||
result = gnome_vfs_get_file_info (home_link_uri, &info, 0);
|
||||
if (result != GNOME_VFS_OK) {
|
||||
/* FIXME: Maybe we should only create if the error was "not found". */
|
||||
/* There was no link file. Create it and add it to the desktop view */
|
||||
home_dir_uri = nautilus_get_uri_from_local_path (g_get_home_dir ());
|
||||
result = nautilus_link_create (desktop_path, home_link_name, "temp-home.png", home_dir_uri);
|
||||
g_free (home_dir_uri);
|
||||
if (result != GNOME_VFS_OK) {
|
||||
/* FIXME: Is a message to the console acceptable here? */
|
||||
MESSAGE ("Unable to create home link: %s", gnome_vfs_result_to_string (result));
|
||||
}
|
||||
}
|
||||
|
||||
g_free (home_link_uri);
|
||||
g_free (home_link_path);
|
||||
g_free (home_link_name);
|
||||
g_free (desktop_path);
|
||||
}
|
105
libnautilus-extensions/nautilus-volume-monitor.h
Normal file
105
libnautilus-extensions/nautilus-volume-monitor.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
|
||||
|
||||
/* nautilus-volume-monitor.h - interface for desktop mounting functions.
|
||||
|
||||
Copyright (C) 2000 Eazel, Inc.
|
||||
|
||||
The Gnome Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The Gnome Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the Gnome Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
Authors: Gene Z. Ragan <gzr@eazel.com>
|
||||
*/
|
||||
|
||||
#ifndef NAUTILUS_VOLUME_MONITOR_H
|
||||
#define NAUTILUS_VOLUME_MONITOR_H
|
||||
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include "nautilus-icon-container.h"
|
||||
|
||||
typedef struct NautilusVolumeMonitor NautilusVolumeMonitor;
|
||||
typedef struct NautilusVolumeMonitorClass NautilusVolumeMonitorClass;
|
||||
typedef struct NautilusVolumeMonitorDetails NautilusVolumeMonitorDetails;
|
||||
|
||||
#define NAUTILUS_TYPE_VOLUME_MONITOR (nautilus_volume_monitor_get_type())
|
||||
#define NAUTILUS_VOLUME_MONITOR(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_VOLUME_MONITOR, NautilusVolumeMonitor))
|
||||
#define NAUTILUS_VOLUME_MONITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_VOLUME_MONITOR, NautilusVolumeMonitorClass))
|
||||
#define IS_NAUTILUS_VOLUME_MONITOR(obj) (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_VOLUME_MONITOR))
|
||||
|
||||
struct NautilusVolumeMonitor {
|
||||
GtkObject parent;
|
||||
NautilusVolumeMonitorDetails *details;
|
||||
};
|
||||
|
||||
struct NautilusVolumeMonitorClass {
|
||||
GtkObjectClass parent_class;
|
||||
|
||||
/* Signals */
|
||||
char * (* volume_mounted) (NautilusVolumeMonitor *monitor);
|
||||
};
|
||||
|
||||
struct NautilusVolumeMonitorDetails
|
||||
{
|
||||
GHashTable *devices_by_fsname;
|
||||
GList *devices;
|
||||
guint mount_device_timer_id;
|
||||
};
|
||||
|
||||
|
||||
#define MOUNT_TYPE_ISO9660 "iso9660"
|
||||
#define MOUNT_TYPE_EXT2 "ext2"
|
||||
#define MOUNT_OPTIONS_USER "user"
|
||||
#define MOUNT_OPTIONS_OWNER "owner"
|
||||
|
||||
#define CHECK_INTERVAL 2000
|
||||
|
||||
typedef enum {
|
||||
STATE_ACTIVE = 0,
|
||||
STATE_INACTIVE,
|
||||
STATE_EMPTY,
|
||||
STATE_LAST,
|
||||
} DeviceState;
|
||||
|
||||
typedef enum {
|
||||
DEVICE_CDROM,
|
||||
DEVICE_FLOPPY,
|
||||
DEVICE_EXT2,
|
||||
DEVICE_OTHER
|
||||
} DeviceType;
|
||||
|
||||
typedef struct {
|
||||
DeviceType type;
|
||||
DeviceState state;
|
||||
int device_fd;
|
||||
|
||||
char *fsname;
|
||||
char *mount_path;
|
||||
char *mount_type;
|
||||
char *volume_name;
|
||||
char *link_uri;
|
||||
|
||||
gboolean is_mounted;
|
||||
gboolean did_mount;
|
||||
} DeviceInfo;
|
||||
|
||||
GtkType nautilus_volume_monitor_get_type (void);
|
||||
NautilusVolumeMonitor *nautilus_volume_monitor_get (void);
|
||||
GList *fm_desktop_get_removable_volume_list (void);
|
||||
gboolean nautilus_volume_monitor_volume_is_mounted (const char *mount_point);
|
||||
void nautilus_volume_monitor_find_mount_devices (NautilusVolumeMonitor *icon_view);
|
||||
gboolean nautilus_volume_monitor_mount_unmount_removable (NautilusVolumeMonitor *monitor,
|
||||
const char *mount_point);
|
||||
|
||||
#endif
|
|
@ -103,6 +103,7 @@ libnautilus_extensions_la_SOURCES = \
|
|||
nautilus-undo-signal-handlers.c \
|
||||
nautilus-user-level-manager.c \
|
||||
nautilus-view-identifier.c \
|
||||
nautilus-volume-monitor.c \
|
||||
nautilus-xml-extensions.c \
|
||||
$(NULL)
|
||||
|
||||
|
|
222
libnautilus-private/nautilus-cdrom-extensions.h
Normal file
222
libnautilus-private/nautilus-cdrom-extensions.h
Normal file
|
@ -0,0 +1,222 @@
|
|||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
|
||||
|
||||
/* fm-cdrom-extension.c - CDROM handliong constants copied from <linux/cdrom.h>.
|
||||
|
||||
Copyright (C) 2000 Eazel, Inc.
|
||||
|
||||
The Gnome Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The Gnome Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the Gnome Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
Authors: Gene Z. Ragan <gzr@eazel.com>
|
||||
*/
|
||||
|
||||
#ifndef FM_CDROM_EXTENSIONS_H
|
||||
#define FM_CDROM_EXTENSIONS_H
|
||||
|
||||
/*******************************************************
|
||||
* The CD-ROM IOCTL commands -- these should be supported by
|
||||
* all the various cdrom drivers. For the CD-ROM ioctls, we
|
||||
* will commandeer byte 0x53, or 'S'.
|
||||
*******************************************************/
|
||||
#define CDROMPAUSE 0x5301 /* Pause Audio Operation */
|
||||
#define CDROMRESUME 0x5302 /* Resume paused Audio Operation */
|
||||
#define CDROMPLAYMSF 0x5303 /* Play Audio MSF (struct cdrom_msf) */
|
||||
#define CDROMPLAYTRKIND 0x5304 /* Play Audio Track/index
|
||||
(struct cdrom_ti) */
|
||||
#define CDROMREADTOCHDR 0x5305 /* Read TOC header
|
||||
(struct cdrom_tochdr) */
|
||||
#define CDROMREADTOCENTRY 0x5306 /* Read TOC entry
|
||||
(struct cdrom_tocentry) */
|
||||
#define CDROMSTOP 0x5307 /* Stop the cdrom drive */
|
||||
#define CDROMSTART 0x5308 /* Start the cdrom drive */
|
||||
#define CDROMEJECT 0x5309 /* Ejects the cdrom media */
|
||||
#define CDROMVOLCTRL 0x530a /* Control output volume
|
||||
(struct cdrom_volctrl) */
|
||||
#define CDROMSUBCHNL 0x530b /* Read subchannel data
|
||||
(struct cdrom_subchnl) */
|
||||
#define CDROMREADMODE2 0x530c /* Read CDROM mode 2 data (2336 Bytes)
|
||||
(struct cdrom_read) */
|
||||
#define CDROMREADMODE1 0x530d /* Read CDROM mode 1 data (2048 Bytes)
|
||||
(struct cdrom_read) */
|
||||
#define CDROMREADAUDIO 0x530e /* (struct cdrom_read_audio) */
|
||||
#define CDROMEJECT_SW 0x530f /* enable(1)/disable(0) auto-ejecting */
|
||||
#define CDROMMULTISESSION 0x5310 /* Obtain the start-of-last-session
|
||||
address of multi session disks
|
||||
(struct cdrom_multisession) */
|
||||
#define CDROM_GET_MCN 0x5311 /* Obtain the "Universal Product Code"
|
||||
if available (struct cdrom_mcn) */
|
||||
#define CDROM_GET_UPC CDROM_GET_MCN /* This one is depricated,
|
||||
but here anyway for compatability */
|
||||
#define CDROMRESET 0x5312 /* hard-reset the drive */
|
||||
#define CDROMVOLREAD 0x5313 /* Get the drive's volume setting
|
||||
(struct cdrom_volctrl) */
|
||||
#define CDROMREADRAW 0x5314 /* read data in raw mode (2352 Bytes)
|
||||
(struct cdrom_read) */
|
||||
/*
|
||||
* These ioctls are used only used in aztcd.c and optcd.c
|
||||
*/
|
||||
#define CDROMREADCOOKED 0x5315 /* read data in cooked mode */
|
||||
#define CDROMSEEK 0x5316 /* seek msf address */
|
||||
|
||||
/*
|
||||
* This ioctl is only used by the scsi-cd driver.
|
||||
It is for playing audio in logical block addressing mode.
|
||||
*/
|
||||
#define CDROMPLAYBLK 0x5317 /* (struct cdrom_blk) */
|
||||
|
||||
/*
|
||||
* These ioctls are only used in optcd.c
|
||||
*/
|
||||
#define CDROMREADALL 0x5318 /* read all 2646 bytes */
|
||||
|
||||
/*
|
||||
* These ioctls are (now) only in ide-cd.c for controlling
|
||||
* drive spindown time. They should be implemented in the
|
||||
* Uniform driver, via generic packet commands, GPCMD_MODE_SELECT_10,
|
||||
* GPCMD_MODE_SENSE_10 and the GPMODE_POWER_PAGE...
|
||||
* -Erik
|
||||
*/
|
||||
#define CDROMGETSPINDOWN 0x531d
|
||||
#define CDROMSETSPINDOWN 0x531e
|
||||
|
||||
/*
|
||||
* These ioctls are implemented through the uniform CD-ROM driver
|
||||
* They _will_ be adopted by all CD-ROM drivers, when all the CD-ROM
|
||||
* drivers are eventually ported to the uniform CD-ROM driver interface.
|
||||
*/
|
||||
#define CDROMCLOSETRAY 0x5319 /* pendant of CDROMEJECT */
|
||||
#define CDROM_SET_OPTIONS 0x5320 /* Set behavior options */
|
||||
#define CDROM_CLEAR_OPTIONS 0x5321 /* Clear behavior options */
|
||||
#define CDROM_SELECT_SPEED 0x5322 /* Set the CD-ROM speed */
|
||||
#define CDROM_SELECT_DISC 0x5323 /* Select disc (for juke-boxes) */
|
||||
#define CDROM_MEDIA_CHANGED 0x5325 /* Check is media changed */
|
||||
#define CDROM_DRIVE_STATUS 0x5326 /* Get tray position, etc. */
|
||||
#define CDROM_DISC_STATUS 0x5327 /* Get disc type, etc. */
|
||||
#define CDROM_CHANGER_NSLOTS 0x5328 /* Get number of slots */
|
||||
#define CDROM_LOCKDOOR 0x5329 /* lock or unlock door */
|
||||
#define CDROM_DEBUG 0x5330 /* Turn debug messages on/off */
|
||||
#define CDROM_GET_CAPABILITY 0x5331 /* get capabilities */
|
||||
|
||||
/* This ioctl is only used by sbpcd at the moment */
|
||||
#define CDROMAUDIOBUFSIZ 0x5382 /* set the audio buffer size */
|
||||
|
||||
/* DVD-ROM Specific ioctls */
|
||||
#define DVD_READ_STRUCT 0x5390 /* Read structure */
|
||||
#define DVD_WRITE_STRUCT 0x5391 /* Write structure */
|
||||
#define DVD_AUTH 0x5392 /* Authentication */
|
||||
|
||||
#define CDROM_SEND_PACKET 0x5393 /* send a packet to the drive */
|
||||
#define CDROM_NEXT_WRITABLE 0x5394 /* get next writable block */
|
||||
#define CDROM_LAST_WRITTEN 0x5395 /* get last block written on disc */
|
||||
|
||||
/* Some generally useful CD-ROM information -- mostly based on the above */
|
||||
#define CD_MINS 74 /* max. minutes per CD, not really a limit */
|
||||
#define CD_SECS 60 /* seconds per minute */
|
||||
#define CD_FRAMES 75 /* frames per second */
|
||||
#define CD_SYNC_SIZE 12 /* 12 sync bytes per raw data frame */
|
||||
#define CD_MSF_OFFSET 150 /* MSF numbering offset of first frame */
|
||||
#define CD_CHUNK_SIZE 24 /* lowest-level "data bytes piece" */
|
||||
#define CD_NUM_OF_CHUNKS 98 /* chunks per frame */
|
||||
#define CD_FRAMESIZE_SUB 96 /* subchannel data "frame" size */
|
||||
#define CD_HEAD_SIZE 4 /* header (address) bytes per raw data frame */
|
||||
#define CD_SUBHEAD_SIZE 8 /* subheader bytes per raw XA data frame */
|
||||
#define CD_EDC_SIZE 4 /* bytes EDC per most raw data frame types */
|
||||
#define CD_ZERO_SIZE 8 /* bytes zero per yellow book mode 1 frame */
|
||||
#define CD_ECC_SIZE 276 /* bytes ECC per most raw data frame types */
|
||||
#define CD_FRAMESIZE 2048 /* bytes per frame, "cooked" mode */
|
||||
#define CD_FRAMESIZE_RAW 2352 /* bytes per frame, "raw" mode */
|
||||
#define CD_FRAMESIZE_RAWER 2646 /* The maximum possible returned bytes */
|
||||
/* most drives don't deliver everything: */
|
||||
#define CD_FRAMESIZE_RAW1 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE) /*2340*/
|
||||
#define CD_FRAMESIZE_RAW0 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE-CD_HEAD_SIZE) /*2336*/
|
||||
|
||||
#define CD_XA_HEAD (CD_HEAD_SIZE+CD_SUBHEAD_SIZE) /* "before data" part of raw XA frame */
|
||||
#define CD_XA_TAIL (CD_EDC_SIZE+CD_ECC_SIZE) /* "after data" part of raw XA frame */
|
||||
#define CD_XA_SYNC_HEAD (CD_SYNC_SIZE+CD_XA_HEAD) /* sync bytes + header of XA frame */
|
||||
|
||||
/* CD-ROM address types (cdrom_tocentry.cdte_format) */
|
||||
#define CDROM_LBA 0x01 /* "logical block": first frame is #0 */
|
||||
#define CDROM_MSF 0x02 /* "minute-second-frame": binary, not bcd here! */
|
||||
|
||||
/* bit to tell whether track is data or audio (cdrom_tocentry.cdte_ctrl) */
|
||||
#define CDROM_DATA_TRACK 0x04
|
||||
|
||||
/* The leadout track is always 0xAA, regardless of # of tracks on disc */
|
||||
#define CDROM_LEADOUT 0xAA
|
||||
|
||||
/* audio states (from SCSI-2, but seen with other drives, too) */
|
||||
#define CDROM_AUDIO_INVALID 0x00 /* audio status not supported */
|
||||
#define CDROM_AUDIO_PLAY 0x11 /* audio play operation in progress */
|
||||
#define CDROM_AUDIO_PAUSED 0x12 /* audio play operation paused */
|
||||
#define CDROM_AUDIO_COMPLETED 0x13 /* audio play successfully completed */
|
||||
#define CDROM_AUDIO_ERROR 0x14 /* audio play stopped due to error */
|
||||
#define CDROM_AUDIO_NO_STATUS 0x15 /* no current audio status to return */
|
||||
|
||||
/* capability flags used with the uniform CD-ROM driver */
|
||||
#define CDC_CLOSE_TRAY 0x1 /* caddy systems _can't_ close */
|
||||
#define CDC_OPEN_TRAY 0x2 /* but _can_ eject. */
|
||||
#define CDC_LOCK 0x4 /* disable manual eject */
|
||||
#define CDC_SELECT_SPEED 0x8 /* programmable speed */
|
||||
#define CDC_SELECT_DISC 0x10 /* select disc from juke-box */
|
||||
#define CDC_MULTI_SESSION 0x20 /* read sessions>1 */
|
||||
#define CDC_MCN 0x40 /* Medium Catalog Number */
|
||||
#define CDC_MEDIA_CHANGED 0x80 /* media changed */
|
||||
#define CDC_PLAY_AUDIO 0x100 /* audio functions */
|
||||
#define CDC_RESET 0x200 /* hard reset device */
|
||||
#define CDC_IOCTLS 0x400 /* driver has non-standard ioctls */
|
||||
#define CDC_DRIVE_STATUS 0x800 /* driver implements drive status */
|
||||
#define CDC_GENERIC_PACKET 0x1000 /* driver implements generic packets */
|
||||
#define CDC_CD_R 0x2000 /* drive is a CD-R */
|
||||
#define CDC_CD_RW 0x4000 /* drive is a CD-RW */
|
||||
#define CDC_DVD 0x8000 /* drive is a DVD */
|
||||
#define CDC_DVD_R 0x10000 /* drive can write DVD-R */
|
||||
#define CDC_DVD_RAM 0x20000 /* drive can write DVD-RAM */
|
||||
|
||||
/* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */
|
||||
#define CDS_NO_INFO 0 /* if not implemented */
|
||||
#define CDS_NO_DISC 1
|
||||
#define CDS_TRAY_OPEN 2
|
||||
#define CDS_DRIVE_NOT_READY 3
|
||||
#define CDS_DISC_OK 4
|
||||
|
||||
/* return values for the CDROM_DISC_STATUS ioctl */
|
||||
/* can also return CDS_NO_[INFO|DISC], from above */
|
||||
#define CDS_AUDIO 100
|
||||
#define CDS_DATA_1 101
|
||||
#define CDS_DATA_2 102
|
||||
#define CDS_XA_2_1 103
|
||||
#define CDS_XA_2_2 104
|
||||
#define CDS_MIXED 105
|
||||
|
||||
/* User-configurable behavior options for the uniform CD-ROM driver */
|
||||
#define CDO_AUTO_CLOSE 0x1 /* close tray on first open() */
|
||||
#define CDO_AUTO_EJECT 0x2 /* open tray on last release() */
|
||||
#define CDO_USE_FFLAGS 0x4 /* use O_NONBLOCK information on open */
|
||||
#define CDO_LOCK 0x8 /* lock tray on open files */
|
||||
#define CDO_CHECK_TYPE 0x10 /* check type on open for data */
|
||||
|
||||
/* Special codes used when specifying changer slots. */
|
||||
#define CDSL_NONE ((int) (~0U>>1)-1)
|
||||
#define CDSL_CURRENT ((int) (~0U>>1))
|
||||
|
||||
/* For partition based multisession access. IDE can handle 64 partitions
|
||||
* per drive - SCSI CD-ROM's use minors to differentiate between the
|
||||
* various drives, so we can't do multisessions the same way there.
|
||||
* Use the -o session=x option to mount on them.
|
||||
*/
|
||||
#define CD_PART_MAX 64
|
||||
#define CD_PART_MASK (CD_PART_MAX - 1)
|
||||
|
||||
#endif /* FM_CDROM_EXTENSIONS_H */
|
106
libnautilus-private/nautilus-iso9660.h
Normal file
106
libnautilus-private/nautilus-iso9660.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Header file iso9660.h - assorted structure definitions and typecasts.
|
||||
* specific to iso9660 filesystem.
|
||||
|
||||
Written by Eric Youngdale (1993).
|
||||
|
||||
Copyright 1993 Yggdrasil Computing, Incorporated
|
||||
|
||||
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifndef _ISOFS_FS_H
|
||||
#define _ISOFS_FS_H
|
||||
|
||||
/*
|
||||
* The isofs filesystem constants/structures
|
||||
*/
|
||||
|
||||
#define ISODCL(from, to) (to - from + 1)
|
||||
|
||||
struct iso_volume_descriptor {
|
||||
char type[ISODCL(1,1)]; /* 711 */
|
||||
char id[ISODCL(2,6)];
|
||||
char version[ISODCL(7,7)];
|
||||
char data[ISODCL(8,2048)];
|
||||
};
|
||||
|
||||
/* volume descriptor types */
|
||||
#define ISO_VD_PRIMARY 1
|
||||
#define ISO_VD_END 255
|
||||
|
||||
#define ISO_STANDARD_ID "CD001"
|
||||
|
||||
struct iso_primary_descriptor {
|
||||
char type [ISODCL ( 1, 1)]; /* 711 */
|
||||
char id [ISODCL ( 2, 6)];
|
||||
char version [ISODCL ( 7, 7)]; /* 711 */
|
||||
char unused1 [ISODCL ( 8, 8)];
|
||||
char system_id [ISODCL ( 9, 40)]; /* achars */
|
||||
char volume_id [ISODCL ( 41, 72)]; /* dchars */
|
||||
char unused2 [ISODCL ( 73, 80)];
|
||||
char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
|
||||
char unused3 [ISODCL ( 89, 120)];
|
||||
char volume_set_size [ISODCL (121, 124)]; /* 723 */
|
||||
char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
|
||||
char logical_block_size [ISODCL (129, 132)]; /* 723 */
|
||||
char path_table_size [ISODCL (133, 140)]; /* 733 */
|
||||
char type_l_path_table [ISODCL (141, 144)]; /* 731 */
|
||||
char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
|
||||
char type_m_path_table [ISODCL (149, 152)]; /* 732 */
|
||||
char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
|
||||
char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
|
||||
char volume_set_id [ISODCL (191, 318)]; /* dchars */
|
||||
char publisher_id [ISODCL (319, 446)]; /* achars */
|
||||
char preparer_id [ISODCL (447, 574)]; /* achars */
|
||||
char application_id [ISODCL (575, 702)]; /* achars */
|
||||
char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
|
||||
char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
|
||||
char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
|
||||
char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
|
||||
char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
|
||||
char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
|
||||
char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
|
||||
char file_structure_version [ISODCL (882, 882)]; /* 711 */
|
||||
char unused4 [ISODCL (883, 883)];
|
||||
char application_data [ISODCL (884, 1395)];
|
||||
char unused5 [ISODCL (1396, 2048)];
|
||||
};
|
||||
|
||||
/* We use this to help us look up the parent inode numbers. */
|
||||
|
||||
struct iso_path_table{
|
||||
unsigned char name_len[2]; /* 721 */
|
||||
char extent[4]; /* 731 */
|
||||
char parent[2]; /* 721 */
|
||||
char name[1];
|
||||
};
|
||||
|
||||
struct iso_directory_record {
|
||||
unsigned char length [ISODCL (1, 1)]; /* 711 */
|
||||
char ext_attr_length [ISODCL (2, 2)]; /* 711 */
|
||||
char extent [ISODCL (3, 10)]; /* 733 */
|
||||
char size [ISODCL (11, 18)]; /* 733 */
|
||||
char date [ISODCL (19, 25)]; /* 7 by 711 */
|
||||
char flags [ISODCL (26, 26)];
|
||||
char file_unit_size [ISODCL (27, 27)]; /* 711 */
|
||||
char interleave [ISODCL (28, 28)]; /* 711 */
|
||||
char volume_sequence_number [ISODCL (29, 32)]; /* 723 */
|
||||
unsigned char name_len [ISODCL (33, 33)]; /* 711 */
|
||||
char name [34]; /* Not really, but we need something here */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
977
libnautilus-private/nautilus-volume-monitor.c
Normal file
977
libnautilus-private/nautilus-volume-monitor.c
Normal file
|
@ -0,0 +1,977 @@
|
|||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
|
||||
|
||||
/* nautilus-volume-monitor.c - Desktop volume mounting routines.
|
||||
|
||||
Copyright (C) 2000 Eazel, Inc.
|
||||
|
||||
The Gnome Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The Gnome Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the Gnome Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
Authors: Gene Z. Ragan <gzr@eazel.com>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <fstab.h>
|
||||
#include <glib.h>
|
||||
#include <gnome.h>
|
||||
#include <libgnome/gnome-i18n.h>
|
||||
#include <libgnomevfs/gnome-vfs.h>
|
||||
#include <mntent.h>
|
||||
#include <libnautilus-extensions/nautilus-cdrom-extensions.h>
|
||||
#include <libnautilus-extensions/nautilus-directory-private.h>
|
||||
#include <libnautilus-extensions/nautilus-file-utilities.h>
|
||||
#include <libnautilus-extensions/nautilus-gtk-extensions.h>
|
||||
#include <libnautilus-extensions/nautilus-gtk-macros.h>
|
||||
#include <libnautilus-extensions/nautilus-iso9660.h>
|
||||
#include <libnautilus-extensions/nautilus-link.h>
|
||||
#include <libnautilus-extensions/nautilus-volume-monitor.h>
|
||||
|
||||
#include <parser.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <xmlmemory.h>
|
||||
|
||||
|
||||
/* FIXME: Remove messages when this code is done. */
|
||||
#define MESSAGE g_message
|
||||
|
||||
NautilusVolumeMonitor *global_volume_monitor = NULL;
|
||||
|
||||
const char * const state_names[] = {
|
||||
"ACTIVE",
|
||||
"INACTIVE",
|
||||
"EMPTY"
|
||||
};
|
||||
|
||||
const char * const type_names[] = {
|
||||
"CDROM",
|
||||
"FLOPPY",
|
||||
"LOCAL_DISK",
|
||||
"OTHER"
|
||||
};
|
||||
|
||||
/* The NautilusVolumeMonitor signals. */
|
||||
enum {
|
||||
VOLUME_MOUNTED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
static guint signals[LAST_SIGNAL];
|
||||
|
||||
static void nautilus_volume_monitor_initialize (NautilusVolumeMonitor *desktop_mounter);
|
||||
static void nautilus_volume_monitor_initialize_class (NautilusVolumeMonitorClass *klass);
|
||||
static void nautilus_volume_monitor_destroy (GtkObject *object);
|
||||
static void remove_mount_link (DeviceInfo *device);
|
||||
static void get_iso9660_volume_name (DeviceInfo *device);
|
||||
static void get_ext2_volume_name (DeviceInfo *device);
|
||||
static void get_floppy_volume_name (DeviceInfo *device);
|
||||
static void mount_device_mount (NautilusVolumeMonitor *view,
|
||||
DeviceInfo *device);
|
||||
static gboolean mount_device_is_mounted (DeviceInfo *device);
|
||||
static void mount_device_activate (NautilusVolumeMonitor *view,
|
||||
DeviceInfo *device);
|
||||
static void mount_device_deactivate (NautilusVolumeMonitor *monitor,
|
||||
DeviceInfo *device);
|
||||
static void mount_device_activate_floppy (NautilusVolumeMonitor *view,
|
||||
DeviceInfo *device);
|
||||
static gboolean mntent_is_removable_fs (struct mntent *ent);
|
||||
static void free_device_info (DeviceInfo *device,
|
||||
NautilusVolumeMonitor *monitor);
|
||||
|
||||
|
||||
NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusVolumeMonitor, nautilus_volume_monitor, GTK_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
nautilus_volume_monitor_initialize (NautilusVolumeMonitor *monitor)
|
||||
{
|
||||
/* Set up details */
|
||||
monitor->details = g_new0 (NautilusVolumeMonitorDetails, 1);
|
||||
monitor->details->devices_by_fsname = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
monitor->details->devices = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_volume_monitor_initialize_class (NautilusVolumeMonitorClass *klass)
|
||||
{
|
||||
GtkObjectClass *object_class;
|
||||
|
||||
object_class = GTK_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->destroy = nautilus_volume_monitor_destroy;
|
||||
|
||||
signals[VOLUME_MOUNTED]
|
||||
= gtk_signal_new ("volume_mounted",
|
||||
GTK_RUN_LAST,
|
||||
object_class->type,
|
||||
GTK_SIGNAL_OFFSET (NautilusVolumeMonitorClass,
|
||||
volume_mounted),
|
||||
nautilus_gtk_marshal_STRING__NONE,
|
||||
GTK_TYPE_STRING, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
nautilus_volume_monitor_destroy (GtkObject *object)
|
||||
{
|
||||
NautilusVolumeMonitor *monitor;
|
||||
|
||||
monitor = NAUTILUS_VOLUME_MONITOR (object);
|
||||
|
||||
/* Remove timer function */
|
||||
gtk_timeout_remove (monitor->details->mount_device_timer_id);
|
||||
|
||||
/* Clean up other device info */
|
||||
g_list_foreach (monitor->details->devices, (GFunc)free_device_info, monitor);
|
||||
|
||||
/* Remove timer function */
|
||||
gtk_timeout_remove (monitor->details->mount_device_timer_id);
|
||||
|
||||
/* Clean up details */
|
||||
g_hash_table_destroy (monitor->details->devices_by_fsname);
|
||||
g_list_free (monitor->details->devices);
|
||||
g_free (monitor->details);
|
||||
|
||||
NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object));
|
||||
}
|
||||
|
||||
/* Return the global instance of the NautilusVolumeMonitor. Create one
|
||||
* if we have not done so already
|
||||
*/
|
||||
NautilusVolumeMonitor *
|
||||
nautilus_volume_monitor_get (void)
|
||||
{
|
||||
if (global_volume_monitor == NULL) {
|
||||
global_volume_monitor = NAUTILUS_VOLUME_MONITOR
|
||||
(gtk_object_new (nautilus_volume_monitor_get_type(),
|
||||
NULL));
|
||||
}
|
||||
|
||||
return global_volume_monitor;
|
||||
}
|
||||
|
||||
static int
|
||||
floppy_sort (const char *name_1, const char *name_2)
|
||||
{
|
||||
/* If both are floppies, we don't care yet */
|
||||
if ((strncmp (name_1, "/mnt/fd", strlen("/mnt/fd")) == 0) &&
|
||||
(strncmp (name_2, "/mnt/fd", strlen("/mnt/fd")) == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strncmp (name_1, "/mnt/fd", strlen("/mnt/fd")) != 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
GList *
|
||||
fm_desktop_get_removable_volume_list (void)
|
||||
{
|
||||
GList *list;
|
||||
FILE *mef;
|
||||
struct mntent *ent;
|
||||
|
||||
list = NULL;
|
||||
|
||||
mef = setmntent (_PATH_FSTAB, "r");
|
||||
g_return_val_if_fail (mef, NULL);
|
||||
|
||||
while ((ent = getmntent (mef))) {
|
||||
if (mntent_is_removable_fs (ent)) {
|
||||
list = g_list_append (list, g_strdup (ent->mnt_dir));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
endmntent (mef);
|
||||
|
||||
/* Move all floppy mounts to top of list */
|
||||
list = g_list_sort (list, (GCompareFunc) floppy_sort);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nautilus_volume_monitor_volume_is_mounted (const char *mount_point)
|
||||
{
|
||||
FILE *fh;
|
||||
char line[PATH_MAX * 3];
|
||||
char mntpoint[PATH_MAX], devname[PATH_MAX];
|
||||
|
||||
/* Open mtab */
|
||||
fh = fopen (_PATH_MOUNTED, "r");
|
||||
if (!fh) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
while (fgets (line, sizeof(line), fh)) {
|
||||
sscanf(line, "%s %s", devname, mntpoint);
|
||||
if (strcmp (mntpoint, mount_point) == 0) {
|
||||
fclose (fh);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
fclose (fh);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
mount_device_is_mounted (DeviceInfo *device)
|
||||
{
|
||||
return device->is_mounted;
|
||||
}
|
||||
|
||||
static void
|
||||
mount_device_cdrom_set_state (NautilusVolumeMonitor *monitor, DeviceInfo *device)
|
||||
{
|
||||
if (device->device_fd < 0) {
|
||||
device->device_fd = open (device->fsname, O_RDONLY|O_NONBLOCK);
|
||||
}
|
||||
|
||||
if (ioctl (device->device_fd, CDROM_DRIVE_STATUS, CDSL_CURRENT) == CDS_DISC_OK) {
|
||||
int disctype;
|
||||
|
||||
disctype = ioctl (device->device_fd, CDROM_DISC_STATUS, CDSL_CURRENT);
|
||||
switch (disctype) {
|
||||
case CDS_AUDIO:
|
||||
/* It's pretty hard to know whether it is actually in use */
|
||||
device->state = STATE_INACTIVE;
|
||||
break;
|
||||
|
||||
case CDS_DATA_1:
|
||||
case CDS_DATA_2:
|
||||
case CDS_XA_2_1:
|
||||
case CDS_XA_2_2:
|
||||
case CDS_MIXED:
|
||||
/* Check if it is mounted */
|
||||
if (mount_device_is_mounted (device)) {
|
||||
device->state = STATE_ACTIVE;
|
||||
} else {
|
||||
device->state = STATE_EMPTY;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
device->state = STATE_EMPTY;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
device->state = STATE_EMPTY;
|
||||
}
|
||||
|
||||
if(device->device_fd >= 0) {
|
||||
close (device->device_fd);
|
||||
device->device_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mount_device_floppy_set_state (NautilusVolumeMonitor *monitor, DeviceInfo *device)
|
||||
{
|
||||
/* If the floppy is not in mtab, then we set it to empty */
|
||||
if (nautilus_volume_monitor_volume_is_mounted (device->mount_path)) {
|
||||
device->state = STATE_ACTIVE;
|
||||
} else {
|
||||
device->state = STATE_EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mount_device_ext2_set_state (NautilusVolumeMonitor *monitor, DeviceInfo *device)
|
||||
{
|
||||
device->state = STATE_ACTIVE;
|
||||
}
|
||||
|
||||
static void
|
||||
mount_device_set_state (DeviceInfo *device, NautilusVolumeMonitor *monitor)
|
||||
{
|
||||
switch (device->type) {
|
||||
case DEVICE_CDROM:
|
||||
mount_device_cdrom_set_state (monitor, device);
|
||||
break;
|
||||
|
||||
case DEVICE_FLOPPY:
|
||||
mount_device_floppy_set_state (monitor, device);
|
||||
break;
|
||||
|
||||
case DEVICE_EXT2:
|
||||
mount_device_ext2_set_state (monitor, device);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
device_set_state_empty (DeviceInfo *device, NautilusVolumeMonitor *monitor)
|
||||
{
|
||||
device->state = STATE_EMPTY;
|
||||
}
|
||||
|
||||
static void
|
||||
mount_device_mount (NautilusVolumeMonitor *view, DeviceInfo *device)
|
||||
{
|
||||
char *target_uri, *desktop_path;
|
||||
const char *icon_name;
|
||||
gboolean result;
|
||||
int index;
|
||||
|
||||
desktop_path = nautilus_get_desktop_directory ();
|
||||
target_uri = nautilus_get_uri_from_local_path (device->mount_path);
|
||||
|
||||
/* Make volume name link "nice" */
|
||||
|
||||
/* Strip whitespace from the end of the name. */
|
||||
for (index = strlen (device->volume_name) - 1; index > 0; index--) {
|
||||
if (device->volume_name [index] != ' ') {
|
||||
break;
|
||||
}
|
||||
device->volume_name [index] = '\0';
|
||||
}
|
||||
|
||||
/* The volume name may have '/' characters. We need to convert
|
||||
* them to something legal.
|
||||
*/
|
||||
for (index = 0; ; index++) {
|
||||
if (device->volume_name [index] == '\0') {
|
||||
break;
|
||||
}
|
||||
if (device->volume_name [index] == '/') {
|
||||
device->volume_name [index] = '-';
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up old link, This should have been done earlier, but
|
||||
* we double check to be sure.
|
||||
*/
|
||||
remove_mount_link (device);
|
||||
|
||||
/* Get icon type */
|
||||
if (strcmp (device->mount_type, "cdrom") == 0) {
|
||||
icon_name = "i-cdrom.png";
|
||||
} else if (strcmp (device->mount_type, "floppy") == 0) {
|
||||
icon_name = "i-floppy.png";
|
||||
} else {
|
||||
icon_name = "i-blockdev.png";
|
||||
}
|
||||
|
||||
/* Create link */
|
||||
result = nautilus_link_create (desktop_path, device->volume_name, icon_name, target_uri);
|
||||
if (result) {
|
||||
device->link_uri = nautilus_make_path (desktop_path, device->volume_name);
|
||||
} else {
|
||||
MESSAGE ("Unable to create mount link");
|
||||
}
|
||||
|
||||
g_free (desktop_path);
|
||||
g_free (target_uri);
|
||||
|
||||
device->did_mount = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
mount_device_activate_cdrom (NautilusVolumeMonitor *monitor, DeviceInfo *device)
|
||||
{
|
||||
int disctype;
|
||||
|
||||
if (device->device_fd < 0) {
|
||||
device->device_fd = open (device->fsname, O_RDONLY|O_NONBLOCK);
|
||||
}
|
||||
|
||||
disctype = ioctl (device->device_fd, CDROM_DISC_STATUS, CDSL_CURRENT);
|
||||
switch (disctype) {
|
||||
case CDS_AUDIO:
|
||||
/* Should we run a CD player here? */
|
||||
break;
|
||||
|
||||
case CDS_DATA_1:
|
||||
case CDS_DATA_2:
|
||||
case CDS_XA_2_1:
|
||||
case CDS_XA_2_2:
|
||||
case CDS_MIXED:
|
||||
/* Get volume name */
|
||||
get_iso9660_volume_name (device);
|
||||
mount_device_mount (monitor, device);
|
||||
break;
|
||||
|
||||
default:
|
||||
MESSAGE ("Unknown CDROM type");
|
||||
break;
|
||||
}
|
||||
|
||||
if (device->device_fd >= 0) {
|
||||
close (device->device_fd);
|
||||
device->device_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mount_device_activate_floppy (NautilusVolumeMonitor *view, DeviceInfo *device)
|
||||
{
|
||||
/* Get volume name */
|
||||
get_floppy_volume_name (device);
|
||||
|
||||
mount_device_mount (view, device);
|
||||
}
|
||||
|
||||
static void
|
||||
mount_device_activate_ext2 (NautilusVolumeMonitor *view, DeviceInfo *device)
|
||||
{
|
||||
/* Get volume name */
|
||||
get_ext2_volume_name (device);
|
||||
|
||||
mount_device_mount (view, device);
|
||||
}
|
||||
|
||||
typedef void (* ChangeDeviceInfoFunction) (NautilusVolumeMonitor *view, DeviceInfo *device);
|
||||
|
||||
static void
|
||||
mount_device_activate (NautilusVolumeMonitor *monitor, DeviceInfo *device)
|
||||
{
|
||||
switch (device->type) {
|
||||
case DEVICE_CDROM:
|
||||
mount_device_activate_cdrom (monitor, device);
|
||||
break;
|
||||
|
||||
case DEVICE_FLOPPY:
|
||||
mount_device_activate_floppy (monitor, device);
|
||||
break;
|
||||
|
||||
case DEVICE_EXT2:
|
||||
mount_device_activate_ext2 (monitor, device);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
gtk_signal_emit (GTK_OBJECT (monitor),
|
||||
signals[VOLUME_MOUNTED],
|
||||
&device->mount_path);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
eject_cdrom (DeviceInfo *device)
|
||||
{
|
||||
#if 0
|
||||
if (device->device_fd < 0) {
|
||||
device->device_fd = open (device->fsname, O_RDONLY|O_NONBLOCK);
|
||||
}
|
||||
|
||||
if(device->device_fd < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_message ("Trying to eject");
|
||||
ioctl (device->device_fd, CDROMEJECT, 0);
|
||||
|
||||
close (device->device_fd);
|
||||
device->device_fd = -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
mount_device_deactivate (NautilusVolumeMonitor *monitor, DeviceInfo *device)
|
||||
{
|
||||
GList dummy_list;
|
||||
|
||||
/* Remove mounted device icon from desktop */
|
||||
dummy_list.data = device->link_uri;
|
||||
dummy_list.next = NULL;
|
||||
dummy_list.prev = NULL;
|
||||
nautilus_directory_notify_files_removed (&dummy_list);
|
||||
|
||||
/* Clean up old link */
|
||||
remove_mount_link (device);
|
||||
|
||||
switch (device->type) {
|
||||
case DEVICE_CDROM:
|
||||
eject_cdrom (device);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mount_device_do_nothing (NautilusVolumeMonitor *monitor, DeviceInfo *device)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
mount_device_check_change (gpointer data, gpointer callback_data)
|
||||
{
|
||||
/* What functions to run for particular state transitions */
|
||||
static const ChangeDeviceInfoFunction state_transitions[STATE_LAST][STATE_LAST] = {
|
||||
/************ from: ACTIVE INACTIVE EMPTY */
|
||||
/* to */
|
||||
/* ACTIVE */ { mount_device_do_nothing, mount_device_activate, mount_device_activate },
|
||||
/* INACTIVE */ { mount_device_deactivate, mount_device_do_nothing, mount_device_do_nothing },
|
||||
/* EMPTY */ { mount_device_deactivate, mount_device_deactivate, mount_device_do_nothing }
|
||||
};
|
||||
|
||||
DeviceInfo *device;
|
||||
NautilusVolumeMonitor *monitor;
|
||||
DeviceState old_state;
|
||||
ChangeDeviceInfoFunction f;
|
||||
|
||||
g_assert (data != NULL);
|
||||
|
||||
device = data;
|
||||
monitor = NAUTILUS_VOLUME_MONITOR (callback_data);
|
||||
|
||||
old_state = device->state;
|
||||
|
||||
mount_device_set_state (device, monitor);
|
||||
|
||||
if (old_state != device->state) {
|
||||
f = state_transitions[device->state][old_state];
|
||||
|
||||
MESSAGE ("State on %s changed from %s to %s, running %p",
|
||||
device->fsname, state_names[old_state], state_names[device->state], f);
|
||||
|
||||
(* f) (monitor, device);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mount_devices_update_is_mounted (NautilusVolumeMonitor *monitor)
|
||||
{
|
||||
FILE *fh;
|
||||
char line[PATH_MAX * 3], mntpoint[PATH_MAX], devname[PATH_MAX];
|
||||
GList *element;
|
||||
DeviceInfo *device;
|
||||
|
||||
/* Toggle mount state to off and then recheck in mtab. */
|
||||
for (element = monitor->details->devices; element != NULL; element = element->next) {
|
||||
device = element->data;
|
||||
device->is_mounted = FALSE;
|
||||
}
|
||||
|
||||
/* Open mtab */
|
||||
fh = fopen (_PATH_MOUNTED, "r");
|
||||
if (!fh) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (fgets (line, sizeof(line), fh)) {
|
||||
sscanf(line, "%s %s", devname, mntpoint);
|
||||
device = g_hash_table_lookup (monitor->details->devices_by_fsname, devname);
|
||||
|
||||
if(device) {
|
||||
device->is_mounted = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
fclose (fh);
|
||||
}
|
||||
|
||||
static gint
|
||||
mount_devices_check_status (NautilusVolumeMonitor *monitor)
|
||||
{
|
||||
mount_devices_update_is_mounted (monitor);
|
||||
|
||||
g_list_foreach (monitor->details->devices,
|
||||
mount_device_check_change,
|
||||
monitor);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Like access, but a bit more accurate - access will let
|
||||
* root do anything. Does not get read-only or no-exec
|
||||
* filesystems right.
|
||||
*/
|
||||
static gboolean
|
||||
check_permissions (gchar *filename, int mode)
|
||||
{
|
||||
int euid = geteuid();
|
||||
int egid = getegid();
|
||||
|
||||
struct stat statbuf;
|
||||
|
||||
if (stat (filename, &statbuf) == 0) {
|
||||
if ((mode & R_OK) &&
|
||||
!((statbuf.st_mode & S_IROTH) ||
|
||||
((statbuf.st_mode & S_IRUSR) && euid == statbuf.st_uid) ||
|
||||
((statbuf.st_mode & S_IRGRP) && egid == statbuf.st_gid)))
|
||||
return FALSE;
|
||||
if ((mode & W_OK) &&
|
||||
!((statbuf.st_mode & S_IWOTH) ||
|
||||
((statbuf.st_mode & S_IWUSR) && euid == statbuf.st_uid) ||
|
||||
((statbuf.st_mode & S_IWGRP) && egid == statbuf.st_gid)))
|
||||
return FALSE;
|
||||
if ((mode & X_OK) &&
|
||||
!((statbuf.st_mode & S_IXOTH) ||
|
||||
((statbuf.st_mode & S_IXUSR) && euid == statbuf.st_uid) ||
|
||||
((statbuf.st_mode & S_IXGRP) && egid == statbuf.st_gid)))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
mount_device_floppy_add (NautilusVolumeMonitor *monitor, DeviceInfo *device)
|
||||
{
|
||||
device->mount_type = g_strdup ("floppy");
|
||||
device->type = DEVICE_FLOPPY;
|
||||
return TRUE;
|
||||
#if 0
|
||||
if (check_permissions (device->fsname, R_OK)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
mount_device_ext2_add (DeviceInfo *device)
|
||||
{
|
||||
if (check_permissions (device->fsname, R_OK)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Only mount root partition for now */
|
||||
if ( strcmp (device->mount_path, "/") != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
device->mount_type = g_strdup ("blockdevice");
|
||||
device->type = DEVICE_EXT2;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cdrom_ioctl_frenzy (int fd)
|
||||
{
|
||||
ioctl (fd, CDROM_CLEAR_OPTIONS, CDO_LOCK|CDO_AUTO_CLOSE | CDO_AUTO_EJECT);
|
||||
ioctl (fd, CDROM_SET_OPTIONS, CDO_USE_FFLAGS | CDO_CHECK_TYPE);
|
||||
ioctl (fd, CDROM_LOCKDOOR, 0);
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
mount_device_iso9660_add (NautilusVolumeMonitor *monitor, DeviceInfo *device)
|
||||
{
|
||||
device->device_fd = open (device->fsname, O_RDONLY|O_NONBLOCK);
|
||||
if(device->device_fd < 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
device->type = DEVICE_CDROM;
|
||||
|
||||
/* It's probably not a CD-ROM drive */
|
||||
if (ioctl (device->device_fd, CDROM_DRIVE_STATUS, CDSL_CURRENT) < 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cdrom_ioctl_frenzy (device->device_fd);
|
||||
close (device->device_fd); device->device_fd = -1;
|
||||
|
||||
device->mount_type = g_strdup ("cdrom");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* This is here because mtab lists devices by their symlink-followed names rather than what is listed in fstab. *sigh* */
|
||||
static void
|
||||
mount_device_add_aliases (NautilusVolumeMonitor *monitor, const char *alias, DeviceInfo *device)
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
int buflen;
|
||||
|
||||
g_hash_table_insert (monitor->details->devices_by_fsname, (gpointer)alias, device);
|
||||
|
||||
buflen = readlink (alias, buf, sizeof(buf));
|
||||
if(buflen < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
buf[buflen] = '\0';
|
||||
|
||||
if(buf[0] != '/') {
|
||||
char buf2[PATH_MAX];
|
||||
char *dn;
|
||||
dn = g_dirname(alias);
|
||||
sprintf(buf2, "%s/%s", dn, buf);
|
||||
g_free(dn);
|
||||
strcpy(buf, buf2);
|
||||
}
|
||||
|
||||
mount_device_add_aliases (monitor, g_strdup(buf), device);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
add_mount_device (NautilusVolumeMonitor *monitor, struct mntent *ent)
|
||||
{
|
||||
DeviceInfo *newdev = NULL;
|
||||
gboolean mounted;
|
||||
|
||||
newdev = g_new0 (DeviceInfo, 1);
|
||||
g_assert (newdev);
|
||||
newdev->device_fd = -1;
|
||||
newdev->fsname = g_strdup (ent->mnt_fsname);
|
||||
newdev->mount_path = g_strdup (ent->mnt_dir);
|
||||
newdev->volume_name = NULL;
|
||||
newdev->link_uri = NULL;
|
||||
newdev->state = STATE_EMPTY;
|
||||
|
||||
mounted = FALSE;
|
||||
|
||||
if (strcmp (ent->mnt_type, MOUNT_TYPE_ISO9660) == 0) {
|
||||
mounted = mount_device_iso9660_add (monitor, newdev);
|
||||
} else if (strncmp (ent->mnt_fsname, "/dev/fd", strlen("/dev/fd")) == 0) {
|
||||
mounted = mount_device_floppy_add (monitor, newdev);
|
||||
} else if (strcmp (ent->mnt_type, MOUNT_TYPE_EXT2) == 0) {
|
||||
mounted = mount_device_ext2_add (newdev);
|
||||
} else {
|
||||
/* FIXME: Is this a reasonable way to report this error? */
|
||||
MESSAGE ("Unknown file system: %s", ent->mnt_type);
|
||||
}
|
||||
|
||||
if (mounted) {
|
||||
monitor->details->devices = g_list_append (monitor->details->devices, newdev);
|
||||
mount_device_add_aliases (monitor, newdev->fsname, newdev);
|
||||
MESSAGE ("Device %s came through (type %s)", newdev->fsname, type_names[newdev->type]);
|
||||
} else {
|
||||
close (newdev->device_fd);
|
||||
g_free (newdev->fsname);
|
||||
g_free (newdev->mount_path);
|
||||
g_free (newdev);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
mntent_is_removable_fs (struct mntent *ent)
|
||||
{
|
||||
if (strcmp (ent->mnt_type, MOUNT_TYPE_ISO9660) == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (strncmp (ent->mnt_fsname, "/dev/fd", strlen("/dev/fd")) == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static gboolean
|
||||
mntent_has_option(const char *optlist, const char *option)
|
||||
{
|
||||
gboolean retval = FALSE;
|
||||
char **options;
|
||||
int i;
|
||||
|
||||
options = g_strsplit (optlist, ",", -1);
|
||||
|
||||
for(i = 0; options[i]; i++) {
|
||||
if (strcmp (options[i], option) == 0) {
|
||||
retval = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev (options);
|
||||
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
nautilus_volume_monitor_find_mount_devices (NautilusVolumeMonitor *monitor)
|
||||
{
|
||||
FILE *mef;
|
||||
struct mntent *ent;
|
||||
|
||||
mef = setmntent (_PATH_MNTTAB, "r");
|
||||
g_return_if_fail (mef);
|
||||
|
||||
while ((ent = getmntent (mef))) {
|
||||
MESSAGE ("Checking device %s", ent->mnt_fsname);
|
||||
|
||||
#if 0
|
||||
/* Think some more about these checks */
|
||||
/* Check for removable device */
|
||||
if (!mntent_is_removable_fs (ent)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!mntent_has_option (ent->mnt_opts, MOUNT_OPTIONS_USER)
|
||||
&& !mntent_has_option (ent->mnt_opts, MOUNT_OPTIONS_OWNER)) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
/* Add it to our list of mount points */
|
||||
add_mount_device (monitor, ent);
|
||||
}
|
||||
|
||||
|
||||
endmntent (mef);
|
||||
|
||||
g_list_foreach (monitor->details->devices, (GFunc) mount_device_set_state, monitor);
|
||||
|
||||
/* Manually set state of all volumes to empty so we update */
|
||||
g_list_foreach (monitor->details->devices, (GFunc) device_set_state_empty, monitor);
|
||||
|
||||
/* Add a timer function to check for status change in mounted devices */
|
||||
monitor->details->mount_device_timer_id =
|
||||
gtk_timeout_add (CHECK_INTERVAL, (GtkFunction) mount_devices_check_status, monitor);
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
nautilus_volume_monitor_mount_unmount_removable (NautilusVolumeMonitor *monitor, const char *mount_point)
|
||||
{
|
||||
gboolean is_mounted, found_device;
|
||||
char *argv[3];
|
||||
GList *element;
|
||||
DeviceInfo *device;
|
||||
int exec_err;
|
||||
|
||||
is_mounted = FALSE;
|
||||
found_device = FALSE;
|
||||
device = NULL;
|
||||
|
||||
/* Locate DeviceInfo for mount point */
|
||||
for (element = monitor->details->devices; element != NULL; element = element->next) {
|
||||
device = element->data;
|
||||
if (strcmp (mount_point, device->mount_path) == 0) {
|
||||
found_device = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get mount state and then decide to mount/unmount the volume */
|
||||
if (found_device) {
|
||||
is_mounted = nautilus_volume_monitor_volume_is_mounted (mount_point);
|
||||
argv[1] = (char *)mount_point;
|
||||
argv[2] = NULL;
|
||||
|
||||
if (is_mounted) {
|
||||
/* Unount */
|
||||
argv[0] = "/bin/umount";
|
||||
exec_err = gnome_execute_async (g_get_home_dir(), 2, argv);
|
||||
is_mounted = FALSE;
|
||||
} else {
|
||||
/* Mount */
|
||||
argv[0] = "/bin/mount";
|
||||
exec_err = gnome_execute_async (g_get_home_dir(), 2, argv);
|
||||
is_mounted = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return is_mounted;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
remove_mount_link (DeviceInfo *device)
|
||||
{
|
||||
GnomeVFSResult result;
|
||||
|
||||
if (device->link_uri != NULL) {
|
||||
result = gnome_vfs_unlink (device->link_uri);
|
||||
if (result != GNOME_VFS_OK) {
|
||||
/* FIXME: Is a message to the console acceptable here? */
|
||||
MESSAGE ("Unable to remove mount link: %s", gnome_vfs_result_to_string (result));
|
||||
}
|
||||
g_free (device->link_uri);
|
||||
device->link_uri = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
free_device_info (DeviceInfo *device, NautilusVolumeMonitor *monitor)
|
||||
{
|
||||
|
||||
if (device->device_fd != -1) {
|
||||
close (device->device_fd);
|
||||
device->device_fd = -1;
|
||||
}
|
||||
|
||||
if (device->fsname != NULL) {
|
||||
g_free (device->fsname);
|
||||
device->fsname = NULL;
|
||||
}
|
||||
|
||||
if (device->mount_path != NULL) {
|
||||
g_free (device->mount_path);
|
||||
device->mount_path = NULL;
|
||||
}
|
||||
|
||||
if (device->mount_type != NULL) {
|
||||
g_free (device->mount_type);
|
||||
device->mount_type = NULL;
|
||||
}
|
||||
|
||||
if (device->volume_name != NULL) {
|
||||
g_free (device->volume_name);
|
||||
device->volume_name = NULL;
|
||||
}
|
||||
|
||||
if (device->link_uri != NULL) {
|
||||
g_free (device->link_uri);
|
||||
device->link_uri = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_iso9660_volume_name (DeviceInfo *device)
|
||||
{
|
||||
struct iso_primary_descriptor iso_buffer;
|
||||
|
||||
lseek (device->device_fd, (off_t) 2048*16, SEEK_SET);
|
||||
read (device->device_fd, &iso_buffer, 2048);
|
||||
|
||||
if (device->volume_name != NULL) {
|
||||
g_free (device->volume_name);
|
||||
}
|
||||
|
||||
device->volume_name = g_strdup (iso_buffer.volume_id);
|
||||
if (device->volume_name == NULL) {
|
||||
device->volume_name = g_strdup (device->mount_type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
get_ext2_volume_name (DeviceInfo *device)
|
||||
{
|
||||
device->volume_name = g_strdup ("Ext2 Volume");
|
||||
}
|
||||
|
||||
static void
|
||||
get_floppy_volume_name (DeviceInfo *device)
|
||||
{
|
||||
device->volume_name = g_strdup ("Floppy");
|
||||
}
|
105
libnautilus-private/nautilus-volume-monitor.h
Normal file
105
libnautilus-private/nautilus-volume-monitor.h
Normal file
|
@ -0,0 +1,105 @@
|
|||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
|
||||
|
||||
/* nautilus-volume-monitor.h - interface for desktop mounting functions.
|
||||
|
||||
Copyright (C) 2000 Eazel, Inc.
|
||||
|
||||
The Gnome Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The Gnome Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the Gnome Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
Authors: Gene Z. Ragan <gzr@eazel.com>
|
||||
*/
|
||||
|
||||
#ifndef NAUTILUS_VOLUME_MONITOR_H
|
||||
#define NAUTILUS_VOLUME_MONITOR_H
|
||||
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include "nautilus-icon-container.h"
|
||||
|
||||
typedef struct NautilusVolumeMonitor NautilusVolumeMonitor;
|
||||
typedef struct NautilusVolumeMonitorClass NautilusVolumeMonitorClass;
|
||||
typedef struct NautilusVolumeMonitorDetails NautilusVolumeMonitorDetails;
|
||||
|
||||
#define NAUTILUS_TYPE_VOLUME_MONITOR (nautilus_volume_monitor_get_type())
|
||||
#define NAUTILUS_VOLUME_MONITOR(obj) (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_VOLUME_MONITOR, NautilusVolumeMonitor))
|
||||
#define NAUTILUS_VOLUME_MONITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_VOLUME_MONITOR, NautilusVolumeMonitorClass))
|
||||
#define IS_NAUTILUS_VOLUME_MONITOR(obj) (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_VOLUME_MONITOR))
|
||||
|
||||
struct NautilusVolumeMonitor {
|
||||
GtkObject parent;
|
||||
NautilusVolumeMonitorDetails *details;
|
||||
};
|
||||
|
||||
struct NautilusVolumeMonitorClass {
|
||||
GtkObjectClass parent_class;
|
||||
|
||||
/* Signals */
|
||||
char * (* volume_mounted) (NautilusVolumeMonitor *monitor);
|
||||
};
|
||||
|
||||
struct NautilusVolumeMonitorDetails
|
||||
{
|
||||
GHashTable *devices_by_fsname;
|
||||
GList *devices;
|
||||
guint mount_device_timer_id;
|
||||
};
|
||||
|
||||
|
||||
#define MOUNT_TYPE_ISO9660 "iso9660"
|
||||
#define MOUNT_TYPE_EXT2 "ext2"
|
||||
#define MOUNT_OPTIONS_USER "user"
|
||||
#define MOUNT_OPTIONS_OWNER "owner"
|
||||
|
||||
#define CHECK_INTERVAL 2000
|
||||
|
||||
typedef enum {
|
||||
STATE_ACTIVE = 0,
|
||||
STATE_INACTIVE,
|
||||
STATE_EMPTY,
|
||||
STATE_LAST,
|
||||
} DeviceState;
|
||||
|
||||
typedef enum {
|
||||
DEVICE_CDROM,
|
||||
DEVICE_FLOPPY,
|
||||
DEVICE_EXT2,
|
||||
DEVICE_OTHER
|
||||
} DeviceType;
|
||||
|
||||
typedef struct {
|
||||
DeviceType type;
|
||||
DeviceState state;
|
||||
int device_fd;
|
||||
|
||||
char *fsname;
|
||||
char *mount_path;
|
||||
char *mount_type;
|
||||
char *volume_name;
|
||||
char *link_uri;
|
||||
|
||||
gboolean is_mounted;
|
||||
gboolean did_mount;
|
||||
} DeviceInfo;
|
||||
|
||||
GtkType nautilus_volume_monitor_get_type (void);
|
||||
NautilusVolumeMonitor *nautilus_volume_monitor_get (void);
|
||||
GList *fm_desktop_get_removable_volume_list (void);
|
||||
gboolean nautilus_volume_monitor_volume_is_mounted (const char *mount_point);
|
||||
void nautilus_volume_monitor_find_mount_devices (NautilusVolumeMonitor *icon_view);
|
||||
gboolean nautilus_volume_monitor_mount_unmount_removable (NautilusVolumeMonitor *monitor,
|
||||
const char *mount_point);
|
||||
|
||||
#endif
|
|
@ -28,7 +28,6 @@ libnautilus_file_manager_la_SOURCES= \
|
|||
dfos-xfer.c \
|
||||
dfos.c \
|
||||
fm-desktop-icon-view.c \
|
||||
fm-desktop-mounting.c \
|
||||
fm-directory-view.c \
|
||||
fm-error-reporting.c \
|
||||
fm-icon-text-window.c \
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
|
||||
#include <config.h>
|
||||
#include "fm-desktop-icon-view.h"
|
||||
|
||||
#include "fm-desktop-mounting.h"
|
||||
#include "fm-icon-view.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
|
@ -39,6 +37,7 @@
|
|||
#include <libnautilus-extensions/nautilus-gnome-extensions.h>
|
||||
#include <libnautilus-extensions/nautilus-gtk-macros.h>
|
||||
#include <libnautilus-extensions/nautilus-link.h>
|
||||
#include <libnautilus-extensions/nautilus-volume-monitor.h>
|
||||
#include <mntent.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -67,6 +66,10 @@ static void fm_desktop_icon_view_set_directory_auto_layout (FMIco
|
|||
static void fm_desktop_icon_view_trash_state_changed_callback (NautilusTrashMonitor *trash,
|
||||
gboolean state,
|
||||
gpointer callback_data);
|
||||
|
||||
static void mount_unmount_removable (GtkCheckMenuItem *item,
|
||||
FMDesktopIconView *icon_view);
|
||||
static void place_home_directory (FMDesktopIconView *icon_view);
|
||||
|
||||
NAUTILUS_DEFINE_CLASS_BOILERPLATE (FMDesktopIconView, fm_desktop_icon_view, FM_TYPE_ICON_VIEW);
|
||||
|
||||
|
@ -86,20 +89,10 @@ fm_desktop_icon_view_destroy (GtkObject *object)
|
|||
|
||||
icon_view = FM_DESKTOP_ICON_VIEW (object);
|
||||
|
||||
/* Remove timer function */
|
||||
gtk_timeout_remove (icon_view->details->mount_device_timer_id);
|
||||
|
||||
/* Remove mount link files */
|
||||
g_list_foreach (icon_view->details->devices, (GFunc)fm_desktop_remove_mount_links, icon_view);
|
||||
|
||||
/* Clean up other device info */
|
||||
g_list_foreach (icon_view->details->devices, (GFunc)fm_desktop_free_device_info, icon_view);
|
||||
|
||||
/* Clean up details */
|
||||
g_hash_table_destroy (icon_view->details->devices_by_fsname);
|
||||
g_list_free (icon_view->details->devices);
|
||||
g_free (icon_view->details);
|
||||
|
||||
|
||||
NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object));
|
||||
}
|
||||
|
||||
|
@ -175,11 +168,10 @@ fm_desktop_icon_view_initialize (FMDesktopIconView *desktop_icon_view)
|
|||
|
||||
/* Set up details */
|
||||
desktop_icon_view->details = g_new0 (FMDesktopIconViewDetails, 1);
|
||||
desktop_icon_view->details->devices_by_fsname = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
desktop_icon_view->details->devices = NULL;
|
||||
desktop_icon_view->details->volume_monitor = nautilus_volume_monitor_get ();
|
||||
|
||||
/* Setup home directory link */
|
||||
fm_desktop_place_home_directory (desktop_icon_view);
|
||||
place_home_directory (desktop_icon_view);
|
||||
|
||||
gtk_signal_connect (GTK_OBJECT (icon_container),
|
||||
"middle_click",
|
||||
|
@ -192,7 +184,7 @@ fm_desktop_icon_view_initialize (FMDesktopIconView *desktop_icon_view)
|
|||
desktop_icon_view);
|
||||
|
||||
/* Check for mountable devices */
|
||||
fm_desktop_find_mount_devices (desktop_icon_view, _PATH_MNTTAB);
|
||||
nautilus_volume_monitor_find_mount_devices (desktop_icon_view->details->volume_monitor);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -253,7 +245,7 @@ fm_desktop_icon_view_create_background_context_menu_items (FMDirectoryView *view
|
|||
}
|
||||
|
||||
/* Add check mark if volume is mounted */
|
||||
active = fm_desktop_volume_is_mounted (element->data);
|
||||
active = nautilus_volume_monitor_volume_is_mounted (element->data);
|
||||
gtk_check_menu_item_set_show_toggle (GTK_CHECK_MENU_ITEM (check_menu_item), TRUE);
|
||||
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (check_menu_item), active);
|
||||
|
||||
|
@ -263,7 +255,7 @@ fm_desktop_icon_view_create_background_context_menu_items (FMDirectoryView *view
|
|||
|
||||
gtk_signal_connect (GTK_OBJECT (check_menu_item),
|
||||
"activate",
|
||||
GTK_SIGNAL_FUNC (fm_desktop_mount_unmount_removable),
|
||||
GTK_SIGNAL_FUNC (mount_unmount_removable),
|
||||
FM_DESKTOP_ICON_VIEW (view));
|
||||
|
||||
gtk_menu_append (sub_menu, check_menu_item);
|
||||
|
@ -326,3 +318,58 @@ fm_desktop_icon_view_trash_state_changed_callback (NautilusTrashMonitor *trash_m
|
|||
g_free (path);
|
||||
g_free (desktop_directory_path);
|
||||
}
|
||||
|
||||
static void
|
||||
mount_unmount_removable (GtkCheckMenuItem *item, FMDesktopIconView *icon_view)
|
||||
{
|
||||
gboolean is_mounted;
|
||||
char *mount_point;
|
||||
|
||||
is_mounted = FALSE;
|
||||
|
||||
/* Locate our mount point data */
|
||||
mount_point = gtk_object_get_data (GTK_OBJECT (item), "mount_point");
|
||||
if (mount_point != NULL) {
|
||||
is_mounted = nautilus_volume_monitor_mount_unmount_removable
|
||||
(icon_view->details->volume_monitor, mount_point);
|
||||
}
|
||||
|
||||
/* Set the check state of menu item even thought the user may not see it */
|
||||
gtk_check_menu_item_set_active (item, is_mounted);
|
||||
}
|
||||
|
||||
/* fm_desktop_place_home_directory
|
||||
*
|
||||
* Add an icon representing the user's home directory on the desktop.
|
||||
* Create if necessary
|
||||
*/
|
||||
static void
|
||||
place_home_directory (FMDesktopIconView *icon_view)
|
||||
{
|
||||
char *desktop_path, *home_link_name, *home_link_path, *home_link_uri, *home_dir_uri;
|
||||
GnomeVFSResult result;
|
||||
GnomeVFSFileInfo info;
|
||||
|
||||
desktop_path = nautilus_get_desktop_directory ();
|
||||
home_link_name = g_strdup_printf ("%s's Home", g_get_user_name ());
|
||||
home_link_path = nautilus_make_path (desktop_path, home_link_name);
|
||||
home_link_uri = nautilus_get_uri_from_local_path (home_link_path);
|
||||
|
||||
result = gnome_vfs_get_file_info (home_link_uri, &info, 0);
|
||||
if (result != GNOME_VFS_OK) {
|
||||
/* FIXME: Maybe we should only create if the error was "not found". */
|
||||
/* There was no link file. Create it and add it to the desktop view */
|
||||
home_dir_uri = nautilus_get_uri_from_local_path (g_get_home_dir ());
|
||||
result = nautilus_link_create (desktop_path, home_link_name, "temp-home.png", home_dir_uri);
|
||||
g_free (home_dir_uri);
|
||||
if (result != GNOME_VFS_OK) {
|
||||
/* FIXME: Is a message to the console acceptable here? */
|
||||
g_message ("Unable to create home link: %s", gnome_vfs_result_to_string (result));
|
||||
}
|
||||
}
|
||||
|
||||
g_free (home_link_uri);
|
||||
g_free (home_link_path);
|
||||
g_free (home_link_name);
|
||||
g_free (desktop_path);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#define FM_DESKSTOP_ICON_VIEW_H
|
||||
|
||||
#include "fm-icon-view.h"
|
||||
#include <libnautilus-extensions/nautilus-volume-monitor.h>
|
||||
|
||||
typedef struct FMDesktopIconView FMDesktopIconView;
|
||||
typedef struct FMDesktopIconViewClass FMDesktopIconViewClass;
|
||||
|
@ -48,12 +49,11 @@ struct FMDesktopIconViewClass {
|
|||
|
||||
struct FMDesktopIconViewDetails
|
||||
{
|
||||
GHashTable *devices_by_fsname;
|
||||
GList *devices;
|
||||
guint mount_device_timer_id;
|
||||
NautilusVolumeMonitor *volume_monitor;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* GtkObject support */
|
||||
GtkType fm_desktop_icon_view_get_type (void);
|
||||
|
||||
|
|
|
@ -1,78 +0,0 @@
|
|||
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
|
||||
|
||||
/* fm-desktop-mounting.h - interface for desktop mounting functions.
|
||||
|
||||
Copyright (C) 2000 Eazel, Inc.
|
||||
|
||||
The Gnome Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The Gnome Library 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the Gnome Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
Authors: Gene Z. Ragan <gzr@eazel.com>
|
||||
*/
|
||||
|
||||
#ifndef FM_DESKSTOP_MOUTING
|
||||
#define FM_DESKSTOP_MOUTING
|
||||
|
||||
#include "fm-desktop-icon-view.h"
|
||||
|
||||
#define MOUNT_TYPE_ISO9660 "iso9660"
|
||||
#define MOUNT_TYPE_EXT2 "ext2"
|
||||
#define MOUNT_OPTIONS_USER "user"
|
||||
#define MOUNT_OPTIONS_OWNER "owner"
|
||||
|
||||
#define CHECK_INTERVAL 2000
|
||||
|
||||
typedef enum {
|
||||
STATE_ACTIVE = 0,
|
||||
STATE_INACTIVE,
|
||||
STATE_EMPTY,
|
||||
STATE_LAST,
|
||||
} DeviceState;
|
||||
|
||||
typedef enum {
|
||||
DEVICE_CDROM,
|
||||
DEVICE_FLOPPY,
|
||||
DEVICE_EXT2,
|
||||
DEVICE_OTHER
|
||||
} DeviceType;
|
||||
|
||||
typedef struct {
|
||||
DeviceType type;
|
||||
DeviceState state;
|
||||
int device_fd;
|
||||
|
||||
char *fsname;
|
||||
char *mount_path;
|
||||
char *mount_type;
|
||||
char *volume_name;
|
||||
char *link_uri;
|
||||
|
||||
gboolean is_mounted;
|
||||
gboolean did_mount;
|
||||
} DeviceInfo;
|
||||
|
||||
GList *fm_desktop_get_removable_volume_list (void);
|
||||
void fm_desktop_remove_mount_links (DeviceInfo *device,
|
||||
FMDesktopIconView *icon_view);
|
||||
void fm_desktop_place_home_directory (FMDesktopIconView *icon_view);
|
||||
void fm_desktop_free_device_info (DeviceInfo *device,
|
||||
FMDesktopIconView *icon_view);
|
||||
void fm_desktop_find_mount_devices (FMDesktopIconView *icon_view,
|
||||
const char *fstab_path);
|
||||
void fm_desktop_mount_unmount_removable (GtkCheckMenuItem *item,
|
||||
FMDesktopIconView *icon_view);
|
||||
gboolean fm_desktop_volume_is_mounted (const char *mount_point);
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue