[PATCH] libsmbclient read-dir-plus

Jeremy Allison jra at samba.org
Tue Aug 29 18:36:48 UTC 2017


On Wed, Aug 16, 2017 at 05:37:06PM +0530, Puran Chand wrote:
> added patch file

OK, I'm looking at this and it needs some changes. I'll get
back to you soon with a modified version.

Jeremy.

> On Mon, Aug 7, 2017 at 7:09 AM, Puran Chand <puran157 at gmail.com> wrote:
> 
>     Hi all,
> 
>     Raised a PR which addresses this.
>     https://github.com/samba-team/samba/pull/94
> 
>     P.S notification script is broken hence sending the mail
> 
>     On Wed, Feb 15, 2017 at 12:17 AM, Jeremy Allison <jra at samba.org> wrote:
> 
>         On Tue, Feb 14, 2017 at 11:11:10PM +0530, shravan a wrote:
>         > Hi,
>         >
>         >
>         > LibSmbClient exposes an api  *int **smbc_opendir*(*const* *char*
>         *durl) which
>         > accepts the parent folder path and fetches metadata about all its
>         immediate
>         > children and returns the directory handle to the parent folder. The
>         api
>         > *struct* smbc_dirent **smbc_readdir*(*unsigned* *int* dh) accepts
>         this
>         > directory handle(dh) and returns metadata as a structure
>         (smbc_dirent) that
>         > contains limited info such as smbc_type, dirlen, commentlen,comment,
>         > namelen, name. Repetitive calls to this API fetches the next child
>         metadata
>         > in sequence and returns the structure. Unfortunately, it doesn’t give
>         any
>         > information regarding the resource size(important in case of files),
>         > create/modified date time. To get these info, this library exposes
>         two
>         > API’s,
>         >
>         > *int* *smbc_stat*(*const* *char* *url, *struct* stat *st) - that
>         accepts
>         > the url and
>         >
>         > *int **smbc_fstat*(*int* fd, *struct* stat *st) that accepts the file
>         > descriptor.
>         >
>         >      Both returns the required metadata as a structure ‘stat’ which
>         > contains all the time stamps(create, modified, access) and the size. 
>         Both
>         > needs to be invoked once for every child resource within the parent
>         > resource. smbc_stat() is found to be an expensive task since it makes
>         an
>         > extra SMB call to the resource , while smbc_fstat() is found to be
>         faster
>         > since it accepts the file descriptor. But this still requires the
>         file
>         > descriptor which can be obtained only via another smbc_opendir
>         (resource
>         > url) or smbc_open(resource url).
>         >
>         >   Another API I tried out is –
>         >
>         > *Int **smbc_getxattr*(*const* *char* *fname,
>         >
>         >               *const* *char* *name,
>         >
>         >               *const* *void* *value,
>         >
>         >               size_t size)
>         >
>         >      This accepts the resourceurl, and the attribute name, returns
>         the
>         > attribute value. But this API also needs to be invoked once per child
>         > resource within the parent folder which again is expensive.
>         >
>         >
>         >
>         > This extra API call for every child resource still makes the whole
>         process
>         > expensive.
>         >
>         >
>         > However, when I open a smb session from the shell "ls" command
>         performs
>         > very fast. The function that "ls" internally calls in "list_dir".
>         >
>         > I would like to write a public API that would call the internal
>         > implementation of "ls". Thoughts?
> 
>         What you need is readdirplus - a readdir that also returns
>         stat info.
> 
>         Add a new call to libsmbclient called smbc_readdirplus().
> 
>         The internal call to cli_list gets most of the info you
>         want (except for the EA values) so you will need to change
>         the SMBC_opendir_ctx() function to use an internal callback
>         that does more with the info returned by cli_list.
> 
> 
> 
> 
> 
>     --
>     Regards
>     Puran Chand
> 
> 
> 
> 
> --
> Regards
> Puran Chand

> From 057a2737b958fcbf2860cac4bc85bf0ebf1f370b Mon Sep 17 00:00:00 2001
> From: Puran Chand <pchand at vmware.com>
> Date: Sun, 6 Aug 2017 12:39:58 +0530
> Subject: [PATCH] Added an API read-dir-plus which performs similar to that of
>  read-dir except it returns file_info struct which has more information about
>  file or directory
> 
> Signed-off-by: Puran Chand <pchand at vmware.com>
> ---
>  source3/include/client.h                |   2 +
>  source3/include/libsmb_internal.h       |  16 ++-
>  source3/include/libsmbclient.h          |  40 +++++++
>  source3/libsmb/ABI/smbclient-0.2.4.sigs | 182 ++++++++++++++++++++++++++++++++
>  source3/libsmb/clilist.c                |   2 +
>  source3/libsmb/libsmb_compat.c          |   8 ++
>  source3/libsmb/libsmb_context.c         |   2 +
>  source3/libsmb/libsmb_dir.c             | 154 ++++++++++++++++++++++++++-
>  source3/libsmb/libsmb_setget.c          |  12 +++
>  source3/libsmb/wscript                  |   2 +-
>  10 files changed, 417 insertions(+), 3 deletions(-)
>  create mode 100644 source3/libsmb/ABI/smbclient-0.2.4.sigs
> 
> diff --git a/source3/include/client.h b/source3/include/client.h
> index 1fe3f1c..6f19a07 100644
> --- a/source3/include/client.h
> +++ b/source3/include/client.h
> @@ -4,6 +4,7 @@
>     Copyright (C) Andrew Tridgell 1992-1998
>     Copyright (C) Luke Kenneth Casson Leighton 1996-1998
>     Copyright (C) Jeremy Allison 1998
> +   Copyright (C) 2017 VMware, Inc. All rights reserved.
>  
>     This program is free software; you can redistribute it and/or modify
>     it under the terms of the GNU General Public License as published by
> @@ -108,6 +109,7 @@ struct file_info {
>  	uid_t uid;
>  	gid_t gid;
>  	/* these times are normally kept in GMT */
> +	struct timespec crtime_ts;
>  	struct timespec mtime_ts;
>  	struct timespec atime_ts;
>  	struct timespec ctime_ts;
> diff --git a/source3/include/libsmb_internal.h b/source3/include/libsmb_internal.h
> index 0e0045e..5250c69 100644
> --- a/source3/include/libsmb_internal.h
> +++ b/source3/include/libsmb_internal.h
> @@ -7,6 +7,7 @@
>     Copyright (C) Tom Jansen (Ninja ISD) 2002
>     Copyright (C) Derrell Lipman 2003-2008
>     Copyright (C) Jeremy Allison 2007, 2008
> +   Copyright (C) 2017 VMware, Inc. All rights reserved.
>  
>     This program is free software; you can redistribute it and/or modify
>     it under the terms of the GNU General Public License as published by
> @@ -95,6 +96,13 @@ struct smbc_dir_list {
>  };
>  
>  
> +struct smbc_dirplus_list
> +{
> +	struct smbc_dirplus_list *next;
> +	struct file_info *data;
> +};
> +
> +
>  /*
>   * Structure for open file management
>   */
> @@ -110,7 +118,8 @@ struct _SMBCFILE {
>  	struct _SMBCSRV *srv;
>  	bool file;
>  	struct smbc_dir_list *dir_list, *dir_end, *dir_next;
> -	int dir_type, dir_error;
> +	struct smbc_dirplus_list *dirplus_list, *dirplus_end, *dirplus_next;
> +	int dir_type, dir_error, dirplus_error;
>  
>  	SMBCFILE *next, *prev;
>  };
> @@ -126,6 +135,7 @@ struct SMBC_internal_data {
>  
>          /* dirent pointer location */
>  	struct smbc_dirent			dirent;
> +	struct file_info			finfo;
>  	/*
>           * Leave room for any urlencoded filename and the comment field.
>           *
> @@ -292,6 +302,10 @@ int
>  SMBC_closedir_ctx(SMBCCTX *context,
>                    SMBCFILE *dir);
>  
> +struct file_info *
> +SMBC_readdirplus_ctx(SMBCCTX *context,
> +					 SMBCFILE *dir);
> +
>  struct smbc_dirent *
>  SMBC_readdir_ctx(SMBCCTX *context,
>                   SMBCFILE *dir);
> diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h
> index cf67b1d..6da9c54 100644
> --- a/source3/include/libsmbclient.h
> +++ b/source3/include/libsmbclient.h
> @@ -6,6 +6,7 @@
>    Copyright (C) John Terpsra 2000
>    Copyright (C) Tom Jansen (Ninja ISD) 2002
>    Copyright (C) Derrell Lipman 2003-2008
> +  Copyright (C) 2017 VMware, Inc. All rights reserved.
>  
>  
>    This program is free software; you can redistribute it and/or modify
> @@ -129,6 +130,26 @@ struct smbc_dirent
>  	char name[1];
>  };
>  
> +/**@ingroup structure
> + * Structure that represents all attributes of a directory entry.
> + *
> + */
> +#ifndef _CLIENT_H
> +struct file_info {
> +	uint64_t size;
> +	uint16_t mode;
> +	uid_t uid;
> +	gid_t gid;
> +	/* these times are normally kept in GMT */
> +	struct timespec crtime_ts;
> +	struct timespec mtime_ts;
> +	struct timespec atime_ts;
> +	struct timespec ctime_ts;
> +	char *name;
> +	char *short_name;
> +};
> +#endif /* _CLIENT_H */
> +
>  /*
>   * Flags for smbc_setxattr()
>   *   Specify a bitwise OR of these, or 0 to add or replace as necessary
> @@ -958,6 +979,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 struct 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,
> @@ -1552,6 +1578,19 @@ 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 pointer to a 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()
> + */
> +struct file_info* smbc_readdirplus(unsigned int dh);
>  
>  /**@ingroup directory
>   * Get the current directory offset.
> @@ -3001,6 +3040,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.2.4.sigs b/source3/libsmb/ABI/smbclient-0.2.4.sigs
> new file mode 100644
> index 0000000..9aaffe5
> --- /dev/null
> +++ b/source3/libsmb/ABI/smbclient-0.2.4.sigs
> @@ -0,0 +1,182 @@
> +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: struct file_info *(unsigned int)
> +smbc_removexattr: int (const char *, const char *)
> +smbc_rename: int (const char *, const char *)
> +smbc_rmdir: int (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_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 *, 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/clilist.c b/source3/libsmb/clilist.c
> index 41f5851..7b4adab 100644
> --- a/source3/libsmb/clilist.c
> +++ b/source3/libsmb/clilist.c
> @@ -2,6 +2,7 @@
>     Unix SMB/CIFS implementation.
>     client directory list routines
>     Copyright (C) Andrew Tridgell 1994-1998
> +   Copyright (C) 2017 VMware, Inc. All rights reserved.
>  
>     This program is free software; you can redistribute it and/or modify
>     it under the terms of the GNU General Public License as published by
> @@ -171,6 +172,7 @@ static size_t interpret_long_filename(TALLOC_CTX *ctx,
>  			p += 4; /* fileindex */
>  
>  			/* Offset zero is "create time", not "change time". */
> +			finfo->crtime_ts = interpret_long_date(p);
>  			p += 8;
>  			finfo->atime_ts = interpret_long_date(p);
>  			p += 8;
> diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c
> index 5fed44a..97bd9ee 100644
> --- a/source3/libsmb/libsmb_compat.c
> +++ b/source3/libsmb/libsmb_compat.c
> @@ -6,6 +6,7 @@
>     Copyright (C) John Terpstra 2000
>     Copyright (C) Tom Jansen (Ninja ISD) 2002
>     Copyright (C) Derrell Lipman 2003, 2008
> +   Copyright (C) 2017 VMware, Inc. All rights reserved.
>  
>     This program is free software; you can redistribute it and/or modify
>     it under the terms of the GNU General Public License as published by
> @@ -285,6 +286,13 @@ smbc_readdir(unsigned int dh)
>          return smbc_getFunctionReaddir(statcont)(statcont, file);
>  }
>  
> +struct 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 ed6ca2b..dbaf169 100644
> --- a/source3/libsmb/libsmb_context.c
> +++ b/source3/libsmb/libsmb_context.c
> @@ -7,6 +7,7 @@
>     Copyright (C) Tom Jansen (Ninja ISD) 2002
>     Copyright (C) Derrell Lipman 2003-2008
>     Copyright (C) Jeremy Allison 2007, 2008
> +   Copyright (C) 2017 VMware, Inc. All rights reserved.
>  
>     This program is free software; you can redistribute it and/or modify
>     it under the terms of the GNU General Public License as published by
> @@ -208,6 +209,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 8038584..2bfe792 100644
> --- a/source3/libsmb/libsmb_dir.c
> +++ b/source3/libsmb/libsmb_dir.c
> @@ -7,6 +7,7 @@
>     Copyright (C) Tom Jansen (Ninja ISD) 2002
>     Copyright (C) Derrell Lipman 2003-2008
>     Copyright (C) Jeremy Allison 2007, 2008
> +   Copyright (C) 2017 VMware, Inc. All rights reserved.
>  
>     This program is free software; you can redistribute it and/or modify
>     it under the terms of the GNU General Public License as published by
> @@ -58,6 +59,96 @@ remove_dir(SMBCFILE *dir)
>  
>  }
>  
> +
> +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->data->short_name);
> +		SAFE_FREE(f->data->name);
> +		SAFE_FREE(f->data);
> +		SAFE_FREE(f);
> +
> +	}
> +
> +	dir->dirplus_list = dir->dirplus_end = dir->dirplus_next = NULL;
> +
> +}
> +
> +static int
> +add_fileinfo(SMBCFILE *dir,
> +           struct file_info *finfo)
> +{
> +	struct file_info *info;
> +
> +	info = SMB_MALLOC_P(struct file_info);
> +
> +	if (!info) {
> +
> +		dir->dir_error = ENOMEM;
> +		return -1;
> +
> +	}
> +
> +	ZERO_STRUCTP(info);
> +
> +	if (dir->dirplus_list == NULL) {
> +
> +		dir->dirplus_list = SMB_MALLOC_P(struct smbc_dirplus_list);
> +		if (!dir->dirplus_list) {
> +
> +			SAFE_FREE(info);
> +			dir->dirplus_error = ENOMEM;
> +			return -1;
> +
> +		}
> +		ZERO_STRUCTP(dir->dirplus_list);
> +
> +		dir->dirplus_end = dir->dirplus_next = dir->dirplus_list;
> +	}
> +	else {
> +
> +		dir->dirplus_end->next = SMB_MALLOC_P(struct smbc_dirplus_list);
> +
> +		if (!dir->dirplus_end->next) {
> +
> +			SAFE_FREE(info);
> +			dir->dirplus_error = ENOMEM;
> +			return -1;
> +
> +		}
> +		ZERO_STRUCTP(dir->dirplus_end->next);
> +
> +		dir->dirplus_end = dir->dirplus_end->next;
> +	}
> +
> +	dir->dirplus_end->next = NULL;
> +	dir->dirplus_end->data = info;
> +
> +	info->crtime_ts = finfo->crtime_ts;
> +	info->atime_ts = finfo->atime_ts;
> +	info->ctime_ts = finfo->ctime_ts;
> +	info->gid = finfo->gid;
> +	info->mode = finfo->mode;
> +	info->mtime_ts = finfo->mtime_ts;
> +	info->name = SMB_STRDUP(finfo->name);
> +	if (finfo->short_name)
> +		info->short_name = SMB_STRDUP(finfo->short_name);
> +	else
> +		info->short_name = SMB_STRDUP("");
> +	info->size = finfo->size;
> +	info->uid = finfo->uid;
> +
> +	return 0;
> +
> +}
> +
>  static int
>  add_dirent(SMBCFILE *dir,
>             const char *name,
> @@ -253,6 +344,13 @@ dir_list_fn(const char *mnt,
>  		SMBCFILE *dir = (SMBCFILE *)state;
>  		return map_nt_error_from_unix(dir->dir_error);
>  	}
> +
> +	if(add_fileinfo((SMBCFILE *)state, finfo) < 0)
> +	{
> +		SMBCFILE *dir = (SMBCFILE *)state;
> +		return map_nt_error_from_unix(dir->dirplus_error);
> +
> +	}
>  	return NT_STATUS_OK;
>  }
>  
> @@ -456,6 +554,7 @@ SMBC_opendir_ctx(SMBCCTX *context,
>  	dir->offset   = 0;
>  	dir->file     = False;
>  	dir->dir_list = dir->dir_next = dir->dir_end = NULL;
> +	dir->dirplus_list = dir->dirplus_next = dir->dirplus_end = NULL;
>  
>  	if (server[0] == (char)0) {
>  
> @@ -915,7 +1014,9 @@ SMBC_closedir_ctx(SMBCCTX *context,
>  		return -1;
>  	}
>  
> -	remove_dir(dir); /* Clean it up */
> +	/* Clean it up */
> +	remove_dir(dir);
> +    remove_dirplus(dir);
>  
>  	DLIST_REMOVE(context->internal->files, dir);
>  
> @@ -1033,6 +1134,57 @@ SMBC_readdir_ctx(SMBCCTX *context,
>  }
>  
>  /*
> + * Routine to get a directory entry with all attributes
> + */
> +
> +struct file_info *
> +SMBC_readdirplus_ctx(SMBCCTX *context,
> +                     SMBCFILE *dir)
> +{
> +    struct file_info *finfo;
> +    TALLOC_CTX *frame = talloc_stackframe();
> +
> +    /* Check that all is ok first ... */
> +
> +    if (!context || !context->internal->initialized) {
> +
> +        errno = EINVAL;
> +        DEBUG(0, ("Invalid context in SMBC_readdirplus_ctx()\n"));
> +        TALLOC_FREE(frame);
> +        return NULL;
> +
> +    }
> +
> +    if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) {
> +
> +        errno = EBADF;
> +        DEBUG(0, ("Invalid dir in SMBC_readdirplus_ctx()\n"));
> +        TALLOC_FREE(frame);
> +        return NULL;
> +
> +    }
> +
> +    if (!dir->dirplus_next) {
> +        TALLOC_FREE(frame);
> +        return NULL;
> +    }
> +
> +    finfo = dir->dirplus_next->data;
> +    if (!finfo) {
> +
> +        errno = ENOENT;
> +        TALLOC_FREE(frame);
> +        return NULL;
> +
> +    }
> +
> +    dir->dirplus_next = dir->dirplus_next->next;
> +
> +    TALLOC_FREE(frame);
> +    return finfo;
> +}
> +
> +/*
>   * Routine to get directory entries
>   */
>  
> diff --git a/source3/libsmb/libsmb_setget.c b/source3/libsmb/libsmb_setget.c
> index 80ac673..b830d41 100644
> --- a/source3/libsmb/libsmb_setget.c
> +++ b/source3/libsmb/libsmb_setget.c
> @@ -7,6 +7,7 @@
>     Copyright (C) Tom Jansen (Ninja ISD) 2002
>     Copyright (C) Derrell Lipman 2003-2008
>     Copyright (C) Jeremy Allison 2007, 2008
> +   Copyright (C) 2017 VMware, Inc. All rights reserved.
>  
>     This program is free software; you can redistribute it and/or modify
>     it under the terms of the GNU General Public License as published by
> @@ -928,6 +929,17 @@ smbc_setFunctionFstatdir(SMBCCTX *c, smbc_fstatdir_fn fn)
>          c->fstatdir = fn;
>  }
>  
> +smbc_readdirplus_fn smbc_getFunctionReaddirPlus(SMBCCTX *c)
> +{
> +	return c->readdirplus;
> +}
> +
> +void smbc_setFunctionReaddirPlus(SMBCCTX *c, smbc_readdirplus_fn fn)
> +{
> +	c->readdirplus = fn;
> +}
> +
> +
>  smbc_notify_fn
>  smbc_getFunctionNotify(SMBCCTX *c)
>  {
> diff --git a/source3/libsmb/wscript b/source3/libsmb/wscript
> index 6d862f7..66209da 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.2.3',
> +                       vnum='0.2.4',
>                         pc_files='smbclient.pc')
> -- 
> 1.8.3.1
> 




More information about the samba-technical mailing list