From fa341d526293f4d986f2f3d838a728ce4223ee88 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Tue, 26 Feb 2008 21:44:51 -0500 Subject: add smbc_ftruncate() to emulate POSIX ftruncate() (This used to be commit 6f5051b9c1405ab1dc3e697419ceedb3acac46d8) --- source3/include/libsmbclient.h | 31 +++++++++++++++++ source3/libsmb/libsmb_compat.c | 6 ++++ source3/libsmb/libsmbclient.c | 75 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+) (limited to 'source3') diff --git a/source3/include/libsmbclient.h b/source3/include/libsmbclient.h index 07242f7956..64afc09499 100644 --- a/source3/include/libsmbclient.h +++ b/source3/include/libsmbclient.h @@ -427,6 +427,8 @@ struct _SMBCCTX { off_t (*lseek) (SMBCCTX *c, SMBCFILE * file, off_t offset, int whence); int (*stat) (SMBCCTX *c, const char *fname, struct stat *st); int (*fstat) (SMBCCTX *c, SMBCFILE *file, struct stat *st); + /* ftruncate added near _internal for ABI compatibility */ + int (*close_fn) (SMBCCTX *c, SMBCFILE *file); /** callable functions for dirs @@ -520,6 +522,12 @@ struct _SMBCCTX { int flags; /** user options selections that apply to this session + * + * NEW OPTIONS ARE NOT ADDED HERE! + * + * We must maintain ABI backward compatibility. We now use + * smbc_option_set() and smbc_option_get() for all newly added + * options. */ struct _smbc_options { @@ -580,6 +588,9 @@ struct _SMBCCTX { int one_share_per_server; } options; + /* Add additional functions here for ABI backward compatibility */ + int (*ftruncate)(SMBCCTX *c, SMBCFILE *f, off_t size); + /** INTERNAL DATA * do _NOT_ touch this from your program ! */ @@ -1193,6 +1204,26 @@ int smbc_stat(const char *url, struct stat *st); int smbc_fstat(int fd, struct stat *st); +/**@ingroup attribute + * Truncate a file given a file descriptor + * + * @param fd Open file handle from smbc_open() or smbc_creat() + * + * @param size size to truncate the file to + * + * @return EBADF filedes is bad. + * - EACCES Permission denied. + * - EBADF fd is not a valid file descriptor + * - EINVAL Problems occurred in the underlying routines + * or smbc_init not called. + * - ENOMEM Out of memory + * + * @see , Unix ftruncate() + * + */ +int smbc_ftruncate(int fd, off_t size); + + /**@ingroup attribue * Change the ownership of a file or directory. * diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index 573d087d6e..6042464fd2 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -289,6 +289,12 @@ int smbc_fstat(int fd, struct stat *st) return (statcont->fstat)(statcont, file, st); } +int smbc_ftruncate(int fd, off_t size) +{ + SMBCFILE * file = find_fd(fd); + return (statcont->ftruncate)(statcont, file, size); +} + int smbc_chmod(const char *url, mode_t mode) { return (statcont->chmod)(statcont, url, mode); diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index e84de59637..fe008ed6b6 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2482,6 +2482,80 @@ smbc_fstat_ctx(SMBCCTX *context, } +/* + * Routine to truncate a file given by its file descriptor, to a specified size + */ + +static int +smbc_ftruncate_ctx(SMBCCTX *context, + SMBCFILE *file, + off_t length) +{ + SMB_OFF_T size = length; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal || + !context->internal->_initialized) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { + errno = EBADF; + TALLOC_FREE(frame); + return -1; + } + + if (!file->file) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ + if (smbc_parse_path(frame, + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /*d_printf(">>>fstat: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", file->srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ + + if (!cli_ftruncate(targetcli, file->cli_fd, size)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + TALLOC_FREE(frame); + return 0; + +} + /* * Routine to open a directory * We accept the URL syntax explained in smbc_parse_path(), above. @@ -6703,6 +6777,7 @@ smbc_new_context(void) context->telldir = smbc_telldir_ctx; context->lseekdir = smbc_lseekdir_ctx; context->fstatdir = smbc_fstatdir_ctx; + context->ftruncate = smbc_ftruncate_ctx; context->chmod = smbc_chmod_ctx; context->utimes = smbc_utimes_ctx; context->setxattr = smbc_setxattr_ctx; -- cgit