mirror of
https://github.com/samba-team/samba.git
synced 2025-08-04 08:22:08 +03:00
r5160: First cut at refactoring of directory code to handle non-wildcard
directory match more efficiently. Passes RAW-SEARCH under valgrind but needs more testing (which I'll do later today :-). Jeremy.
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
d6c7de2408
commit
0b04dd9d0c
@ -40,10 +40,6 @@ struct smb_Dir {
|
||||
char *dir_path;
|
||||
struct name_cache_entry *name_cache;
|
||||
unsigned int name_cache_index;
|
||||
BOOL hide_unreadable;
|
||||
BOOL hide_unwriteable;
|
||||
BOOL hide_special;
|
||||
BOOL use_veto;
|
||||
};
|
||||
|
||||
struct dptr_struct {
|
||||
@ -142,7 +138,7 @@ static struct dptr_struct *dptr_get(int key, BOOL forclose)
|
||||
if (dptrs_open >= MAX_OPEN_DIRECTORIES)
|
||||
dptr_idleoldest();
|
||||
DEBUG(4,("dptr_get: Reopening dptr key %d\n",key));
|
||||
if (!(dptr->dir_hnd = OpenDir(dptr->conn, dptr->path, True))) {
|
||||
if (!(dptr->dir_hnd = OpenDir(dptr->conn, dptr->path))) {
|
||||
DEBUG(4,("dptr_get: Failed to open %s (%s)\n",dptr->path,
|
||||
strerror(errno)));
|
||||
return False;
|
||||
@ -205,7 +201,11 @@ BOOL dptr_set_wcard_and_attributes(int key, const char *wcard, uint16 attr)
|
||||
dptr->wcard = SMB_STRDUP(wcard);
|
||||
if (!dptr->wcard)
|
||||
return False;
|
||||
if (wcard[0] == '.' && wcard[1] == 0) {
|
||||
dptr->has_wild = True;
|
||||
} else {
|
||||
dptr->has_wild = ms_has_wild(wcard);
|
||||
}
|
||||
return True;
|
||||
}
|
||||
return False;
|
||||
@ -378,7 +378,7 @@ int dptr_create(connection_struct *conn, pstring path, BOOL old_handle, BOOL exp
|
||||
if (!*dir2)
|
||||
dir2 = ".";
|
||||
|
||||
dir_hnd = OpenDir(conn, dir2, True);
|
||||
dir_hnd = OpenDir(conn, dir2);
|
||||
if (!dir_hnd) {
|
||||
return (-2);
|
||||
}
|
||||
@ -490,11 +490,6 @@ int dptr_CloseDir(struct dptr_struct *dptr)
|
||||
return CloseDir(dptr->dir_hnd);
|
||||
}
|
||||
|
||||
const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset)
|
||||
{
|
||||
return ReadDirName(dptr->dir_hnd, poffset);
|
||||
}
|
||||
|
||||
void dptr_SeekDir(struct dptr_struct *dptr, long offset)
|
||||
{
|
||||
SeekDir(dptr->dir_hnd, offset);
|
||||
@ -505,9 +500,90 @@ long dptr_TellDir(struct dptr_struct *dptr)
|
||||
return TellDir(dptr->dir_hnd);
|
||||
}
|
||||
|
||||
BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, BOOL case_sensitive)
|
||||
/****************************************************************************
|
||||
Return the next visible file name, skipping veto'd and invisible files.
|
||||
****************************************************************************/
|
||||
|
||||
static const char *dptr_normal_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT_STAT *pst)
|
||||
{
|
||||
return SearchDir(dptr->dir_hnd, name, poffset, case_sensitive);
|
||||
/* Normal search for the next file. */
|
||||
const char *name;
|
||||
while ((name = ReadDirName(dptr->dir_hnd, poffset)) != NULL) {
|
||||
if (is_visible_file(dptr->conn, dptr->path, name, pst, True)) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Return the next visible file name, skipping veto'd and invisible files.
|
||||
****************************************************************************/
|
||||
|
||||
const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT_STAT *pst)
|
||||
{
|
||||
pstring pathreal;
|
||||
|
||||
ZERO_STRUCTP(pst);
|
||||
if (dptr->has_wild) {
|
||||
return dptr_normal_ReadDirName(dptr, poffset, pst);
|
||||
}
|
||||
|
||||
/* We know the stored wcard contains no wildcard characters. See if we can match
|
||||
with a stat call. If we can't, then set has_wild to true to
|
||||
prevent us from doing this on every call. */
|
||||
|
||||
/* First check if it should be visible. */
|
||||
if (!is_visible_file(dptr->conn, dptr->path, dptr->wcard, pst, True)) {
|
||||
dptr->has_wild = True;
|
||||
return dptr_normal_ReadDirName(dptr, poffset, pst);
|
||||
}
|
||||
|
||||
if (VALID_STAT(*pst)) {
|
||||
return dptr->wcard;
|
||||
}
|
||||
|
||||
pstrcpy(pathreal,dptr->path);
|
||||
pstrcat(pathreal,"/");
|
||||
pstrcat(pathreal,dptr->wcard);
|
||||
|
||||
if (SMB_VFS_STAT(dptr->conn,pathreal,pst) == 0) {
|
||||
return dptr->wcard;
|
||||
} else {
|
||||
/* If we get any other error than ENOENT or ENOTDIR
|
||||
then the file exists we just can't stat it. */
|
||||
if (errno != ENOENT && errno != ENOTDIR) {
|
||||
return dptr->wcard;
|
||||
}
|
||||
}
|
||||
|
||||
dptr->has_wild = True;
|
||||
|
||||
/* In case sensitive mode we don't search - we know if it doesn't exist
|
||||
with a stat we will fail. */
|
||||
|
||||
if (dptr->conn->case_sensitive) {
|
||||
return NULL;
|
||||
} else {
|
||||
return dptr_normal_ReadDirName(dptr, poffset, pst);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Search for a file by name, skipping veto'ed and not visible files.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL dptr_SearchDir(struct dptr_struct *dptr, const char *name, long *poffset, SMB_STRUCT_STAT *pst)
|
||||
{
|
||||
BOOL ret;
|
||||
|
||||
ZERO_STRUCTP(pst);
|
||||
while ((ret = SearchDir(dptr->dir_hnd, name, poffset)) == True) {
|
||||
if (is_visible_file(dptr->conn, dptr->path, name, pst, True)) {
|
||||
return True;
|
||||
}
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -573,7 +649,7 @@ struct dptr_struct *dptr_fetch_lanman2(int dptr_num)
|
||||
Check a filetype for being valid.
|
||||
****************************************************************************/
|
||||
|
||||
BOOL dir_check_ftype(connection_struct *conn,int mode,SMB_STRUCT_STAT *st,int dirtype)
|
||||
BOOL dir_check_ftype(connection_struct *conn,int mode,int dirtype)
|
||||
{
|
||||
int mask;
|
||||
|
||||
@ -629,8 +705,8 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname
|
||||
return(False);
|
||||
|
||||
while (!found) {
|
||||
long curoff = TellDir(conn->dirptr->dir_hnd);
|
||||
dname = ReadDirName(conn->dirptr->dir_hnd, &curoff);
|
||||
long curoff = dptr_TellDir(conn->dirptr);
|
||||
dname = dptr_ReadDirName(conn->dirptr, &curoff, &sbuf);
|
||||
|
||||
DEBUG(6,("readdir on dirptr 0x%lx now at offset %ld\n",
|
||||
(long)conn->dirptr,TellDir(conn->dirptr->dir_hnd)));
|
||||
@ -661,14 +737,14 @@ BOOL get_dir_entry(connection_struct *conn,char *mask,int dirtype, pstring fname
|
||||
pstrcpy(pathreal,path);
|
||||
pstrcat(path,fname);
|
||||
pstrcat(pathreal,dname);
|
||||
if (SMB_VFS_STAT(conn, pathreal, &sbuf) != 0) {
|
||||
if (!VALID_STAT(sbuf) && (SMB_VFS_STAT(conn, pathreal, &sbuf)) != 0) {
|
||||
DEBUG(5,("Couldn't stat 1 [%s]. Error = %s\n",path, strerror(errno) ));
|
||||
continue;
|
||||
}
|
||||
|
||||
*mode = dos_mode(conn,pathreal,&sbuf);
|
||||
|
||||
if (!dir_check_ftype(conn,*mode,&sbuf,dirtype)) {
|
||||
if (!dir_check_ftype(conn,*mode,dirtype)) {
|
||||
DEBUG(5,("[%s] attribs didn't match %x\n",filename,dirtype));
|
||||
continue;
|
||||
}
|
||||
@ -816,11 +892,58 @@ static BOOL file_is_special(connection_struct *conn, char *name, SMB_STRUCT_STAT
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Should the file be seen by the client ?
|
||||
********************************************************************/
|
||||
|
||||
BOOL is_visible_file(connection_struct *conn, const char *dir_path, const char *name, SMB_STRUCT_STAT *pst, BOOL use_veto)
|
||||
{
|
||||
BOOL hide_unreadable = lp_hideunreadable(SNUM(conn));
|
||||
BOOL hide_unwriteable = lp_hideunwriteable_files(SNUM(conn));
|
||||
BOOL hide_special = lp_hide_special_files(SNUM(conn));
|
||||
|
||||
ZERO_STRUCT(pst);
|
||||
|
||||
if ((strcmp(".",name) == 0) || (strcmp("..",name) == 0)) {
|
||||
return True; /* . and .. are always visible. */
|
||||
}
|
||||
|
||||
/* If it's a vetoed file, pretend it doesn't even exist */
|
||||
if (use_veto && IS_VETO_PATH(conn, name)) {
|
||||
return False;
|
||||
}
|
||||
|
||||
if (hide_unreadable || hide_unwriteable || hide_special) {
|
||||
char *entry = NULL;
|
||||
|
||||
if (asprintf(&entry, "%s/%s", dir_path, name) == -1) {
|
||||
return False;
|
||||
}
|
||||
/* Honour _hide unreadable_ option */
|
||||
if (hide_unreadable && !user_can_read_file(conn, entry, pst)) {
|
||||
SAFE_FREE(entry);
|
||||
return False;
|
||||
}
|
||||
/* Honour _hide unwriteable_ option */
|
||||
if (hide_unwriteable && !user_can_write_file(conn, entry, pst)) {
|
||||
SAFE_FREE(entry);
|
||||
return False;
|
||||
}
|
||||
/* Honour _hide_special_ option */
|
||||
if (hide_special && !file_is_special(conn, entry, pst)) {
|
||||
SAFE_FREE(entry);
|
||||
return False;
|
||||
}
|
||||
SAFE_FREE(entry);
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Open a directory.
|
||||
********************************************************************/
|
||||
|
||||
struct smb_Dir *OpenDir(connection_struct *conn, const char *name, BOOL use_veto)
|
||||
struct smb_Dir *OpenDir(connection_struct *conn, const char *name)
|
||||
{
|
||||
struct smb_Dir *dirp = SMB_MALLOC_P(struct smb_Dir);
|
||||
if (!dirp) {
|
||||
@ -829,7 +952,6 @@ struct smb_Dir *OpenDir(connection_struct *conn, const char *name, BOOL use_veto
|
||||
ZERO_STRUCTP(dirp);
|
||||
|
||||
dirp->conn = conn;
|
||||
dirp->use_veto = use_veto;
|
||||
|
||||
dirp->dir_path = SMB_STRDUP(name);
|
||||
if (!dirp->dir_path) {
|
||||
@ -846,10 +968,6 @@ struct smb_Dir *OpenDir(connection_struct *conn, const char *name, BOOL use_veto
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dirp->hide_unreadable = lp_hideunreadable(SNUM(conn));
|
||||
dirp->hide_unwriteable = lp_hideunwriteable_files(SNUM(conn));
|
||||
dirp->hide_special = lp_hide_special_files(SNUM(conn));
|
||||
|
||||
dptrs_open++;
|
||||
return dirp;
|
||||
|
||||
@ -892,6 +1010,7 @@ int CloseDir(struct smb_Dir *dirp)
|
||||
|
||||
/*******************************************************************
|
||||
Read from a directory. Also return current offset.
|
||||
Don't check for veto or invisible files.
|
||||
********************************************************************/
|
||||
|
||||
const char *ReadDirName(struct smb_Dir *dirp, long *poffset)
|
||||
@ -902,40 +1021,6 @@ const char *ReadDirName(struct smb_Dir *dirp, long *poffset)
|
||||
SeekDir(dirp, *poffset);
|
||||
while ((n = vfs_readdirname(conn, dirp->dir))) {
|
||||
struct name_cache_entry *e;
|
||||
|
||||
if (!((strcmp(".",n) == 0) || (strcmp("..",n) == 0))) {
|
||||
/* If it's a vetoed file, pretend it doesn't even exist */
|
||||
if (dirp->use_veto && IS_VETO_PATH(conn, n)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dirp->hide_unreadable || dirp->hide_unwriteable || dirp->hide_special) {
|
||||
SMB_STRUCT_STAT st;
|
||||
char *entry = NULL;
|
||||
ZERO_STRUCT(st);
|
||||
|
||||
if (asprintf(&entry, "%s/%s/%s", conn->origpath, dirp->dir_path, n) == -1) {
|
||||
return NULL;
|
||||
}
|
||||
/* Honour _hide unreadable_ option */
|
||||
if (dirp->hide_unreadable && !user_can_read_file(conn, entry, &st)) {
|
||||
SAFE_FREE(entry);
|
||||
continue;
|
||||
}
|
||||
/* Honour _hide unwriteable_ option */
|
||||
if (dirp->hide_unwriteable && !user_can_write_file(conn, entry, &st)) {
|
||||
SAFE_FREE(entry);
|
||||
continue;
|
||||
}
|
||||
/* Honour _hide_special_ option */
|
||||
if (dirp->hide_special && !file_is_special(conn, entry, &st)) {
|
||||
SAFE_FREE(entry);
|
||||
continue;
|
||||
}
|
||||
SAFE_FREE(entry);
|
||||
}
|
||||
}
|
||||
|
||||
dirp->offset = SMB_VFS_TELLDIR(conn, dirp->dir);
|
||||
if (dirp->offset == -1) {
|
||||
return NULL;
|
||||
@ -974,9 +1059,10 @@ long TellDir(struct smb_Dir *dirp)
|
||||
|
||||
/*******************************************************************
|
||||
Find an entry by name. Leave us at the offset after it.
|
||||
Don't check for veto or invisible files.
|
||||
********************************************************************/
|
||||
|
||||
BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset, BOOL case_sensitive)
|
||||
BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset)
|
||||
{
|
||||
int i;
|
||||
const char *entry;
|
||||
@ -985,7 +1071,7 @@ BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset, BOOL case_
|
||||
/* Search back in the name cache. */
|
||||
for (i = dirp->name_cache_index; i >= 0; i--) {
|
||||
struct name_cache_entry *e = &dirp->name_cache[i];
|
||||
if (e->name && (case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) {
|
||||
if (e->name && (conn->case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) {
|
||||
*poffset = e->offset;
|
||||
SeekDir(dirp, e->offset);
|
||||
return True;
|
||||
@ -993,7 +1079,7 @@ BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset, BOOL case_
|
||||
}
|
||||
for (i = NAME_CACHE_SIZE-1; i > dirp->name_cache_index; i--) {
|
||||
struct name_cache_entry *e = &dirp->name_cache[i];
|
||||
if (e->name && (case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) {
|
||||
if (e->name && (conn->case_sensitive ? (strcmp(e->name, name) == 0) : strequal(e->name, name))) {
|
||||
*poffset = e->offset;
|
||||
SeekDir(dirp, e->offset);
|
||||
return True;
|
||||
@ -1004,7 +1090,7 @@ BOOL SearchDir(struct smb_Dir *dirp, const char *name, long *poffset, BOOL case_
|
||||
SMB_VFS_REWINDDIR(conn, dirp->dir);
|
||||
*poffset = 0;
|
||||
while ((entry = ReadDirName(dirp, poffset))) {
|
||||
if (case_sensitive ? (strcmp(entry, name) == 0) : strequal(entry, name)) {
|
||||
if (conn->case_sensitive ? (strcmp(entry, name) == 0) : strequal(entry, name)) {
|
||||
return True;
|
||||
}
|
||||
}
|
||||
|
@ -454,7 +454,7 @@ static BOOL scan_directory(connection_struct *conn, const char *path, char *name
|
||||
mangled = !mangle_check_cache( name, maxlength );
|
||||
|
||||
/* open the directory */
|
||||
if (!(cur_dir = OpenDir(conn, path, True))) {
|
||||
if (!(cur_dir = OpenDir(conn, path))) {
|
||||
DEBUG(3,("scan dir didn't open dir [%s]\n",path));
|
||||
return(False);
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags,
|
||||
* larger than the max time_t value).
|
||||
*/
|
||||
|
||||
dp = OpenDir(conn, path, True);
|
||||
dp = OpenDir(conn, path);
|
||||
if (dp == NULL)
|
||||
return False;
|
||||
|
||||
@ -91,18 +91,22 @@ static BOOL notify_hash(connection_struct *conn, char *path, uint32 flags,
|
||||
|
||||
offset = 0;
|
||||
while ((fname = ReadDirName(dp, &offset))) {
|
||||
ZERO_STRUCT(st);
|
||||
if(strequal(fname, ".") || strequal(fname, ".."))
|
||||
continue;
|
||||
|
||||
if (!is_visible_file(conn, path, fname, &st, True))
|
||||
continue;
|
||||
|
||||
data->num_entries++;
|
||||
safe_strcpy(p, fname, remaining_len);
|
||||
|
||||
ZERO_STRUCT(st);
|
||||
|
||||
/*
|
||||
* Do the stat - but ignore errors.
|
||||
*/
|
||||
if (!VALID_STAT(st)) {
|
||||
SMB_VFS_STAT(conn,full_name, &st);
|
||||
}
|
||||
|
||||
/*
|
||||
* Always sum the times.
|
||||
|
@ -1610,7 +1610,7 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
|
||||
const char *dname;
|
||||
|
||||
if (check_name(directory,conn))
|
||||
dir_hnd = OpenDir(conn, directory, True);
|
||||
dir_hnd = OpenDir(conn, directory);
|
||||
|
||||
/* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
|
||||
the pattern matches against the long name, otherwise the short name
|
||||
@ -1625,10 +1625,15 @@ NTSTATUS unlink_internals(connection_struct *conn, int dirtype, char *name)
|
||||
pstrcpy(mask,"*");
|
||||
|
||||
while ((dname = ReadDirName(dir_hnd, &offset))) {
|
||||
SMB_STRUCT_STAT st;
|
||||
pstring fname;
|
||||
BOOL sys_direntry = False;
|
||||
pstrcpy(fname,dname);
|
||||
|
||||
if (!is_visible_file(conn, directory, dname, &st, True)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Quick check for "." and ".." */
|
||||
if (fname[0] == '.') {
|
||||
if (!fname[1] || (fname[1] == '.' && !fname[2])) {
|
||||
@ -3368,7 +3373,7 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory)
|
||||
const char *dname = NULL;
|
||||
BOOL ret = False;
|
||||
long offset = 0;
|
||||
struct smb_Dir *dir_hnd = OpenDir(conn, directory, False);
|
||||
struct smb_Dir *dir_hnd = OpenDir(conn, directory);
|
||||
|
||||
if(dir_hnd == NULL)
|
||||
return True;
|
||||
@ -3380,6 +3385,9 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory)
|
||||
if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
|
||||
continue;
|
||||
|
||||
if (!is_visible_file(conn, directory, dname, &st, False))
|
||||
continue;
|
||||
|
||||
/* Construct the full name. */
|
||||
if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
|
||||
errno = ENOMEM;
|
||||
@ -3421,6 +3429,7 @@ static BOOL recursive_rmdir(connection_struct *conn, char *directory)
|
||||
BOOL rmdir_internals(connection_struct *conn, char *directory)
|
||||
{
|
||||
BOOL ok;
|
||||
SMB_STRUCT_STAT st;
|
||||
|
||||
ok = (SMB_VFS_RMDIR(conn,directory) == 0);
|
||||
if(!ok && ((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
|
||||
@ -3432,13 +3441,15 @@ BOOL rmdir_internals(connection_struct *conn, char *directory)
|
||||
*/
|
||||
BOOL all_veto_files = True;
|
||||
const char *dname;
|
||||
struct smb_Dir *dir_hnd = OpenDir(conn, directory, False);
|
||||
struct smb_Dir *dir_hnd = OpenDir(conn, directory);
|
||||
|
||||
if(dir_hnd != NULL) {
|
||||
long dirpos = TellDir(dir_hnd);
|
||||
while ((dname = ReadDirName(dir_hnd,&dirpos))) {
|
||||
if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
|
||||
continue;
|
||||
if (!is_visible_file(conn, directory, dname, &st, False))
|
||||
continue;
|
||||
if(!IS_VETO_PATH(conn, dname)) {
|
||||
all_veto_files = False;
|
||||
break;
|
||||
@ -3449,10 +3460,11 @@ BOOL rmdir_internals(connection_struct *conn, char *directory)
|
||||
SeekDir(dir_hnd,dirpos);
|
||||
while ((dname = ReadDirName(dir_hnd,&dirpos))) {
|
||||
pstring fullname;
|
||||
SMB_STRUCT_STAT st;
|
||||
|
||||
if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0))
|
||||
continue;
|
||||
if (!is_visible_file(conn, directory, dname, &st, False))
|
||||
continue;
|
||||
|
||||
/* Construct the full name. */
|
||||
if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) {
|
||||
@ -3988,7 +4000,7 @@ directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n",
|
||||
pstring destname;
|
||||
|
||||
if (check_name(directory,conn))
|
||||
dir_hnd = OpenDir(conn, directory, True);
|
||||
dir_hnd = OpenDir(conn, directory);
|
||||
|
||||
if (dir_hnd) {
|
||||
long offset = 0;
|
||||
@ -4015,6 +4027,9 @@ directory = %s, newname = %s, last_component_dest = %s, is_8_3 = %d\n",
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_visible_file(conn, directory, dname, &sbuf1, False))
|
||||
continue;
|
||||
|
||||
if(!mask_match(fname, mask, conn->case_sensitive))
|
||||
continue;
|
||||
|
||||
@ -4342,7 +4357,7 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
pstring destname;
|
||||
|
||||
if (check_name(directory,conn))
|
||||
dir_hnd = OpenDir(conn, directory, True);
|
||||
dir_hnd = OpenDir(conn, directory);
|
||||
|
||||
if (dir_hnd) {
|
||||
long offset = 0;
|
||||
@ -4355,6 +4370,9 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
pstring fname;
|
||||
pstrcpy(fname,dname);
|
||||
|
||||
if (!is_visible_file(conn, directory, dname, &sbuf1, False))
|
||||
continue;
|
||||
|
||||
if(!mask_match(fname, mask, conn->case_sensitive))
|
||||
continue;
|
||||
|
||||
|
@ -864,11 +864,12 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
|
||||
} else
|
||||
pstrcpy(mask, path_mask);
|
||||
|
||||
|
||||
while (!found) {
|
||||
BOOL got_match;
|
||||
/* Needed if we run out of space */
|
||||
long curr_dirpos = prev_dirpos = dptr_TellDir(conn->dirptr);
|
||||
dname = dptr_ReadDirName(conn->dirptr,&curr_dirpos);
|
||||
dname = dptr_ReadDirName(conn->dirptr,&curr_dirpos,&sbuf);
|
||||
|
||||
/*
|
||||
* Due to bugs in NT client redirectors we are not using
|
||||
@ -922,7 +923,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
|
||||
pathreal,strerror(errno)));
|
||||
continue;
|
||||
}
|
||||
} else if (SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
|
||||
} else if (!VALID_STAT(sbuf) && SMB_VFS_STAT(conn,pathreal,&sbuf) != 0) {
|
||||
|
||||
/* Needed to show the msdfs symlinks as
|
||||
* directories */
|
||||
@ -945,7 +946,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
|
||||
|
||||
mode = dos_mode(conn,pathreal,&sbuf);
|
||||
|
||||
if (!dir_check_ftype(conn,mode,&sbuf,dirtype)) {
|
||||
if (!dir_check_ftype(conn,mode,dirtype)) {
|
||||
DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
|
||||
continue;
|
||||
}
|
||||
@ -1341,7 +1342,7 @@ static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outb
|
||||
int info_level = SVAL(params,6);
|
||||
pstring directory;
|
||||
pstring mask;
|
||||
char *p, *wcard;
|
||||
char *p;
|
||||
int last_name_off=0;
|
||||
int dptr_num = -1;
|
||||
int numentries = 0;
|
||||
@ -1442,7 +1443,7 @@ close_if_end = %d requires_resume_key = %d level = 0x%x, max_data_bytes = %d\n",
|
||||
return ERROR_DOS(ERRDOS,ERRnomem);
|
||||
}
|
||||
|
||||
DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
|
||||
DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, mask, dirtype));
|
||||
|
||||
/* We don't need to check for VOL here as this is returned by
|
||||
a different TRANS2 call. */
|
||||
@ -1667,6 +1668,8 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
|
||||
*/
|
||||
|
||||
if(*resume_name && !continue_bit) {
|
||||
SMB_STRUCT_STAT st;
|
||||
|
||||
long current_pos = 0;
|
||||
/*
|
||||
* Remember, mangle_map is called by
|
||||
@ -1687,7 +1690,7 @@ resume_key = %d resume name = %s continue=%d level = %d\n",
|
||||
* should already be at the correct place.
|
||||
*/
|
||||
|
||||
finished = !dptr_SearchDir(conn->dirptr, resume_name, ¤t_pos, True);
|
||||
finished = !dptr_SearchDir(conn->dirptr, resume_name, ¤t_pos, &st);
|
||||
} /* end if resume_name && !continue_bit */
|
||||
|
||||
for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
|
||||
|
Reference in New Issue
Block a user