r5968: derrell's large file fix for libsmbclient (BUG 2505)
authorGerald Carter <jerry@samba.org>
Tue, 22 Mar 2005 21:17:01 +0000 (21:17 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:56:13 +0000 (10:56 -0500)
(This used to be commit 85be4c5df398faa6c5bfacd1f9d2f12c39d411e1)

source3/client/client.c
source3/client/clitar.c
source3/include/libsmb_internal.h
source3/libsmb/clifile.c
source3/libsmb/clirap.c
source3/libsmb/libsmbclient.c
source3/python/py_smb.c
source3/smbwrapper/smbw.c
source3/smbwrapper/smbw_stat.c
source3/torture/torture.c
source3/torture/utable.c

index 9a09d50cc08000e9363860d3b0e961541a16ccf2..d03c32312723310d146944c7ba753da91afe9f66 100644 (file)
@@ -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;
index 524feca1d2ac5bc89ba24bf51e97bd78780a3791..919545291f19b05f39758a5cf328c771300ea6b7 100644 (file)
@@ -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;
index a1db5c27926aa46dfd7b3f08747f6a3147847bd3..2eca879cbe2a03f76bc8ceba98d1c98228fbd2e9 100644 (file)
@@ -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;
index 9d20ed3adcd268ca01629982c13b7bf3562aba5e..93492ec08229654b38ca5502321e31689a61a3dd 100644 (file)
@@ -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;
 
index 8e6742d438077cb608c5740812211b2b0ed33711..1f6a99d4bee4269de2cb62ad77b4bc6be85bf3ba 100644 (file)
@@ -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);
index 44f77117de9195b380ae036e92b7ca87481d84ef..5289f36d0f38c09cad69d8d25c2870b49123d7f7 100644 (file)
@@ -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);
                 }
index c3d59d4fb8c064c662e95797559685ba08048007..ad83e469b24a8b9acc6d0a0ed79c6de4e50cf599 100644 (file)
@@ -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;
 
index bf60c2bc68c96d4f20d29fcf6c9c3d1e2d5b30e2..edcc7a5c2f958568b4a0724d76715acf3646c12b 100644 (file)
@@ -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++;
 
index bb76ef006a442fc2f3818126b0838cf7478d2c2c..6effc9a71bcfa85f2bc0fbf90673b296690c4991 100644 (file)
@@ -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;
 
index 37aefc55acfb2a5bc75c888ad0c05ee4cf2c541c..4828861906fd013cd75b062978ddf5cfcee189ac 100644 (file)
@@ -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;
 
index ba803a0da4fabf980387367e62b524e7ca8ab141..c9b30f06e1cdc1b3c61061b857cbf7bb7e63176b 100644 (file)
@@ -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;