The branch, v3-2-test has been updated via 7e6da154b18f0aabcf2f8050bc5a57677bc9b322 (commit) via df995eddbddec80a0d9d4659bbb9c6ca8a45d02b (commit) via 6f5051b9c1405ab1dc3e697419ceedb3acac46d8 (commit) via a19e5fd5846685d5264e92bedf5cb57d99271f28 (commit) via 7e5752812d6d9e3bcf9a545cbdcf3afe2175dbc4 (commit) from a3da677bf0faed56e6731ee96708a7847a61d118 (commit)
http://gitweb.samba.org/?samba.git;a=shortlog;h=v3-2-test - Log ----------------------------------------------------------------- commit 7e6da154b18f0aabcf2f8050bc5a57677bc9b322 Author: Derrell Lipman <[EMAIL PROTECTED]> Date: Tue Feb 26 21:46:48 2008 -0500 update .gitignore with new test program executable commit df995eddbddec80a0d9d4659bbb9c6ca8a45d02b Author: Derrell Lipman <[EMAIL PROTECTED]> Date: Tue Feb 26 21:46:08 2008 -0500 add a test program for the new ftruncate functionality commit 6f5051b9c1405ab1dc3e697419ceedb3acac46d8 Author: Derrell Lipman <[EMAIL PROTECTED]> Date: Tue Feb 26 21:44:51 2008 -0500 add smbc_ftruncate() to emulate POSIX ftruncate() commit a19e5fd5846685d5264e92bedf5cb57d99271f28 Author: Derrell Lipman <[EMAIL PROTECTED]> Date: Tue Feb 26 21:43:13 2008 -0500 add 64-bit macros from samba4 commit 7e5752812d6d9e3bcf9a545cbdcf3afe2175dbc4 Author: Derrell Lipman <[EMAIL PROTECTED]> Date: Tue Feb 26 21:42:26 2008 -0500 add a function to truncate a file to a specified size ----------------------------------------------------------------------- Summary of changes: .gitignore | 1 + examples/libsmbclient/Makefile | 5 ++ examples/libsmbclient/testtruncate.c | 82 ++++++++++++++++++++++++++++++++++ source/include/byteorder.h | 6 +++ source/include/libsmbclient.h | 31 +++++++++++++ source/libsmb/clifile.c | 49 ++++++++++++++++++++ source/libsmb/libsmb_compat.c | 6 +++ source/libsmb/libsmbclient.c | 75 +++++++++++++++++++++++++++++++ 8 files changed, 255 insertions(+), 0 deletions(-) create mode 100644 examples/libsmbclient/testtruncate.c Changeset truncated at 500 lines: diff --git a/.gitignore b/.gitignore index b445ccf..516fd45 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,4 @@ examples/libsmbclient/teststat2 examples/libsmbclient/teststat3 examples/libsmbclient/testutime examples/libsmbclient/testwrite +examples/libsmbclient/testtruncate diff --git a/examples/libsmbclient/Makefile b/examples/libsmbclient/Makefile index 6c70659..e2d8b68 100644 --- a/examples/libsmbclient/Makefile +++ b/examples/libsmbclient/Makefile @@ -24,6 +24,7 @@ TESTS= testsmbc \ teststat \ teststat2 \ teststat3 \ + testtruncate \ testchmod \ testutime \ testread \ @@ -73,6 +74,10 @@ teststat3: teststat3.o @echo Linking teststat3 $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt +testtruncate: testtruncate.o + @echo Linking testtruncate + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt + testchmod: testchmod.o @echo Linking testchmod $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBSMBCLIENT) -lpopt diff --git a/examples/libsmbclient/testtruncate.c b/examples/libsmbclient/testtruncate.c new file mode 100644 index 0000000..8882acd --- /dev/null +++ b/examples/libsmbclient/testtruncate.c @@ -0,0 +1,82 @@ +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <time.h> +#include <errno.h> +#include <libsmbclient.h> +#include "get_auth_data_fn.h" + + +int main(int argc, char * argv[]) +{ + int fd; + int ret; + int debug = 0; + int savedErrno; + char buffer[128]; + char * pSmbPath = NULL; + char * pLocalPath = NULL; + struct stat st; + + if (argc != 2) + { + printf("usage: " + "%s smb://path/to/file\n", + argv[0]); + return 1; + } + + smbc_init(get_auth_data_fn, debug); + + if ((fd = smbc_open(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0)) < 0) + { + perror("smbc_open"); + return 1; + } + + strcpy(buffer, "Hello world.\nThis is a test.\n"); + + ret = smbc_write(fd, buffer, strlen(buffer)); + savedErrno = errno; + smbc_close(fd); + + if (ret < 0) + { + errno = savedErrno; + perror("write"); + } + + if (smbc_stat(argv[1], &st) < 0) + { + perror("smbc_stat"); + return 1; + } + + printf("Original size: %lu\n", (unsigned long) st.st_size); + + if ((fd = smbc_open(argv[1], O_WRONLY, 0)) < 0) + { + perror("smbc_open"); + return 1; + } + + ret = smbc_ftruncate(fd, 13); + savedErrno = errno; + smbc_close(fd); + if (ret < 0) + { + errno = savedErrno; + perror("smbc_ftruncate"); + return 1; + } + + if (smbc_stat(argv[1], &st) < 0) + { + perror("smbc_stat"); + return 1; + } + + printf("New size: %lu\n", (unsigned long) st.st_size); + + return 0; +} diff --git a/source/include/byteorder.h b/source/include/byteorder.h index 32138a8..9ced9ce 100644 --- a/source/include/byteorder.h +++ b/source/include/byteorder.h @@ -167,4 +167,10 @@ it also defines lots of intermediate macros, just ignore those :-) #define ALIGN4(p,base) ((p) + ((4 - (PTR_DIFF((p), (base)) & 3)) & 3)) #define ALIGN2(p,base) ((p) + ((2 - (PTR_DIFF((p), (base)) & 1)) & 1)) +/* 64 bit macros */ +#define BVAL(p, ofs) (IVAL(p,ofs) | (((uint64_t)IVAL(p,(ofs)+4)) << 32)) +#define BVALS(p, ofs) ((int64_t)BVAL(p,ofs)) +#define SBVAL(p, ofs, v) (SIVAL(p,ofs,(v)&0xFFFFFFFF), SIVAL(p,(ofs)+4,((uint64_t)(v))>>32)) +#define SBVALS(p, ofs, v) (SBVAL(p,ofs,(uint64_t)v)) + #endif /* _BYTEORDER_H */ diff --git a/source/include/libsmbclient.h b/source/include/libsmbclient.h index 07242f7..64afc09 100644 --- a/source/include/libsmbclient.h +++ b/source/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); +/[EMAIL PROTECTED] 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); + + /[EMAIL PROTECTED] attribue * Change the ownership of a file or directory. * diff --git a/source/libsmb/clifile.c b/source/libsmb/clifile.c index 10c35a3..12c427a 100644 --- a/source/libsmb/clifile.c +++ b/source/libsmb/clifile.c @@ -889,6 +889,55 @@ bool cli_close(struct cli_state *cli, int fnum) /**************************************************************************** + Truncate a file to a specified size +****************************************************************************/ + +bool cli_ftruncate(struct cli_state *cli, int fnum, uint64_t size) +{ + unsigned int param_len = 6; + unsigned int data_len = 8; + uint16 setup = TRANSACT2_SETFILEINFO; + char param[6]; + unsigned char data[8]; + char *rparam=NULL, *rdata=NULL; + int saved_timeout = cli->timeout; + + SSVAL(param,0,fnum); + SSVAL(param,2,SMB_SET_FILE_END_OF_FILE_INFO); + SSVAL(param,4,0); + + SBVAL(data, 0, size); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + (char *)&data, data_len,/* data, length, ... */ + cli->max_xmit)) { /* ... max */ + cli->timeout = saved_timeout; + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + cli->timeout = saved_timeout; + SAFE_FREE(rdata); + SAFE_FREE(rparam); + return False; + } + + cli->timeout = saved_timeout; + + SAFE_FREE(rdata); + SAFE_FREE(rparam); + + return True; +} + + +/**************************************************************************** send a lock with a specified locktype this is used for testing LOCKING_ANDX_CANCEL_LOCK ****************************************************************************/ diff --git a/source/libsmb/libsmb_compat.c b/source/libsmb/libsmb_compat.c index 573d087..6042464 100644 --- a/source/libsmb/libsmb_compat.c +++ b/source/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/source/libsmb/libsmbclient.c b/source/libsmb/libsmbclient.c index e84de59..fe008ed 100644 --- a/source/libsmb/libsmbclient.c +++ b/source/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; -- Samba Shared Repository