svn commit: samba r7473 - in trunk/source/smbd: .

jra at samba.org jra at samba.org
Fri Jun 10 23:13:22 GMT 2005


Author: jra
Date: 2005-06-10 23:13:21 +0000 (Fri, 10 Jun 2005)
New Revision: 7473

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=7473

Log:
A *foul* and *disgusting* hack to ensure that, at the very lowest
level, . and .. are the first two entries returned when reading a
directory. This also means we can't seek to these offsets, but we
will never be doing that anyway (as far as I can think). The reason
we have to do this is that the NT4 explorer will happily display a
folder marked ".." as a clickable folder (and probably would display
"." as a clickable folder too) if these are not in positions zero
and one of the returned file list. W2K seems to have fixed this but
there are too many older systems out there... Never mind, more for
the "Undocumented CIFS talk", coming to a CIFS2005 conference near
you soon.... :-).
Jeremy.

Modified:
   trunk/source/smbd/dir.c


Changeset:
Modified: trunk/source/smbd/dir.c
===================================================================
--- trunk/source/smbd/dir.c	2005-06-10 22:03:33 UTC (rev 7472)
+++ trunk/source/smbd/dir.c	2005-06-10 23:13:21 UTC (rev 7473)
@@ -42,6 +42,7 @@
 	char *dir_path;
 	struct name_cache_entry *name_cache;
 	unsigned int name_cache_index;
+	unsigned int file_number;
 };
 
 struct dptr_struct {
@@ -1074,15 +1075,35 @@
 	const char *n;
 	connection_struct *conn = dirp->conn;
 
-	SeekDir(dirp, *poffset);
+	/* Cheat to allow . and .. to be the first entries returned. */
+	if ((*poffset == 0) && (dirp->file_number < 2)) {
+		if (dirp->file_number == 0) {
+			n = ".";
+		} else {
+			n = "..";
+		}
+		dirp->file_number++;
+		return n;
+	} else {
+		/* A real offset, seek to it. */
+		SeekDir(dirp, *poffset);
+	}
+
 	while ((n = vfs_readdirname(conn, dirp->dir))) {
 		struct name_cache_entry *e;
+		/* Ignore . and .. - we've already returned them. */
+		if (*n == '.') {
+			if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
+				continue;
+			}
+		}
 		dirp->offset = SMB_VFS_TELLDIR(conn, dirp->dir);
 		dirp->name_cache_index = (dirp->name_cache_index+1) % NAME_CACHE_SIZE;
 		e = &dirp->name_cache[dirp->name_cache_index];
 		SAFE_FREE(e->name);
 		e->name = SMB_STRDUP(n);
 		*poffset = e->offset= dirp->offset;
+		dirp->file_number++;
 		return e->name;
 	}
 	dirp->offset = -1;
@@ -1141,6 +1162,7 @@
 
 	/* Not found in the name cache. Rewind directory and start from scratch. */
 	SMB_VFS_REWINDDIR(conn, dirp->dir);
+	dirp->file_number = 0;
 	*poffset = 0;
 	while ((entry = ReadDirName(dirp, poffset))) {
 		if (conn->case_sensitive ? (strcmp(entry, name) == 0) : strequal(entry, name)) {



More information about the samba-cvs mailing list