Put OpenDir() back the way it was - don't overload with an fsp arg. Create OpenDir_fs...
[samba.git] / source3 / smbd / dir.c
index edc1ffe65f342524eb6605b3868ac40e1bb5ced0..5c502f77068bd65de0765875bc4340ba555bc362 100644 (file)
@@ -63,6 +63,10 @@ struct dptr_struct {
        bool did_stat; /* Optimisation for non-wcard searches. */
 };
 
+static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn,
+                       files_struct *fsp,
+                       const char *mask,
+                       uint32 attr);
 
 #define INVALID_DPTR_KEY (-3)
 
@@ -190,7 +194,7 @@ static struct dptr_struct *dptr_get(struct smbd_server_connection *sconn,
                                        dptr_idleoldest(sconn);
                                DEBUG(4,("dptr_get: Reopening dptr key %d\n",key));
                                if (!(dptr->dir_hnd = OpenDir(
-                                             NULL, dptr->conn, NULL, dptr->path,
+                                             NULL, dptr->conn, dptr->path,
                                              dptr->wcard, dptr->attr))) {
                                        DEBUG(4,("dptr_get: Failed to open %s (%s)\n",dptr->path,
                                                strerror(errno)));
@@ -437,14 +441,16 @@ NTSTATUS dptr_create(connection_struct *conn, files_struct *fsp,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       if (!fsp) {
+       if (fsp) {
+               dir_hnd = OpenDir_fsp(NULL, conn, fsp, wcard, attr);
+       } else {
                status = check_name(conn,path);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
+               dir_hnd = OpenDir(NULL, conn, path, wcard, attr);
        }
 
-       dir_hnd = OpenDir(NULL, conn, fsp, path, wcard, attr);
        if (!dir_hnd) {
                return map_nt_error_from_unix(errno);
        }
@@ -1312,7 +1318,6 @@ static int smb_Dir_destructor(struct smb_Dir *dirp)
 ********************************************************************/
 
 struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn,
-                       files_struct *fsp,
                        const char *name,
                        const char *mask,
                        uint32 attr)
@@ -1327,11 +1332,51 @@ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn,
        dirp->conn = conn;
        dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn));
 
-       if (fsp) {
-               dirp->dir_path = talloc_strdup(dirp, fsp->fsp_name->base_name);
-       } else {
-               dirp->dir_path = talloc_strdup(dirp, name);
+       dirp->dir_path = talloc_strdup(dirp, name);
+       if (!dirp->dir_path) {
+               errno = ENOMEM;
+               goto fail;
        }
+
+       if (sconn) {
+               sconn->smb1.searches.dirhandles_open++;
+       }
+       talloc_set_destructor(dirp, smb_Dir_destructor);
+
+       dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr);
+       if (!dirp->dir) {
+               DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path,
+                        strerror(errno) ));
+               goto fail;
+       }
+
+       return dirp;
+
+  fail:
+       TALLOC_FREE(dirp);
+       return NULL;
+}
+
+/*******************************************************************
+ Open a directory from an fsp.
+********************************************************************/
+
+static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn,
+                       files_struct *fsp,
+                       const char *mask,
+                       uint32 attr)
+{
+       struct smb_Dir *dirp = TALLOC_ZERO_P(mem_ctx, struct smb_Dir);
+       struct smbd_server_connection *sconn = conn->sconn;
+
+       if (!dirp) {
+               return NULL;
+       }
+
+       dirp->conn = conn;
+       dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn));
+
+       dirp->dir_path = talloc_strdup(dirp, fsp->fsp_name->base_name);
        if (!dirp->dir_path) {
                errno = ENOMEM;
                goto fail;
@@ -1342,10 +1387,10 @@ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn,
        }
        talloc_set_destructor(dirp, smb_Dir_destructor);
 
-       if (fsp && fsp->is_directory && fsp->fh->fd != -1) {
+       if (fsp->is_directory && fsp->fh->fd != -1) {
                dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr);
                if (dirp->dir == NULL) {
-                       DEBUG(10,("OpenDir: SMB_VFS_FDOPENDIR on %s returned "
+                       DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned "
                                "NULL (%s)\n",
                                dirp->dir_path,
                                strerror(errno)));
@@ -1356,13 +1401,12 @@ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn,
        }
 
        if (dirp->dir == NULL) {
-               /* FDOPENDIR didn't work - or fsp == NULL. Use
-                  OPENDIR instead. */
+               /* FDOPENDIR didn't work. Use OPENDIR instead. */
                dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr);
        }
 
        if (!dirp->dir) {
-               DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path,
+               DEBUG(5,("OpenDir_fsp: Can't open %s. %s\n", dirp->dir_path,
                         strerror(errno) ));
                goto fail;
        }
@@ -1374,6 +1418,7 @@ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn,
        return NULL;
 }
 
+
 /*******************************************************************
  Read from a directory.
  Return directory entry, current offset, and optional stat information.
@@ -1568,7 +1613,7 @@ NTSTATUS can_delete_directory(struct connection_struct *conn,
        const char *dname = NULL;
        char *talloced = NULL;
        SMB_STRUCT_STAT st;
-       struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, NULL,
+       struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
                                        dirname, NULL, 0);
 
        if (!dir_hnd) {