summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2005-06-10 23:13:25 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:57:10 -0500
commitc3fedee2a67966e4640b26dd084e75125e58f55c (patch)
tree0c1919f5331aa020555287ab21cdbe5dbf315d2e /source3
parent46c94b2659fa1f9d7ce2b6fd798e3abb3c7760d8 (diff)
downloadsamba-c3fedee2a67966e4640b26dd084e75125e58f55c.tar.gz
samba-c3fedee2a67966e4640b26dd084e75125e58f55c.tar.bz2
samba-c3fedee2a67966e4640b26dd084e75125e58f55c.zip
r7474: 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. (This used to be commit 7b6e907922b7d98abe4430ea73712a9c6419ea08)
Diffstat (limited to 'source3')
-rw-r--r--source3/smbd/dir.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index f335c60897..b9c6cf8797 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -42,6 +42,7 @@ struct smb_Dir {
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 *ReadDirName(struct smb_Dir *dirp, long *poffset)
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 @@ BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset)
/* 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)) {