diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-02-05 20:53:40 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2019-02-05 20:53:40 +0100 |
commit | a2abe177e4ec99e3ca22d96fd472c68a19ffe152 (patch) | |
tree | 12d71a665b326e6530ae02f011a48bf0ad819b5e /sys/src/cmd/cifs | |
parent | 31637404ba902c53ad26a1686e60dd1340000cdb (diff) |
cifs: fix pruning of . and .. directory entries (thanks steve simon)
steve wrote:
> I cam across a bug in cifs.
>
> An empty directory under windows 7 pro contains a single entry "." but it
> doesn't appear to contain "..". As a result "." is not removed on dirscan
> and plan9 gets when trying to traverse the hierarchy.
Diffstat (limited to 'sys/src/cmd/cifs')
-rw-r--r-- | sys/src/cmd/cifs/main.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/sys/src/cmd/cifs/main.c b/sys/src/cmd/cifs/main.c index 67895b42f..720f728fc 100644 --- a/sys/src/cmd/cifs/main.c +++ b/sys/src/cmd/cifs/main.c @@ -189,6 +189,27 @@ newpath(char *path, char *name) return smprint("%s/%s", path, name); } +/* remove "." and ".." from the cache */ +static int +rmdots(Aux *a, int got) +{ + int i, num; + FInfo *fi; + + num = 0; + fi = (FInfo *)a->cache; + for(i = 0; i < got; i++){ + if(strcmp(fi->name, ".") == 0 || strcmp(fi->name, "..") == 0){ + memmove(fi, fi+1, got * sizeof(FInfo)); + continue; + } + fi++; + num++; + } + + return num; +} + static int dirgen(int slot, Dir *d, void *aux) { @@ -200,7 +221,7 @@ dirgen(int slot, Dir *d, void *aux) int numinf = numinfo(); int slots; - slots = 128; /* number of dir entries to fetch at one time */ + slots = 32; /* number of dir entries to fetch at one time */ if(strcmp(a->path, "/") == 0){ if(slot < numinf){ @@ -221,7 +242,6 @@ dirgen(int slot, Dir *d, void *aux) goto from_cache; if(off == 0){ - fi = (FInfo *)a->cache; npath = smprint("%s/*", mapfile(a->path)); a->sh = T2findfirst(Sess, a->sp, slots, npath, &got, &a->srch, (FInfo *)a->cache); @@ -229,15 +249,10 @@ dirgen(int slot, Dir *d, void *aux) if(a->sh == -1) return -1; + got = rmdots(a, got); a->off = 0; a->end = got * sizeof(FInfo); - - if(got >= 2 && strcmp(fi[0].name, ".") == 0 && - strcmp(fi[1].name, "..") == 0){ - a->end = (got - 2) * sizeof(FInfo); - memmove(a->cache, a->cache + sizeof(FInfo)*2, - a->end - a->off); - } + goto from_cache; } while(off >= a->end && a->sh != -1){ @@ -249,6 +264,7 @@ dirgen(int slot, Dir *d, void *aux) free(npath); if(rc == -1 || got == 0) break; + got = rmdots(a, got); a->end = a->off + got * sizeof(FInfo); } a->expire = time(nil) + CACHETIME; @@ -259,10 +275,11 @@ dirgen(int slot, Dir *d, void *aux) a->sh = -1; } + +from_cache: if(off >= a->end) return -1; -from_cache: fi = (FInfo *)(a->cache + (off - a->off)); npath = smprint("%s/%s", mapfile(a->path), fi->name); I2D(d, a->sp, npath, fi); |