[PR PATCH] [Updated] Added ReadDirPlus API in libsmbclient which returns detailed file properties

Jeremy Allison jra at samba.org
Tue Apr 10 16:34:12 UTC 2018


On Tue, Apr 10, 2018 at 10:57:46AM +0530, Puran Chand via samba-technical wrote:
> Hi Jeremy,
> 
> I tested the changes.
> Seems good to me.
> 
> Thanks Jim for spotting the typo.
> Its fixed now.

Updated version just for our records.

I still need to create a simple test scenario
for this before I can propose review. I'm on
vacation all next week so this may have to
wait until after I return, sorry.

Jeremy.
-------------- next part --------------
From 1efd162ef910bbde2c7d53437dc126d2d85f9095 Mon Sep 17 00:00:00 2001
From: Jeremy Allison <jra at samba.org>
Date: Fri, 6 Apr 2018 13:35:05 -0700
Subject: [PATCH 1/5] s3: client: Add btime_ts to struct finfo.

Fill it in when available, else return it as zero.

Based on a patch from Puran Chand <pchand at vmware.com>.

Signed-off-by: Jeremy Allison <jra at samba.org>
---
 examples/fuse/clifuse.c        |  1 +
 source3/include/client.h       |  1 +
 source3/libsmb/cli_smb2_fnum.c |  1 +
 source3/libsmb/clilist.c       | 19 +++++++++++++++++++
 4 files changed, 22 insertions(+)

diff --git a/examples/fuse/clifuse.c b/examples/fuse/clifuse.c
index da9dd4d3e82..3c7e4982475 100644
--- a/examples/fuse/clifuse.c
+++ b/examples/fuse/clifuse.c
@@ -484,6 +484,7 @@ static NTSTATUS parse_finfo_id_both_directory_info(uint8_t *dir_data,
 		return NT_STATUS_INFO_LENGTH_MISMATCH;
 	}
 
+	finfo->btime_ts = interpret_long_date((const char *)dir_data + 8);
 	finfo->atime_ts = interpret_long_date((const char *)dir_data + 16);
 	finfo->mtime_ts = interpret_long_date((const char *)dir_data + 24);
 	finfo->ctime_ts = interpret_long_date((const char *)dir_data + 32);
diff --git a/source3/include/client.h b/source3/include/client.h
index 1fe3f1cb960..0cb21384f17 100644
--- a/source3/include/client.h
+++ b/source3/include/client.h
@@ -108,6 +108,7 @@ struct file_info {
 	uid_t uid;
 	gid_t gid;
 	/* these times are normally kept in GMT */
+	struct timespec btime_ts; /* Birth-time if supported by system */
 	struct timespec mtime_ts;
 	struct timespec atime_ts;
 	struct timespec ctime_ts;
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
index c397b29b381..1eb1bea7a72 100644
--- a/source3/libsmb/cli_smb2_fnum.c
+++ b/source3/libsmb/cli_smb2_fnum.c
@@ -803,6 +803,7 @@ static NTSTATUS parse_finfo_id_both_directory_info(uint8_t *dir_data,
 		return NT_STATUS_INFO_LENGTH_MISMATCH;
 	}
 
+	finfo->btime_ts = interpret_long_date((const char *)dir_data + 8);
 	finfo->atime_ts = interpret_long_date((const char *)dir_data + 16);
 	finfo->mtime_ts = interpret_long_date((const char *)dir_data + 24);
 	finfo->ctime_ts = interpret_long_date((const char *)dir_data + 32);
diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c
index 41f585120b9..5cb1fce4338 100644
--- a/source3/libsmb/clilist.c
+++ b/source3/libsmb/clilist.c
@@ -77,6 +77,14 @@ static size_t interpret_long_filename(TALLOC_CTX *ctx,
 			if (pdata_end - base < 27) {
 				return pdata_end - base;
 			}
+			/*
+			 * What we're returning here as ctime_ts is
+			 * actually the server create time.
+			 */
+			finfo->btime_ts = convert_time_t_to_timespec(
+				make_unix_date2(p+4,
+					smb1cli_conn_server_time_zone(
+						cli->conn)));
 			finfo->ctime_ts = convert_time_t_to_timespec(
 				make_unix_date2(p+4, smb1cli_conn_server_time_zone(cli->conn)));
 			finfo->atime_ts = convert_time_t_to_timespec(
@@ -128,6 +136,14 @@ static size_t interpret_long_filename(TALLOC_CTX *ctx,
 			if (pdata_end - base < 31) {
 				return pdata_end - base;
 			}
+			/*
+			 * What we're returning here as ctime_ts is
+			 * actually the server create time.
+			 */
+			finfo->btime_ts = convert_time_t_to_timespec(
+				make_unix_date2(p+4,
+					smb1cli_conn_server_time_zone(
+						cli->conn)));
 			finfo->ctime_ts = convert_time_t_to_timespec(
 				make_unix_date2(p+4, smb1cli_conn_server_time_zone(cli->conn)));
 			finfo->atime_ts = convert_time_t_to_timespec(
@@ -250,6 +266,9 @@ static bool interpret_short_filename(TALLOC_CTX *ctx,
 
 	finfo->mode = CVAL(p,21);
 
+	/* We don't get birth time. */
+	finfo->btime_ts.tv_sec = 0;
+	finfo->btime_ts.tv_nsec = 0;
 	/* this date is converted to GMT by make_unix_date */
 	finfo->ctime_ts.tv_sec = make_unix_date(p+22, smb1cli_conn_server_time_zone(cli->conn));
 	finfo->ctime_ts.tv_nsec = 0;
-- 
2.17.0.484.g0c8726318c-goog


From 26c6d0d0debfbe17f0f95c1eb1719697cdcbaca1 Mon Sep 17 00:00:00 2001
From: Puran Chand <pchand at vmware.com>
Date: Fri, 6 Apr 2018 14:08:03 -0700
Subject: [PATCH 2/5] s3: libsmbclient: Add internal/external structures needed
 for readdirplus.

Not yet used.

Signed-off-by: Puran Chand <pchand at vmware.com>
Reviewed-by: Jeremy Allison <jra at samba.org>
---
 source3/include/libsmb_internal.h |  5 ++++
 source3/include/libsmbclient.h    | 49 +++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+)

diff --git a/source3/include/libsmb_internal.h b/source3/include/libsmb_internal.h
index 0e0045e8c0e..a7bda3dd1be 100644
--- a/source3/include/libsmb_internal.h
+++ b/source3/include/libsmb_internal.h
@@ -94,6 +94,10 @@ struct smbc_dir_list {
 	struct smbc_dirent *dirent;
 };
 
+struct smbc_dirplus_list {
+	struct smbc_dirplus_list *next;
+	struct libsmb_file_info *smb_finfo;
+};
 
 /*
  * Structure for open file management
@@ -110,6 +114,7 @@ struct _SMBCFILE {
 	struct _SMBCSRV *srv;
 	bool file;
 	struct smbc_dir_list *dir_list, *dir_end, *dir_next;
+	struct smbc_dirplus_list *dirplus_list, *dirplus_end, *dirplus_next;
 	int dir_type, dir_error;
 
 	SMBCFILE *next, *prev;
diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h
index 7a2067915af..65aa7db21d3 100644
--- a/source3/include/libsmbclient.h
+++ b/source3/include/libsmbclient.h
@@ -129,6 +129,55 @@ struct smbc_dirent
 	char name[1];
 };
 
+/**@ingroup structure
+ * Structure that represents all attributes of a directory entry.
+ *
+ */
+struct libsmb_file_info
+{
+	/**
+	 * Size of file
+	 */
+	uint64_t size;
+	/**
+	 * DOS attributes of file
+	 */
+	uint16_t attrs;
+	/**
+	 * User ID of file
+	 */
+	uid_t uid;
+	/**
+	 * Group ID of file
+	 */
+	gid_t gid;
+	/**
+	 * Birth/Create time of file (if supported by system)
+	 * Otherwise the value will be 0
+	 */
+	struct timespec btime_ts;
+	/**
+	 * Modified time for the file
+	 */
+	struct timespec mtime_ts;
+	/**
+	 * Access time for the file
+	 */
+	struct timespec atime_ts;
+	/**
+	 * Change time for the file
+	 */
+	struct timespec ctime_ts;
+	/**
+	 * Name of file
+	 */
+	char *name;
+	/**
+	 * Short name of file
+	 */
+	char *short_name;
+};
+
 /*
  * Logging callback function
  */
-- 
2.17.0.484.g0c8726318c-goog


From b4a67f628e0be47232be96f5178fe5c69ddb0fdb Mon Sep 17 00:00:00 2001
From: Puran Chand <pchand at vmware.com>
Date: Fri, 6 Apr 2018 14:17:35 -0700
Subject: [PATCH 3/5] s3: libsmbclient: Add readdirplus cleanup code on
 directory close.

Signed-off-by: Puran Chand <pchand at vmware.com>
Reviewed-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/libsmb_dir.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c
index 72441c46736..41725681c82 100644
--- a/source3/libsmb/libsmb_dir.c
+++ b/source3/libsmb/libsmb_dir.c
@@ -39,6 +39,26 @@
  * We accept the URL syntax explained in SMBC_parse_path(), above.
  */
 
+static void remove_dirplus(SMBCFILE *dir)
+{
+	struct smbc_dirplus_list *d, *f;
+
+	d = dir->dirplus_list;
+	while (d) {
+		f = d;
+		d = d->next;
+
+		SAFE_FREE(f->smb_finfo->short_name);
+		SAFE_FREE(f->smb_finfo->name);
+		SAFE_FREE(f->smb_finfo);
+		SAFE_FREE(f);
+	}
+
+	dir->dirplus_list = NULL;
+	dir->dirplus_end = NULL;
+	dir->dirplus_next = NULL;
+}
+
 static void
 remove_dir(SMBCFILE *dir)
 {
@@ -929,6 +949,7 @@ SMBC_closedir_ctx(SMBCCTX *context,
 	}
 
 	remove_dir(dir); /* Clean it up */
+	remove_dirplus(dir);
 
 	DLIST_REMOVE(context->internal->files, dir);
 
-- 
2.17.0.484.g0c8726318c-goog


From 418c6e485b6b0c7682213546cd9d055f0a0ef772 Mon Sep 17 00:00:00 2001
From: Puran Chand <pchand at vmware.com>
Date: Fri, 6 Apr 2018 14:50:39 -0700
Subject: [PATCH 4/5] s3: libsmbclient: Add function add_dirplus() to fill the
 list from a returned file info.

Not yet externally visible.

Signed-off-by: Puran Chand <pchand at vmware.com>
Reviewed-by: Jeremy Allison <jra at samba.org>
---
 source3/libsmb/libsmb_dir.c | 73 +++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c
index 41725681c82..ba7ba9a6270 100644
--- a/source3/libsmb/libsmb_dir.c
+++ b/source3/libsmb/libsmb_dir.c
@@ -158,6 +158,73 @@ add_dirent(SMBCFILE *dir,
 
 }
 
+static int add_dirplus(SMBCFILE *dir, struct file_info *finfo)
+{
+	struct smbc_dirplus_list *new_entry = NULL;
+	struct libsmb_file_info *info = NULL;
+
+	new_entry = SMB_MALLOC_P(struct smbc_dirplus_list);
+	if (new_entry == NULL) {
+		dir->dir_error = ENOMEM;
+		return -1;
+	}
+	ZERO_STRUCTP(new_entry);
+
+	info = SMB_MALLOC_P(struct libsmb_file_info);
+	if (info == NULL) {
+		SAFE_FREE(new_entry);
+		dir->dir_error = ENOMEM;
+		return -1;
+	}
+
+	ZERO_STRUCTP(info);
+
+	info->btime_ts = finfo->btime_ts;
+	info->atime_ts = finfo->atime_ts;
+	info->ctime_ts = finfo->ctime_ts;
+	info->mtime_ts = finfo->mtime_ts;
+	info->gid = finfo->gid;
+	info->attrs = finfo->mode;
+	info->size = finfo->size;
+	info->uid = finfo->uid;
+	info->name = SMB_STRDUP(finfo->name);
+	if (info->name == NULL) {
+		SAFE_FREE(info);
+		SAFE_FREE(new_entry);
+		dir->dir_error = ENOMEM;
+		return -1;
+	}
+
+	if (finfo->short_name) {
+		info->short_name = SMB_STRDUP(finfo->short_name);
+	} else {
+		info->short_name = SMB_STRDUP("");
+	}
+
+	if (info->short_name == NULL) {
+		SAFE_FREE(info->name);
+		SAFE_FREE(info);
+		SAFE_FREE(new_entry);
+		dir->dir_error = ENOMEM;
+		return -1;
+	}
+	new_entry->smb_finfo = info;
+
+	/* Now add to the list. */
+	if (dir->dirplus_list == NULL) {
+		/* Empty list - point everything at new_entry. */
+		dir->dirplus_list = new_entry;
+		dir->dirplus_end = new_entry;
+		dir->dirplus_next = new_entry;
+	} else {
+		/* Append to list but leave the ->next cursor alone. */
+		dir->dirplus_end->next = new_entry;
+		dir->dirplus_end = new_entry;
+	}
+
+	return 0;
+}
+
 static void
 list_unique_wg_fn(const char *name,
                   uint32_t type,
@@ -267,12 +334,18 @@ dir_list_fn(const char *mnt,
             const char *mask,
             void *state)
 {
+	SMBCFILE *dirp = (SMBCFILE *)state;
+	int ret;
 
 	if (add_dirent((SMBCFILE *)state, finfo->name, "",
 		       (finfo->mode&FILE_ATTRIBUTE_DIRECTORY?SMBC_DIR:SMBC_FILE)) < 0) {
 		SMBCFILE *dir = (SMBCFILE *)state;
 		return map_nt_error_from_unix(dir->dir_error);
 	}
+	ret = add_dirplus(dirp, finfo);
+	if (ret < 0) {
+		return map_nt_error_from_unix(dirp->dir_error);
+	}
 	return NT_STATUS_OK;
 }
 
-- 
2.17.0.484.g0c8726318c-goog


From 5f4b3ec1bb1ab46f2ee6537e8d64c7dbb4deeb4f Mon Sep 17 00:00:00 2001
From: Puran Chand <pchand at vmware.com>
Date: Mon, 9 Apr 2018 10:10:28 -0700
Subject: [PATCH 5/5] s3: libsmbclient: Add new function
 SMBC_readdirplus_ctx().

New ABI function, move to library version 0.33.

Signed-off-by: Puran Chand <pchand at vmware.com>
Reviewed-by: Jeremy Allison <jra at samba.org>
---
 source3/include/libsmb_internal.h       |   4 +
 source3/include/libsmbclient.h          |  20 +++
 source3/libsmb/ABI/smbclient-0.3.3.sigs | 184 ++++++++++++++++++++++++
 source3/libsmb/libsmb_compat.c          |   6 +
 source3/libsmb/libsmb_context.c         |   1 +
 source3/libsmb/libsmb_dir.c             |  46 ++++++
 source3/libsmb/libsmb_setget.c          |  10 ++
 source3/libsmb/wscript                  |   2 +-
 8 files changed, 272 insertions(+), 1 deletion(-)
 create mode 100644 source3/libsmb/ABI/smbclient-0.3.3.sigs

diff --git a/source3/include/libsmb_internal.h b/source3/include/libsmb_internal.h
index a7bda3dd1be..f3e44e875d8 100644
--- a/source3/include/libsmb_internal.h
+++ b/source3/include/libsmb_internal.h
@@ -301,6 +301,10 @@ struct smbc_dirent *
 SMBC_readdir_ctx(SMBCCTX *context,
                  SMBCFILE *dir);
 
+const struct libsmb_file_info *
+SMBC_readdirplus_ctx(SMBCCTX *context,
+                     SMBCFILE *dir);
+
 int
 SMBC_getdents_ctx(SMBCCTX *context,
                   SMBCFILE *dir,
diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h
index 65aa7db21d3..3faf2e07703 100644
--- a/source3/include/libsmbclient.h
+++ b/source3/include/libsmbclient.h
@@ -1024,6 +1024,11 @@ typedef struct smbc_dirent * (*smbc_readdir_fn)(SMBCCTX *c,
 smbc_readdir_fn smbc_getFunctionReaddir(SMBCCTX *c);
 void smbc_setFunctionReaddir(SMBCCTX *c, smbc_readdir_fn fn);
 
+typedef const struct libsmb_file_info * (*smbc_readdirplus_fn)(SMBCCTX *c,
+                                                               SMBCFILE *dir);
+smbc_readdirplus_fn smbc_getFunctionReaddirPlus(SMBCCTX *c);
+void smbc_setFunctionReaddirPlus(SMBCCTX *c, smbc_readdirplus_fn fn);
+
 typedef int (*smbc_getdents_fn)(SMBCCTX *c,
                                 SMBCFILE *dir,
                                 struct smbc_dirent *dirp,
@@ -1618,6 +1623,20 @@ int smbc_getdents(unsigned int dh, struct smbc_dirent *dirp, int count);
  */
 struct smbc_dirent* smbc_readdir(unsigned int dh);
 
+/**@ingroup directory
+ * Works similar as smbc_readdir but returns more information about file.
+ *
+ * @param dh        Valid directory as returned by smbc_opendir()
+ *
+ * @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()
+ */
+const struct libsmb_file_info *smbc_readdirplus(unsigned int dh);
+
 
 /**@ingroup directory
  * Get the current directory offset.
@@ -3067,6 +3086,7 @@ struct _SMBCCTX
         smbc_opendir_fn                 opendir DEPRECATED_SMBC_INTERFACE;
         smbc_closedir_fn                closedir DEPRECATED_SMBC_INTERFACE;
         smbc_readdir_fn                 readdir DEPRECATED_SMBC_INTERFACE;
+	smbc_readdirplus_fn             readdirplus DEPRECATED_SMBC_INTERFACE;
         smbc_getdents_fn                getdents DEPRECATED_SMBC_INTERFACE;
         smbc_mkdir_fn                   mkdir DEPRECATED_SMBC_INTERFACE;
         smbc_rmdir_fn                   rmdir DEPRECATED_SMBC_INTERFACE;
diff --git a/source3/libsmb/ABI/smbclient-0.3.3.sigs b/source3/libsmb/ABI/smbclient-0.3.3.sigs
new file mode 100644
index 00000000000..833d0df6b5f
--- /dev/null
+++ b/source3/libsmb/ABI/smbclient-0.3.3.sigs
@@ -0,0 +1,184 @@
+smbc_chmod: int (const char *, mode_t)
+smbc_close: int (int)
+smbc_closedir: int (int)
+smbc_creat: int (const char *, mode_t)
+smbc_fgetxattr: int (int, const char *, const void *, size_t)
+smbc_flistxattr: int (int, char *, size_t)
+smbc_free_context: int (SMBCCTX *, int)
+smbc_fremovexattr: int (int, const char *)
+smbc_fsetxattr: int (int, const char *, const void *, size_t, int)
+smbc_fstat: int (int, struct stat *)
+smbc_fstatvfs: int (int, struct statvfs *)
+smbc_ftruncate: int (int, off_t)
+smbc_getDebug: int (SMBCCTX *)
+smbc_getFunctionAddCachedServer: smbc_add_cached_srv_fn (SMBCCTX *)
+smbc_getFunctionAuthData: smbc_get_auth_data_fn (SMBCCTX *)
+smbc_getFunctionAuthDataWithContext: smbc_get_auth_data_with_context_fn (SMBCCTX *)
+smbc_getFunctionCheckServer: smbc_check_server_fn (SMBCCTX *)
+smbc_getFunctionChmod: smbc_chmod_fn (SMBCCTX *)
+smbc_getFunctionClose: smbc_close_fn (SMBCCTX *)
+smbc_getFunctionClosedir: smbc_closedir_fn (SMBCCTX *)
+smbc_getFunctionCreat: smbc_creat_fn (SMBCCTX *)
+smbc_getFunctionFstat: smbc_fstat_fn (SMBCCTX *)
+smbc_getFunctionFstatVFS: smbc_fstatvfs_fn (SMBCCTX *)
+smbc_getFunctionFstatdir: smbc_fstatdir_fn (SMBCCTX *)
+smbc_getFunctionFtruncate: smbc_ftruncate_fn (SMBCCTX *)
+smbc_getFunctionGetCachedServer: smbc_get_cached_srv_fn (SMBCCTX *)
+smbc_getFunctionGetdents: smbc_getdents_fn (SMBCCTX *)
+smbc_getFunctionGetxattr: smbc_getxattr_fn (SMBCCTX *)
+smbc_getFunctionListPrintJobs: smbc_list_print_jobs_fn (SMBCCTX *)
+smbc_getFunctionListxattr: smbc_listxattr_fn (SMBCCTX *)
+smbc_getFunctionLseek: smbc_lseek_fn (SMBCCTX *)
+smbc_getFunctionLseekdir: smbc_lseekdir_fn (SMBCCTX *)
+smbc_getFunctionMkdir: smbc_mkdir_fn (SMBCCTX *)
+smbc_getFunctionNotify: smbc_notify_fn (SMBCCTX *)
+smbc_getFunctionOpen: smbc_open_fn (SMBCCTX *)
+smbc_getFunctionOpenPrintJob: smbc_open_print_job_fn (SMBCCTX *)
+smbc_getFunctionOpendir: smbc_opendir_fn (SMBCCTX *)
+smbc_getFunctionPrintFile: smbc_print_file_fn (SMBCCTX *)
+smbc_getFunctionPurgeCachedServers: smbc_purge_cached_fn (SMBCCTX *)
+smbc_getFunctionRead: smbc_read_fn (SMBCCTX *)
+smbc_getFunctionReaddir: smbc_readdir_fn (SMBCCTX *)
+smbc_getFunctionReaddirPlus: smbc_readdirplus_fn (SMBCCTX *)
+smbc_getFunctionRemoveCachedServer: smbc_remove_cached_srv_fn (SMBCCTX *)
+smbc_getFunctionRemoveUnusedServer: smbc_remove_unused_server_fn (SMBCCTX *)
+smbc_getFunctionRemovexattr: smbc_removexattr_fn (SMBCCTX *)
+smbc_getFunctionRename: smbc_rename_fn (SMBCCTX *)
+smbc_getFunctionRmdir: smbc_rmdir_fn (SMBCCTX *)
+smbc_getFunctionSetxattr: smbc_setxattr_fn (SMBCCTX *)
+smbc_getFunctionSplice: smbc_splice_fn (SMBCCTX *)
+smbc_getFunctionStat: smbc_stat_fn (SMBCCTX *)
+smbc_getFunctionStatVFS: smbc_statvfs_fn (SMBCCTX *)
+smbc_getFunctionTelldir: smbc_telldir_fn (SMBCCTX *)
+smbc_getFunctionUnlink: smbc_unlink_fn (SMBCCTX *)
+smbc_getFunctionUnlinkPrintJob: smbc_unlink_print_job_fn (SMBCCTX *)
+smbc_getFunctionUtimes: smbc_utimes_fn (SMBCCTX *)
+smbc_getFunctionWrite: smbc_write_fn (SMBCCTX *)
+smbc_getNetbiosName: char *(SMBCCTX *)
+smbc_getOptionBrowseMaxLmbCount: int (SMBCCTX *)
+smbc_getOptionCaseSensitive: smbc_bool (SMBCCTX *)
+smbc_getOptionDebugToStderr: smbc_bool (SMBCCTX *)
+smbc_getOptionFallbackAfterKerberos: smbc_bool (SMBCCTX *)
+smbc_getOptionFullTimeNames: smbc_bool (SMBCCTX *)
+smbc_getOptionNoAutoAnonymousLogin: smbc_bool (SMBCCTX *)
+smbc_getOptionOneSharePerServer: smbc_bool (SMBCCTX *)
+smbc_getOptionOpenShareMode: smbc_share_mode (SMBCCTX *)
+smbc_getOptionSmbEncryptionLevel: smbc_smb_encrypt_level (SMBCCTX *)
+smbc_getOptionUrlEncodeReaddirEntries: smbc_bool (SMBCCTX *)
+smbc_getOptionUseCCache: smbc_bool (SMBCCTX *)
+smbc_getOptionUseKerberos: smbc_bool (SMBCCTX *)
+smbc_getOptionUseNTHash: smbc_bool (SMBCCTX *)
+smbc_getOptionUserData: void *(SMBCCTX *)
+smbc_getPort: uint16_t (SMBCCTX *)
+smbc_getServerCacheData: struct smbc_server_cache *(SMBCCTX *)
+smbc_getTimeout: int (SMBCCTX *)
+smbc_getUser: char *(SMBCCTX *)
+smbc_getWorkgroup: char *(SMBCCTX *)
+smbc_getdents: int (unsigned int, struct smbc_dirent *, int)
+smbc_getxattr: int (const char *, const char *, const void *, size_t)
+smbc_init: int (smbc_get_auth_data_fn, int)
+smbc_init_context: SMBCCTX *(SMBCCTX *)
+smbc_lgetxattr: int (const char *, const char *, const void *, size_t)
+smbc_list_print_jobs: int (const char *, smbc_list_print_job_fn)
+smbc_listxattr: int (const char *, char *, size_t)
+smbc_llistxattr: int (const char *, char *, size_t)
+smbc_lremovexattr: int (const char *, const char *)
+smbc_lseek: off_t (int, off_t, int)
+smbc_lseekdir: int (int, off_t)
+smbc_lsetxattr: int (const char *, const char *, const void *, size_t, int)
+smbc_mkdir: int (const char *, mode_t)
+smbc_new_context: SMBCCTX *(void)
+smbc_notify: int (int, smbc_bool, uint32_t, unsigned int, smbc_notify_callback_fn, void *)
+smbc_open: int (const char *, int, mode_t)
+smbc_open_print_job: int (const char *)
+smbc_opendir: int (const char *)
+smbc_option_get: void *(SMBCCTX *, char *)
+smbc_option_set: void (SMBCCTX *, char *, ...)
+smbc_print_file: int (const char *, const char *)
+smbc_read: ssize_t (int, void *, size_t)
+smbc_readdir: struct smbc_dirent *(unsigned int)
+smbc_readdirplus: const struct libsmb_file_info *(unsigned int)
+smbc_removexattr: int (const char *, const char *)
+smbc_rename: int (const char *, const char *)
+smbc_rmdir: int (const char *)
+smbc_setConfiguration: int (SMBCCTX *, const char *)
+smbc_setDebug: void (SMBCCTX *, int)
+smbc_setFunctionAddCachedServer: void (SMBCCTX *, smbc_add_cached_srv_fn)
+smbc_setFunctionAuthData: void (SMBCCTX *, smbc_get_auth_data_fn)
+smbc_setFunctionAuthDataWithContext: void (SMBCCTX *, smbc_get_auth_data_with_context_fn)
+smbc_setFunctionCheckServer: void (SMBCCTX *, smbc_check_server_fn)
+smbc_setFunctionChmod: void (SMBCCTX *, smbc_chmod_fn)
+smbc_setFunctionClose: void (SMBCCTX *, smbc_close_fn)
+smbc_setFunctionClosedir: void (SMBCCTX *, smbc_closedir_fn)
+smbc_setFunctionCreat: void (SMBCCTX *, smbc_creat_fn)
+smbc_setFunctionFstat: void (SMBCCTX *, smbc_fstat_fn)
+smbc_setFunctionFstatVFS: void (SMBCCTX *, smbc_fstatvfs_fn)
+smbc_setFunctionFstatdir: void (SMBCCTX *, smbc_fstatdir_fn)
+smbc_setFunctionFtruncate: void (SMBCCTX *, smbc_ftruncate_fn)
+smbc_setFunctionGetCachedServer: void (SMBCCTX *, smbc_get_cached_srv_fn)
+smbc_setFunctionGetdents: void (SMBCCTX *, smbc_getdents_fn)
+smbc_setFunctionGetxattr: void (SMBCCTX *, smbc_getxattr_fn)
+smbc_setFunctionListPrintJobs: void (SMBCCTX *, smbc_list_print_jobs_fn)
+smbc_setFunctionListxattr: void (SMBCCTX *, smbc_listxattr_fn)
+smbc_setFunctionLseek: void (SMBCCTX *, smbc_lseek_fn)
+smbc_setFunctionLseekdir: void (SMBCCTX *, smbc_lseekdir_fn)
+smbc_setFunctionMkdir: void (SMBCCTX *, smbc_mkdir_fn)
+smbc_setFunctionNotify: void (SMBCCTX *, smbc_notify_fn)
+smbc_setFunctionOpen: void (SMBCCTX *, smbc_open_fn)
+smbc_setFunctionOpenPrintJob: void (SMBCCTX *, smbc_open_print_job_fn)
+smbc_setFunctionOpendir: void (SMBCCTX *, smbc_opendir_fn)
+smbc_setFunctionPrintFile: void (SMBCCTX *, smbc_print_file_fn)
+smbc_setFunctionPurgeCachedServers: void (SMBCCTX *, smbc_purge_cached_fn)
+smbc_setFunctionRead: void (SMBCCTX *, smbc_read_fn)
+smbc_setFunctionReaddir: void (SMBCCTX *, smbc_readdir_fn)
+smbc_setFunctionReaddirPlus: void (SMBCCTX *, smbc_readdirplus_fn)
+smbc_setFunctionRemoveCachedServer: void (SMBCCTX *, smbc_remove_cached_srv_fn)
+smbc_setFunctionRemoveUnusedServer: void (SMBCCTX *, smbc_remove_unused_server_fn)
+smbc_setFunctionRemovexattr: void (SMBCCTX *, smbc_removexattr_fn)
+smbc_setFunctionRename: void (SMBCCTX *, smbc_rename_fn)
+smbc_setFunctionRmdir: void (SMBCCTX *, smbc_rmdir_fn)
+smbc_setFunctionSetxattr: void (SMBCCTX *, smbc_setxattr_fn)
+smbc_setFunctionSplice: void (SMBCCTX *, smbc_splice_fn)
+smbc_setFunctionStat: void (SMBCCTX *, smbc_stat_fn)
+smbc_setFunctionStatVFS: void (SMBCCTX *, smbc_statvfs_fn)
+smbc_setFunctionTelldir: void (SMBCCTX *, smbc_telldir_fn)
+smbc_setFunctionUnlink: void (SMBCCTX *, smbc_unlink_fn)
+smbc_setFunctionUnlinkPrintJob: void (SMBCCTX *, smbc_unlink_print_job_fn)
+smbc_setFunctionUtimes: void (SMBCCTX *, smbc_utimes_fn)
+smbc_setFunctionWrite: void (SMBCCTX *, smbc_write_fn)
+smbc_setLogCallback: void (SMBCCTX *, void *, smbc_debug_callback_fn)
+smbc_setNetbiosName: void (SMBCCTX *, char *)
+smbc_setOptionBrowseMaxLmbCount: void (SMBCCTX *, int)
+smbc_setOptionCaseSensitive: void (SMBCCTX *, smbc_bool)
+smbc_setOptionDebugToStderr: void (SMBCCTX *, smbc_bool)
+smbc_setOptionFallbackAfterKerberos: void (SMBCCTX *, smbc_bool)
+smbc_setOptionFullTimeNames: void (SMBCCTX *, smbc_bool)
+smbc_setOptionNoAutoAnonymousLogin: void (SMBCCTX *, smbc_bool)
+smbc_setOptionOneSharePerServer: void (SMBCCTX *, smbc_bool)
+smbc_setOptionOpenShareMode: void (SMBCCTX *, smbc_share_mode)
+smbc_setOptionSmbEncryptionLevel: void (SMBCCTX *, smbc_smb_encrypt_level)
+smbc_setOptionUrlEncodeReaddirEntries: void (SMBCCTX *, smbc_bool)
+smbc_setOptionUseCCache: void (SMBCCTX *, smbc_bool)
+smbc_setOptionUseKerberos: void (SMBCCTX *, smbc_bool)
+smbc_setOptionUseNTHash: void (SMBCCTX *, smbc_bool)
+smbc_setOptionUserData: void (SMBCCTX *, void *)
+smbc_setPort: void (SMBCCTX *, uint16_t)
+smbc_setServerCacheData: void (SMBCCTX *, struct smbc_server_cache *)
+smbc_setTimeout: void (SMBCCTX *, int)
+smbc_setUser: void (SMBCCTX *, const char *)
+smbc_setWorkgroup: void (SMBCCTX *, char *)
+smbc_set_context: SMBCCTX *(SMBCCTX *)
+smbc_set_credentials: void (const char *, const char *, const char *, smbc_bool, const char *)
+smbc_set_credentials_with_fallback: void (SMBCCTX *, const char *, const char *, const char *)
+smbc_setxattr: int (const char *, const char *, const void *, size_t, int)
+smbc_stat: int (const char *, struct stat *)
+smbc_statvfs: int (char *, struct statvfs *)
+smbc_telldir: off_t (int)
+smbc_unlink: int (const char *)
+smbc_unlink_print_job: int (const char *, int)
+smbc_urldecode: int (char *, char *, size_t)
+smbc_urlencode: int (char *, char *, int)
+smbc_utime: int (const char *, struct utimbuf *)
+smbc_utimes: int (const char *, struct timeval *)
+smbc_version: const char *(void)
+smbc_write: ssize_t (int, const void *, size_t)
diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c
index 5fed44abc4a..eb38480a5c6 100644
--- a/source3/libsmb/libsmb_compat.c
+++ b/source3/libsmb/libsmb_compat.c
@@ -285,6 +285,12 @@ smbc_readdir(unsigned int dh)
         return smbc_getFunctionReaddir(statcont)(statcont, file);
 }
 
+const struct libsmb_file_info *smbc_readdirplus(unsigned int dh)
+{
+	SMBCFILE * file = find_fd(dh);
+	return smbc_getFunctionReaddirPlus(statcont)(statcont, file);
+}
+
 off_t
 smbc_telldir(int dh)
 {
diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c
index b55cf1e2d15..80b2666b40b 100644
--- a/source3/libsmb/libsmb_context.c
+++ b/source3/libsmb/libsmb_context.c
@@ -208,6 +208,7 @@ smbc_new_context(void)
         smbc_setFunctionOpendir(context, SMBC_opendir_ctx);
         smbc_setFunctionClosedir(context, SMBC_closedir_ctx);
         smbc_setFunctionReaddir(context, SMBC_readdir_ctx);
+	smbc_setFunctionReaddirPlus(context, SMBC_readdirplus_ctx);
         smbc_setFunctionGetdents(context, SMBC_getdents_ctx);
         smbc_setFunctionMkdir(context, SMBC_mkdir_ctx);
         smbc_setFunctionRmdir(context, SMBC_rmdir_ctx);
diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c
index ba7ba9a6270..faaccdaae5c 100644
--- a/source3/libsmb/libsmb_dir.c
+++ b/source3/libsmb/libsmb_dir.c
@@ -1139,6 +1139,52 @@ SMBC_readdir_ctx(SMBCCTX *context,
         return dirp;
 }
 
+/*
+ * Routine to get a directory entry with all attributes
+ */
+
+const struct libsmb_file_info *
+SMBC_readdirplus_ctx(SMBCCTX *context,
+                     SMBCFILE *dir)
+{
+	struct libsmb_file_info *smb_finfo = NULL;
+	TALLOC_CTX *frame = talloc_stackframe();
+
+	/* Check that all is ok first ... */
+
+	if (!context || !context->internal->initialized) {
+		DBG_ERR("Invalid context in SMBC_readdirplus_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_readdirplus_ctx()\n");
+		TALLOC_FREE(frame);
+		errno = EBADF;
+		return NULL;
+	}
+
+	if (dir->dirplus_next == NULL) {
+		TALLOC_FREE(frame);
+		return NULL;
+	}
+
+	smb_finfo = dir->dirplus_next->smb_finfo;
+	if (smb_finfo == NULL) {
+		TALLOC_FREE(frame);
+		errno = ENOENT;
+		return NULL;
+	}
+	dir->dirplus_next = dir->dirplus_next->next;
+
+	TALLOC_FREE(frame);
+	return smb_finfo;
+}
+
 /*
  * Routine to get directory entries
  */
diff --git a/source3/libsmb/libsmb_setget.c b/source3/libsmb/libsmb_setget.c
index cb32f5fc20e..7a17cadc891 100644
--- a/source3/libsmb/libsmb_setget.c
+++ b/source3/libsmb/libsmb_setget.c
@@ -879,6 +879,16 @@ smbc_setFunctionReaddir(SMBCCTX *c, smbc_readdir_fn fn)
         c->readdir = fn;
 }
 
+smbc_readdirplus_fn smbc_getFunctionReaddirPlus(SMBCCTX *c)
+{
+	return c->readdirplus;
+}
+
+void smbc_setFunctionReaddirPlus(SMBCCTX *c, smbc_readdirplus_fn fn)
+{
+	c->readdirplus = fn;
+}
+
 smbc_getdents_fn
 smbc_getFunctionGetdents(SMBCCTX *c)
 {
diff --git a/source3/libsmb/wscript b/source3/libsmb/wscript
index 526434eabe0..15575bcc6ab 100644
--- a/source3/libsmb/wscript
+++ b/source3/libsmb/wscript
@@ -27,5 +27,5 @@ def build(bld):
                        public_headers='../include/libsmbclient.h',
                        abi_directory='ABI',
                        abi_match='smbc_*',
-                       vnum='0.3.2',
+                       vnum='0.3.3',
                        pc_files='smbclient.pc')
-- 
2.17.0.484.g0c8726318c-goog



More information about the samba-technical mailing list