svn commit: samba r8753 - in branches/SAMBA_4_0/source/ntvfs/posix:
.
tridge at samba.org
tridge at samba.org
Mon Jul 25 10:40:18 GMT 2005
Author: tridge
Date: 2005-07-25 10:40:17 +0000 (Mon, 25 Jul 2005)
New Revision: 8753
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=8753
Log:
fixed directory handling on systems that do not return . and .. as the
first two entries in a directory. This is what caused the FC3 system
shelob in the build farm to fail the RAW-UNLINK and RAW-SEARCH tests.
Modified:
branches/SAMBA_4_0/source/ntvfs/posix/pvfs_dirlist.c
Changeset:
Modified: branches/SAMBA_4_0/source/ntvfs/posix/pvfs_dirlist.c
===================================================================
--- branches/SAMBA_4_0/source/ntvfs/posix/pvfs_dirlist.c 2005-07-25 06:33:51 UTC (rev 8752)
+++ branches/SAMBA_4_0/source/ntvfs/posix/pvfs_dirlist.c 2005-07-25 10:40:17 UTC (rev 8753)
@@ -45,6 +45,11 @@
uint32_t name_cache_index;
};
+#define DIR_OFFSET_DOT 0
+#define DIR_OFFSET_DOTDOT 1
+#define DIR_OFFSET_BASE 2
+
+
/*
a special directory listing case where the pattern has no wildcard. We can just do a single stat()
thus avoiding the more expensive directory scan
@@ -150,12 +155,29 @@
return NT_STATUS_OK;
}
+/*
+ add an entry to the local cache
+*/
+static void dcache_add(struct pvfs_dir *dir, const char *name)
+{
+ struct name_cache_entry *e;
+
+ dir->name_cache_index = (dir->name_cache_index+1) % NAME_CACHE_SIZE;
+ e = &dir->name_cache[dir->name_cache_index];
+
+ if (e->name) talloc_free(e->name);
+
+ e->name = talloc_strdup(dir->name_cache, name);
+ e->offset = dir->offset;
+}
+
/*
return the next entry
*/
const char *pvfs_list_next(struct pvfs_dir *dir, uint_t *ofs)
{
struct dirent *de;
+ enum protocol_types protocol = dir->pvfs->tcon->smb_conn->negotiate.protocol;
/* non-wildcard searches are easy */
if (dir->no_wildcard) {
@@ -165,39 +187,58 @@
return dir->single_name;
}
- if (*ofs != dir->offset) {
- seekdir(dir->dir, *ofs);
+ /* . and .. are handled separately as some unix systems will
+ not return them first in a directory, but windows client
+ may assume that these entries always appear first */
+ if (*ofs == DIR_OFFSET_DOT) {
+ (*ofs)++;
dir->offset = *ofs;
+ if (ms_fnmatch(dir->pattern, ".", protocol) == 0) {
+ dcache_add(dir, ".");
+ return ".";
+ }
}
+
+ if (*ofs == DIR_OFFSET_DOTDOT) {
+ (*ofs)++;
+ dir->offset = *ofs;
+ if (ms_fnmatch(dir->pattern, "..", protocol) == 0) {
+ dcache_add(dir, "..");
+ return "..";
+ }
+ }
+
+ if (*ofs == DIR_OFFSET_BASE) {
+ rewinddir(dir->dir);
+ } else if (*ofs != dir->offset) {
+ seekdir(dir->dir, (*ofs) - DIR_OFFSET_BASE);
+ }
+ dir->offset = *ofs;
while ((de = readdir(dir->dir))) {
const char *dname = de->d_name;
- struct name_cache_entry *e;
- if (ms_fnmatch(dir->pattern, dname,
- dir->pvfs->tcon->smb_conn->negotiate.protocol) != 0) {
+ if (strcmp(dname, ".") == 0 ||
+ strcmp(dname, "..") == 0) {
+ continue;
+ }
+
+ if (ms_fnmatch(dir->pattern, dname, protocol) != 0) {
char *short_name = pvfs_short_name_component(dir->pvfs, dname);
if (short_name == NULL ||
- ms_fnmatch(dir->pattern, short_name,
- dir->pvfs->tcon->smb_conn->negotiate.protocol) != 0) {
+ ms_fnmatch(dir->pattern, short_name, protocol) != 0) {
talloc_free(short_name);
continue;
}
talloc_free(short_name);
}
- dir->offset = telldir(dir->dir);
+ dir->offset = telldir(dir->dir) + DIR_OFFSET_BASE;
(*ofs) = dir->offset;
- dir->name_cache_index = (dir->name_cache_index+1) % NAME_CACHE_SIZE;
- e = &dir->name_cache[dir->name_cache_index];
+ dcache_add(dir, dname);
- if (e->name) talloc_free(e->name);
-
- e->name = talloc_strdup(dir->name_cache, de->d_name);
- e->offset = dir->offset;
-
- return e->name;
+ return dname;
}
dir->end_of_search = True;
@@ -228,6 +269,18 @@
struct dirent *de;
int i;
+ if (strcmp(name, ".") == 0) {
+ dir->offset = DIR_OFFSET_DOTDOT;
+ *ofs = dir->offset;
+ return NT_STATUS_OK;
+ }
+
+ if (strcmp(name, "..") == 0) {
+ dir->offset = DIR_OFFSET_BASE;
+ *ofs = dir->offset;
+ return NT_STATUS_OK;
+ }
+
for (i=dir->name_cache_index;i>=0;i--) {
struct name_cache_entry *e = &dir->name_cache[i];
if (e->name && StrCaseCmp(name, e->name) == 0) {
@@ -247,7 +300,7 @@
while ((de = readdir(dir->dir))) {
if (StrCaseCmp(name, de->d_name) == 0) {
- dir->offset = telldir(dir->dir);
+ dir->offset = telldir(dir->dir) + DIR_OFFSET_BASE;
*ofs = dir->offset;
return NT_STATUS_OK;
}
More information about the samba-cvs
mailing list