s3:smbd: let get_dir_entry() use smbd_dirptr_get_entry()
authorStefan Metzmacher <metze@samba.org>
Fri, 7 Aug 2009 06:54:06 +0000 (08:54 +0200)
committerStefan Metzmacher <metze@samba.org>
Fri, 7 Aug 2009 12:18:16 +0000 (14:18 +0200)
metze

source3/smbd/dir.c

index 4c802ab893f9f0ab9186a515240d02792d87f440..e2f8e694494c72642a446340423ad3fbb546dc6a 100644 (file)
@@ -971,158 +971,108 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
  Get an 8.3 directory entry.
 ****************************************************************************/
 
-bool get_dir_entry(TALLOC_CTX *ctx,
-               connection_struct *conn,
-               const char *mask,
-               uint32 dirtype,
-               char **pp_fname_out,
-               SMB_OFF_T *size,
-               uint32 *mode,
-               struct timespec *date,
-               bool check_descend,
-               bool ask_sharemode)
+static bool smbd_dirptr_8_3_match_fn(TALLOC_CTX *ctx,
+                                    void *private_data,
+                                    const char *dname,
+                                    const char *mask,
+                                    char **_fname)
 {
-       char *dname = NULL;
-       bool found = False;
-       SMB_STRUCT_STAT sbuf;
-       char *pathreal = NULL;
-       char *filename = NULL;
-       bool needslash;
-
-       *pp_fname_out = NULL;
-
-       needslash = ( conn->dirpath[strlen(conn->dirpath) -1] != '/');
-
-       if (!conn->dirptr) {
-               return(False);
-       }
-
-       while (!found) {
-               long curoff = dptr_TellDir(conn->dirptr);
-               dname = dptr_ReadDirName(ctx, conn->dirptr, &curoff, &sbuf);
-
-               DEBUG(6,("readdir on dirptr 0x%lx now at offset %ld\n",
-                       (long)conn->dirptr,TellDir(conn->dirptr->dir_hnd)));
-
-               if (dname == NULL) {
-                       return(False);
-               }
-
-               filename = dname;
-
-               /* notice the special *.* handling. This appears to be the only difference
-                       between the wildcard handling in this routine and in the trans2 routines.
-                       see masktest for a demo
-               */
-               if ((strcmp(mask,"*.*") == 0) ||
-                   mask_match_search(filename,mask,False) ||
-                   mangle_mask_match(conn,filename,mask)) {
-                       bool isdots = (ISDOT(dname) || ISDOTDOT(dname));
-                       char mname[13];
-                       struct smb_filename *smb_fname = NULL;
-                       NTSTATUS status;
-
-                       if (!mangle_is_8_3(filename, False, conn->params)) {
-                               if (!name_to_8_3(filename,mname,False,
-                                          conn->params)) {
-                                       TALLOC_FREE(filename);
-                                       continue;
-                               }
-                               filename = talloc_strdup(ctx, mname);
-                               if (!filename) {
-                                       return False;
-                               }
-                       }
-
-                       if (check_descend && !isdots) {
-                               TALLOC_FREE(filename);
-                               continue;
-                       }
-
-                       if (needslash) {
-                               pathreal = talloc_asprintf(ctx,
-                                               "%s/%s",
-                                               conn->dirpath,
-                                               dname);
-                       } else {
-                               pathreal = talloc_asprintf(ctx,
-                                               "%s%s",
-                                               conn->dirpath,
-                                               dname);
-                       }
-                       if (!pathreal) {
-                               TALLOC_FREE(filename);
-                               return False;
-                       }
-
-                       /* Create smb_fname with NULL stream_name. */
-                       status = create_synthetic_smb_fname(ctx, pathreal,
-                                                           NULL, &sbuf,
-                                                           &smb_fname);
-
-                       TALLOC_FREE(pathreal);
-                       if (!NT_STATUS_IS_OK(status)) {
-                               TALLOC_FREE(filename);
+       connection_struct *conn = (connection_struct *)private_data;
+
+       if ((strcmp(mask,"*.*") == 0) ||
+           mask_match_search(dname, mask, false) ||
+           mangle_mask_match(conn, dname, mask)) {
+               char mname[13];
+               const char *fname;
+
+               if (!mangle_is_8_3(dname, false, conn->params)) {
+                       bool ok = name_to_8_3(dname, mname, false,
+                                             conn->params);
+                       if (!ok) {
                                return false;
                        }
+                       fname = mname;
+               } else {
+                       fname = dname;
+               }
 
-                       if (!VALID_STAT(smb_fname->st)) {
-                               if ((SMB_VFS_STAT(conn, smb_fname)) != 0) {
-                                       DEBUG(5,("Couldn't stat 1 [%s]. Error "
-                                                "= %s\n",
-                                                smb_fname_str_dbg(smb_fname),
-                                                strerror(errno)));
-                                       TALLOC_FREE(smb_fname);
-                                       TALLOC_FREE(filename);
-                                       continue;
-                               }
-                       }
-
-                       *mode = dos_mode(conn, smb_fname);
-
-                       if (!dir_check_ftype(conn,*mode,dirtype)) {
-                               DEBUG(5,("[%s] attribs 0x%x didn't match 0x%x\n",filename,(unsigned int)*mode,(unsigned int)dirtype));
-                               TALLOC_FREE(smb_fname);
-                               TALLOC_FREE(filename);
-                               continue;
-                       }
-
-                       *size = smb_fname->st.st_ex_size;
-                       *date = smb_fname->st.st_ex_mtime;
+               *_fname = talloc_strdup(ctx, fname);
+               if (*_fname == NULL) {
+                       return false;
+               }
 
-                       if (ask_sharemode) {
-                               struct timespec write_time_ts;
-                               struct file_id fileid;
+               return true;
+       }
 
-                               fileid = vfs_file_id_from_sbuf(conn,
-                                                              &smb_fname->st);
-                               get_file_infos(fileid, NULL, &write_time_ts);
-                               if (!null_timespec(write_time_ts)) {
-                                       *date = write_time_ts;
-                               }
-                       }
+       return false;
+}
 
-                       DEBUG(3,("get_dir_entry mask=[%s] found %s "
-                               "fname=%s (%s)\n",
-                               mask,
-                               smb_fname_str_dbg(smb_fname),
-                               dname,
-                               filename));
+static bool smbd_dirptr_8_3_mode_fn(TALLOC_CTX *ctx,
+                                   void *private_data,
+                                   struct smb_filename *smb_fname,
+                                   uint32_t *_mode)
+{
+       connection_struct *conn = (connection_struct *)private_data;
+
+       if (!VALID_STAT(smb_fname->st)) {
+               if ((SMB_VFS_STAT(conn, smb_fname)) != 0) {
+                       DEBUG(5,("smbd_dirptr_8_3_mode_fn: "
+                                "Couldn't stat [%s]. Error "
+                                "= %s\n",
+                                smb_fname_str_dbg(smb_fname),
+                                strerror(errno)));
+                       return false;
+               }
+       }
 
-                       found = True;
+       *_mode = dos_mode(conn, smb_fname);
+       return true;
+}
 
-                       SMB_ASSERT(filename != NULL);
-                       *pp_fname_out = filename;
+bool get_dir_entry(TALLOC_CTX *ctx,
+               connection_struct *conn,
+               const char *mask,
+               uint32_t dirtype,
+               char **_fname,
+               SMB_OFF_T *_size,
+               uint32_t *_mode,
+               struct timespec *_date,
+               bool check_descend,
+               bool ask_sharemode)
+{
+       char *fname = NULL;
+       struct smb_filename *smb_fname = NULL;
+       uint32_t mode = 0;
+       long prev_offset;
+       bool ok;
 
-                       DirCacheAdd(conn->dirptr->dir_hnd, dname, curoff);
-                       TALLOC_FREE(smb_fname);
-               }
+       if (!conn->dirptr) {
+               return false;
+       }
 
-               if (!found)
-                       TALLOC_FREE(filename);
+       ok = smbd_dirptr_get_entry(ctx,
+                                  conn->dirptr,
+                                  mask,
+                                  dirtype,
+                                  check_descend,
+                                  ask_sharemode,
+                                  smbd_dirptr_8_3_match_fn,
+                                  smbd_dirptr_8_3_mode_fn,
+                                  conn,
+                                  &fname,
+                                  &smb_fname,
+                                  &mode,
+                                  &prev_offset);
+       if (!ok) {
+               return false;
        }
 
-       return(found);
+       *_fname = talloc_move(ctx, &fname);
+       *_size = smb_fname->st.st_ex_size;
+       *_mode = mode;
+       *_date = smb_fname->st.st_ex_mtime;
+       TALLOC_FREE(smb_fname);
+       return true;
 }
 
 /*******************************************************************