Convert cli_open to tevent_req
authorVolker Lendecke <vl@samba.org>
Sun, 5 Apr 2009 21:17:55 +0000 (23:17 +0200)
committerVolker Lendecke <vl@samba.org>
Mon, 6 Apr 2009 19:32:07 +0000 (21:32 +0200)
source3/include/proto.h
source3/libsmb/clifile.c

index 557e5f2c71f6813a8e3cb0af2b769a2c9052f566..514ee68e7ad501497296150aeedd95cfac8584bd 100644 (file)
@@ -2513,10 +2513,15 @@ NTSTATUS cli_ntcreate(struct cli_state *cli,
 int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess);
 uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2, const char *str,
                            size_t str_len, size_t *pconverted_size);
-struct async_req *cli_open_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
-                               struct cli_state *cli,
-                               const char *fname, int flags, int share_mode);
-NTSTATUS cli_open_recv(struct async_req *req, int *fnum);
+struct tevent_req *cli_open_create(TALLOC_CTX *mem_ctx,
+                                  struct event_context *ev,
+                                  struct cli_state *cli, const char *fname,
+                                  int flags, int share_mode,
+                                  struct tevent_req **psmbreq);
+struct tevent_req *cli_open_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+                                struct cli_state *cli, const char *fname,
+                                int flags, int share_mode);
+NTSTATUS cli_open_recv(struct tevent_req *req, int *fnum);
 int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode);
 struct tevent_req *cli_close_create(TALLOC_CTX *mem_ctx,
                                    struct event_context *ev,
index c492f2b01f2b557b2d8dadf6e860b0cdf4e56117..42938282145edf25abbcf25125ce7d63ce2c0ab7 100644 (file)
@@ -998,17 +998,33 @@ uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2,
  WARNING: if you open with O_WRONLY then getattrE won't work!
 ****************************************************************************/
 
-struct async_req *cli_open_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
-                               struct cli_state *cli,
-                               const char *fname, int flags, int share_mode)
+struct cli_open_state {
+       uint16_t vwv[15];
+       int fnum;
+       struct iovec bytes;
+};
+
+static void cli_open_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_open_create(TALLOC_CTX *mem_ctx,
+                                  struct event_context *ev,
+                                  struct cli_state *cli, const char *fname,
+                                  int flags, int share_mode,
+                                  struct tevent_req **psmbreq)
 {
-       unsigned openfn = 0;
-       unsigned accessmode = 0;
-       uint8_t additional_flags = 0;
+       struct tevent_req *req, *subreq;
+       struct cli_open_state *state;
+       unsigned openfn;
+       unsigned accessmode;
+       uint8_t additional_flags;
        uint8_t *bytes;
-       uint16_t vwv[15];
-       struct async_req *result;
 
+       req = tevent_req_create(mem_ctx, &state, struct cli_open_state);
+       if (req == NULL) {
+               return NULL;
+       }
+
+       openfn = 0;
        if (flags & O_CREAT) {
                openfn |= (1<<4);
        }
@@ -1037,63 +1053,96 @@ struct async_req *cli_open_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
                accessmode = 0xFF;
        }
 
-       SCVAL(vwv + 0, 0, 0xFF);
-       SCVAL(vwv + 0, 1, 0);
-       SSVAL(vwv + 1, 0, 0);
-       SSVAL(vwv + 2, 0, 0);  /* no additional info */
-       SSVAL(vwv + 3, 0, accessmode);
-       SSVAL(vwv + 4, 0, aSYSTEM | aHIDDEN);
-       SSVAL(vwv + 5, 0, 0);
-       SIVAL(vwv + 6, 0, 0);
-       SSVAL(vwv + 8, 0, openfn);
-       SIVAL(vwv + 9, 0, 0);
-       SIVAL(vwv + 11, 0, 0);
-       SIVAL(vwv + 13, 0, 0);
+       SCVAL(state->vwv + 0, 0, 0xFF);
+       SCVAL(state->vwv + 0, 1, 0);
+       SSVAL(state->vwv + 1, 0, 0);
+       SSVAL(state->vwv + 2, 0, 0);  /* no additional info */
+       SSVAL(state->vwv + 3, 0, accessmode);
+       SSVAL(state->vwv + 4, 0, aSYSTEM | aHIDDEN);
+       SSVAL(state->vwv + 5, 0, 0);
+       SIVAL(state->vwv + 6, 0, 0);
+       SSVAL(state->vwv + 8, 0, openfn);
+       SIVAL(state->vwv + 9, 0, 0);
+       SIVAL(state->vwv + 11, 0, 0);
+       SIVAL(state->vwv + 13, 0, 0);
+
+       additional_flags = 0;
 
        if (cli->use_oplocks) {
                /* if using oplocks then ask for a batch oplock via
                    core and extended methods */
                additional_flags =
                        FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK;
-               SSVAL(vwv+2, 0, SVAL(vwv+2, 0) | 6);
+               SSVAL(state->vwv+2, 0, SVAL(state->vwv+2, 0) | 6);
        }
 
-       bytes = talloc_array(talloc_tos(), uint8_t, 0);
+       bytes = talloc_array(state, uint8_t, 0);
        bytes = smb_bytes_push_str(bytes, cli_ucs2(cli), fname,
                                   strlen(fname)+1, NULL);
-       if (bytes == NULL) {
+
+       if (tevent_req_nomem(bytes, req)) {
+               return tevent_req_post(req, ev);
+       }
+
+       state->bytes.iov_base = bytes;
+       state->bytes.iov_len = talloc_get_size(bytes);
+
+       subreq = cli_smb_req_create(state, ev, cli, SMBopenX, additional_flags,
+                                   15, state->vwv, 1, &state->bytes);
+       if (subreq == NULL) {
+               TALLOC_FREE(req);
                return NULL;
        }
+       tevent_req_set_callback(subreq, cli_open_done, req);
+       *psmbreq = subreq;
+       return req;
+}
 
-       result = cli_request_send(mem_ctx, ev, cli, SMBopenX, additional_flags,
-                                 15, vwv, 0, talloc_get_size(bytes), bytes);
-       TALLOC_FREE(bytes);
-       return result;
+struct tevent_req *cli_open_send(TALLOC_CTX *mem_ctx, struct event_context *ev,
+                                struct cli_state *cli, const char *fname,
+                                int flags, int share_mode)
+{
+       struct tevent_req *req, *subreq;
+
+       req = cli_open_create(mem_ctx, ev, cli, fname, flags, share_mode,
+                             &subreq);
+       if ((req == NULL) || !cli_smb_req_send(subreq)) {
+               TALLOC_FREE(req);
+               return NULL;
+       }
+       return req;
 }
 
-NTSTATUS cli_open_recv(struct async_req *req, int *fnum)
+static void cli_open_done(struct tevent_req *subreq)
 {
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct cli_open_state *state = tevent_req_data(
+               req, struct cli_open_state);
        uint8_t wct;
        uint16_t *vwv;
-       uint16_t num_bytes;
-       uint8_t *bytes;
        NTSTATUS status;
 
-       if (async_req_is_nterror(req, &status)) {
-               return status;
-       }
-
-       status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes);
+       status = cli_smb_recv(subreq, 3, &wct, &vwv, NULL, NULL);
        if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       if (wct < 3) {
-               return NT_STATUS_INVALID_NETWORK_RESPONSE;
+               TALLOC_FREE(subreq);
+               tevent_req_nterror(req, status);
+               return;
        }
+       state->fnum = SVAL(vwv+2, 0);
+       tevent_req_done(req);
+}
 
-       *fnum = SVAL(vwv+2, 0);
+NTSTATUS cli_open_recv(struct tevent_req *req, int *fnum)
+{
+       struct cli_open_state *state = tevent_req_data(
+               req, struct cli_open_state);
+       NTSTATUS status;
 
+       if (tevent_req_is_nterror(req, &status)) {
+               return status;
+       }
+       *fnum = state->fnum;
        return NT_STATUS_OK;
 }
 
@@ -1102,34 +1151,41 @@ int cli_open(struct cli_state *cli, const char *fname, int flags,
 {
        TALLOC_CTX *frame = talloc_stackframe();
        struct event_context *ev;
-       struct async_req *req;
+       struct tevent_req *req;
+       NTSTATUS status = NT_STATUS_OK;
        int result = -1;
 
-       if (cli->fd_event != NULL) {
+       if (cli_has_async_calls(cli)) {
                /*
                 * Can't use sync call while an async call is in flight
                 */
-               cli_set_error(cli, NT_STATUS_INVALID_PARAMETER);
+               status = NT_STATUS_INVALID_PARAMETER;
                goto fail;
        }
 
        ev = event_context_init(frame);
        if (ev == NULL) {
+               status = NT_STATUS_NO_MEMORY;
                goto fail;
        }
 
        req = cli_open_send(frame, ev, cli, fname, flags, share_mode);
        if (req == NULL) {
+               status = NT_STATUS_NO_MEMORY;
                goto fail;
        }
 
-       while (req->state < ASYNC_REQ_DONE) {
-               event_loop_once(ev);
+       if (!tevent_req_poll(req, ev)) {
+               status = map_nt_error_from_unix(errno);
+               goto fail;
        }
 
        cli_open_recv(req, &result);
  fail:
        TALLOC_FREE(frame);
+       if (!NT_STATUS_IS_OK(status)) {
+               cli_set_error(cli, status);
+       }
        return result;
 }