/* return the short name for a given entry in a directory */ const char *pvfs_short_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, struct pvfs_filename *name) { char *p = strrchr(name->full_name, '/'); char *ret = pvfs_short_name_component(pvfs, p+1); if (ret == NULL) { return p+1; } talloc_steal(mem_ctx, ret); return ret; }
/* return the next entry */ const char *pvfs_list_next(struct pvfs_dir *dir, off_t *ofs) { struct dirent *de; enum protocol_types protocol = dir->pvfs->ntvfs->ctx->protocol; /* non-wildcard searches are easy */ if (dir->no_wildcard) { dir->end_of_search = True; if (*ofs != 0) return NULL; (*ofs)++; return dir->single_name; } /* . 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_DOTDOT; dir->offset = *ofs; if (ms_fnmatch(dir->pattern, ".", protocol) == 0) { dcache_add(dir, "."); return "."; } } if (*ofs == DIR_OFFSET_DOTDOT) { (*ofs) = DIR_OFFSET_BASE; 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; if (ISDOT(dname) || ISDOTDOT(dname)) { 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, protocol) != 0) { talloc_free(short_name); continue; } talloc_free(short_name); } dir->offset = telldir(dir->dir) + DIR_OFFSET_BASE; (*ofs) = dir->offset; dcache_add(dir, dname); return dname; } dir->end_of_search = True; return NULL; }