[2.2 patch] client/client.c: reget and reput commands

Simo Sorce simo.sorce at xsec.it
Mon Aug 19 09:17:00 GMT 2002


Interesting, but can you make a patch against head instead?
Thank you,
Simo.

On Mon, 2002-08-19 at 19:52, Josef Zlomek wrote:
> Hello!
> 
> I have written the reget and reput commands for samba 2.2.
> When user gets/puts a large file and the connection brokes
> the user is unhappy (s)he has to transfer the file from the beginning.
> So with this patch (s)he can use command reget/reput that
> will continue in the transfer, i.e. it will seek both in local and remote file
> to position of the end of target file and continue with the transfer from this position.
> Although the local networks are fast, it takes several minutes to tranfer
> a 650 MB large file (e.g. ISO image) so I think this commands are useful.
> 
> While writing these commands I found something that confuses me:
> the get and put commands are similar so one would thing that get and put would
> use similar functions.  But function writefile (that is used by command get)
> uses function write, and function readfile (that is used by command get) uses
> function fread.  I think that both functions should use either
> open/read/write/close, or fopen/fread/fwrite/fclose.
> Because of this, I'm not sending the patch for samba 3.0 right now, because
> seek is not supported by XFILE (that is used in 3.0's put) yet.  I would like
> to know first whether it is better to use syscalls in both get and put,
> or write x_fseek for reput.
> 
> Patch follows.
> 
> Josef Zlomek
> 
> Index: source/client/client.c
> ===================================================================
> RCS file: /cvsroot/samba/source/client/client.c,v
> retrieving revision 1.148.2.28
> diff -u -r1.148.2.28 client.c
> --- source/client/client.c	14 May 2002 14:00:49 -0000	1.148.2.28
> +++ source/client/client.c	19 Aug 2002 12:49:11 -0000
> @@ -57,6 +57,7 @@
>  /* value for unused fid field in trans2 secondary request */
>  #define FID_UNUSED (0xFFFF)
>  
> +BOOL restart_at_file_end = False;
>  time_t newer_than = 0;
>  int archive_level = 0;
>  
> @@ -638,7 +639,7 @@
>    ****************************************************************************/
>  static void do_get(char *rname,char *lname)
>  {  
> -	int handle=0,fnum;
> +	int handle = -1, fnum;
>  	BOOL newhandle = False;
>  	char *data;
>  	struct timeval tp_start;
> @@ -646,6 +647,7 @@
>  	uint16 attr;
>  	size_t size;
>  	off_t nread = 0;
> +	off_t start = 0;
>  
>  	GetTimeOfDay(&tp_start);
>  
> @@ -663,7 +665,18 @@
>  	if(!strcmp(lname,"-")) {
>  		handle = fileno(stdout);
>  	} else {
> -		handle = sys_open(lname,O_WRONLY|O_CREAT|O_TRUNC,0644);
> +		if (restart_at_file_end) {
> +			handle = sys_open(lname,O_WRONLY|O_CREAT,0644);
> +			if (handle >= 0) {
> +				start = sys_lseek(handle, 0, SEEK_END);
> +				if (start == -1) {
> +					DEBUG(0,("Error seeking local file\n"));
> +					return;
> +				}
> +			}
> +		}
> +		if (handle < 0)
> +			handle = sys_open(lname,O_WRONLY|O_CREAT|O_TRUNC,0644);
>  		newhandle = True;
>  	}
>  	if (handle < 0) {
> @@ -690,7 +703,7 @@
>  	}
>  
>  	while (1) {
> -		int n = cli_read(cli, fnum, data, nread, read_size);
> +		int n = cli_read(cli, fnum, data, nread + start, read_size);
>  
>  		if (n <= 0) break;
>   
> @@ -702,7 +715,7 @@
>  		nread += n;
>  	}
>  
> -	if (nread < size) {
> +	if (nread + start < size) {
>  		DEBUG (0, ("Short read when getting file %s. Only got %ld bytes.\n",
>                 rname, (long)nread));
>  	}
> @@ -767,6 +780,17 @@
>  
>  
>  /****************************************************************************
> +  get a file restarting at end of local file
> +  ****************************************************************************/
> +static void cmd_reget(void)
> +{
> +	restart_at_file_end = True;
> +	cmd_get();
> +	restart_at_file_end = False;
> +}
> +
> +
> +/****************************************************************************
>    do a mget operation on one file
>    ****************************************************************************/
>  static void do_mget(file_info *finfo)
> @@ -1015,16 +1039,31 @@
>    ****************************************************************************/
>  static void do_put(char *rname,char *lname)
>  {
> -	int fnum;
> +	int fnum = -1;
>  	FILE *f;
> -	int nread=0;
> +	size_t nread = 0;
> +	size_t start = 0;
>  	char *buf=NULL;
>  	int maxwrite=io_bufsize;
>  	
>  	struct timeval tp_start;
>  	GetTimeOfDay(&tp_start);
>  
> -	fnum = cli_open(cli, rname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE);
> +	if (restart_at_file_end) {
> +		fnum = cli_open(cli, rname, O_RDWR|O_CREAT, DENY_NONE);
> +		if (fnum >= 0) {
> +			if (!cli_qfileinfo(cli, fnum, NULL, &start,
> +					   NULL, NULL, NULL, NULL, NULL) &&
> +			    !cli_getattrE(cli, fnum, NULL, &start,
> +					  NULL, NULL, NULL)) {
> +				DEBUG(0,("getattrib: %s\n",cli_errstr(cli)));
> +				return;
> +			}
> +		}
> +	}
> +	if (fnum == -1) {
> +		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));
> @@ -1038,6 +1077,12 @@
>  		/* size of file is not known */
>  	} else {
>  		f = sys_fopen(lname,"r");
> +		if (f != NULL && restart_at_file_end) {
> +			if (sys_fseek(f, start, SEEK_SET) == -1) {
> +				DEBUG(0,("Error seeking local file\n"));
> +				return;
> +			}
> +		}
>  	}
>  
>  	if (!f) {
> @@ -1066,7 +1111,7 @@
>  			break;
>  		}
>  
> -		ret = cli_write(cli, fnum, 0, buf, nread, n);
> +		ret = cli_write(cli, fnum, 0, buf, nread + start, n);
>  
>  		if (n != ret) {
>  			DEBUG(0,("Error writing file: %s\n", cli_errstr(cli)));
> @@ -1151,6 +1196,18 @@
>  	do_put(rname,lname);
>  }
>  
> +
> +/****************************************************************************
> +  put a file restarting at end of local file
> +  ****************************************************************************/
> +static void cmd_reput(void)
> +{
> +	restart_at_file_end = True;
> +	cmd_put();
> +	restart_at_file_end = False;
> +}
> +
> +
>  /*************************************
>    File list structure
>  *************************************/
> @@ -1920,7 +1977,9 @@
>    {"quit",cmd_quit,"logoff the server",{COMPL_NONE,COMPL_NONE}},
>    {"rd",cmd_rmdir,"<directory> remove a directory",{COMPL_NONE,COMPL_NONE}},
>    {"recurse",cmd_recurse,"toggle directory recursion for mget and mput",{COMPL_NONE,COMPL_NONE}},  
> +  {"reget",cmd_reget,"<remote name> [local name] get a file restarting at end of local file",{COMPL_REMOTE,COMPL_LOCAL}},
>    {"rename",cmd_rename,"<src> <dest> rename some files",{COMPL_REMOTE,COMPL_REMOTE}},
> +  {"reput",cmd_reput,"<local name> [remote name] put a file restarting at end of remote file",{COMPL_LOCAL,COMPL_REMOTE}},
>    {"rm",cmd_del,"<mask> delete all matching files",{COMPL_REMOTE,COMPL_NONE}},
>    {"rmdir",cmd_rmdir,"<directory> remove a directory",{COMPL_NONE,COMPL_NONE}},
>    {"setmode",cmd_setmode,"filename <setmode string> change modes of file",{COMPL_REMOTE,COMPL_NONE}},
-- 
Simo Sorce - simo.sorce at xsec.it
Xsec s.r.l.
via Durando 10 Ed. G - 20158 - Milano
tel. +39 02 2399 7130 - fax: +39 02 700 442 399
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 232 bytes
Desc: This is a digitally signed message part
Url : http://lists.samba.org/archive/samba-technical/attachments/20020819/30783a67/attachment.bin


More information about the samba-technical mailing list