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:
Gene Z. Ragan 2000-08-02 22:04:26 +00:00 committed by Gene Ragan
parent 9bd742ccff
commit 1d671db24c
15 changed files with 1853 additions and 271 deletions

View file

@ -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:

View file

@ -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)

View file

@ -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);
}

View 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

View file

@ -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)

View 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 */

View 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

View 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");
}

View 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

View file

@ -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 \

View file

@ -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);
}

View file

@ -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);

View file

@ -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