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

Jeremy Allison jra at samba.org
Mon Apr 9 20:24:08 UTC 2018


On Fri, Apr 06, 2018 at 12:17:18AM +0000, Puran Chand wrote:
> Sure Jeremy.
> Thanks.

OK, here is a preliminary version of the patchset (minus
the test) that I'd like you to take a look at please.

It splits the patches into small, review-sized chunks
and updates the coding style to match README.Coding.

I'm still looking at the test code. The reason is you've
copied the libsmbclient.opendir tests, which are explicitly
marked as "knownfail" as they depend on NetBIOS browsing
service, so as posted they won't work.

I'm thinking of how to modify these to work against
the existing test shares. I'll post more when I've
gotten it working.

In the meantime can you review and test this patchset,
and make sure I didn't break anything ?

Thanks,

	Jeremy.
-------------- next part --------------
From 819bda7e92762a42bef933dff6be8e349390b5d1 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..af23d6b5d15 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;
 	}
 
+	info->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 82d15215536be7693d1c56983c8482b1497cdc20 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 37cf9d49c969d808559885474b2fe7fe3f695e0e 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 7e5734e32089af8f8391453c481644a3c2db9afe 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 e256bf89634de020518c4b623ee21a1812651bee 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