diff options
author | Volker Lendecke <vl@samba.org> | 2008-02-28 15:21:33 +0100 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2008-02-28 15:27:55 +0100 |
commit | 525aac775ecef275dbd0732830a9bac0fd023135 (patch) | |
tree | f94f42e0cff50c92d927f3b1c33d3d87305be997 /source3/client | |
parent | 1d41b5bd2a58dcc6966a3a49ccb063ff05e46125 (diff) | |
download | samba-525aac775ecef275dbd0732830a9bac0fd023135.tar.gz samba-525aac775ecef275dbd0732830a9bac0fd023135.tar.bz2 samba-525aac775ecef275dbd0732830a9bac0fd023135.zip |
Add async cli_pull support
This is the big (and potentially controversial) one. It took a phone call to
explain to metze what is going on inside cli_pull_read_done, but I would really
like everybody to understand this function. It is a very good and reasonably
complex example of async programming. If we want more asynchronism in s3, this
is what we will have to deal with :-)
Make use of it in the smbclient "get" command.
Volker
(This used to be commit 844a163458c7585e4306a21ffdae5d08e03d6e4d)
Diffstat (limited to 'source3/client')
-rw-r--r-- | source3/client/client.c | 42 |
1 files changed, 15 insertions, 27 deletions
diff --git a/source3/client/client.c b/source3/client/client.c index f7ed33ad8a..1410fc2f33 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -964,12 +964,20 @@ static int cmd_echo(void) Get a file from rname to lname ****************************************************************************/ +static NTSTATUS writefile_sink(char *buf, size_t n, void *priv) +{ + int *pfd = (int *)priv; + if (writefile(*pfd, buf, n) == -1) { + return map_nt_error_from_unix(errno); + } + return NT_STATUS_OK; +} + static int do_get(const char *rname, const char *lname_in, bool reget) { TALLOC_CTX *ctx = talloc_tos(); int handle = 0, fnum; bool newhandle = false; - char *data = NULL; struct timeval tp_start; int read_size = io_bufsize; uint16 attr; @@ -980,6 +988,7 @@ static int do_get(const char *rname, const char *lname_in, bool reget) struct cli_state *targetcli = NULL; char *targetname = NULL; char *lname = NULL; + NTSTATUS status; lname = talloc_strdup(ctx, lname_in); if (!lname) { @@ -1038,36 +1047,15 @@ static int do_get(const char *rname, const char *lname_in, bool reget) DEBUG(1,("getting file %s of size %.0f as %s ", rname, (double)size, lname)); - if(!(data = (char *)SMB_MALLOC(read_size))) { - d_printf("malloc fail for size %d\n", read_size); + status = cli_pull(targetcli, fnum, start, size, 1024*1024, + writefile_sink, (void *)&handle, &nread); + if (!NT_STATUS_IS_OK(status)) { + d_fprintf(stderr, "parallel_read returned %s\n", + nt_errstr(status)); cli_close(targetcli, fnum); return 1; } - while (1) { - int n = cli_read(targetcli, fnum, data, nread + start, read_size); - - if (n <= 0) - break; - - if (writefile(handle,data, n) != n) { - d_printf("Error writing local file\n"); - rc = 1; - break; - } - - nread += n; - } - - if (nread + start < size) { - DEBUG (0, ("Short read when getting file %s. Only got %ld bytes.\n", - rname, (long)nread)); - - rc = 1; - } - - SAFE_FREE(data); - if (!cli_close(targetcli, fnum)) { d_printf("Error %s closing remote file\n",cli_errstr(cli)); rc = 1; |