summaryrefslogtreecommitdiffstats
path: root/source3/libsmb
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2014-06-27 09:47:36 +0000
committerJeremy Allison <jra@samba.org>2014-06-30 22:28:15 +0200
commit4964b0606652169cc8dc59ee45bceae80ac4c46a (patch)
tree8ef2b80d0e727b298fbb24017d136265d3ed4793 /source3/libsmb
parent379cbb6397ce6228cf02125f4f29b2438b384d1c (diff)
downloadsamba-4964b0606652169cc8dc59ee45bceae80ac4c46a.tar.gz
samba-4964b0606652169cc8dc59ee45bceae80ac4c46a.tar.xz
samba-4964b0606652169cc8dc59ee45bceae80ac4c46a.zip
libcli: Make cli_smb2_close_fnum async
Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/cli_smb2_fnum.c110
-rw-r--r--source3/libsmb/cli_smb2_fnum.h5
2 files changed, 92 insertions, 23 deletions
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c
index 3fdd49a74f..3a04ea16cd 100644
--- a/source3/libsmb/cli_smb2_fnum.c
+++ b/source3/libsmb/cli_smb2_fnum.c
@@ -318,45 +318,109 @@ NTSTATUS cli_smb2_create_fnum(struct cli_state *cli,
/***************************************************************
Small wrapper that allows SMB2 close to use a uint16_t fnum.
- Synchronous only.
***************************************************************/
-NTSTATUS cli_smb2_close_fnum(struct cli_state *cli, uint16_t fnum)
+struct cli_smb2_close_fnum_state {
+ struct cli_state *cli;
+ uint16_t fnum;
+ struct smb2_hnd *ph;
+};
+
+static void cli_smb2_close_fnum_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_smb2_close_fnum_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum)
{
- struct smb2_hnd *ph = NULL;
+ struct tevent_req *req, *subreq;
+ struct cli_smb2_close_fnum_state *state;
NTSTATUS status;
- if (smbXcli_conn_has_async_calls(cli->conn)) {
- /*
- * Can't use sync call while an async call is in flight
- */
- return NT_STATUS_INVALID_PARAMETER;
+ req = tevent_req_create(mem_ctx, &state,
+ struct cli_smb2_close_fnum_state);
+ if (req == NULL) {
+ return NULL;
}
+ state->cli = cli;
+ state->fnum = fnum;
if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) {
- return NT_STATUS_INVALID_PARAMETER;
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
}
- status = map_fnum_to_smb2_handle(cli,
- fnum,
- &ph);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ status = map_fnum_to_smb2_handle(cli, fnum, &state->ph);
+ if (tevent_req_nterror(req, status)) {
+ return tevent_req_post(req, ev);
}
- status = smb2cli_close(cli->conn,
- cli->timeout,
- cli->smb2.session,
- cli->smb2.tcon,
- 0,
- ph->fid_persistent,
- ph->fid_volatile);
+ subreq = smb2cli_close_send(state, ev, cli->conn, cli->timeout,
+ cli->smb2.session, cli->smb2.tcon,
+ 0, state->ph->fid_persistent,
+ state->ph->fid_volatile);
+ if (tevent_req_nomem(subreq, req)) {
+ return tevent_req_post(req, ev);
+ }
+ tevent_req_set_callback(subreq, cli_smb2_close_fnum_done, req);
+ return req;
+}
+
+static void cli_smb2_close_fnum_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(
+ subreq, struct tevent_req);
+ struct cli_smb2_close_fnum_state *state = tevent_req_data(
+ req, struct cli_smb2_close_fnum_state);
+ NTSTATUS status;
+
+ status = smb2cli_close_recv(subreq);
+ if (tevent_req_nterror(req, status)) {
+ return;
+ }
/* Delete the fnum -> handle mapping. */
- if (NT_STATUS_IS_OK(status)) {
- status = delete_smb2_handle_mapping(cli, &ph, fnum);
+ status = delete_smb2_handle_mapping(state->cli, &state->ph,
+ state->fnum);
+ if (tevent_req_nterror(req, status)) {
+ return;
}
+ tevent_req_done(req);
+}
+
+NTSTATUS cli_smb2_close_fnum_recv(struct tevent_req *req)
+{
+ return tevent_req_simple_recv_ntstatus(req);
+}
+
+NTSTATUS cli_smb2_close_fnum(struct cli_state *cli, uint16_t fnum)
+{
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct tevent_context *ev;
+ struct tevent_req *req;
+ NTSTATUS status = NT_STATUS_NO_MEMORY;
+ if (smbXcli_conn_has_async_calls(cli->conn)) {
+ /*
+ * Can't use sync call while an async call is in flight
+ */
+ status = NT_STATUS_INVALID_PARAMETER;
+ goto fail;
+ }
+ ev = samba_tevent_context_init(frame);
+ if (ev == NULL) {
+ goto fail;
+ }
+ req = cli_smb2_close_fnum_send(frame, ev, cli, fnum);
+ if (req == NULL) {
+ goto fail;
+ }
+ if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+ goto fail;
+ }
+ status = cli_smb2_close_fnum_recv(req);
+ fail:
+ TALLOC_FREE(frame);
return status;
}
diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h
index 9394918dfc..173dba06de 100644
--- a/source3/libsmb/cli_smb2_fnum.h
+++ b/source3/libsmb/cli_smb2_fnum.h
@@ -48,6 +48,11 @@ NTSTATUS cli_smb2_create_fnum(struct cli_state *cli,
uint16_t *pfid,
struct smb_create_returns *cr);
+struct tevent_req *cli_smb2_close_fnum_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct cli_state *cli,
+ uint16_t fnum);
+NTSTATUS cli_smb2_close_fnum_recv(struct tevent_req *req);
NTSTATUS cli_smb2_close_fnum(struct cli_state *cli, uint16_t fnum);
NTSTATUS cli_smb2_mkdir(struct cli_state *cli, const char *dirname);
NTSTATUS cli_smb2_rmdir(struct cli_state *cli, const char *dirname);