output overwrite problem with smbclient when i copy a large ( > 4 GB ) file

gerzson gyorgyf.m at oep.hu
Fri Nov 29 13:53:00 GMT 2002


Hi,

I tried to copy more than 4 GB from an AIX host to a W2K NTFS share with
smbclient of Samba 2.2.4.

I tested it something like that:



$ dd if=/dev/zero bs=1024000 count=4200 | cat - f1 >PIPE  &

$ /smbclient //w2k_pc/t -U test%test -c "put PIPE d.zer"



Smbclient said everything ok on the client side, but the output file size
wasn't greater than 4GB on W2K side.

When I looked at the output file closer I noticed that smbclient overwrote
the beginning of the output file with the ending of the input file!

I think that is because of the nread variable overflowed in the do_put
function in the client.c.



I tried to modified type of the nread from int to off_t, but it also didn't
work. So I modified the do_put function to check overflowing of the nread:



static void do_put(char *rname,char *lname)

{

            int fnum;

            FILE *f;

            unsigned int nread=0;            /* int nread=0;
gerzson-20021128 */

            char *buf=NULL;

            int maxwrite=io_bufsize;



            unsigned int MAX_FILE_SIZE=~0;       /* gerzson-20021128 */

            BOOL toolarge = False;             /* gerzson-20021128 */



            int prev_nread=0;



            struct timeval tp_start;

            GetTimeOfDay(&tp_start);





            fnum = cli_open(cli, rname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE);



            if (fnum == -1) {

                        DEBUG(0,("%s opening remote file
%s\n",cli_errstr(cli),rname));

                        return;

            }



            /* allow files to be piped into smbclient

               jdblair 24.jun.98 */

            if (!strcmp(lname, "-")) {

                        f = stdin;

                        /* size of file is not known */

            } else {

                        f = sys_fopen(lname,"r");

            }



            if (!f) {

                        DEBUG(0,("Error opening local file %s\n",lname));

                        return;

            }





            DEBUG(1,("putting file %s as %s ",lname,

                         rname));



            buf = (char *)malloc(maxwrite);

            if (!buf) {

                        DEBUG(0, ("ERROR: Not enough memory!\n"));

                        return;

            }

            while (!feof(f)) {

                        int n = maxwrite;

                        int ret;



                        if ((n = readfile(buf,1,n,f)) < 1) {

                                    if((n == 0) && feof(f))

                                                break; /* Empty local file.
*/



                                    DEBUG(0,("Error reading local file:
%s\n", strerror(errno) ));

                                    break;

                        }



                        if ((toolarge = (nread > (MAX_FILE_SIZE-n+1))))
{            /* gerzson-20021128 */

                                    break;

                        }



                        ret = cli_write(cli, fnum, 0, buf, nread, n);



                        if (n != ret) {

                                    DEBUG(0,("Error writing file: %s\n",
cli_errstr(cli)));

                                    break;

                        }



                        nread += n;

            }



            if (!cli_close(cli, fnum)) {

                        DEBUG(0,("%s closing remote file
%s\n",cli_errstr(cli),rname));

                        fclose(f);

                        SAFE_FREE(buf);

                        return;

            }





            fclose(f);

            SAFE_FREE(buf);



            if (toolarge) {                    /* gerzson-20021128 */

                        if (f == stdin) {

                                    cli_shutdown(cli);

                        }

                        DEBUG(0, ("ERROR: Input file is too large (more than
%10u bytes)!\n",MAX_FILE_SIZE));

                        if (cmdstr) {

                                    exit(1);

                        } else {

                                    return;

                        }

            }





            {

                        struct timeval tp_end;

                        int this_time;



                        GetTimeOfDay(&tp_end);

                        this_time =

                                    (tp_end.tv_sec - tp_start.tv_sec)*1000 +

                                    (tp_end.tv_usec -
tp_start.tv_usec)/1000;

                        put_total_time_ms += this_time;

                        put_total_size += nread;



                        DEBUG(1,("(%3.1f kb/s) (average %3.1f kb/s)\n",

                                     nread / (1.024*this_time + 1.0e-4),

                                     put_total_size /
(1.024*put_total_time_ms)));

            }



            if (f == stdin) {

                        cli_shutdown(cli);

                        exit(0);

            }

}



Györgyfalvay Miklós (gerzson)
gyogyf.m at oep.hu






More information about the samba-technical mailing list