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