diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/proto.h | 4 | ||||
-rw-r--r-- | source3/libsmb/clireadwrite.c | 54 |
2 files changed, 55 insertions, 3 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 69672cfdf5..a729cf6057 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1773,6 +1773,10 @@ struct tevent_req *cli_write_andx_send(TALLOC_CTX *mem_ctx, off_t offset, size_t size); NTSTATUS cli_write_andx_recv(struct tevent_req *req, size_t *pwritten); +NTSTATUS cli_writeall(struct cli_state *cli, uint16_t fnum, uint16_t mode, + const uint8_t *buf, off_t offset, size_t size, + size_t *pwritten); + struct tevent_req *cli_push_send(TALLOC_CTX *mem_ctx, struct event_context *ev, struct cli_state *cli, uint16_t fnum, uint16_t mode, diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index e243f8a0fc..6482a335e1 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -1138,9 +1138,57 @@ static void cli_writeall_written(struct tevent_req *subreq) tevent_req_set_callback(subreq, cli_writeall_written, req); } -static NTSTATUS cli_writeall_recv(struct tevent_req *req) +static NTSTATUS cli_writeall_recv(struct tevent_req *req, + size_t *pwritten) { - return tevent_req_simple_recv_ntstatus(req); + struct cli_writeall_state *state = tevent_req_data( + req, struct cli_writeall_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + if (pwritten != NULL) { + *pwritten = state->written; + } + return NT_STATUS_OK; +} + +NTSTATUS cli_writeall(struct cli_state *cli, uint16_t fnum, uint16_t mode, + const uint8_t *buf, off_t offset, size_t size, + size_t *pwritten) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + req = cli_writeall_send(frame, ev, cli, fnum, mode, buf, offset, size); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + status = cli_writeall_recv(req, pwritten); + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } struct cli_push_write_state { @@ -1305,7 +1353,7 @@ static void cli_push_written(struct tevent_req *subreq) state->reqs[idx] = NULL; state->pending -= 1; - status = cli_writeall_recv(subreq); + status = cli_writeall_recv(subreq, NULL); TALLOC_FREE(subreq); TALLOC_FREE(substate); if (tevent_req_nterror(req, status)) { |