From b3e57cb3ffb6eeb3edb1a7b02be35f70e1e7dfcf Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 22 Mar 2005 21:17:01 +0000 Subject: r5968: derrell's large file fix for libsmbclient (BUG 2505) (This used to be commit 85be4c5df398faa6c5bfacd1f9d2f12c39d411e1) --- source3/client/client.c | 4 +-- source3/client/clitar.c | 2 +- source3/include/libsmb_internal.h | 2 +- source3/libsmb/clifile.c | 4 +-- source3/libsmb/clirap.c | 30 +++++++++---------- source3/libsmb/libsmbclient.c | 63 +++++++++++++++++++-------------------- source3/python/py_smb.c | 2 +- source3/smbwrapper/smbw.c | 2 +- source3/smbwrapper/smbw_stat.c | 24 ++++++++++++--- source3/torture/torture.c | 6 ++-- source3/torture/utable.c | 2 +- 11 files changed, 78 insertions(+), 63 deletions(-) (limited to 'source3') diff --git a/source3/client/client.c b/source3/client/client.c index 9a09d50cc0..d03c323127 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -710,7 +710,7 @@ static int do_get(char *rname, char *lname, BOOL reget) struct timeval tp_start; int read_size = io_bufsize; uint16 attr; - size_t size; + SMB_OFF_T size; off_t start = 0; off_t nread = 0; int rc = 0; @@ -1134,7 +1134,7 @@ static int do_put(char *rname, char *lname, BOOL reput) { int fnum; XFILE *f; - size_t start = 0; + SMB_OFF_T start = 0; off_t nread = 0; char *buf = NULL; int maxwrite = io_bufsize; diff --git a/source3/client/clitar.c b/source3/client/clitar.c index 524feca1d2..919545291f 100644 --- a/source3/client/clitar.c +++ b/source3/client/clitar.c @@ -44,7 +44,7 @@ static int clipfind(char **aret, int ret, char *tok); typedef struct file_info_struct file_info2; struct file_info_struct { - SMB_BIG_UINT size; + SMB_OFF_T size; uint16 mode; uid_t uid; gid_t gid; diff --git a/source3/include/libsmb_internal.h b/source3/include/libsmb_internal.h index a1db5c2792..2eca879cbe 100644 --- a/source3/include/libsmb_internal.h +++ b/source3/include/libsmb_internal.h @@ -35,7 +35,7 @@ struct smbc_dir_list { struct _SMBCFILE { int cli_fd; char *fname; - off_t offset; + SMB_OFF_T offset; struct _SMBCSRV *srv; BOOL file; struct smbc_dir_list *dir_list, *dir_end, *dir_next; diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 9d20ed3adc..93492ec082 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1071,7 +1071,7 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ ****************************************************************************/ BOOL cli_getattrE(struct cli_state *cli, int fd, - uint16 *attr, SMB_BIG_UINT *size, + uint16 *attr, SMB_OFF_T *size, time_t *c_time, time_t *a_time, time_t *m_time) { memset(cli->outbuf,'\0',smb_size); @@ -1122,7 +1122,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, ****************************************************************************/ BOOL cli_getatr(struct cli_state *cli, const char *fname, - uint16 *attr, size_t *size, time_t *t) + uint16 *attr, SMB_OFF_T *size, time_t *t) { char *p; diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 8e6742d438..1f6a99d4be 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -382,7 +382,7 @@ send a qpathinfo call ****************************************************************************/ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, - size_t *size, uint16 *mode) + SMB_OFF_T *size, uint16 *mode) { unsigned int data_len = 0; unsigned int param_len = 0; @@ -462,7 +462,7 @@ send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level ****************************************************************************/ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, size_t *size, uint16 *mode, + time_t *w_time, SMB_OFF_T *size, uint16 *mode, SMB_INO_T *ino) { unsigned int data_len = 0; @@ -516,7 +516,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, *mode = SVAL(rdata, 32); } if (size) { - *size = IVAL(rdata, 48); + *size = IVAL2_TO_SMB_BIG_UINT(rdata,48); } if (ino) { *ino = IVAL(rdata, 64); @@ -546,11 +546,11 @@ BOOL cli_qfilename(struct cli_state *cli, int fnum, SSVAL(param, 2, SMB_QUERY_FILE_NAME_INFO); 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 */ - NULL, data_len, cli->max_xmit /* data, length, max */ + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ )) { return False; } @@ -575,7 +575,7 @@ BOOL cli_qfilename(struct cli_state *cli, int fnum, send a qfileinfo call ****************************************************************************/ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, - uint16 *mode, size_t *size, + uint16 *mode, SMB_OFF_T *size, time_t *c_time, time_t *a_time, time_t *m_time, time_t *w_time, SMB_INO_T *ino) { @@ -596,11 +596,11 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO); 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 */ - NULL, data_len, cli->max_xmit /* data, length, max */ + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ )) { return False; } @@ -631,7 +631,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, *mode = SVAL(rdata, 32); } if (size) { - *size = IVAL(rdata, 48); + *size = IVAL2_TO_SMB_BIG_UINT(rdata,48); } if (ino) { *ino = IVAL(rdata, 64); diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 44f77117de..5289f36d0f 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1017,6 +1017,17 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t { int ret; + /* + * 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 = file->offset; + if (!context || !context->internal || !context->internal->_initialized) { @@ -1043,7 +1054,7 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t } - ret = cli_read(&file->srv->cli, file->cli_fd, buf, file->offset, count); + ret = cli_read(&file->srv->cli, file->cli_fd, buf, offset, count); if (ret < 0) { @@ -1067,6 +1078,7 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t count) { int ret; + off_t offset = file->offset; /* See "offset" comment in smbc_read_ctx() */ if (!context || !context->internal || !context->internal->_initialized) { @@ -1092,7 +1104,7 @@ static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_ } - ret = cli_write(&file->srv->cli, file->cli_fd, 0, buf, file->offset, count); + ret = cli_write(&file->srv->cli, file->cli_fd, 0, buf, offset, count); if (ret <= 0) { @@ -1165,7 +1177,7 @@ static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo */ static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, - uint16 *mode, size_t *size, + uint16 *mode, SMB_OFF_T *size, time_t *c_time, time_t *a_time, time_t *m_time, SMB_INO_T *ino) { @@ -1272,7 +1284,7 @@ static int smbc_unlink_ctx(SMBCCTX *context, const char *fname) if (errno == EACCES) { /* Check if the file is a directory */ int saverr = errno; - size_t size = 0; + SMB_OFF_T size = 0; uint16 mode = 0; time_t m_time = 0, a_time = 0, c_time = 0; SMB_INO_T ino = 0; @@ -1396,7 +1408,7 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int whence) { - size_t size; + SMB_OFF_T size; if (!context || !context->internal || !context->internal->_initialized) { @@ -1482,7 +1494,8 @@ ino_t smbc_inode(SMBCCTX *context, const char *name) */ static -int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname, size_t size, int mode) +int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname, + SMB_OFF_T size, int mode) { st->st_mode = 0; @@ -1532,7 +1545,7 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) fstring server, share, user, password, workgroup; pstring path; time_t m_time = 0, a_time = 0, c_time = 0; - size_t size = 0; + SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T ino = 0; @@ -1602,7 +1615,7 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) { time_t c_time, a_time, m_time; - size_t size; + SMB_OFF_T size; uint16 mode; SMB_INO_T ino = 0; @@ -1629,15 +1642,12 @@ static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) if (!cli_qfileinfo(&file->srv->cli, file->cli_fd, &mode, &size, &c_time, &a_time, &m_time, NULL, &ino)) { - SMB_BIG_UINT b_size = size; if (!cli_getattrE(&file->srv->cli, file->cli_fd, - &mode, &b_size, &c_time, &a_time, &m_time)) { + &mode, &size, &c_time, &a_time, &m_time)) { errno = EINVAL; return -1; - } else - size = b_size; - + } } st->st_ino = ino; @@ -1960,7 +1970,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) } for (i = 0; i < count && i < max_lmb_count; i++) { - DEBUG(99, ("Found master browser %s\n", inet_ntoa(ip_list[i].ip))); + DEBUG(99, ("Found master browser %d of %d: %s\n", i+1, MAX(count, max_lmb_count), inet_ntoa(ip_list[i].ip))); cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, &u_info); /* cli == NULL is the master browser refused to talk or @@ -1983,12 +1993,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) srv = smbc_server(context, server, "IPC$", workgroup, user, password); if (!srv) { - - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - return NULL; + continue; } dir->srv = srv; @@ -1999,13 +2004,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) if (!cli_NetServerEnum(&srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_unique_wg_fn, (void *)dir)) { - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - - return NULL; - + continue; } } } else { @@ -3233,7 +3232,7 @@ static DOS_ATTR_DESC *dos_attr_query(SMBCCTX *context, SMBCSRV *srv) { time_t m_time = 0, a_time = 0, c_time = 0; - size_t size = 0; + SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T inode = 0; DOS_ATTR_DESC *ret; @@ -3245,7 +3244,7 @@ static DOS_ATTR_DESC *dos_attr_query(SMBCCTX *context, } /* Obtain the DOS attributes */ - if (!smbc_getatr(context, srv, filename, &mode, &size, + if (!smbc_getatr(context, srv, (char *) filename, &mode, &size, &c_time, &a_time, &m_time, &inode)) { errno = smbc_errno(context, &srv->cli); @@ -3331,7 +3330,7 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, fstring sidstr; char *p; time_t m_time = 0, a_time = 0, c_time = 0; - size_t size = 0; + SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T ino = 0; struct cli_state *cli = &srv->cli; @@ -3840,7 +3839,7 @@ static int cacl_set(TALLOC_CTX *ctx, struct cli_state *cli, the_acl = p + 1; } - sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, the_acl); + sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, (char *) the_acl); if (!sd) { errno = EINVAL; @@ -4368,7 +4367,7 @@ int smbc_getxattr_ctx(SMBCCTX *context, /* Yup. */ ret = cacl_get(context, ctx, srv, ipc_srv == NULL ? NULL : &ipc_srv->cli, - &pol, path, name, (char *) value, size); + &pol, path, (char*)name, (char *) value, size); if (ret < 0 && errno == 0) { errno = smbc_errno(context, &srv->cli); } diff --git a/source3/python/py_smb.c b/source3/python/py_smb.c index c3d59d4fb8..ad83e469b2 100644 --- a/source3/python/py_smb.c +++ b/source3/python/py_smb.c @@ -212,7 +212,7 @@ static PyObject *py_smb_read(PyObject *self, PyObject *args, PyObject *kw) static char *kwlist[] = { "fnum", "offset", "size", NULL }; int fnum, offset=0, size=0; ssize_t result; - size_t fsize; + SMB_OFF_T fsize; char *data; PyObject *ret; diff --git a/source3/smbwrapper/smbw.c b/source3/smbwrapper/smbw.c index bf60c2bc68..edcc7a5c2f 100644 --- a/source3/smbwrapper/smbw.c +++ b/source3/smbwrapper/smbw.c @@ -1224,7 +1224,7 @@ a wrapper for lseek() off_t smbw_lseek(int fd, off_t offset, int whence) { struct smbw_file *file; - size_t size; + SMB_OFF_T size; smbw_busy++; diff --git a/source3/smbwrapper/smbw_stat.c b/source3/smbwrapper/smbw_stat.c index bb76ef006a..6effc9a71b 100644 --- a/source3/smbwrapper/smbw_stat.c +++ b/source3/smbwrapper/smbw_stat.c @@ -69,17 +69,33 @@ BOOL smbw_getatr(struct smbw_server *srv, char *path, time_t *c_time, time_t *a_time, time_t *m_time, SMB_INO_T *ino) { + time_t c_a_m_time; + /* + * "size" (size_t) is only 32 bits. Rather than change the interface + * in this code as we change cli_qpathinfo2() and cli_getatr() to + * support 64-bit file sizes, we'll use a temporary variable and + * maintain the interface size_t. At some point, someone may want to + * change the interface as well. djl + */ + SMB_OFF_T fullsize; + DEBUG(4,("sending qpathinfo\n")); if (!srv->no_pathinfo2 && cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL, - size, mode, ino)) return True; + &fullsize, mode, ino)) { + if (size != NULL) *size = (size_t) fullsize; + return True; + } /* if this is NT then don't bother with the getatr */ if (srv->cli.capabilities & CAP_NT_SMBS) return False; - if (cli_getatr(&srv->cli, path, mode, size, m_time)) { - a_time = c_time = m_time; + if (cli_getatr(&srv->cli, path, mode, &fullsize, &c_a_m_time)) { + if (a_time != NULL) *a_time = c_a_m_time; + if (c_time != NULL) *a_time = c_a_m_time; + if (m_time != NULL) *a_time = c_a_m_time; + if (size != NULL) *size = (size_t) fullsize; srv->no_pathinfo2 = True; return True; } @@ -129,7 +145,7 @@ int smbw_fstat(int fd, struct stat *st) { struct smbw_file *file; time_t c_time, a_time, m_time; - size_t size; + SMB_OFF_T size; uint16 mode; SMB_INO_T ino = 0; diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 37aefc55ac..4828861906 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -590,7 +590,7 @@ static BOOL run_readwritelarge(int dummy) static struct cli_state *cli1; int fnum1; const char *lockfname = "\\large.dat"; - size_t fsize; + SMB_OFF_T fsize; char buf[126*1024]; BOOL correct = True; @@ -2360,7 +2360,7 @@ static BOOL run_trans2test(int dummy) { struct cli_state *cli; int fnum; - size_t size; + SMB_OFF_T size; time_t c_time, a_time, m_time, w_time, m_time2; const char *fname = "\\trans2.tst"; const char *dname = "\\trans2"; @@ -3591,7 +3591,7 @@ static BOOL run_opentest(int dummy) const char *fname = "\\readonly.file"; int fnum1, fnum2; char buf[20]; - size_t fsize; + SMB_OFF_T fsize; BOOL correct = True; char *tmp_path; diff --git a/source3/torture/utable.c b/source3/torture/utable.c index ba803a0da4..c9b30f06e1 100644 --- a/source3/torture/utable.c +++ b/source3/torture/utable.c @@ -137,7 +137,7 @@ BOOL torture_casetable(int dummy) } for (c=1; c < 0x10000; c++) { - size_t size; + SMB_OFF_T size; if (c == '.' || c == '\\') continue; -- cgit