[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