The Samba-Bugzilla – Attachment 4720 Details for
Bug 6606
cli_read_andx_done() not handling short reads
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch for 3.3
0001-s3-smbclient-Fix-bug-6606-reported-as-6744-in-3.3.patch (text/plain), 4.86 KB, created by
Volker Lendecke
on 2009-09-18 13:12:56 UTC
(
hide
)
Description:
Patch for 3.3
Filename:
MIME Type:
Creator:
Volker Lendecke
Created:
2009-09-18 13:12:56 UTC
Size:
4.86 KB
patch
obsolete
>From c66fd3932beaf13ef6e3a4fe25f7d49c72895077 Mon Sep 17 00:00:00 2001 >From: Volker Lendecke <vl@samba.org> >Date: Fri, 18 Sep 2009 19:45:36 +0200 >Subject: [PATCH] s3:smbclient: Fix bug 6606 (reported as 6744) in 3.3 > >This is a port of 1f34ffa0ca and 24309bdb2efc to 3.3. >--- > source/libsmb/clireadwrite.c | 133 ++++++++++++++++++++++++++++++++++++++++- > 1 files changed, 129 insertions(+), 4 deletions(-) > >diff --git a/source/libsmb/clireadwrite.c b/source/libsmb/clireadwrite.c >index a57f1e0..db59798 100644 >--- a/source/libsmb/clireadwrite.c >+++ b/source/libsmb/clireadwrite.c >@@ -154,6 +154,131 @@ NTSTATUS cli_read_andx_recv(struct async_req *req, ssize_t *received, > return NT_STATUS_OK; > } > >+struct cli_readall_state { >+ struct cli_state *cli; >+ uint16_t fnum; >+ off_t start_offset; >+ size_t size; >+ size_t received; >+ uint8_t *buf; >+}; >+ >+static void cli_readall_done(struct async_req *subreq); >+ >+static struct async_req *cli_readall_send(TALLOC_CTX *mem_ctx, >+ struct cli_state *cli, >+ uint16_t fnum, >+ off_t offset, size_t size) >+{ >+ struct async_req *req, *subreq; >+ struct cli_readall_state *state; >+ >+ req = async_req_new(mem_ctx, cli->event_ctx); >+ if (req == NULL) { >+ return NULL; >+ } >+ state = talloc(req, struct cli_readall_state); >+ if (state == NULL) { >+ TALLOC_FREE(req); >+ return NULL; >+ } >+ state->cli = cli; >+ state->fnum = fnum; >+ state->start_offset = offset; >+ state->size = size; >+ state->received = 0; >+ state->buf = NULL; >+ >+ subreq = cli_read_andx_send(state, cli, fnum, offset, size); >+ if (subreq == NULL) { >+ TALLOC_FREE(req); >+ return NULL; >+ } >+ subreq->async.fn = cli_readall_done; >+ subreq->async.priv = req; >+ return req; >+} >+ >+static void cli_readall_done(struct async_req *subreq) >+{ >+ struct async_req *req = talloc_get_type_abort( >+ subreq->async.priv, struct async_req); >+ struct cli_readall_state *state = talloc_get_type_abort( >+ req->private_data, struct cli_readall_state); >+ ssize_t received; >+ uint8_t *buf; >+ NTSTATUS status; >+ >+ status = cli_read_andx_recv(subreq, &received, &buf); >+ if (!NT_STATUS_IS_OK(status)) { >+ async_req_error(req, status); >+ return; >+ } >+ >+ if (received == 0) { >+ /* EOF */ >+ async_req_done(req); >+ return; >+ } >+ >+ if ((state->received == 0) && (received == state->size)) { >+ /* Ideal case: Got it all in one run */ >+ state->buf = buf; >+ state->received += received; >+ async_req_done(req); >+ return; >+ } >+ >+ /* >+ * We got a short read, issue a read for the >+ * rest. Unfortunately we have to allocate the buffer >+ * ourselves now, as our caller expects to receive a single >+ * buffer. cli_read_andx does it from the buffer received from >+ * the net, but with a short read we have to put it together >+ * from several reads. >+ */ >+ >+ if (state->buf == NULL) { >+ state->buf = talloc_array(state, uint8_t, state->size); >+ if (async_req_nomem(state->buf, req)) { >+ return; >+ } >+ } >+ memcpy(state->buf + state->received, buf, received); >+ state->received += received; >+ >+ TALLOC_FREE(subreq); >+ >+ if (state->received >= state->size) { >+ async_req_done(req); >+ return; >+ } >+ >+ subreq = cli_read_andx_send(state, state->cli, state->fnum, >+ state->start_offset + state->received, >+ state->size - state->received); >+ if (async_req_nomem(subreq, req)) { >+ return; >+ } >+ subreq->async.fn = cli_readall_done; >+ subreq->async.priv = req; >+} >+ >+static NTSTATUS cli_readall_recv(struct async_req *req, ssize_t *received, >+ uint8_t **rcvbuf) >+{ >+ struct cli_readall_state *state = talloc_get_type_abort( >+ req->private_data, struct cli_readall_state); >+ >+ SMB_ASSERT(req->state >= ASYNC_REQ_DONE); >+ if (req->state == ASYNC_REQ_ERROR) { >+ return req->status; >+ } >+ *received = state->received; >+ *rcvbuf = state->buf; >+ return NT_STATUS_OK; >+} >+ > /* > * Parallel read support. > * >@@ -288,7 +413,7 @@ struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, > size_left = size - state->requested; > request_thistime = MIN(size_left, state->chunk_size); > >- state->reqs[i] = cli_read_andx_send( >+ state->reqs[i] = cli_readall_send( > state->reqs, cli, fnum, > state->start_offset + state->requested, > request_thistime); >@@ -323,8 +448,8 @@ static void cli_pull_read_done(struct async_req *read_req) > struct cli_request *read_state = cli_request_get(read_req); > NTSTATUS status; > >- status = cli_read_andx_recv(read_req, &read_state->data.read.received, >- &read_state->data.read.rcvbuf); >+ status = cli_readall_recv(read_req, &read_state->data.read.received, >+ &read_state->data.read.rcvbuf); > if (!NT_STATUS_IS_OK(status)) { > async_req_error(state->req, status); > return; >@@ -383,7 +508,7 @@ static void cli_pull_read_done(struct async_req *read_req) > + state->requested), > state->top_req)); > >- new_req = cli_read_andx_send( >+ new_req = cli_readall_send( > state->reqs, state->cli, state->fnum, > state->start_offset + state->requested, > request_thistime); >-- >1.6.0.4 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 6606
:
4720
|
4722
|
4724
|
4830