From 248805d5d9f29dd364c41ac01bbfb77e0a1e1739 Mon Sep 17 00:00:00 2001 From: Jeremy Allison 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 . Signed-off-by: Jeremy Allison --- 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 2d87b58d730..bf686dad3d6 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; From ca546f359e40a7a07f7896eb51ec40bbb95c3348 Mon Sep 17 00:00:00 2001 From: Puran Chand 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 Reviewed-by: Jeremy Allison --- 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 */ From e0fabfc21a3a4cc3ca1229a846053d681b84b828 Mon Sep 17 00:00:00 2001 From: Puran Chand 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 Reviewed-by: Jeremy Allison --- 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); From 47433f0129a1183a8a7ebb059cb160c6a87cf5e0 Mon Sep 17 00:00:00 2001 From: Puran Chand 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 Reviewed-by: Jeremy Allison --- 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; } From af003a96cbb2607c1b12388f574d8eea72fcac89 Mon Sep 17 00:00:00 2001 From: Puran Chand 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 Reviewed-by: Jeremy Allison --- examples/fuse/clifuse.c | 2 +- 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 +- 9 files changed, 273 insertions(+), 2 deletions(-) create mode 100644 source3/libsmb/ABI/smbclient-0.3.3.sigs diff --git a/examples/fuse/clifuse.c b/examples/fuse/clifuse.c index af23d6b5d15..3c7e4982475 100644 --- a/examples/fuse/clifuse.c +++ b/examples/fuse/clifuse.c @@ -484,7 +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->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/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')