From 257b7b09298f7cb983b2f31b87fc5e46e0f62f0c Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 28 Feb 2008 11:23:20 -0500 Subject: Initial revamp of the libsmbclient interface. The libsmbclient interface has suffered from difficulty of improvement and feature enrichment without causing ABI breakage. Although there were a number of issues, the primary ones were: (a) the user of the library would manually manipulate the context structure members, meaning that nothing in the context structure could change other than adding stuff at the end; (b) there were three methods of setting options: setting bits in a flags field within the context structure, setting explicit options variables within an options structure in the context structure, and by calling the smbc_option_set() function; (c) the authentication callback did not traditionally provide enough information to the callee which required adding an option for a callback with a different signature, and now there are requests for even more information at the callback, requiring yet a third signature and option to set it (if we implement that feature). This commit provides a reorganization of the code which fixes (a) and (b). The context structure is now entirely opaque, and there are setter and getter functions for manipulating it. This makes maintaining ABI consistency much, much easier. Additionally, the options setting/getting has been unified into a single mechanism using smbc_option_set() and smbc_option_get(). Yet to be completed is a refactoring of the authentication callback (c). The test programs in examples/libsmbclient have been modified (if necessary; some applications require no changes at all) for the new API and a few have been minimally tested. Derrell (This used to be commit d4b4bae8ded824d06ad5ab0e219f71187ee5c771) --- source3/libsmb/libsmb_file.c | 859 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 859 insertions(+) create mode 100644 source3/libsmb/libsmb_file.c (limited to 'source3/libsmb/libsmb_file.c') diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c new file mode 100644 index 0000000000..619176697b --- /dev/null +++ b/source3/libsmb/libsmb_file.c @@ -0,0 +1,859 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 2007, 2008 + + 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 + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "libsmbclient.h" +#include "libsmb_internal.h" + + +/* + * Routine to open() a file ... + */ + +SMBCFILE * +SMBC_open_ctx(SMBCCTX *context, + const char *fname, + int flags, + mode_t mode) +{ + char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *workgroup = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + SMBCSRV *srv = NULL; + SMBCFILE *file = NULL; + int fd; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); + return NULL; + + } + + if (!fname) { + + errno = EINVAL; + TALLOC_FREE(frame); + return NULL; + + } + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return NULL; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return NULL; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + + if (!srv) { + if (errno == EPERM) errno = EACCES; + TALLOC_FREE(frame); + return NULL; /* SMBC_server sets errno */ + } + + /* Hmmm, the test for a directory is suspect here ... FIXME */ + + if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') { + fd = -1; + } else { + file = SMB_MALLOC_P(SMBCFILE); + + if (!file) { + errno = ENOMEM; + TALLOC_FREE(frame); + return NULL; + } + + ZERO_STRUCTP(file); + + /*d_printf(">>>open: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", srv->cli, path, &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + SAFE_FREE(file); + TALLOC_FREE(frame); + return NULL; + } + /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/ + + if ((fd = cli_open(targetcli, targetpath, flags, + context->share_mode)) < 0) { + + /* Handle the error ... */ + + SAFE_FREE(file); + errno = SMBC_errno(context, targetcli); + TALLOC_FREE(frame); + return NULL; + + } + + /* Fill in file struct */ + + file->cli_fd = fd; + file->fname = SMB_STRDUP(fname); + file->srv = srv; + file->offset = 0; + file->file = True; + + DLIST_ADD(context->files, file); + + /* + * If the file was opened in O_APPEND mode, all write + * operations should be appended to the file. To do that, + * though, using this protocol, would require a getattrE() + * call for each and every write, to determine where the end + * of the file is. (There does not appear to be an append flag + * in the protocol.) Rather than add all of that overhead of + * retrieving the current end-of-file offset prior to each + * write operation, we'll assume that most append operations + * will continuously write, so we'll just set the offset to + * the end of the file now and hope that's adequate. + * + * Note to self: If this proves inadequate, and O_APPEND + * should, in some cases, be forced for each write, add a + * field in the context options structure, for + * "strict_append_mode" which would select between the current + * behavior (if FALSE) or issuing a getattrE() prior to each + * write and forcing the write to the end of the file (if + * TRUE). Adding that capability will likely require adding + * an "append" flag into the _SMBCFILE structure to track + * whether a file was opened in O_APPEND mode. -- djl + */ + if (flags & O_APPEND) { + if (SMBC_lseek_ctx(context, file, 0, SEEK_END) < 0) { + (void) SMBC_close_ctx(context, file); + errno = ENXIO; + TALLOC_FREE(frame); + return NULL; + } + } + + TALLOC_FREE(frame); + return file; + + } + + /* Check if opendir needed ... */ + + if (fd == -1) { + int eno = 0; + + eno = SMBC_errno(context, srv->cli); + file = (context->posix_emu.opendir_fn)(context, fname); + if (!file) errno = eno; + TALLOC_FREE(frame); + return file; + + } + + errno = EINVAL; /* FIXME, correct errno ? */ + TALLOC_FREE(frame); + return NULL; + +} + +/* + * Routine to create a file + */ + +static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC; /* FIXME: Do we need this */ + +SMBCFILE * +SMBC_creat_ctx(SMBCCTX *context, + const char *path, + mode_t mode) +{ + + if (!context || !context->initialized) { + + errno = EINVAL; + return NULL; + + } + + return SMBC_open_ctx(context, path, creat_bits, mode); +} + +/* + * Routine to read() a file ... + */ + +ssize_t +SMBC_read_ctx(SMBCCTX *context, + SMBCFILE *file, + void *buf, + size_t count) +{ + int ret; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + /* + * offset: + * + * Compiler bug (possibly) -- gcc (GCC) 3.3.5 (Debian 1:3.3.5-2) -- + * appears to pass file->offset (which is type off_t) differently than + * a local variable of type off_t. Using local variable "offset" in + * the call to cli_read() instead of file->offset fixes a problem + * retrieving data at an offset greater than 4GB. + */ + off_t offset; + + if (!context || !context->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); + + if (!file || !SMBC_dlist_contains(context->files, file)) { + errno = EBADF; + TALLOC_FREE(frame); + return -1; + + } + + offset = file->offset; + + /* Check that the buffer exists ... */ + + if (buf == NULL) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + /*d_printf(">>>read: 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(">>>read: 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);*/ + + ret = cli_read(targetcli, file->cli_fd, (char *)buf, offset, count); + + if (ret < 0) { + + errno = SMBC_errno(context, targetcli); + TALLOC_FREE(frame); + return -1; + + } + + file->offset += ret; + + DEBUG(4, (" --> %d\n", ret)); + + TALLOC_FREE(frame); + return ret; /* Success, ret bytes of data ... */ + +} + +/* + * Routine to write() a file ... + */ + +ssize_t +SMBC_write_ctx(SMBCCTX *context, + SMBCFILE *file, + void *buf, + size_t count) +{ + int ret; + off_t offset; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + /* First check all pointers before dereferencing them */ + + if (!context || !context->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + if (!file || !SMBC_dlist_contains(context->files, file)) { + errno = EBADF; + TALLOC_FREE(frame); + return -1; + } + + /* Check that the buffer exists ... */ + + if (buf == NULL) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + offset = file->offset; /* See "offset" comment in SMBC_read_ctx() */ + + /*d_printf(">>>write: 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(">>>write: 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(">>>write: resolved path as %s\n", targetpath);*/ + + ret = cli_write(targetcli, file->cli_fd, 0, (char *)buf, offset, count); + + if (ret <= 0) { + errno = SMBC_errno(context, targetcli); + TALLOC_FREE(frame); + return -1; + + } + + file->offset += ret; + + TALLOC_FREE(frame); + return ret; /* Success, 0 bytes of data ... */ +} + +/* + * Routine to close() a file ... + */ + +int +SMBC_close_ctx(SMBCCTX *context, + SMBCFILE *file) +{ + SMBCSRV *srv; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!file || !SMBC_dlist_contains(context->files, file)) { + errno = EBADF; + TALLOC_FREE(frame); + return -1; + } + + /* IS a dir ... */ + if (!file->file) { + TALLOC_FREE(frame); + return (context->posix_emu.closedir_fn)(context, file); + } + + /*d_printf(">>>close: 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(">>>close: 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(">>>close: resolved path as %s\n", targetpath);*/ + + if (!cli_close(targetcli, file->cli_fd)) { + + DEBUG(3, ("cli_close failed on %s. purging server.\n", + file->fname)); + /* Deallocate slot and remove the server + * from the server cache if unused */ + errno = SMBC_errno(context, targetcli); + srv = file->srv; + DLIST_REMOVE(context->files, file); + SAFE_FREE(file->fname); + SAFE_FREE(file); + (context->server.remove_unused_server_fn)(context, srv); + TALLOC_FREE(frame); + return -1; + + } + + DLIST_REMOVE(context->files, file); + SAFE_FREE(file->fname); + SAFE_FREE(file); + TALLOC_FREE(frame); + + return 0; +} + +/* + * Get info from an SMB server on a file. Use a qpathinfo call first + * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo + */ +bool +SMBC_getatr(SMBCCTX * context, + SMBCSRV *srv, + char *path, + uint16 *mode, + SMB_OFF_T *size, + struct timespec *create_time_ts, + struct timespec *access_time_ts, + struct timespec *write_time_ts, + struct timespec *change_time_ts, + SMB_INO_T *ino) +{ + char *fixedpath = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + time_t write_time; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /* path fixup for . and .. */ + if (strequal(path, ".") || strequal(path, "..")) { + fixedpath = talloc_strdup(frame, "\\"); + if (!fixedpath) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } else { + fixedpath = talloc_strdup(frame, path); + if (!fixedpath) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + trim_string(fixedpath, NULL, "\\.."); + trim_string(fixedpath, NULL, "\\."); + } + DEBUG(4,("SMBC_getatr: sending qpathinfo\n")); + + if (!cli_resolve_path(frame, "", srv->cli, fixedpath, + &targetcli, &targetpath)) { + d_printf("Couldn't resolve %s\n", path); + TALLOC_FREE(frame); + return False; + } + + if (!srv->no_pathinfo2 && + cli_qpathinfo2(targetcli, targetpath, + create_time_ts, + access_time_ts, + write_time_ts, + change_time_ts, + size, mode, ino)) { + TALLOC_FREE(frame); + return True; + } + + /* if this is NT then don't bother with the getatr */ + if (targetcli->capabilities & CAP_NT_SMBS) { + errno = EPERM; + TALLOC_FREE(frame); + return False; + } + + if (cli_getatr(targetcli, targetpath, mode, size, &write_time)) { + + struct timespec w_time_ts; + + w_time_ts = convert_time_t_to_timespec(write_time); + + if (write_time_ts != NULL) { + *write_time_ts = w_time_ts; + } + + if (create_time_ts != NULL) { + *create_time_ts = w_time_ts; + } + + if (access_time_ts != NULL) { + *access_time_ts = w_time_ts; + } + + if (change_time_ts != NULL) { + *change_time_ts = w_time_ts; + } + + srv->no_pathinfo2 = True; + TALLOC_FREE(frame); + return True; + } + + errno = EPERM; + TALLOC_FREE(frame); + return False; + +} + +/* + * Set file info on an SMB server. Use setpathinfo call first. If that + * fails, use setattrE.. + * + * Access and modification time parameters are always used and must be + * provided. Create time, if zero, will be determined from the actual create + * time of the file. If non-zero, the create time will be set as well. + * + * "mode" (attributes) parameter may be set to -1 if it is not to be set. + */ +bool +SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, + time_t create_time, + time_t access_time, + time_t write_time, + time_t change_time, + uint16 mode) +{ + int fd; + int ret; + TALLOC_CTX *frame = talloc_stackframe(); + + /* + * First, try setpathinfo (if qpathinfo succeeded), for it is the + * modern function for "new code" to be using, and it works given a + * filename rather than requiring that the file be opened to have its + * attributes manipulated. + */ + if (srv->no_pathinfo || + ! cli_setpathinfo(srv->cli, path, + create_time, + access_time, + write_time, + change_time, + mode)) { + + /* + * setpathinfo is not supported; go to plan B. + * + * cli_setatr() does not work on win98, and it also doesn't + * support setting the access time (only the modification + * time), so in all cases, we open the specified file and use + * cli_setattrE() which should work on all OS versions, and + * supports both times. + */ + + /* Don't try {q,set}pathinfo() again, with this server */ + srv->no_pathinfo = True; + + /* Open the file */ + if ((fd = cli_open(srv->cli, path, O_RDWR, DENY_NONE)) < 0) { + + errno = SMBC_errno(context, srv->cli); + TALLOC_FREE(frame); + return -1; + } + + /* Set the new attributes */ + ret = cli_setattrE(srv->cli, fd, + change_time, + access_time, + write_time); + + /* Close the file */ + cli_close(srv->cli, fd); + + /* + * Unfortunately, setattrE() doesn't have a provision for + * setting the access mode (attributes). We'll have to try + * cli_setatr() for that, and with only this parameter, it + * seems to work on win98. + */ + if (ret && mode != (uint16) -1) { + ret = cli_setatr(srv->cli, path, mode, 0); + } + + if (! ret) { + errno = SMBC_errno(context, srv->cli); + TALLOC_FREE(frame); + return False; + } + } + + TALLOC_FREE(frame); + return True; +} + +/* + * A routine to lseek() a file + */ + +off_t +SMBC_lseek_ctx(SMBCCTX *context, + SMBCFILE *file, + off_t offset, + int whence) +{ + SMB_OFF_T size; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!file || !SMBC_dlist_contains(context->files, file)) { + + errno = EBADF; + TALLOC_FREE(frame); + return -1; + + } + + if (!file->file) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; /* Can't lseek a dir ... */ + + } + + switch (whence) { + case SEEK_SET: + file->offset = offset; + break; + + case SEEK_CUR: + file->offset += offset; + break; + + case SEEK_END: + /*d_printf(">>>lseek: 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(">>>lseek: 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(">>>lseek: resolved path as %s\n", targetpath);*/ + + if (!cli_qfileinfo(targetcli, file->cli_fd, NULL, + &size, NULL, NULL, NULL, NULL, NULL)) + { + SMB_OFF_T b_size = size; + if (!cli_getattrE(targetcli, file->cli_fd, + NULL, &b_size, NULL, NULL, NULL)) + { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } else + size = b_size; + } + file->offset = size + offset; + break; + + default: + errno = EINVAL; + break; + + } + + TALLOC_FREE(frame); + return file->offset; + +} + + +/* + * Routine to truncate a file given by its file descriptor, to a specified size + */ + +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->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!file || !SMBC_dlist_contains(context->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; + +} -- cgit From 4ba42cbe0f6bbd25848786e1a87c06aca79b98ea Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Fri, 29 Feb 2008 13:34:35 -0500 Subject: Modified revamp of the libsmbclient interface. Given the tacit (if that) approval by some people, and clear disapproval by others for my proposed clean-up and reorganization of libsmbclient, I've come up with a slightly different approach. This commit changes back to the original libsmbclient.h SMBCCTX structure which will maintain ABI compatibility. I retain, here, the setter and getter functions which all new code should use. Older programs already compiled should continue to work fine. Older programs being recompiled will encounter compile-time errors (intentionally!) so that the code can be corrected to use the setter/getter interfaces. Although this doesn't clean up the interface in the way I had wanted, the code reorganization and requirement for new programs to use the setters and getters allows future progress to be made on libsmbclient without further muddying up the interface, while retaining the ABI compatibility that was the big issue causing disapproval. I hope that this compromise is adequate. Derrell (This used to be commit 56429a3d60b2a48963342f6340b3c01469a892c6) --- source3/libsmb/libsmb_file.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'source3/libsmb/libsmb_file.c') diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c index 619176697b..62b990ed00 100644 --- a/source3/libsmb/libsmb_file.c +++ b/source3/libsmb/libsmb_file.c @@ -46,7 +46,7 @@ SMBC_open_ctx(SMBCCTX *context, int fd; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); @@ -78,7 +78,7 @@ SMBC_open_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); + user = talloc_strdup(frame, context->config.user); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -120,7 +120,7 @@ SMBC_open_ctx(SMBCCTX *context, /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/ if ((fd = cli_open(targetcli, targetpath, flags, - context->share_mode)) < 0) { + context->internal->share_mode)) < 0) { /* Handle the error ... */ @@ -139,7 +139,7 @@ SMBC_open_ctx(SMBCCTX *context, file->offset = 0; file->file = True; - DLIST_ADD(context->files, file); + DLIST_ADD(context->internal->files, file); /* * If the file was opened in O_APPEND mode, all write @@ -208,7 +208,7 @@ SMBC_creat_ctx(SMBCCTX *context, mode_t mode) { - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; return NULL; @@ -246,7 +246,7 @@ SMBC_read_ctx(SMBCCTX *context, */ off_t offset; - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); @@ -256,7 +256,7 @@ SMBC_read_ctx(SMBCCTX *context, DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); - if (!file || !SMBC_dlist_contains(context->files, file)) { + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; @@ -338,7 +338,7 @@ SMBC_write_ctx(SMBCCTX *context, /* First check all pointers before dereferencing them */ - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); @@ -346,7 +346,7 @@ SMBC_write_ctx(SMBCCTX *context, } - if (!file || !SMBC_dlist_contains(context->files, file)) { + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; @@ -418,14 +418,14 @@ SMBC_close_ctx(SMBCCTX *context, struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - if (!file || !SMBC_dlist_contains(context->files, file)) { + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; @@ -470,7 +470,7 @@ SMBC_close_ctx(SMBCCTX *context, * from the server cache if unused */ errno = SMBC_errno(context, targetcli); srv = file->srv; - DLIST_REMOVE(context->files, file); + DLIST_REMOVE(context->internal->files, file); SAFE_FREE(file->fname); SAFE_FREE(file); (context->server.remove_unused_server_fn)(context, srv); @@ -479,7 +479,7 @@ SMBC_close_ctx(SMBCCTX *context, } - DLIST_REMOVE(context->files, file); + DLIST_REMOVE(context->internal->files, file); SAFE_FREE(file->fname); SAFE_FREE(file); TALLOC_FREE(frame); @@ -509,7 +509,7 @@ SMBC_getatr(SMBCCTX * context, time_t write_time; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); @@ -698,14 +698,14 @@ SMBC_lseek_ctx(SMBCCTX *context, struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - if (!file || !SMBC_dlist_contains(context->files, file)) { + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); @@ -803,14 +803,14 @@ SMBC_ftruncate_ctx(SMBCCTX *context, struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - if (!file || !SMBC_dlist_contains(context->files, file)) { + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; -- cgit From 223940d9a887c5b98a5c873797302a6a9407ad7f Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sat, 1 Mar 2008 20:44:21 -0500 Subject: Additional revamped libsmbclient documentation - Ensured that all public functions have documentation in libsmbclient.h - Reformatted for "proper" indentation - Re-added temporarily-disabled alternate authentication function capability Derrell (This used to be commit 64b7150d92849a1e1e2416b9dcc12fae8d6bea99) --- source3/libsmb/libsmb_file.c | 393 ++++++++++++++++++++++--------------------- 1 file changed, 199 insertions(+), 194 deletions(-) (limited to 'source3/libsmb/libsmb_file.c') diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c index 62b990ed00..73c9b96978 100644 --- a/source3/libsmb/libsmb_file.c +++ b/source3/libsmb/libsmb_file.c @@ -37,7 +37,11 @@ SMBC_open_ctx(SMBCCTX *context, int flags, mode_t mode) { - char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *workgroup = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; char *path = NULL; char *targetpath = NULL; struct cli_state *targetcli = NULL; @@ -45,38 +49,38 @@ SMBC_open_ctx(SMBCCTX *context, SMBCFILE *file = NULL; int fd; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return NULL; - + } - + if (!fname) { - + errno = EINVAL; TALLOC_FREE(frame); return NULL; - + } - + if (SMBC_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return NULL; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, context->config.user); if (!user) { @@ -85,62 +89,63 @@ SMBC_open_ctx(SMBCCTX *context, return NULL; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - + if (!srv) { if (errno == EPERM) errno = EACCES; TALLOC_FREE(frame); return NULL; /* SMBC_server sets errno */ } - + /* Hmmm, the test for a directory is suspect here ... FIXME */ - + if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') { fd = -1; } else { file = SMB_MALLOC_P(SMBCFILE); - + if (!file) { errno = ENOMEM; TALLOC_FREE(frame); return NULL; } - + ZERO_STRUCTP(file); - + /*d_printf(">>>open: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", srv->cli, path, &targetcli, &targetpath)) { + if (!cli_resolve_path(frame, "", srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); SAFE_FREE(file); TALLOC_FREE(frame); return NULL; } /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/ - + if ((fd = cli_open(targetcli, targetpath, flags, context->internal->share_mode)) < 0) { - + /* Handle the error ... */ - + SAFE_FREE(file); errno = SMBC_errno(context, targetcli); TALLOC_FREE(frame); return NULL; - + } - + /* Fill in file struct */ - + file->cli_fd = fd; file->fname = SMB_STRDUP(fname); file->srv = srv; file->offset = 0; file->file = True; - + DLIST_ADD(context->internal->files, file); - + /* * If the file was opened in O_APPEND mode, all write * operations should be appended to the file. To do that, @@ -171,51 +176,50 @@ SMBC_open_ctx(SMBCCTX *context, return NULL; } } - + TALLOC_FREE(frame); return file; - + } - + /* Check if opendir needed ... */ - + if (fd == -1) { int eno = 0; - + eno = SMBC_errno(context, srv->cli); file = (context->posix_emu.opendir_fn)(context, fname); if (!file) errno = eno; TALLOC_FREE(frame); return file; - + } - + errno = EINVAL; /* FIXME, correct errno ? */ TALLOC_FREE(frame); return NULL; - + } /* * Routine to create a file */ -static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC; /* FIXME: Do we need this */ - SMBCFILE * SMBC_creat_ctx(SMBCCTX *context, const char *path, mode_t mode) { - + if (!context || !context->internal->initialized) { - + errno = EINVAL; return NULL; - + } - - return SMBC_open_ctx(context, path, creat_bits, mode); + + return SMBC_open_ctx(context, path, + O_WRONLY | O_CREAT | O_TRUNC, mode); } /* @@ -234,7 +238,7 @@ SMBC_read_ctx(SMBCCTX *context, char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + /* * offset: * @@ -245,51 +249,51 @@ SMBC_read_ctx(SMBCCTX *context, * retrieving data at an offset greater than 4GB. */ off_t offset; - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; - + } - + DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); - + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; - + } - + offset = file->offset; - + /* Check that the buffer exists ... */ - + if (buf == NULL) { errno = EINVAL; TALLOC_FREE(frame); return -1; - + } - + /*d_printf(">>>read: parsing %s\n", file->fname);*/ if (SMBC_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>read: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", file->srv->cli, path, &targetcli, &targetpath)) { @@ -298,24 +302,24 @@ SMBC_read_ctx(SMBCCTX *context, return -1; } /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ - + ret = cli_read(targetcli, file->cli_fd, (char *)buf, offset, count); - + if (ret < 0) { - + errno = SMBC_errno(context, targetcli); TALLOC_FREE(frame); return -1; - + } - + file->offset += ret; - + DEBUG(4, (" --> %d\n", ret)); - + TALLOC_FREE(frame); return ret; /* Success, ret bytes of data ... */ - + } /* @@ -335,50 +339,50 @@ SMBC_write_ctx(SMBCCTX *context, char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + /* First check all pointers before dereferencing them */ - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; - + } - + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; } - + /* Check that the buffer exists ... */ - + if (buf == NULL) { errno = EINVAL; TALLOC_FREE(frame); return -1; - + } - + offset = file->offset; /* See "offset" comment in SMBC_read_ctx() */ - + /*d_printf(">>>write: parsing %s\n", file->fname);*/ if (SMBC_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>write: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", file->srv->cli, path, &targetcli, &targetpath)) { @@ -387,18 +391,19 @@ SMBC_write_ctx(SMBCCTX *context, return -1; } /*d_printf(">>>write: resolved path as %s\n", targetpath);*/ - - ret = cli_write(targetcli, file->cli_fd, 0, (char *)buf, offset, count); - + + ret = cli_write(targetcli, file->cli_fd, + 0, (char *)buf, offset, count); + if (ret <= 0) { errno = SMBC_errno(context, targetcli); TALLOC_FREE(frame); return -1; - + } - + file->offset += ret; - + TALLOC_FREE(frame); return ret; /* Success, 0 bytes of data ... */ } @@ -417,42 +422,42 @@ SMBC_close_ctx(SMBCCTX *context, char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; } - + /* IS a dir ... */ if (!file->file) { TALLOC_FREE(frame); return (context->posix_emu.closedir_fn)(context, file); } - + /*d_printf(">>>close: parsing %s\n", file->fname);*/ if (SMBC_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>close: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", file->srv->cli, path, &targetcli, &targetpath)) { @@ -461,9 +466,9 @@ SMBC_close_ctx(SMBCCTX *context, return -1; } /*d_printf(">>>close: resolved path as %s\n", targetpath);*/ - + if (!cli_close(targetcli, file->cli_fd)) { - + DEBUG(3, ("cli_close failed on %s. purging server.\n", file->fname)); /* Deallocate slot and remove the server @@ -476,14 +481,14 @@ SMBC_close_ctx(SMBCCTX *context, (context->server.remove_unused_server_fn)(context, srv); TALLOC_FREE(frame); return -1; - + } - + DLIST_REMOVE(context->internal->files, file); SAFE_FREE(file->fname); SAFE_FREE(file); TALLOC_FREE(frame); - + return 0; } @@ -508,14 +513,14 @@ SMBC_getatr(SMBCCTX * context, struct cli_state *targetcli = NULL; time_t write_time; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; } - + /* path fixup for . and .. */ if (strequal(path, ".") || strequal(path, "..")) { fixedpath = talloc_strdup(frame, "\\"); @@ -535,14 +540,14 @@ SMBC_getatr(SMBCCTX * context, trim_string(fixedpath, NULL, "\\."); } DEBUG(4,("SMBC_getatr: sending qpathinfo\n")); - + if (!cli_resolve_path(frame, "", srv->cli, fixedpath, - &targetcli, &targetpath)) { + &targetcli, &targetpath)) { d_printf("Couldn't resolve %s\n", path); TALLOC_FREE(frame); return False; } - + if (!srv->no_pathinfo2 && cli_qpathinfo2(targetcli, targetpath, create_time_ts, @@ -553,45 +558,45 @@ SMBC_getatr(SMBCCTX * context, TALLOC_FREE(frame); return True; } - + /* if this is NT then don't bother with the getatr */ if (targetcli->capabilities & CAP_NT_SMBS) { errno = EPERM; TALLOC_FREE(frame); return False; } - + if (cli_getatr(targetcli, targetpath, mode, size, &write_time)) { - + struct timespec w_time_ts; - + w_time_ts = convert_time_t_to_timespec(write_time); - + if (write_time_ts != NULL) { *write_time_ts = w_time_ts; } - + if (create_time_ts != NULL) { *create_time_ts = w_time_ts; } - + if (access_time_ts != NULL) { *access_time_ts = w_time_ts; } - + if (change_time_ts != NULL) { *change_time_ts = w_time_ts; } - + srv->no_pathinfo2 = True; TALLOC_FREE(frame); return True; } - + errno = EPERM; TALLOC_FREE(frame); return False; - + } /* @@ -615,7 +620,7 @@ SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, int fd; int ret; TALLOC_CTX *frame = talloc_stackframe(); - + /* * First, try setpathinfo (if qpathinfo succeeded), for it is the * modern function for "new code" to be using, and it works given a @@ -629,7 +634,7 @@ SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, write_time, change_time, mode)) { - + /* * setpathinfo is not supported; go to plan B. * @@ -639,27 +644,27 @@ SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, * cli_setattrE() which should work on all OS versions, and * supports both times. */ - + /* Don't try {q,set}pathinfo() again, with this server */ srv->no_pathinfo = True; - + /* Open the file */ if ((fd = cli_open(srv->cli, path, O_RDWR, DENY_NONE)) < 0) { - + errno = SMBC_errno(context, srv->cli); TALLOC_FREE(frame); return -1; } - + /* Set the new attributes */ ret = cli_setattrE(srv->cli, fd, change_time, access_time, write_time); - + /* Close the file */ cli_close(srv->cli, fd); - + /* * Unfortunately, setattrE() doesn't have a provision for * setting the access mode (attributes). We'll have to try @@ -669,14 +674,14 @@ SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, if (ret && mode != (uint16) -1) { ret = cli_setatr(srv->cli, path, mode, 0); } - + if (! ret) { errno = SMBC_errno(context, srv->cli); TALLOC_FREE(frame); return False; } } - + TALLOC_FREE(frame); return True; } @@ -697,56 +702,56 @@ SMBC_lseek_ctx(SMBCCTX *context, char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { - + errno = EBADF; TALLOC_FREE(frame); return -1; - + } - + if (!file->file) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; /* Can't lseek a dir ... */ - + } - + switch (whence) { case SEEK_SET: file->offset = offset; break; - + case SEEK_CUR: file->offset += offset; break; - + case SEEK_END: /*d_printf(">>>lseek: parsing %s\n", file->fname);*/ if (SMBC_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>lseek: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", file->srv->cli, path, &targetcli, &targetpath)) { @@ -755,32 +760,32 @@ SMBC_lseek_ctx(SMBCCTX *context, return -1; } /*d_printf(">>>lseek: resolved path as %s\n", targetpath);*/ - + if (!cli_qfileinfo(targetcli, file->cli_fd, NULL, &size, NULL, NULL, NULL, NULL, NULL)) { - SMB_OFF_T b_size = size; + SMB_OFF_T b_size = size; if (!cli_getattrE(targetcli, file->cli_fd, NULL, &b_size, NULL, NULL, NULL)) - { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } else - size = b_size; + { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } else + size = b_size; } file->offset = size + offset; break; - + default: errno = EINVAL; break; - + } - + TALLOC_FREE(frame); return file->offset; - + } @@ -802,26 +807,26 @@ SMBC_ftruncate_ctx(SMBCCTX *context, char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!file || !SMBC_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, @@ -837,7 +842,7 @@ SMBC_ftruncate_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>fstat: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", file->srv->cli, path, &targetcli, &targetpath)) { @@ -846,14 +851,14 @@ SMBC_ftruncate_ctx(SMBCCTX *context, 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; - + } -- cgit From 1363ee9d65965704f716965c6cbcfc0693ca2401 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Mon, 3 Mar 2008 18:13:33 -0500 Subject: Continued revamping of libsmbclient. - James suggested using gcc's "deprecated" attribute to mark the context structure fields to generate warnings. This creates a scenario with the best of all worlds. I'm able to move to an organization that more easily allows future enhancements, while avoiding any mandatory changes by applications. Thanks, James! - Updated WHATSNEW.txt so that it accurately reflects the current state of affairs. Derrell (This used to be commit a67f96fbe9683b46c2149f7cb439d13f7f0e6ecd) --- source3/libsmb/libsmb_file.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/libsmb_file.c') diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c index 73c9b96978..423450b23e 100644 --- a/source3/libsmb/libsmb_file.c +++ b/source3/libsmb/libsmb_file.c @@ -82,7 +82,7 @@ SMBC_open_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->config.user); + user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -188,7 +188,7 @@ SMBC_open_ctx(SMBCCTX *context, int eno = 0; eno = SMBC_errno(context, srv->cli); - file = (context->posix_emu.opendir_fn)(context, fname); + file = smbc_getFunctionOpendir(context)(context, fname); if (!file) errno = eno; TALLOC_FREE(frame); return file; @@ -439,7 +439,7 @@ SMBC_close_ctx(SMBCCTX *context, /* IS a dir ... */ if (!file->file) { TALLOC_FREE(frame); - return (context->posix_emu.closedir_fn)(context, file); + return smbc_getFunctionClosedir(context)(context, file); } /*d_printf(">>>close: parsing %s\n", file->fname);*/ @@ -478,7 +478,7 @@ SMBC_close_ctx(SMBCCTX *context, DLIST_REMOVE(context->internal->files, file); SAFE_FREE(file->fname); SAFE_FREE(file); - (context->server.remove_unused_server_fn)(context, srv); + smbc_getFunctionRemoveUnusedServer(context)(context, srv); TALLOC_FREE(frame); return -1; -- cgit From 43892abff68054928312fd54e50d5bdebe604b63 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 16 Jul 2008 12:05:52 +0200 Subject: The buf in the smbclient write function should be const. As we try to provide POSIX function, we should use const like all other POSIX function. Signed-off-by: Andreas Schneider Signed-off-by: Derrell Lipman (This used to be commit 36e5df59544de9df140ca40ad0efd77afd8e1468) --- source3/libsmb/libsmb_file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/libsmb_file.c') diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c index 423450b23e..7b287096c2 100644 --- a/source3/libsmb/libsmb_file.c +++ b/source3/libsmb/libsmb_file.c @@ -329,7 +329,7 @@ SMBC_read_ctx(SMBCCTX *context, ssize_t SMBC_write_ctx(SMBCCTX *context, SMBCFILE *file, - void *buf, + const void *buf, size_t count) { int ret; -- cgit