struct name_cache_entry *name_cache;
unsigned int name_cache_index;
unsigned int file_number;
+ files_struct *fsp; /* Back pointer to containing fsp, only
+ set from OpenDir_fsp(). */
};
struct dptr_struct {
return False;
}
- if ((mode & aDIR) != 0) {
+ if ((mode & FILE_ATTRIBUTE_DIRECTORY) != 0) {
size = 0;
}
goto done;
}
+ if (sconn->using_smb2) {
+ goto done;
+ }
+
DLIST_REMOVE(sconn->searches.dirptrs, dptr);
/*
/* Lanman 2 specific code */
SAFE_FREE(dptr->wcard);
- string_set(&dptr->path,"");
+ SAFE_FREE(dptr->path);
SAFE_FREE(dptr);
}
ZERO_STRUCTP(dptr);
+ dptr->path = SMB_STRDUP(path);
+ if (!dptr->path) {
+ SAFE_FREE(dptr);
+ TALLOC_FREE(dir_hnd);
+ return NT_STATUS_NO_MEMORY;
+ }
+ dptr->conn = conn;
+ dptr->dir_hnd = dir_hnd;
+ dptr->spid = spid;
+ dptr->expect_close = expect_close;
+ dptr->wcard = SMB_STRDUP(wcard);
+ if (!dptr->wcard) {
+ SAFE_FREE(dptr->path);
+ SAFE_FREE(dptr);
+ TALLOC_FREE(dir_hnd);
+ return NT_STATUS_NO_MEMORY;
+ }
+ if (lp_posix_pathnames() || (wcard[0] == '.' && wcard[1] == 0)) {
+ dptr->has_wild = True;
+ } else {
+ dptr->has_wild = wcard_has_wild;
+ }
+
+ dptr->attr = attr;
+
+ if (sconn->using_smb2) {
+ goto done;
+ }
+
if(old_handle) {
/*
dptr->dnum = bitmap_find(sconn->searches.dptr_bmap, 0);
if(dptr->dnum == -1 || dptr->dnum > 254) {
DEBUG(0,("dptr_create: returned %d: Error - all old dirptrs in use ?\n", dptr->dnum));
+ SAFE_FREE(dptr->path);
+ SAFE_FREE(dptr->wcard);
SAFE_FREE(dptr);
TALLOC_FREE(dir_hnd);
return NT_STATUS_TOO_MANY_OPENED_FILES;
if(dptr->dnum == -1 || dptr->dnum < 255) {
DEBUG(0,("dptr_create: returned %d: Error - all new dirptrs in use ?\n", dptr->dnum));
+ SAFE_FREE(dptr->path);
+ SAFE_FREE(dptr->wcard);
SAFE_FREE(dptr);
TALLOC_FREE(dir_hnd);
return NT_STATUS_TOO_MANY_OPENED_FILES;
dptr->dnum += 1; /* Always bias the dnum by one - no zero dnums allowed. */
- string_set(&dptr->path,path);
- dptr->conn = conn;
- dptr->dir_hnd = dir_hnd;
- dptr->spid = spid;
- dptr->expect_close = expect_close;
- dptr->wcard = SMB_STRDUP(wcard);
- if (!dptr->wcard) {
- bitmap_clear(sconn->searches.dptr_bmap, dptr->dnum - 1);
- SAFE_FREE(dptr);
- TALLOC_FREE(dir_hnd);
- return NT_STATUS_NO_MEMORY;
- }
- if (lp_posix_pathnames() || (wcard[0] == '.' && wcard[1] == 0)) {
- dptr->has_wild = True;
- } else {
- dptr->has_wild = wcard_has_wild;
- }
-
- dptr->attr = attr;
-
DLIST_ADD(sconn->searches.dirptrs, dptr);
+done:
DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n",
dptr->dnum,path,expect_close));
void dptr_CloseDir(files_struct *fsp)
{
if (fsp->dptr) {
-/*
- * Ugly hack. We have defined fdopendir to return ENOSYS if dirfd also isn't
- * present. I hate Solaris. JRA.
- */
-#ifdef HAVE_DIRFD
- if (fsp->fh->fd != -1 &&
- fsp->dptr->dir_hnd &&
- dirfd(fsp->dptr->dir_hnd->dir)) {
- /* The call below closes the underlying fd. */
- fsp->fh->fd = -1;
- }
-#endif
+ /*
+ * The destructor for the struct smb_Dir
+ * (fsp->dptr->dir_hnd) now handles
+ * all resource deallocation.
+ */
dptr_close_internal(fsp->dptr);
fsp->dptr = NULL;
}
uint32 mask;
/* Check the "may have" search bits. */
- if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0)
+ if (((mode & ~dirtype) & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY)) != 0)
return False;
/* Check the "must have" bits, which are the may have bits shifted eight */
/* If must have bit is set, the file/dir can not be returned in search unless the matching
file attribute is set */
- mask = ((dirtype >> 8) & (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM)); /* & 0x37 */
+ mask = ((dirtype >> 8) & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)); /* & 0x37 */
if(mask) {
- if((mask & (mode & (aDIR|aARCH|aRONLY|aHIDDEN|aSYSTEM))) == mask) /* check if matching attribute present */
+ if((mask & (mode & (FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM))) == mask) /* check if matching attribute present */
return True;
else
return False;
long *_prev_offset)
{
connection_struct *conn = dirptr->conn;
- bool needslash;
+ size_t slashlen;
+ size_t pathlen;
*_smb_fname = NULL;
*_mode = 0;
- needslash = ( dirptr->path[strlen(dirptr->path) -1] != '/');
+ pathlen = strlen(dirptr->path);
+ slashlen = ( dirptr->path[pathlen-1] != '/') ? 1 : 0;
while (true) {
long cur_offset;
continue;
}
- pathreal = talloc_asprintf(ctx, "%s%s%s",
- dirptr->path,
- needslash?"/":"",
- dname);
+ /*
+ * This used to be
+ * pathreal = talloc_asprintf(ctx, "%s%s%s", dirptr->path,
+ * needslash?"/":"", dname);
+ * but this was measurably slower than doing the memcpy.
+ */
+
+ pathreal = talloc_array(
+ ctx, char,
+ pathlen + slashlen + talloc_get_size(dname));
if (!pathreal) {
TALLOC_FREE(dname);
TALLOC_FREE(fname);
return false;
}
+ memcpy(pathreal, dirptr->path, pathlen);
+ pathreal[pathlen] = '/';
+ memcpy(pathreal + slashlen + pathlen, dname,
+ talloc_get_size(dname));
+
/* Create smb_fname with NULL stream_name. */
ZERO_STRUCT(smb_fname);
smb_fname.base_name = pathreal;
static int smb_Dir_destructor(struct smb_Dir *dirp)
{
- if (dirp->dir) {
-#ifdef HAVE_DIRFD
- if (dirp->conn->sconn) {
- files_struct *fsp = file_find_fd(dirp->conn->sconn,
- dirfd(dirp->dir));
- if (fsp) {
- /* The call below closes the underlying fd. */
- fsp->fh->fd = -1;
+ if (dirp->dir != NULL) {
+ SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir);
+ if (dirp->fsp != NULL) {
+ /*
+ * The SMB_VFS_CLOSEDIR above
+ * closes the underlying fd inside
+ * dirp->fsp.
+ */
+ dirp->fsp->fh->fd = -1;
+ if (dirp->fsp->dptr != NULL) {
+ SMB_ASSERT(dirp->fsp->dptr->dir_hnd == dirp);
+ dirp->fsp->dptr->dir_hnd = NULL;
}
+ dirp->fsp = NULL;
}
-#endif
- SMB_VFS_CLOSEDIR(dirp->conn,dirp->dir);
}
- if (dirp->conn->sconn) {
+ if (dirp->conn->sconn && !dirp->conn->sconn->using_smb2) {
dirp->conn->sconn->searches.dirhandles_open--;
}
return 0;
goto fail;
}
- if (sconn) {
+ if (sconn && !sconn->using_smb2) {
sconn->searches.dirhandles_open++;
}
talloc_set_destructor(dirp, smb_Dir_destructor);
goto fail;
}
- if (sconn) {
+ if (sconn && !sconn->using_smb2) {
sconn->searches.dirhandles_open++;
}
talloc_set_destructor(dirp, smb_Dir_destructor);
if (fsp->is_directory && fsp->fh->fd != -1) {
dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr);
- if (dirp->dir == NULL) {
+ if (dirp->dir != NULL) {
+ dirp->fsp = fsp;
+ } else {
DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned "
"NULL (%s)\n",
dirp->dir_path,
Is this directory empty ?
*****************************************************************/
-NTSTATUS can_delete_directory(struct connection_struct *conn,
- const char *dirname)
+NTSTATUS can_delete_directory_fsp(files_struct *fsp)
{
NTSTATUS status = NT_STATUS_OK;
long dirpos = 0;
const char *dname = NULL;
char *talloced = NULL;
SMB_STRUCT_STAT st;
- struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
- dirname, NULL, 0);
+ struct connection_struct *conn = fsp->conn;
+ struct smb_Dir *dir_hnd = OpenDir_fsp(talloc_tos(),
+ conn,
+ fsp,
+ NULL,
+ 0);
if (!dir_hnd) {
return map_nt_error_from_unix(errno);
}
}
- if (!is_visible_file(conn, dirname, dname, &st, True)) {
+ if (!is_visible_file(conn, fsp->fsp_name->base_name, dname, &st, True)) {
TALLOC_FREE(talloced);
continue;
}
- DEBUG(10,("can_delete_directory: got name %s - can't delete\n",
+ DEBUG(10,("can_delete_directory_fsp: got name %s - can't delete\n",
dname ));
status = NT_STATUS_DIRECTORY_NOT_EMPTY;
break;