]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
r5160: First cut at refactoring of directory code to handle non-wildcard
authorJeremy Allison <jra@samba.org>
Tue, 1 Feb 2005 18:33:50 +0000 (18:33 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:55:30 +0000 (10:55 -0500)
directory match more efficiently. Passes RAW-SEARCH under valgrind but needs more
testing (which I'll do later today :-).
Jeremy.

source/smbd/dir.c
source/smbd/filename.c
source/smbd/notify_hash.c
source/smbd/reply.c
source/smbd/trans2.c

index 29ef4cbe61b4d604139b1f973eac692d93791597..e9934ff49c3622f4f45dd317b6d09e95dd3358c5 100644 (file)
@@ -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;
-               dptr->has_wild = ms_has_wild(wcard);
+               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;
                }
        }
index 9af73776ebed8d3b76ad4d75395701d0d7a3c1d1..c04b43b8739b1691123cbaecfab9906cdfbf8f30 100644 (file)
@@ -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);
        }
index d7cb1139dc76b9e9a23e47a73219294d1ec3721c..b16b7677833382575fa6c3e6715a443ff1f62f51 100644 (file)
@@ -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.
                 */             
-               SMB_VFS_STAT(conn,full_name, &st);
+               if (!VALID_STAT(st)) {
+                       SMB_VFS_STAT(conn,full_name, &st);
+               }
 
                /*
                 * Always sum the times.
index 899dba56d86b5859cdfbd3593f463602af228747..748d9958bcdb5a48e5585660db095bc9b6e33cab 100644 (file)
@@ -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;
 
index d2cef6049de52527ac41f3e8d1a621fc1361de09..b5029ccd77016afc2108a57f439b41367e7dab7b 100644 (file)
@@ -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, &current_pos, True);
+               finished = !dptr_SearchDir(conn->dirptr, resume_name, &current_pos, &st);
        } /* end if resume_name && !continue_bit */
 
        for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {