patch for bonobo-storage-fs, dangling symlinks



It appears that the fs storage plugin was a bit too fascist when it
comes to deciding when to abort the operation on a storage.
Specifically, it would return a NotFound exception if you ever tried
to listContents() on a directory that had dangling symlinks -- the
stat() would fail, and it would abort.  It would also abort if it
couldn't find the file for stat() during listContents, which could
happen if the file was removed after the call to opendir().

The attached patch fixes both problems; I'm not quite sure that using
a mime type of "x-symlink/dangling" is ideal for the type but it
should do for now. :-)

A related issue is that Bonobo/StorageInfo only knows about
STORAGE_TYPE_REGULAR and STORAGE_TYPE_DIRECTORY files.  It seems that
it should also have a STORAGE_TYPE_LINK (or _SYMLINK) -- right now,
the behaviour of the fs storage plugin is that it will give you info
about the file that's being pointed to, not the link itself.  Changing
this entails simply using lstat() in the first place instead of
stat(), but I wanted to get people's input if this makes sense...

Anyway, patch follows.

	- Vladimir

? fs-module.patch
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/bonobo/ChangeLog,v
retrieving revision 1.1026
diff -u -u -r1.1026 ChangeLog
--- ChangeLog	2001/04/03 17:01:30	1.1026
+++ ChangeLog	2001/04/07 22:42:38
@@ -1,3 +1,10 @@
+2001-04-07  Vladimir Vukicevic  <vladimir ximian com>
+
+	* storage-modules/bonobo-storage-fs.c (fs_get_info,
+	fs_list_contents): Try lstat if stat fails so we don't
+	abort on dangling symlinks -- also don't abort list_contents
+	if a file disappears before we stat it.
+
 2001-04-03  Michael Meeks  <michael ximian com>
 
 	* bonobo/bonobo-ui-config-widget.c: use
Index: storage-modules/bonobo-storage-fs.c
===================================================================
RCS file: /cvs/gnome/bonobo/storage-modules/bonobo-storage-fs.c,v
retrieving revision 1.38
diff -u -u -r1.38 bonobo-storage-fs.c
--- storage-modules/bonobo-storage-fs.c	2001/03/26 11:54:32	1.38
+++ storage-modules/bonobo-storage-fs.c	2001/04/07 22:42:39
@@ -42,7 +42,8 @@
 	Bonobo_StorageInfo *si;
 	struct stat st;
 	char *full = NULL;
-	
+	gboolean dangling = FALSE;
+
 	if (mask & ~(Bonobo_FIELD_CONTENT_TYPE | Bonobo_FIELD_SIZE |
 		     Bonobo_FIELD_TYPE)) {
 		CORBA_exception_set (ev, CORBA_USER_EXCEPTION, 
@@ -51,9 +52,13 @@
 	}
 
 	full = g_concat_dir_and_file (storage_fs->path, path);
-
-	if (stat (full, &st) == -1)
-		goto get_info_except;
+	if (stat (full, &st) == -1) {
+		if (lstat (full, &st) == -1) {
+			goto get_info_except;
+		} else {
+			dangling = TRUE;
+		}
+	}
 
 	si = Bonobo_StorageInfo__alloc ();
 	
@@ -65,8 +70,12 @@
 		si->content_type = CORBA_string_dup ("x-directory/normal");
 	} else {
 		si->type = Bonobo_STORAGE_TYPE_REGULAR;
-		si->content_type = 
-			CORBA_string_dup (gnome_mime_type_of_file (full));
+		if (dangling)
+			si->content_type =
+				CORBA_string_dup ("x-symlink/dangling");
+		else
+			si->content_type = 
+				CORBA_string_dup (gnome_mime_type_of_file (full));
 	}
 
 	g_free (full);
@@ -234,9 +243,38 @@
 
 		full = g_concat_dir_and_file (storage_fs->path, de->d_name);
 		v = stat (full, &st);
+
+		if (v == -1) {
+			/* The stat failed -- two common cases are where
+			 * the file was removed between the call to readdir
+			 * and the iteration, and where the file is a dangling
+			 * symlink.
+			 */
+			if (errno == ENOENT || errno == ELOOP) {
+				v = lstat (full, &st);
+				if (v == 0) {
+					/* the file is a dangling symlink
+					 * "x-symlink/dangling should" probably be changed
+					 */
+					buf [i].size = st.st_size;
+					buf [i].type = Bonobo_STORAGE_TYPE_REGULAR;
+					buf [i].content_type =
+						CORBA_string_dup ("x-symlink/dangling");
+					g_free (full);
+					num_entries++;
+					continue;
+				}
+			}
+
+			/* Unless it's something grave, just skip the file */
+			if (errno != ENOMEM && errno != EFAULT && errno != ENOTDIR) {
+				i--;
+				g_free (full);
+				continue;
+			}
 
-		if (v == -1)
 			goto list_contents_except;
+		}
 
 		buf [i].size = st.st_size;
 	





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