Make rpc_transport_np_init async
authorVolker Lendecke <vl@samba.org>
Thu, 29 Jan 2009 21:41:33 +0000 (22:41 +0100)
committerVolker Lendecke <vl@samba.org>
Fri, 30 Jan 2009 11:47:59 +0000 (12:47 +0100)
source3/include/proto.h
source3/rpc_client/rpc_transport_np.c

index 04740f5cae97de13eaa6682e6027566b95ce1942..60e80bd87ddbd3645bcc123f6495d166980f74d3 100644 (file)
@@ -5329,6 +5329,13 @@ NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx,
 
 /* The following definitions come from rpc_client/rpc_transport_np.c  */
 
+struct async_req *rpc_transport_np_init_send(TALLOC_CTX *mem_ctx,
+                                            struct event_context *ev,
+                                            struct cli_state *cli,
+                                            const struct ndr_syntax_id *abstract_syntax);
+NTSTATUS rpc_transport_np_init_recv(struct async_req *req,
+                                   TALLOC_CTX *mem_ctx,
+                                   struct rpc_cli_transport **presult);
 NTSTATUS rpc_transport_np_init(TALLOC_CTX *mem_ctx, struct cli_state *cli,
                               const struct ndr_syntax_id *abstract_syntax,
                               struct rpc_cli_transport **presult);
index e8a333e5092f2b04c626e327cf081a8c40cb1c7c..68aae6a0cc62e923d9cdcfb56a103f6223c552cc 100644 (file)
@@ -272,51 +272,140 @@ static NTSTATUS rpc_np_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
        return NT_STATUS_OK;
 }
 
-NTSTATUS rpc_transport_np_init(TALLOC_CTX *mem_ctx, struct cli_state *cli,
-                              const struct ndr_syntax_id *abstract_syntax,
-                              struct rpc_cli_transport **presult)
+struct rpc_transport_np_init_state {
+       struct rpc_cli_transport *transport;
+       struct rpc_transport_np_state *transport_np;
+};
+
+static void rpc_transport_np_init_pipe_open(struct async_req *subreq);
+
+struct async_req *rpc_transport_np_init_send(TALLOC_CTX *mem_ctx,
+                                            struct event_context *ev,
+                                            struct cli_state *cli,
+                                            const struct ndr_syntax_id *abstract_syntax)
 {
-       struct rpc_cli_transport *result;
-       struct rpc_transport_np_state *state;
-       int fnum;
+       struct async_req *result, *subreq;
+       struct rpc_transport_np_init_state *state;
+       NTSTATUS status;
 
-       result = talloc(mem_ctx, struct rpc_cli_transport);
-       if (result == NULL) {
-               return NT_STATUS_NO_MEMORY;
+       if (!async_req_setup(mem_ctx, &result, &state,
+                            struct rpc_transport_np_init_state)) {
+               return NULL;
        }
-       state = talloc(result, struct rpc_transport_np_state);
-       if (state == NULL) {
-               TALLOC_FREE(result);
-               return NT_STATUS_NO_MEMORY;
+
+       state->transport = talloc(state, struct rpc_cli_transport);
+       if (state->transport == NULL) {
+               goto fail;
+       }
+       state->transport_np = talloc(state->transport,
+                                    struct rpc_transport_np_state);
+       if (state->transport_np == NULL) {
+               goto fail;
        }
-       result->priv = state;
+       state->transport->priv = state->transport_np;
 
-       state->cli = cli;
-       state->pipe_name = cli_get_pipe_name_from_iface(
+       state->transport_np->pipe_name = cli_get_pipe_name_from_iface(
                state, abstract_syntax);
+       if (state->transport_np->pipe_name == NULL) {
+               status = NT_STATUS_PIPE_NOT_AVAILABLE;
+               goto post_status;
+       }
+       state->transport_np->cli = cli;
+
+       subreq = cli_ntcreate_send(
+               state, ev, cli, state->transport_np->pipe_name, 0,
+               DESIRED_ACCESS_PIPE, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
+               FILE_OPEN, 0, 0);
+       if (subreq == NULL) {
+               goto fail;
+       }
+       subreq->async.fn = rpc_transport_np_init_pipe_open;
+       subreq->async.priv = result;
+       return result;
+
+ post_status:
+       if (async_post_status(result, ev, status)) {
+               return result;
+       }
+ fail:
+       TALLOC_FREE(result);
+       return NULL;
+}
+
+static void rpc_transport_np_init_pipe_open(struct async_req *subreq)
+{
+       struct async_req *req = talloc_get_type_abort(
+               subreq->async.priv, struct async_req);
+       struct rpc_transport_np_init_state *state = talloc_get_type_abort(
+               req->private_data, struct rpc_transport_np_init_state);
+       NTSTATUS status;
+
+       status = cli_ntcreate_recv(subreq, &state->transport_np->fnum);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               async_req_error(req, status);
+               return;
+       }
+
+       talloc_set_destructor(state->transport_np,
+                             rpc_transport_np_state_destructor);
+       async_req_done(req);
+}
+
+NTSTATUS rpc_transport_np_init_recv(struct async_req *req,
+                                   TALLOC_CTX *mem_ctx,
+                                   struct rpc_cli_transport **presult)
+{
+       struct rpc_transport_np_init_state *state = talloc_get_type_abort(
+               req->private_data, struct rpc_transport_np_init_state);
+       NTSTATUS status;
 
-       fnum = cli_nt_create(cli, state->pipe_name, DESIRED_ACCESS_PIPE);
-       if (fnum == -1) {
-               DEBUG(3,("rpc_pipe_open_np: cli_nt_create failed on pipe %s "
-                        "to machine %s.  Error was %s\n", state->pipe_name,
-                        cli->desthost, cli_errstr(cli)));
-               TALLOC_FREE(result);
-               return cli_get_nt_error(cli);
+       if (async_req_is_error(req, &status)) {
+               return status;
        }
-       state->fnum = fnum;
-       talloc_set_destructor(state, rpc_transport_np_state_destructor);
 
-       result->write_send = rpc_np_write_send;
-       result->write_recv = rpc_np_write_recv;
-       result->read_send = rpc_np_read_send;
-       result->read_recv = rpc_np_read_recv;
-       result->trans_send = rpc_np_trans_send;
-       result->trans_recv = rpc_np_trans_recv;
+       state->transport->write_send = rpc_np_write_send;
+       state->transport->write_recv = rpc_np_write_recv;
+       state->transport->read_send = rpc_np_read_send;
+       state->transport->read_recv = rpc_np_read_recv;
+       state->transport->trans_send = rpc_np_trans_send;
+       state->transport->trans_recv = rpc_np_trans_recv;
 
-       *presult = result;
+       *presult = talloc_move(mem_ctx, &state->transport);
        return NT_STATUS_OK;
 }
 
+NTSTATUS rpc_transport_np_init(TALLOC_CTX *mem_ctx, struct cli_state *cli,
+                              const struct ndr_syntax_id *abstract_syntax,
+                              struct rpc_cli_transport **presult)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct event_context *ev;
+       struct async_req *req;
+       NTSTATUS status;
+
+       ev = event_context_init(frame);
+       if (ev == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto fail;
+       }
+
+       req = rpc_transport_np_init_send(frame, ev, cli, abstract_syntax);
+       if (req == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto fail;
+       }
+
+       while (req->state < ASYNC_REQ_DONE) {
+               event_loop_once(ev);
+       }
+
+       status = rpc_transport_np_init_recv(req, mem_ctx, presult);
+ fail:
+       TALLOC_FREE(frame);
+       return status;
+}
+
 struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
 {
        struct rpc_transport_np_state *state = talloc_get_type(