summaryrefslogtreecommitdiff
path: root/libnautilus-extensions
diff options
context:
space:
mode:
authorDarin Adler <darin@src.gnome.org>2001-03-23 02:34:16 +0000
committerDarin Adler <darin@src.gnome.org>2001-03-23 02:34:16 +0000
commit6a3ac19781a4868006b755038b2f6c97a7ccc15f (patch)
treed315783ee374366ec01d21e0d6715949c9cd3cf5 /libnautilus-extensions
parent9f0d5e97730739875032c072e4b7f004a64e9d1c (diff)
downloadnautilus-6a3ac19781a4868006b755038b2f6c97a7ccc15f.tar.gz
reviewed by: John Sullivan <sullivan@eazel.com>
Fix bug 6613 (no way to delete files without using trash) by integrating Maciej's patch to add an optional Delete command (with some fixes to the patch). There may still be some loose ends. Fix bug 2206 (No way to move or copy a file to a different directory from keyboard) by implementing Cut, Copy, and Paste for files, in a way that will be familiar to Windows users. The positioning of the new files is not right yet (they inherit their position from the old files), there is no feedback when you have cut some files (Arlo's idea, which I might implement, is to make them translucent to show they are "on the way out") or when you have copied some files, and I think there are some other loose ends. Fixed cut, copy, and paste within the file names when you do a rename. This wasn't working at all. Got rid of configure-time checks that were looking at the existence of some special system files. Fixed a few minor bugs discovered by code inspection. * libnautilus-extensions/nautilus-global-preferences.h: * libnautilus-extensions/nautilus-global-preferences.c: (global_preferences_install_descriptions), (global_preferences_install_defaults), (global_preferences_install_visibility), (global_preferences_create_dialog): Add expert preference to add a Delete command that bypasses the Trash. * src/file-manager/nautilus-directory-view-ui.xml: Add Delete, Cut Files, Copy Files, and Paste Files. * src/file-manager/fm-directory-view.c: (confirm_delete_directly), (delete_callback): Add delete code. (bonobo_menu_empty_trash_callback): Get rid of extraneous cast. (fm_directory_view_initialize): Track the delete preference. Set the flags properly to indicate we have our own X window. Add a target so GTK knows that we accept pastes of copied files. (forget_clipboard_contents): Helper for when we are no longer the clipboard owner. (fm_directory_view_destroy): Remove the delete preference callback. Free the clipboard contents. (offset_drop_points): Change so it handles NULL for the list of points. (trash_or_delete_files_common): Remove unneeded parameters. (get_current_event_time): New function, placeholder that just returned GDK_CURRENT_TIME. Perhaps we should get the real event time here for use in clipboard manipulation calls. (copy_or_cut_files): New function. Save the selection for later use in a paste. (copy_files_callback), (cut_files_callback): Call the new copy_or_cut_files function. (paste_files_callback): Do the clipboard convert that results in the paste operation. (real_selection_clear_event): Forget the clipboard contents. (real_selection_get): Convert the selection into the appropriate format and put it on the clipboard. (convert_lines_to_str_list): Helper function for decoding incoming pasted files. (real_selection_received): Handle pasted files by parsing and then triggering a file copy operation. (real_merge_menus): Add verbs for cut, copy, and paste. (enable_delete_changed_callback): Keep track of delete command status in a boolean. (real_update_menus): Show delete command if the preference is on and we are not showing "Delete from Trash". Update names of the Cut and Copy command depending on how many files are selected. Also desensitize them when none are selected. (fm_directory_view_select_file): Initialize an uninitialized field. (fm_directory_view_move_copy_items): Allow relative_item_points to be NULL. (real_realize): Create our own X window. (real_size_allocate): Trick GtkScrolledWindow into doing the right thing despite the fact that we have our own X window. (fm_directory_view_initialize_class): Moved down to the bottom so we don't need so many forward declaractions. Added code to set up some needed atoms and new default handlers. * libnautilus-extensions/nautilus-icon-text-item.c: (send_focus_event), (iti_stop_editing), (iti_start_editing): Add code to send the appropriate focus events to the fake off-screen GtkEntry. This makes the clipboard code that tracks focus-related signals work properly with this entry. (iti_event): Tweak the sequence and simplify the code a bit. * libnautilus/nautilus-clipboard.c: (set_paste_sensitive_if_clipboard_contains_data): Add more FIXMEs. This function is very far from useful, and it's not clear that it can be implemented efficiently under X. (nautilus_clipboard_set_up_editable): Get rid of silly "grab_focus" hack that was an attempt to address the problems with the NautilusIconTextItem. The real solution was to do focusing for that item too. (nautilus_clipboard_set_up_editable_in_control): Fix this so it works when called on an editable that is already focused. * src/file-manager/fm-icon-view.c: (renaming_icon_callback): Get rid of "grab_focus" workaround, which wasn't working. * acconfig.h: * configure.in: Remove all configure checks that were checking the existence of files. * libnautilus-extensions/nautilus-medusa-support.c: (nautilus_medusa_check_cron_is_enabled): Simplify logic so there's less room for confusion (I did this as a fix for the bug that was reported on the mailing list, but Rebecka checked in the small patch first). Also change it so we don't need a configure-time check for the existence of the process directory and fix it so we won't get a core dump if the file doesn't have a space character in it. Also change the logic so we don't leave the directory open when we do find the cron process. * libnautilus-extensions/nautilus-volume-monitor.c: (nautilus_volume_monitor_initialize_class), (has_removable_mntent_options), (get_removable_volumes), (volume_is_removable), (volume_is_read_only), (mount_volume_get_cdrom_name), (mount_volume_activate_cdda), (mount_volume_activate_cdrom), (build_volume_list_delta), (get_current_mount_list), (mount_lists_are_identical), (verify_current_mount_state), (mount_volume_floppy_add), (get_cdrom_type_solaris), (mount_volume_iso9660_add), (display_mount_status), (close_error_pipe), (nautilus_volume_monitor_mount_unmount_removable), (mount_volume_add_filesystem): Make changes throughout to get rid of dependence on configure-time file checks and do things at runtime instead. Also use typedefs to make less code conditional. Also fix the Solaris CD-ROM code which was casting a GString to a (char *) before, so it used absurd file names, and failed to open and returned FALSE all the time. * libnautilus-extensions/nautilus-icon-container.c: (nautilus_icon_container_start_renaming_selected_item): Send the renaming signal before setting up the rest of the icon. This change is not really needed, but it's a better order to do things. * libnautilus/nautilus-clipboard-ui.xml: Move tips into the commands instead of the menu items (for style mostly, no practical implications at the moment). * src/nautilus-shell-ui.xml: Remove tips from Cut, Copy, and Paste, since tips from insensitive items aren't used, and if we had tips, we'd put them on the command, not the menu item, anyway.
Diffstat (limited to 'libnautilus-extensions')
-rw-r--r--libnautilus-extensions/nautilus-global-preferences.c19
-rw-r--r--libnautilus-extensions/nautilus-global-preferences.h3
-rw-r--r--libnautilus-extensions/nautilus-icon-container.c19
-rw-r--r--libnautilus-extensions/nautilus-icon-text-item.c44
-rw-r--r--libnautilus-extensions/nautilus-medusa-support.c69
-rw-r--r--libnautilus-extensions/nautilus-volume-monitor.c434
6 files changed, 287 insertions, 301 deletions
diff --git a/libnautilus-extensions/nautilus-global-preferences.c b/libnautilus-extensions/nautilus-global-preferences.c
index 14ad7312b..918fadd4f 100644
--- a/libnautilus-extensions/nautilus-global-preferences.c
+++ b/libnautilus-extensions/nautilus-global-preferences.c
@@ -2,7 +2,7 @@
/* nautilus-prefs-dialog.c - Implementation for preferences dialog.
- Copyright (C) 1999, 2000 Eazel, Inc.
+ Copyright (C) 1999, 2000, 2001 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
@@ -100,7 +100,10 @@ global_preferences_install_descriptions (void)
_("Open each file or folder in a separate window"));
nautilus_preferences_set_description (NAUTILUS_PREFERENCES_CONFIRM_TRASH,
- _("Ask before emptying the Trash"));
+ _("Ask before emptying the Trash or deleting files"));
+
+ nautilus_preferences_set_description (NAUTILUS_PREFERENCES_ENABLE_DELETE,
+ _("Include a Delete command that bypasses Trash"));
nautilus_preferences_set_description (NAUTILUS_PREFERENCES_CLICK_POLICY,
_("Click Behavior"));
@@ -260,6 +263,10 @@ global_preferences_install_defaults (void)
NAUTILUS_USER_LEVEL_NOVICE,
TRUE);
+ nautilus_preferences_default_set_boolean (NAUTILUS_PREFERENCES_ENABLE_DELETE,
+ NAUTILUS_USER_LEVEL_NOVICE,
+ FALSE);
+
nautilus_preferences_default_set_integer (NAUTILUS_PREFERENCES_SHOW_TEXT_IN_ICONS,
NAUTILUS_USER_LEVEL_NOVICE,
NAUTILUS_SPEED_TRADEOFF_LOCAL_ONLY);
@@ -426,6 +433,9 @@ global_preferences_install_visibility (void)
nautilus_preferences_set_visible_user_level (NAUTILUS_PREFERENCES_CONFIRM_TRASH,
NAUTILUS_USER_LEVEL_ADVANCED);
+ nautilus_preferences_set_visible_user_level (NAUTILUS_PREFERENCES_ENABLE_DELETE,
+ NAUTILUS_USER_LEVEL_ADVANCED);
+
nautilus_preferences_set_visible_user_level (NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES,
NAUTILUS_USER_LEVEL_INTERMEDIATE);
@@ -612,6 +622,11 @@ global_preferences_create_dialog (void)
NAUTILUS_PREFERENCES_CONFIRM_TRASH,
NAUTILUS_PREFERENCE_ITEM_BOOLEAN);
+ nautilus_preferences_pane_add_item_to_nth_group (NAUTILUS_PREFERENCES_PANE (windows_and_desktop_pane),
+ 2,
+ NAUTILUS_PREFERENCES_ENABLE_DELETE,
+ NAUTILUS_PREFERENCE_ITEM_BOOLEAN);
+
/* FIXME: This group clearly doesn't belong in Windows &
* Desktop, but there's no obviously-better place for it and
* it probably doesn't deserve a pane of its own.
diff --git a/libnautilus-extensions/nautilus-global-preferences.h b/libnautilus-extensions/nautilus-global-preferences.h
index ab2452e74..26678f255 100644
--- a/libnautilus-extensions/nautilus-global-preferences.h
+++ b/libnautilus-extensions/nautilus-global-preferences.h
@@ -2,7 +2,7 @@
/* nautilus-global-prefs.h - Nautilus main preferences api.
- Copyright (C) 1999, 2000 Eazel, Inc.
+ Copyright (C) 1999, 2000, 2001 Eazel, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
@@ -49,6 +49,7 @@ BEGIN_GNOME_DECLS
/* Trash options */
#define NAUTILUS_PREFERENCES_CONFIRM_TRASH "preferences/confirm_trash"
+#define NAUTILUS_PREFERENCES_ENABLE_DELETE "preferences/enable_delete"
/* Desktop options */
#define NAUTILUS_PREFERENCES_SHOW_DESKTOP "preferences/show_desktop"
diff --git a/libnautilus-extensions/nautilus-icon-container.c b/libnautilus-extensions/nautilus-icon-container.c
index 56c8154dd..32e948611 100644
--- a/libnautilus-extensions/nautilus-icon-container.c
+++ b/libnautilus-extensions/nautilus-icon-container.c
@@ -4862,21 +4862,22 @@ nautilus_icon_container_start_renaming_selected_item (NautilusIconContainer *con
gnome_canvas_item_w2i (GNOME_CANVAS_ITEM (details->rename_widget), &icon_rect.x0, &icon_rect.y0);
gnome_canvas_item_w2i (GNOME_CANVAS_ITEM (details->rename_widget), &icon_rect.x1, &icon_rect.y1);
- nautilus_icon_text_item_configure (
- details->rename_widget,
- (icon_rect.x0 + icon_rect.x1) / 2, /* x_center */
- icon_rect.y1, /* y_top */
- nautilus_icon_canvas_item_get_max_text_width (icon->item), /* max_text_width */
- details->label_font[details->zoom_level], /* font */
- editable_text, /* text */
- FALSE); /* allocate local copy */
+ nautilus_icon_text_item_configure
+ (details->rename_widget,
+ (icon_rect.x0 + icon_rect.x1) / 2, /* x_center */
+ icon_rect.y1, /* y_top */
+ nautilus_icon_canvas_item_get_max_text_width (icon->item), /* max_text_width */
+ details->label_font[details->zoom_level], /* font */
+ editable_text, /* text */
+ FALSE); /* allocate local copy */
nautilus_icon_text_item_start_editing (details->rename_widget);
- nautilus_icon_container_update_icon (container, icon);
gtk_signal_emit (GTK_OBJECT (container),
signals[RENAMING_ICON],
nautilus_icon_text_item_get_renaming_editable (details->rename_widget));
+
+ nautilus_icon_container_update_icon (container, icon);
/* We are in renaming mode */
details->renaming = TRUE;
diff --git a/libnautilus-extensions/nautilus-icon-text-item.c b/libnautilus-extensions/nautilus-icon-text-item.c
index 03d28357a..d1cf5388e 100644
--- a/libnautilus-extensions/nautilus-icon-text-item.c
+++ b/libnautilus-extensions/nautilus-icon-text-item.c
@@ -90,6 +90,36 @@ enum {
};
static guint iti_signals [LAST_SIGNAL] = { 0 };
+static void
+send_focus_event (Iti *iti, gboolean in)
+{
+ ItiPrivate *priv;
+ GtkWidget *widget;
+ gboolean has_focus;
+ GdkEvent fake_event;
+
+ g_assert (in == FALSE || in == TRUE);
+
+ priv = iti->priv;
+ if (priv->entry == NULL) {
+ g_assert (!in);
+ return;
+ }
+
+ widget = GTK_WIDGET (priv->entry);
+ has_focus = GTK_WIDGET_HAS_FOCUS (widget);
+ if (has_focus == in) {
+ return;
+ }
+
+ memset (&fake_event, 0, sizeof (fake_event));
+ fake_event.focus_change.type = GDK_FOCUS_CHANGE;
+ fake_event.focus_change.window = widget->window;
+ fake_event.focus_change.in = in;
+ gtk_widget_event (widget, &fake_event);
+ g_assert (GTK_WIDGET_HAS_FOCUS (widget) == in);
+}
+
/* Stops the editing state of an icon text item */
static void
iti_stop_editing (Iti *iti)
@@ -100,6 +130,8 @@ iti_stop_editing (Iti *iti)
iti->editing = FALSE;
+ send_focus_event (iti, FALSE);
+
gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti));
gtk_signal_emit (GTK_OBJECT (iti), iti_signals[EDITING_STOPPED]);
@@ -232,7 +264,7 @@ iti_start_editing (Iti *iti)
gtk_signal_connect (GTK_OBJECT (priv->entry), "activate",
GTK_SIGNAL_FUNC (iti_entry_activate), iti);
/* Make clipboard functions cause an update the appearance of
- the icon text item iteself, since the clipboard functions
+ the icon text item itself, since the clipboard functions
will change the offscreen entry */
gtk_signal_connect_after (GTK_OBJECT (priv->entry), "changed",
GTK_SIGNAL_FUNC (iti_entry_text_changed_by_clipboard), iti);
@@ -249,6 +281,8 @@ iti_start_editing (Iti *iti)
iti->editing = TRUE;
+ send_focus_event (iti, TRUE);
+
gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (iti));
gtk_signal_emit (GTK_OBJECT (iti), iti_signals[EDITING_STARTED]);
@@ -1067,13 +1101,13 @@ iti_event (GnomeCanvasItem *item, GdkEvent *event)
} else {
GTK_WIDGET_UNSET_FLAGS (item->canvas, GTK_HAS_FOCUS);
}
-
- if (iti->editing && !event->focus_change.in) {
- iti_edition_accept (iti);
- }
if (iti->editing) {
gtk_widget_event (GTK_WIDGET (priv->entry), event);
+
+ if (!event->focus_change.in) {
+ iti_edition_accept (iti);
+ }
}
return TRUE;
diff --git a/libnautilus-extensions/nautilus-medusa-support.c b/libnautilus-extensions/nautilus-medusa-support.c
index 2ae619fc4..94a079e66 100644
--- a/libnautilus-extensions/nautilus-medusa-support.c
+++ b/libnautilus-extensions/nautilus-medusa-support.c
@@ -25,16 +25,13 @@
*/
#include <config.h>
-#include <glib.h>
-
-#include <string.h>
-#include <sys/types.h>
-#include <stdio.h>
-#include <dirent.h>
+#include "nautilus-medusa-support.h"
#include "nautilus-glib-extensions.h"
-#include "nautilus-medusa-support.h"
#include "nautilus-string.h"
+#include <dirent.h>
+#include <stdio.h>
+#include <sys/types.h>
#ifdef HAVE_MEDUSA
#include <libmedusa/medusa-system-state.h>
@@ -85,7 +82,6 @@ nautilus_medusa_add_system_state_changed_callback (NautilusMedusaChangedCallback
NautilusCronStatus
nautilus_medusa_check_cron_is_enabled (void)
{
-#ifdef HAVE_PROC_PROCESS_FILES
DIR *proc_directory;
struct dirent *file;
char *stat_file_name;
@@ -93,6 +89,7 @@ nautilus_medusa_check_cron_is_enabled (void)
char stat_file_data[128];
const char *stat_file_process_name;
int process_number, bytes_read;
+ NautilusCronStatus status;
/* We figure out whether cron is running by reading the proc
directory, and checking for a process named or ending with
@@ -103,37 +100,39 @@ nautilus_medusa_check_cron_is_enabled (void)
return NAUTILUS_CRON_STATUS_UNKNOWN;
}
- file = readdir (proc_directory);
- while (file != NULL) {
+ status = NAUTILUS_CRON_STATUS_UNKNOWN;
+
+ while ((file = readdir (proc_directory)) != NULL) {
/* Process files have numbers */
- if (nautilus_str_to_int (file->d_name,
- &process_number)) {
- stat_file_name = g_strdup_printf ("/proc/%d/stat", process_number);
- stat_file = fopen (stat_file_name, "r");
- g_free (stat_file_name);
-
- if (stat_file == NULL) {
- file = readdir (proc_directory);
- continue;
- }
-
- bytes_read = fread (stat_file_data, sizeof (char), NAUTILUS_N_ELEMENTS (stat_file_data) - 1, stat_file);
- fclose (stat_file);
- stat_file_data[bytes_read] = 0;
-
- stat_file_process_name = strchr (stat_file_data, ' ') + 1;
-
- if (nautilus_str_has_prefix (stat_file_process_name, "(crond)")) {
- return NAUTILUS_CRON_STATUS_ON;
- }
+ if (!nautilus_str_to_int (file->d_name, &process_number)) {
+ continue;
+ }
+ /* Since we've seen at least one process file, we can change our state
+ * from "unknown" to "presumed off until proved otherwise".
+ */
+ status = NAUTILUS_CRON_STATUS_OFF;
+
+ stat_file_name = g_strdup_printf ("/proc/%d/stat", process_number);
+ stat_file = fopen (stat_file_name, "r");
+ g_free (stat_file_name);
+
+ if (stat_file == NULL) {
+ continue;
+ }
+
+ bytes_read = fread (stat_file_data, 1, sizeof (stat_file_data) - 1, stat_file);
+ fclose (stat_file);
+ stat_file_data[bytes_read] = '\0';
+
+ stat_file_process_name = strchr (stat_file_data, ' ');
+
+ if (nautilus_str_has_prefix (stat_file_process_name, " (crond)")) {
+ status = NAUTILUS_CRON_STATUS_ON;
+ break;
}
- file = readdir (proc_directory);
}
closedir (proc_directory);
- return NAUTILUS_CRON_STATUS_OFF;
-#else
- return NAUTILUS_CRON_STATUS_UNKNOWN;
-#endif
+ return status;
}
diff --git a/libnautilus-extensions/nautilus-volume-monitor.c b/libnautilus-extensions/nautilus-volume-monitor.c
index e32254a22..8055b44cd 100644
--- a/libnautilus-extensions/nautilus-volume-monitor.c
+++ b/libnautilus-extensions/nautilus-volume-monitor.c
@@ -2,7 +2,7 @@
/* nautilus-volume-monitor.c - Desktop volume mounting routines.
- Copyright (C) 2000 Eazel, Inc.
+ Copyright (C) 2000, 2001 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
@@ -23,8 +23,6 @@
*/
#include <config.h>
-#include <sys/types.h>
-
#include "nautilus-volume-monitor.h"
#include "nautilus-cdrom-extensions.h"
@@ -64,11 +62,13 @@
#ifdef HAVE_MNTENT_H
#include <mntent.h>
+#define MOUNT_TABLE_PATH _PATH_MNTTAB
#endif
#ifdef HAVE_SYS_MNTTAB_H
#define SOLARIS_MNT 1
#include <sys/mnttab.h>
+#define MOUNT_TABLE_PATH "/etc/mnttab"
#endif
#ifdef SOLARIS_MNT
@@ -77,7 +77,16 @@
#define USE_VOLRMMOUNT 0
#endif
+#ifndef MNTOPT_RO
+#define MNTOPT_RO "ro"
+#endif
+
+#ifndef HAVE_SETMNTENT
+#define setmntent(f,m) fopen(f,m)
+#endif
+
#ifdef HAVE_CDDA
+
#define size16 short
#define size32 int
@@ -94,48 +103,17 @@
* due to our strict error checking.
*/
char **broken_header_fix = strerror_tr;
-#endif
-
-#define CHECK_STATUS_INTERVAL 2000
-#ifdef HAVE_ETC_MNTTAB
-#define PATH_PROC_MOUNTS "/etc/mnttab"
-#define PROC_MOUNTS_SEPARATOR "\t"
#endif
-#ifdef HAVE_PROC_MOUNTS
-#define PATH_PROC_MOUNTS "/proc/mounts"
-#define PROC_MOUNTS_SEPARATOR " "
-#endif
+#define CHECK_STATUS_INTERVAL 2000
#define FLOPPY_MOUNT_PATH_PREFIX "/mnt/fd"
-#ifdef HAVE_VOL_DEV
-#define FLOPPY_DEVICE_PATH_PREFIX "/vol/dev/diskette"
-#else
-#define FLOPPY_DEVICE_PATH_PREFIX "/dev/fd"
-#endif
-
#ifdef HAVE_SYS_MNTTAB_H
-#define PATH_MOUNT_TABLE "/etc/mnttab"
-#endif
-
-#ifdef HAVE_MNTENT_H
-#define PATH_MOUNT_TABLE _PATH_MNTTAB
-#endif
-
-#ifdef HAVE_VOL
-# define MNTOPT_NOAUTO "/vol/"
-# else
-# define MNTOPT_NOAUTO "noauto"
-#endif
-
-#ifndef MNTOPT_RO
-# define MNTOPT_RO "ro"
-#endif
-
-#ifndef HAVE_SETMNTENT
-#define setmntent(f,m) fopen(f,m)
+typedef struct mnttab MountTableEntry;
+#else
+typedef struct mntent MountTableEntry;
#endif
struct NautilusVolumeMonitorDetails
@@ -147,6 +125,8 @@ struct NautilusVolumeMonitorDetails
};
static NautilusVolumeMonitor *global_volume_monitor = NULL;
+static const char *floppy_device_path_prefix;
+static const char *noauto_string;
/* The NautilusVolumeMonitor signals. */
@@ -182,7 +162,7 @@ static GList *mount_volume_add_filesystem (NautilusVolume *volume,
static NautilusVolume *create_volume (const char *device_path,
const char *mount_path,
const char *filesystem);
-static NautilusVolume *copy_volume (NautilusVolume *volume);
+static NautilusVolume *copy_volume (NautilusVolume *volume);
static void find_volumes (NautilusVolumeMonitor *monitor);
static void free_mount_list (GList *mount_list);
static GList *get_removable_volumes (void);
@@ -194,7 +174,8 @@ static gboolean locate_audio_cd (void);
#endif
#ifdef SOLARIS_MNT
-static int get_cdrom_type_solaris(char *vol_dev_path, int* fd) ;
+static int get_cdrom_type_solaris (const char *vol_dev_path,
+ int *fd);
#endif
NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusVolumeMonitor,
@@ -242,7 +223,19 @@ nautilus_volume_monitor_initialize_class (NautilusVolumeMonitorClass *klass)
gtk_marshal_NONE__POINTER,
GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
- gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
+ gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
+
+ /* Check environment a bit. */
+ if (g_file_exists ("/vol/dev")) {
+ floppy_device_path_prefix = "/vol/dev/diskette/";
+ } else {
+ floppy_device_path_prefix = "/dev/fd/";
+ }
+ if (g_file_exists ("/vol")) {
+ noauto_string = "/vol/";
+ } else {
+ noauto_string = "/dev/fd/";
+ }
}
static void
@@ -330,31 +323,20 @@ nautilus_volume_monitor_get_removable_volumes (NautilusVolumeMonitor *monitor)
}
-#ifdef HAVE_SYS_MNTTAB_H
-
-static gboolean
-has_removable_mntent_options (struct mnttab *ent)
-{
-
-#else
-
static gboolean
-has_removable_mntent_options (struct mntent *ent)
+has_removable_mntent_options (MountTableEntry *ent)
{
-
-#endif /* HAVE_SYS_MNTTAB_H */
-
/* Use "owner" or "user" or "users" as our way of determining a removable volume */
if (hasmntopt (ent, "user") != NULL
|| hasmntopt (ent, "users") != NULL
|| hasmntopt (ent, "owner") != NULL) {
- return TRUE;
+ return TRUE;
}
-#if SOLARIS_MNT && HAVE_VOL
- if (strstr (ent->mnt_special, "/vol/") == ent->mnt_special) {
- return TRUE;
- }
+#ifdef SOLARIS_MNT
+ if (nautilus_str_has_prefix (ent->mnt_special, "/vol/")) {
+ return TRUE;
+ }
#endif
return FALSE;
@@ -372,36 +354,38 @@ get_removable_volumes (void)
{
FILE *file;
GList *volumes;
-#if HAVE_SYS_MNTTAB_H
- struct mnttab dummy_ent;
- struct mnttab *ent = &dummy_ent;
-#else
- struct mntent *ent;
-#endif /* HAVE_SYS_MNTTAB_H */
+ MountTableEntry *ent;
NautilusVolume *volume;
+#if HAVE_SYS_MNTTAB_H
+ MountTableEntry ent_storage;
+#endif
volumes = NULL;
- file = setmntent (PATH_MOUNT_TABLE, "r");
+ file = setmntent (MOUNT_TABLE_PATH, "r");
if (file == NULL) {
return NULL;
}
#if HAVE_SYS_MNTTAB_H
+ ent = &ent_storage;
while (! getmntent (file, ent)) {
/* On Solaris look for /vol/ for determining a removable volume */
- if (strstr (ent->mnt_special, MNTOPT_NOAUTO) == ent->mnt_special) {
+ if (nautilus_str_has_prefix (ent->mnt_special, noauto_string)) {
volume = create_volume (ent->mnt_special, ent->mnt_mountp, ent->mnt_fstype);
volume->is_removable = TRUE;
- volume->is_read_only = (hasmntopt (ent, MNTOPT_RO) !=NULL);
+ volume->is_read_only = hasmntopt (ent, MNTOPT_RO) != NULL;
+ volumes = mount_volume_add_filesystem (volume, volumes);
+ }
+ }
#else
while ((ent = getmntent (file)) != NULL) {
if (has_removable_mntent_options (ent)) {
volume = create_volume (ent->mnt_fsname, ent->mnt_dir, ent->mnt_type);
-#endif /* HAVE_SYS_MNTTAB_H */
volumes = mount_volume_add_filesystem (volume, volumes);
- }
+ }
}
+#endif /* HAVE_SYS_MNTTAB_H */
fclose (file);
@@ -419,26 +403,24 @@ static gboolean
volume_is_removable (const NautilusVolume *volume)
{
FILE *file;
+ MountTableEntry *ent;
#if HAVE_SYS_MNTTAB_H
- struct mnttab dummy_ent;
- struct mnttab *ent = &dummy_ent;
-#else
- struct mntent *ent;
-#endif /* HAVE_SYS_MNTTAB_H */
+ MountTableEntry ent_storage;
+#endif
- file = setmntent (PATH_MOUNT_TABLE, "r");
+ file = setmntent (MOUNT_TABLE_PATH, "r");
if (file == NULL) {
return FALSE;
}
/* Search for our device in the fstab */
#if HAVE_SYS_MNTTAB_H
+ MountTableEntry *ent = &ent_storage;
while (!getmntent (file, ent)) {
if (strcmp (volume->device_path, ent->mnt_special) == 0) {
/* On Solaris look for /vol/ for determining
a removable volume */
- if (strstr (ent->mnt_special, MNTOPT_NOAUTO)
- == ent->mnt_special) {
+ if (nautilus_str_has_prefix (ent->mnt_special, noauto_string)) {
fclose (file);
return TRUE;
}
@@ -452,7 +434,6 @@ volume_is_removable (const NautilusVolume *volume)
return TRUE;
}
}
-
#endif /* HAVE_SYS_MNTTAB_H */
fclose (file);
@@ -463,18 +444,19 @@ static gboolean
volume_is_read_only (const NautilusVolume *volume)
{
FILE *file;
+ MountTableEntry *ent;
#if HAVE_SYS_MNTTAB_H
- struct mnttab dummy_ent;
- struct mnttab *ent = &dummy_ent;
-
- file = setmntent (PATH_MOUNT_TABLE, "r");
+ MountTableEntry ent_storage;
+
+ file = setmntent (MOUNT_TABLE_PATH, "r");
if (file == NULL) {
return FALSE;
}
/* Search for our device in the fstab */
- while (!getmntent (file, ent)) {
+ ent = &ent_storage;
+ while (!getmntent (file, ent)) {
if (strcmp (volume->device_path, ent->mnt_special) == 0) {
if (strstr (ent->mnt_mntopts, MNTOPT_RO) != NULL) {
fclose (file);
@@ -483,9 +465,7 @@ volume_is_read_only (const NautilusVolume *volume)
}
}
#else
- struct mntent *ent;
-
- file = setmntent (PATH_MOUNT_TABLE, "r");
+ file = setmntent (MOUNT_TABLE_PATH, "r");
if (file == NULL) {
return FALSE;
}
@@ -629,14 +609,12 @@ mount_volume_get_cdrom_name (NautilusVolume *volume)
{
int fd, disctype;
- #ifdef SOLARIS_MNT
- disctype = get_cdrom_type_solaris(volume->device_path, &fd);
-
- #else
+#if SOLARIS_MNT
+ disctype = get_cdrom_type_solaris (volume->device_path, &fd);
+#else
fd = open (volume->device_path, O_RDONLY|O_NONBLOCK);
disctype = ioctl (fd, CDROM_DISC_STATUS, CDSL_CURRENT);
-
- #endif
+#endif
switch (disctype) {
case CDS_AUDIO:
@@ -672,7 +650,7 @@ mount_volume_activate_cdda (NautilusVolumeMonitor *monitor, NautilusVolume *volu
int fd, disctype;
#ifdef SOLARIS_MNT
- disctype = get_cdrom_type_solaris(volume->device_path, &fd);
+ disctype = get_cdrom_type_solaris (volume->device_path, &fd);
#else
fd = open (volume->device_path, O_RDONLY | O_NONBLOCK);
disctype = ioctl (fd, CDROM_DISC_STATUS, CDSL_CURRENT);
@@ -693,7 +671,7 @@ mount_volume_activate_cdrom (NautilusVolumeMonitor *monitor, NautilusVolume *vol
{
int fd, disctype;
#ifdef SOLARIS_MNT
- disctype = get_cdrom_type_solaris(volume->device_path, &fd);
+ disctype = get_cdrom_type_solaris (volume->device_path, &fd);
#else
fd = open (volume->device_path, O_RDONLY | O_NONBLOCK);
disctype = ioctl (fd, CDROM_DISC_STATUS, CDSL_CURRENT);
@@ -918,19 +896,18 @@ build_volume_list_delta (GList *list_one, GList *list_two)
GList *ptrOne, *ptrTwo;
GList *new_list;
NautilusVolume *volOne, *volTwo, *new_volume;
- int index;
gboolean found_match;
new_list = NULL;
- for (ptrOne = list_one, index = 0; ptrOne != NULL; ptrOne = ptrOne->next, index++) {
+ for (ptrOne = list_one; ptrOne != NULL; ptrOne = ptrOne->next) {
found_match = FALSE;
- volOne = (NautilusVolume *)ptrOne->data;
+ volOne = (NautilusVolume *) ptrOne->data;
for (ptrTwo = list_two; ptrTwo != NULL; ptrTwo = ptrTwo->next) {
- volTwo = (NautilusVolume *)ptrTwo->data;
+ volTwo = (NautilusVolume *) ptrTwo->data;
/* Check and see if mount point from list one is in list two */
if (strcmp (volOne->mount_path, volTwo->mount_path) == 0) {
@@ -958,32 +935,36 @@ get_current_mount_list (void)
FILE *fh;
#ifdef SOLARIS_MNT
- struct mnttab dummy_ent;
- struct mnttab *ent = &dummy_ent;
-
- fh = setmntent (PATH_MOUNT_TABLE, "r");
- if (fh == NULL) {
- return NULL;
- }
- while (! getmntent (fh, ent)) {
- volume = create_volume (ent->mnt_special, ent->mnt_mountp, ent->mnt_fstype);
- volume->is_removable = has_removable_mntent_options(ent);
- volume->is_read_only = (hasmntopt (ent, MNTOPT_RO) != NULL);
- current_mounts = mount_volume_add_filesystem (volume, current_mounts);
- }
+ MountTableEntry ent_storage;
+ MountTableEntry *ent = &ent_storage;
+
+ fh = setmntent (MOUNT_TABLE_PATH, "r");
+ if (fh != NULL) {
+ while (! getmntent (fh, ent)) {
+ volume = create_volume (ent->mnt_special, ent->mnt_mountp, ent->mnt_fstype);
+ volume->is_removable = has_removable_mntent_options(ent);
+ volume->is_read_only = hasmntopt (ent, MNTOPT_RO) != NULL;
+ current_mounts = mount_volume_add_filesystem (volume, current_mounts);
+ }
+ }
#else
char line[PATH_MAX * 3];
char device_name[sizeof (line)];
NautilusStringList *list;
char *device_path, *mount_path, *filesystem;
+ const char *separator;
- /* Open /proc/mounts */
- fh = fopen (PATH_PROC_MOUNTS, "r");
+ fh = fopen ("/etc/mnttab", "r");
+ separator = "\t";
+ if (fh == NULL) {
+ fh = fopen ("/proc/mounts", "r");
+ separator = " ";
+ }
g_return_val_if_fail (fh != NULL, NULL);
while (fgets (line, sizeof(line), fh)) {
if (sscanf (line, "%s", device_name) == 1) {
- list = nautilus_string_list_new_from_tokens (line, PROC_MOUNTS_SEPARATOR, FALSE);
+ list = nautilus_string_list_new_from_tokens (line, separator, FALSE);
if (list != NULL) {
/* The string list needs to have at least 3 items per line.
* We need to find at least device path, mount path and file system type.
@@ -1002,9 +983,12 @@ get_current_mount_list (void)
}
}
}
-
#endif /* SOLARIS_MNT */
+ if (fh != NULL) {
+ fclose (fh);
+ }
+
#ifdef HAVE_CDDA
/* CD Audio tricks */
if (locate_audio_cd ()) {
@@ -1014,8 +998,6 @@ get_current_mount_list (void)
}
#endif
- fclose (fh);
-
return current_mounts;
}
@@ -1035,7 +1017,6 @@ update_modifed_volume_name (GList *mount_list, NautilusVolume *volume)
}
}
-
static gboolean
mount_lists_are_identical (GList *list_a, GList *list_b)
{
@@ -1043,7 +1024,6 @@ mount_lists_are_identical (GList *list_a, GList *list_b)
NautilusVolume *volumeOne, *volumeTwo;
for (p = list_a, q = list_b; p != NULL && q != NULL; p = p->next, q = q->next) {
-
volumeOne = p->data;
volumeTwo = q->data;
@@ -1058,17 +1038,7 @@ static void
verify_current_mount_state (NautilusVolumeMonitor *monitor)
{
GList *new_mounts, *old_mounts, *current_mounts;
- GList *saved_mount_list;
- gboolean free_new_mounts;
-
- new_mounts = old_mounts = current_mounts = saved_mount_list = NULL;
-
- /* Free the new mount list only if it is not a copy of the current mount list. */
- if (monitor->details->mounts != NULL) {
- free_new_mounts = TRUE;
- } else {
- free_new_mounts = FALSE;
- }
+ GList *saved_mount_list, *p;
/* Get all current mounts */
current_mounts = get_current_mount_list ();
@@ -1082,17 +1052,9 @@ verify_current_mount_state (NautilusVolumeMonitor *monitor)
return;
}
- /* If saved mounts is NULL, this is the first time we have been here. New mounts
- * are the same as current mounts
- */
- if (monitor->details->mounts == NULL) {
- new_mounts = current_mounts;
- old_mounts = NULL;
- } else {
- /* Create list of new and old mounts */
- new_mounts = build_volume_list_delta (current_mounts, monitor->details->mounts);
- old_mounts = build_volume_list_delta (monitor->details->mounts, current_mounts);
- }
+ /* Create list of new and old mounts */
+ new_mounts = build_volume_list_delta (current_mounts, monitor->details->mounts);
+ old_mounts = build_volume_list_delta (monitor->details->mounts, current_mounts);
/* Stash a copy of the current mount list for updating mount names later. */
saved_mount_list = monitor->details->mounts;
@@ -1101,36 +1063,24 @@ verify_current_mount_state (NautilusVolumeMonitor *monitor)
monitor->details->mounts = current_mounts;
/* Check and see if we have new mounts to add */
- if (new_mounts != NULL) {
- GList *p;
- for (p = new_mounts; p != NULL; p = p->next) {
- mount_volume_activate (monitor, (NautilusVolume *)p->data);
- }
- }
+ for (p = new_mounts; p != NULL; p = p->next) {
+ mount_volume_activate (monitor, (NautilusVolume *)p->data);
+ }
/* Check and see if we have old mounts to remove */
- if (old_mounts != NULL) {
- GList *p;
-
- for (p = old_mounts; p != NULL; p = p->next) {
- /* First we need to update the volume names in this list with modified names in the old list. Names in
- * the old list may have been modifed due to icon name conflicts. The list of old mounts is unable
- * take this into account when it is created
- */
- update_modifed_volume_name (saved_mount_list, (NautilusVolume *)p->data);
-
- /* Deactivate the volume. */
- mount_volume_deactivate (monitor, (NautilusVolume *)p->data);
- }
- free_mount_list (old_mounts);
+ for (p = old_mounts; p != NULL; p = p->next) {
+ /* First we need to update the volume names in this list with modified names in the old list. Names in
+ * the old list may have been modifed due to icon name conflicts. The list of old mounts is unable
+ * take this into account when it is created
+ */
+ update_modifed_volume_name (saved_mount_list, (NautilusVolume *) p->data);
+
+ /* Deactivate the volume. */
+ mount_volume_deactivate (monitor, (NautilusVolume *) p->data);
}
- /* Free the new mount list only if it is not a copy of the current mount list.
- * It will be a copy if there are no previous mounts.
- */
- if (free_new_mounts) {
- free_mount_list (new_mounts);
- }
+ free_mount_list (old_mounts);
+ free_mount_list (new_mounts);
free_mount_list (saved_mount_list);
}
@@ -1148,6 +1098,7 @@ static gboolean
mount_volume_floppy_add (NautilusVolume *volume)
{
volume->type = NAUTILUS_VOLUME_FLOPPY;
+
return TRUE;
}
@@ -1184,43 +1135,49 @@ mount_volume_msdos_add (NautilusVolume *volume)
}
#ifdef SOLARIS_MNT
-static int get_cdrom_type_solaris(char *vol_dev_path, int* fd) {
+static int
+get_cdrom_type_solaris (const char *vol_dev_path, int* fd)
+{
GString *new_dev_path;
struct cdrom_tocentry entry;
- struct cdrom_tochdr header;
- gboolean audio;
-
-/* For ioctl call to work dev_path has to be /vol/dev/rdsk....
- there has to be a nicer way to do this. */
+ struct cdrom_tochdr header;
+ int type;
- new_dev_path = g_string_new(vol_dev_path);
- new_dev_path = g_string_insert_c(new_dev_path, 9, 'r');
-
-
- *fd = open((char *)new_dev_path, O_RDONLY | O_NONBLOCK);
-
- ioctl (*fd, CDROMREADTOCHDR, &header);
- entry.cdte_track = 1;
- entry.cdte_format = CDROM_LBA;
- audio = TRUE;
- while(entry.cdte_track<=header.cdth_trk1 && audio) {
+ /* For ioctl call to work dev_path has to be /vol/dev/rdsk.
+ * There has to be a nicer way to do this.
+ */
+ new_dev_path = g_string_new (vol_dev_path);
+ new_dev_path = g_string_insert_c (new_dev_path, 9, 'r');
+ *fd = open (new_dev_path.str, O_RDONLY | O_NONBLOCK);
+ g_string_free (new_dev_path, TRUE);
- ioctl (*fd, CDROMREADTOCENTRY, &entry);
- if(entry.cdte_ctrl & CDROM_DATA_TRACK)
- audio = FALSE;
- entry.cdte_track++;
+ if (*fd < 0) {
+ return CDS_DATA_1;
}
- g_string_free(new_dev_path, TRUE);
+ if (ioctl (*fd, CDROMREADTOCHDR, &header) == 0) {
+ return CDS_DATA_1;
+ }
- if(audio)
- return(CDS_AUDIO);
+ type = CDS_DATA_1;
+
+ for (entry.cdte_track = 1;
+ entry.cdte_track <= header.cdth_trk1;
+ entry.cdte_track++) {
+ entry.cdte_format = CDROM_LBA;
+ if (ioctl (*fd, CDROMREADTOCENTRY, &entry) == 0) {
+ if (entry.cdte_ctrl & CDROM_DATA_TRACK) {
+ type = CDS_AUDIO;
+ break;
+ }
+ }
+ }
- return(CDS_DATA_1);
+ return type;
}
-#endif
+#endif
static void
cdrom_ioctl_get_info (int fd)
@@ -1233,7 +1190,6 @@ cdrom_ioctl_get_info (int fd)
static gboolean
mount_volume_iso9660_add (NautilusVolume *volume)
{
-
#ifndef SOLARIS_MNT
int fd;
@@ -1249,7 +1205,7 @@ mount_volume_iso9660_add (NautilusVolume *volume)
cdrom_ioctl_get_info (fd);
close (fd);
-#endif /* #ifndef SOLARIS_MNT */
+#endif
volume->type = NAUTILUS_VOLUME_CDROM;
@@ -1376,22 +1332,6 @@ find_volumes (NautilusVolumeMonitor *monitor)
monitor);
}
-#if 0
-void
-nautilus_volume_monitor_each_volume (NautilusVolumeMonitor *monitor,
- NautilusEachVolumeFunction function,
- gpointer context)
-{
- GList *p;
-
- for (p = monitor->details->mounts; p != NULL; p = p->next) {
- if ((* function) ((NautilusVolume *) p->data, context)) {
- break;
- }
- }
-}
-#endif
-
void
nautilus_volume_monitor_each_mounted_volume (NautilusVolumeMonitor *monitor,
NautilusEachVolumeFunction function,
@@ -1434,9 +1374,9 @@ static const char *volrmmount_locations [] = {
};
#define MOUNT_COMMAND volrmmount_locations
-#define MOUNT_SEPERATOR " -i "
+#define MOUNT_SEPARATOR " -i "
#define UMOUNT_COMMAND volrmmount_locations
-#define UMOUNT_SEPERATOR " -e "
+#define UMOUNT_SEPARATOR " -e "
#else
@@ -1453,9 +1393,9 @@ static const char *umount_known_locations [] = {
};
#define MOUNT_COMMAND mount_known_locations
-#define MOUNT_SEPERATOR " "
+#define MOUNT_SEPARATOR " "
#define UMOUNT_COMMAND umount_known_locations
-#define UMOUNT_SEPERATOR " "
+#define UMOUNT_SEPARATOR " "
#endif /* USE_VOLRMMOUNT */
@@ -1503,7 +1443,7 @@ typedef struct {
typedef struct {
char *message;
char *detailed_message;
- char *title;
+ const char *title;
} MountStatusInfo;
@@ -1517,7 +1457,6 @@ display_mount_status (gpointer callback_data)
g_free (info->message);
g_free (info->detailed_message);
- g_free (info->title);
g_free (info);
return FALSE;
@@ -1527,34 +1466,33 @@ static void
close_error_pipe (gboolean mount, const char *mount_path)
{
char *message;
- const char *title;
char detailed_msg[MAX_PIPE_SIZE];
- int length = 0;
+ int length;
gboolean is_floppy;
MountStatusInfo *info;
-
- if (mount) {
- title = _("Mount Error");
- } else {
- title = _("Unmount Error");
+
+ if (old_error < 0) {
+ return;
}
-
- if (old_error >= 0) {
- close (2);
- dup (old_error);
- close (old_error);
-
- do {
- length = read (error_pipe[0], detailed_msg, MAX_PIPE_SIZE);
- } while (length < 0);
-
- if (length >= 0) {
- detailed_msg[length] = 0;
- }
-
- close (error_pipe[0]);
+
+ close (2);
+ dup (old_error);
+ close (old_error);
+
+ /* FIXME: This keeps reading into the same buffer over and
+ * over again and makes no attempt to save bytes from any
+ * calls other than the last read call.
+ */
+ do {
+ length = read (error_pipe[0], detailed_msg, MAX_PIPE_SIZE);
+ } while (length < 0);
+
+ if (length >= 0) {
+ detailed_msg[length] = 0;
}
+ close (error_pipe[0]);
+
/* No output to show */
if (length == 0) {
return;
@@ -1605,13 +1543,11 @@ close_error_pipe (gboolean mount, const char *mount_path)
/* Set up info and pass it to callback to display dialog. We do this because this
routine may be called from a thread */
info = g_new0 (MountStatusInfo, 1);
- info->message = g_strdup (message);
+ info->message = message;
info->detailed_message = g_strdup (detailed_msg);
- info->title = g_strdup (title);
+ info->title = mount ? _("Mount Error") : _("Unmount Error");
gtk_idle_add (display_mount_status, info);
-
- g_free (message);
}
@@ -1667,19 +1603,19 @@ nautilus_volume_monitor_mount_unmount_removable (NautilusVolumeMonitor *monitor,
if (name != NULL) {
name = name + 1;
} else {
- name = mount_point;
+ name = mount_point;
}
#else
name = mount_point;
#endif /* USE_VOLRMMOUNT */
-
+
if (should_mount) {
command = find_command (MOUNT_COMMAND);
- command_string = g_strconcat (command, MOUNT_SEPERATOR, name, NULL);
+ command_string = g_strconcat (command, MOUNT_SEPARATOR, name, NULL);
} else {
command = find_command (UMOUNT_COMMAND);
- command_string = g_strconcat (command, UMOUNT_SEPERATOR, name, NULL);
+ command_string = g_strconcat (command, UMOUNT_SEPARATOR, name, NULL);
}
mount_info = g_new0 (MountThreadInfo, 1);
@@ -1883,7 +1819,7 @@ mount_volume_add_filesystem (NautilusVolume *volume, GList *volume_list)
{
gboolean mounted = FALSE;
- if (nautilus_str_has_prefix (volume->device_path, FLOPPY_DEVICE_PATH_PREFIX)) {
+ if (nautilus_str_has_prefix (volume->device_path, floppy_device_path_prefix)) {
mounted = mount_volume_floppy_add (volume);
} else if (strcmp (volume->filesystem, "affs") == 0) {
mounted = mount_volume_affs_add (volume);
@@ -1931,7 +1867,7 @@ mount_volume_add_filesystem (NautilusVolume *volume, GList *volume_list)
#ifndef SOLARIS_MNT
volume->is_removable = volume_is_removable (volume);
volume->is_read_only = volume_is_read_only (volume);
-#endif /* SOLARIS_MNT */
+#endif
mount_volume_get_name (volume);
volume_list = g_list_append (volume_list, volume);
} else {