diff options
author | Darin Adler <darin@src.gnome.org> | 2001-03-23 02:34:16 +0000 |
---|---|---|
committer | Darin Adler <darin@src.gnome.org> | 2001-03-23 02:34:16 +0000 |
commit | 6a3ac19781a4868006b755038b2f6c97a7ccc15f (patch) | |
tree | d315783ee374366ec01d21e0d6715949c9cd3cf5 /libnautilus-extensions | |
parent | 9f0d5e97730739875032c072e4b7f004a64e9d1c (diff) | |
download | nautilus-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.c | 19 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-global-preferences.h | 3 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-icon-container.c | 19 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-icon-text-item.c | 44 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-medusa-support.c | 69 | ||||
-rw-r--r-- | libnautilus-extensions/nautilus-volume-monitor.c | 434 |
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 { |