summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/include/libsmbclient.h31
-rw-r--r--source3/libsmb/libsmb_compat.c6
-rw-r--r--source3/libsmb/libsmbclient.c75
3 files changed, 112 insertions, 0 deletions
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
@@ -2483,6 +2483,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;