nautilus r13660 - in trunk: . libnautilus-private



Author: alexl
Date: Mon Jan 28 12:50:51 2008
New Revision: 13660
URL: http://svn.gnome.org/viewvc/nautilus?rev=13660&view=rev

Log:
2008-01-28  Alexander Larsson  <alexl redhat com>

        * libnautilus-private/nautilus-autorun.c:
	Better finding of case insensitive files. (#511450)
	
        * libnautilus-private/nautilus-file-utilities.[ch]:
        Add nautilus_find_file_insensitive

	Based on patch from John Millikin



Modified:
   trunk/ChangeLog
   trunk/libnautilus-private/nautilus-autorun.c
   trunk/libnautilus-private/nautilus-file-utilities.c
   trunk/libnautilus-private/nautilus-file-utilities.h

Modified: trunk/libnautilus-private/nautilus-autorun.c
==============================================================================
--- trunk/libnautilus-private/nautilus-autorun.c	(original)
+++ trunk/libnautilus-private/nautilus-autorun.c	Mon Jan 28 12:50:51 2008
@@ -41,6 +41,7 @@
 #include "nautilus-program-choosing.h"
 #include "nautilus-open-with-dialog.h"
 #include "nautilus-desktop-icon-file.h"
+#include "nautilus-file-utilities.h"
 
 enum
 {
@@ -536,15 +537,13 @@
 }
 
 static gboolean
-_check_file (GFile *mount_root, const char *file_path, gboolean must_be_executable)
+_check_file_common (GFile *file, gboolean must_be_executable)
 {
-	GFile *file;
 	GFileInfo *file_info;
 	gboolean ret;
 
 	ret = FALSE;
 
-	file = g_file_get_child (mount_root, file_path);
 	file_info = g_file_query_info (file,
 				       G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE,
 				       G_FILE_QUERY_INFO_NONE,
@@ -564,6 +563,24 @@
 	return ret;
 }
 
+static gboolean
+_check_file (GFile *mount_root, const char *file_path,
+             gboolean must_be_executable)
+{
+	/* Unreffed in _check_file_common() */
+	GFile *file = g_file_get_child (mount_root, file_path);
+	return _check_file_common (file, must_be_executable);
+}
+
+static gboolean
+_check_file_case_insensitive (GFile *mount_root, const char *file_path,
+                              gboolean must_be_executable)
+{
+	/* Unreffed in _check_file_common() */
+	GFile *file = nautilus_find_file_insensitive (mount_root, file_path);
+	return _check_file_common (file, must_be_executable);
+}
+
 /**
  * _g_mount_guess_content_type:
  * @mount: a #GMount.
@@ -713,8 +730,8 @@
 	if (_check_file (root, ".autorun", TRUE) ||
 	    _check_file (root, "autorun", TRUE) ||
 	    _check_file (root, "autorun.sh", TRUE) ||
-	    _check_file (root, "autorun.exe", TRUE) || _check_file (root, "AUTORUN.EXE", TRUE) ||
-	    _check_file (root, "autorun.inf", FALSE) || _check_file (root, "AUTORUN.INF", FALSE)) {
+	    _check_file_case_insensitive (root, "autorun.exe", TRUE) ||
+	    _check_file_case_insensitive (root, "autorun.inf", FALSE)) {
 		/* http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html */
 
 		/* http://bugzilla.gnome.org/show_bug.cgi?id=509823#c3 for the autorun.exe and autorun.inf stuff */

Modified: trunk/libnautilus-private/nautilus-file-utilities.c
==============================================================================
--- trunk/libnautilus-private/nautilus-file-utilities.c	(original)
+++ trunk/libnautilus-private/nautilus-file-utilities.c	Mon Jan 28 12:50:51 2008
@@ -37,6 +37,7 @@
 #include <eel/eel-debug.h>
 #include <libgnome/gnome-util.h>
 #include <glib/gi18n.h>
+#include <glib/gstrfuncs.h>
 #include <gio/gio.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -51,7 +52,7 @@
 static void update_xdg_dir_cache (void);
 static void schedule_user_dirs_changed (void);
 static void desktop_dir_changed (void);
-
+static GFile *nautilus_find_file_insensitive_next (GFile *parent, const gchar *name);
 
 char *
 nautilus_compute_title_for_location (GFile *location)
@@ -844,6 +845,115 @@
 	return location;
 }
 
+/**
+ * nautilus_find_file_insensitive
+ * 
+ * Attempt to find a file case-insentively. If the path can be found, the
+ * returned file maps directly to it. Otherwise, a file using the
+ * originally-cased path is returned. This function performs might perform
+ * I/O.
+ * 
+ * Return value: a #GFile to a child specified by @name.
+ **/
+GFile *
+nautilus_find_file_insensitive (GFile *parent, const gchar *name)
+{
+	gchar **split_path;
+	gchar *component;
+	GFile *file, *next;
+	gint i;
+	
+	split_path = g_strsplit (name, G_DIR_SEPARATOR_S, -1);
+	
+	file = g_object_ref (parent);
+	
+	for (i = 0; (component = split_path[i]) != NULL; i++) {
+		if (!(next = nautilus_find_file_insensitive_next (file,
+		                                                  component))) {
+			/* File does not exist */
+			g_object_unref (file);
+			file = NULL;
+			break;
+		}
+		g_object_unref (file);
+		file = next;
+	}
+	g_strfreev (split_path);
+	
+	if (file) {
+		return file;
+	}
+	return g_file_get_child (parent, name);
+}
+
+static GFile *
+nautilus_find_file_insensitive_next (GFile *parent, const gchar *name)
+{
+	GFileEnumerator *children;
+	GFileInfo *info;
+	gboolean use_utf8, found;
+	char *filename, *case_folded_name, *utf8_collation_key, *ascii_collation_key, *child_key;
+	GFile *file;
+	const char *child_name, *compare_key;
+
+	ascii_collation_key = g_ascii_strdown (name, -1);
+	use_utf8 = g_utf8_validate (name, -1, NULL);
+	utf8_collation_key = NULL;	
+	if (use_utf8) {
+		case_folded_name = g_utf8_casefold (name, -1);
+		utf8_collation_key = g_utf8_collate_key (case_folded_name, -1);
+		g_free (case_folded_name);
+	}
+
+	/* First check the given version */
+	file = g_file_get_child (parent, name);
+	if (g_file_query_exists (file, NULL)) {
+		return file;
+	}
+	g_object_unref (file);
+	
+	/* Enumerate and compare insensitive */
+	filename = NULL;
+	children = g_file_enumerate_children (parent,
+	                                      G_FILE_ATTRIBUTE_STANDARD_NAME,
+	                                      0, NULL, NULL);
+	while ((info = g_file_enumerator_next_file (children, NULL, NULL))) {
+		child_name = g_file_info_get_name (info);
+		
+		if (use_utf8 && g_utf8_validate (child_name, -1, NULL)) {
+			gchar *case_folded;
+			
+			case_folded = g_utf8_casefold (child_name, -1);
+			child_key = g_utf8_collate_key (case_folded, -1);
+			g_free (case_folded);
+			compare_key = utf8_collation_key;
+		} else {
+			child_key = g_ascii_strdown (child_name, -1);
+			compare_key = ascii_collation_key;
+		}
+
+		found = strcmp (child_key, compare_key) == 0;
+		g_free (child_key);
+		if (found) {
+			filename = g_strdup (child_name);
+			break;
+		}
+	}
+	g_file_enumerator_close (children, NULL, NULL);
+	g_object_unref (children);
+	
+	g_free (ascii_collation_key);
+	g_free (utf8_collation_key);
+	
+	if (filename) {
+		file = g_file_get_child (parent, filename);
+		g_free (filename);
+		return file;
+	}
+	
+	return NULL;
+}
+
 #if !defined (NAUTILUS_OMIT_SELF_CHECK)
 
 void

Modified: trunk/libnautilus-private/nautilus-file-utilities.h
==============================================================================
--- trunk/libnautilus-private/nautilus-file-utilities.h	(original)
+++ trunk/libnautilus-private/nautilus-file-utilities.h	Mon Jan 28 12:50:51 2008
@@ -90,4 +90,7 @@
 
 GFile *  nautilus_find_existing_uri_in_hierarchy     (GFile *location);
 
+GFile *
+nautilus_find_file_insensitive (GFile *parent, const gchar *name);
+
 #endif /* NAUTILUS_FILE_UTILITIES_H */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]