]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: libsmb: Added new API smbc_readdirplus2()
authorJeremy Allison <jra@samba.org>
Fri, 18 Oct 2019 17:29:48 +0000 (10:29 -0700)
committerRalph Boehme <slow@samba.org>
Wed, 30 Oct 2019 20:44:31 +0000 (20:44 +0000)
Returns the same as smbc_readdirplus() but also
can return a struct stat if passed in by the caller.

struct stat is synthesized from the data
returned by the SMB server.

Signed-off-by: Puran Chand <pchand@vmware.com>
Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source3/include/libsmb_internal.h
source3/include/libsmbclient.h
source3/libsmb/libsmb_compat.c
source3/libsmb/libsmb_context.c
source3/libsmb/libsmb_dir.c
source3/libsmb/libsmb_setget.c
source3/libsmb/wscript

index 93b8336f067299235f87af3538890ecc1cf059ea..bfb3e064297e157360a79c5544986ddb629dea44 100644 (file)
@@ -306,6 +306,11 @@ const struct libsmb_file_info *
 SMBC_readdirplus_ctx(SMBCCTX *context,
                      SMBCFILE *dir);
 
+const struct libsmb_file_info *
+SMBC_readdirplus2_ctx(SMBCCTX *context,
+               SMBCFILE *dir,
+               struct stat *st);
+
 int
 SMBC_getdents_ctx(SMBCCTX *context,
                   SMBCFILE *dir,
index b045221f12b685e6ca38f049470e9570a349637f..835c832b76a175503f5102354f394059ea8be2e6 100644 (file)
@@ -1046,6 +1046,12 @@ typedef const struct libsmb_file_info * (*smbc_readdirplus_fn)(SMBCCTX *c,
 smbc_readdirplus_fn smbc_getFunctionReaddirPlus(SMBCCTX *c);
 void smbc_setFunctionReaddirPlus(SMBCCTX *c, smbc_readdirplus_fn fn);
 
+typedef const struct libsmb_file_info * (*smbc_readdirplus2_fn)(SMBCCTX *c,
+                                       SMBCFILE *dir,
+                                       struct stat *st);
+smbc_readdirplus2_fn smbc_getFunctionReaddirPlus2(SMBCCTX *c);
+void smbc_setFunctionReaddirPlus2(SMBCCTX *c, smbc_readdirplus2_fn fn);
+
 typedef int (*smbc_getdents_fn)(SMBCCTX *c,
                                 SMBCFILE *dir,
                                 struct smbc_dirent *dirp,
@@ -1654,6 +1660,25 @@ struct smbc_dirent* smbc_readdir(unsigned int dh);
  */
 const struct libsmb_file_info *smbc_readdirplus(unsigned int dh);
 
+/**@ingroup directory
+ * Works similar as smbc_readdirplus as well as fills up stat structure if
+ * provided.
+ *
+ * @param dh        Valid directory as returned by smbc_opendir()
+ *
+ * @param stat      Pointer to stat structure which will receive the
+ *                  information. If this pointer is null the call
+ *                  is identical to smbc_readdirplus.
+ *
+ * @return          A const pointer to a libsmb_file_info structure,
+ *                  or NULL if an error occurs or end-of-directory is reached:
+ *                  - EBADF Invalid directory handle
+ *                  - EINVAL smbc_init() failed or has not been called
+ *
+ * @see             smbc_open(), smbc_readdir(), smbc_readdirplus2()
+ */
+const struct libsmb_file_info *smbc_readdirplus2(unsigned int dh,
+                                       struct stat *st);
 
 /**@ingroup directory
  * Get the current directory offset.
@@ -3104,6 +3129,7 @@ struct _SMBCCTX
         smbc_closedir_fn                closedir DEPRECATED_SMBC_INTERFACE;
         smbc_readdir_fn                 readdir DEPRECATED_SMBC_INTERFACE;
         smbc_readdirplus_fn             readdirplus DEPRECATED_SMBC_INTERFACE;
+       smbc_readdirplus2_fn            readdirplus2 DEPRECATED_SMBC_INTERFACE;
         smbc_getdents_fn                getdents DEPRECATED_SMBC_INTERFACE;
         smbc_mkdir_fn                   mkdir DEPRECATED_SMBC_INTERFACE;
         smbc_rmdir_fn                   rmdir DEPRECATED_SMBC_INTERFACE;
index eb38480a5c654de1fa68408af09ff4f1291d4263..c916122d0b82d1ce2de389f80171249abfb8c036 100644 (file)
@@ -291,6 +291,13 @@ const struct libsmb_file_info *smbc_readdirplus(unsigned int dh)
        return smbc_getFunctionReaddirPlus(statcont)(statcont, file);
 }
 
+const struct libsmb_file_info *smbc_readdirplus2(unsigned int dh,
+               struct stat *st)
+{
+       SMBCFILE *file = find_fd(dh);
+       return smbc_getFunctionReaddirPlus2(statcont)(statcont, file, st);
+}
+
 off_t
 smbc_telldir(int dh)
 {
index 9e7b083952f0c1ed99f773769587932917ebd3d0..48e417ba523a3fd849c55fc3d652580d866ee767 100644 (file)
@@ -209,6 +209,7 @@ smbc_new_context(void)
         smbc_setFunctionClosedir(context, SMBC_closedir_ctx);
         smbc_setFunctionReaddir(context, SMBC_readdir_ctx);
         smbc_setFunctionReaddirPlus(context, SMBC_readdirplus_ctx);
+       smbc_setFunctionReaddirPlus2(context, SMBC_readdirplus2_ctx);
         smbc_setFunctionGetdents(context, SMBC_getdents_ctx);
         smbc_setFunctionMkdir(context, SMBC_mkdir_ctx);
         smbc_setFunctionRmdir(context, SMBC_rmdir_ctx);
index b6523435c50caaeb4c9c9f4753ad840e49d68f4b..851be5de8fff4e40821299d0ba81b27eb19a9630 100644 (file)
@@ -1252,6 +1252,105 @@ SMBC_readdirplus_ctx(SMBCCTX *context,
        return smb_finfo;
 }
 
+/*
+ * Routine to get a directory entry plus a filled in stat structure if
+ * requested.
+ */
+
+const struct libsmb_file_info *SMBC_readdirplus2_ctx(SMBCCTX *context,
+                       SMBCFILE *dir,
+                       struct stat *st)
+{
+       struct libsmb_file_info *smb_finfo = NULL;
+       struct smbc_dirplus_list *dp_list = NULL;
+       ino_t ino;
+       char *full_pathname = NULL;
+       TALLOC_CTX *frame = NULL;
+
+       /*
+        * Allow caller to pass in NULL for stat pointer if
+        * required. This makes this call identical to
+        * smbc_readdirplus().
+        */
+
+       if (st == NULL) {
+               return SMBC_readdirplus_ctx(context, dir);
+       }
+
+       frame = talloc_stackframe();
+
+       /* Check that all is ok first ... */
+       if (context == NULL || !context->internal->initialized) {
+               DBG_ERR("Invalid context in SMBC_readdirplus2_ctx()\n");
+               TALLOC_FREE(frame);
+               errno = EINVAL;
+               return NULL;
+       }
+
+       if (dir == NULL ||
+           SMBC_dlist_contains(context->internal->files,
+                                       dir) == 0)
+       {
+               DBG_ERR("Invalid dir in SMBC_readdirplus2_ctx()\n");
+               TALLOC_FREE(frame);
+               errno = EBADF;
+               return NULL;
+       }
+
+       dp_list = dir->dirplus_next;
+       if (dp_list == NULL) {
+               TALLOC_FREE(frame);
+               return NULL;
+       }
+
+       ino = (ino_t)dp_list->ino;
+
+       smb_finfo = dp_list->smb_finfo;
+       if (smb_finfo == NULL) {
+               TALLOC_FREE(frame);
+               errno = ENOENT;
+               return NULL;
+       }
+
+       full_pathname = talloc_asprintf(frame,
+                               "%s/%s",
+                               dir->fname,
+                               smb_finfo->name);
+       if (full_pathname == NULL) {
+               TALLOC_FREE(frame);
+               errno = ENOENT;
+               return NULL;
+       }
+
+       setup_stat(st,
+               full_pathname,
+               smb_finfo->size,
+               smb_finfo->attrs,
+               ino,
+               dir->srv->dev,
+               smb_finfo->atime_ts,
+               smb_finfo->ctime_ts,
+               smb_finfo->mtime_ts);
+
+       TALLOC_FREE(full_pathname);
+
+       dir->dirplus_next = dir->dirplus_next->next;
+
+       /*
+        * If we are returning file entries, we
+        * have a duplicate list in dir_list
+        *
+        * Update dir_next also so readdir and
+        * readdirplus are kept in sync.
+        */
+       if (dir->dir_list) {
+               dir->dir_next = dir->dir_next->next;
+       }
+
+       TALLOC_FREE(frame);
+       return smb_finfo;
+}
+
 /*
  * Routine to get directory entries
  */
index 9696f5f00acabd920db2408b24105de11277db49..d071efa11910c4797e70c51fb8d59b8641c8b0ff 100644 (file)
@@ -907,6 +907,16 @@ void smbc_setFunctionReaddirPlus(SMBCCTX *c, smbc_readdirplus_fn fn)
        c->readdirplus = fn;
 }
 
+smbc_readdirplus2_fn smbc_getFunctionReaddirPlus2(SMBCCTX *c)
+{
+       return c->readdirplus2;
+}
+
+void smbc_setFunctionReaddirPlus2(SMBCCTX *c, smbc_readdirplus2_fn fn)
+{
+       c->readdirplus2 = fn;
+}
+
 smbc_getdents_fn
 smbc_getFunctionGetdents(SMBCCTX *c)
 {
index febff9df7fc681e69a4ef285408e45194e9202ce..ec4a516b2ee5e3aeb3e4a5ad19969c4486c8517d 100644 (file)
@@ -26,5 +26,5 @@ def build(bld):
                        public_headers='../include/libsmbclient.h',
                        abi_directory='ABI',
                        abi_match='smbc_*',
-                       vnum='0.5.0',
+                       vnum='0.6.0',
                        pc_files='smbclient.pc')