s3: Convert cli_qpathinfo_basic to cli_qpathinfo_send
authorVolker Lendecke <vl@samba.org>
Mon, 26 Jul 2010 07:41:25 +0000 (09:41 +0200)
committerVolker Lendecke <vl@samba.org>
Mon, 26 Jul 2010 21:01:37 +0000 (23:01 +0200)
source3/include/proto.h
source3/libsmb/clirap.c

index c802b699510972b1856c3e1c700bf3dddffe86f7..03b2277fd5eeb3a20ec709f06747792c467f98dc 100644 (file)
@@ -2695,6 +2695,12 @@ bool cli_qfileinfo(struct cli_state *cli, uint16_t fnum,
                    struct timespec *write_time,
                   struct timespec *change_time,
                    SMB_INO_T *ino);
+struct tevent_req *cli_qpathinfo_basic_send(TALLOC_CTX *mem_ctx,
+                                           struct event_context *ev,
+                                           struct cli_state *cli,
+                                           const char *fname);
+NTSTATUS cli_qpathinfo_basic_recv(struct tevent_req *req,
+                                 SMB_STRUCT_STAT *sbuf, uint32 *attributes);
 NTSTATUS cli_qpathinfo_basic(struct cli_state *cli, const char *name,
                             SMB_STRUCT_STAT *sbuf, uint32 *attributes);
 bool cli_qfileinfo_test(struct cli_state *cli, uint16_t fnum, int level, char **poutdata, uint32 *poutlen);
index baa2dcd8e240328202dec46b6b395b8e15e956ef..b1303f68d5e4a11d274e00e6ecc8909d2a3252ec 100644 (file)
@@ -1144,68 +1144,105 @@ bool cli_qfileinfo(struct cli_state *cli, uint16_t fnum,
  Send a qpathinfo BASIC_INFO call.
 ****************************************************************************/
 
-NTSTATUS cli_qpathinfo_basic(struct cli_state *cli, const char *name,
-                            SMB_STRUCT_STAT *sbuf, uint32 *attributes)
+struct cli_qpathinfo_basic_state {
+       uint32_t num_data;
+       uint8_t *data;
+};
+
+static void cli_qpathinfo_basic_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_qpathinfo_basic_send(TALLOC_CTX *mem_ctx,
+                                           struct event_context *ev,
+                                           struct cli_state *cli,
+                                           const char *fname)
 {
-       unsigned int param_len = 0;
-       uint32_t rdata_len;
-       uint16_t setup[1];
-       uint8_t *param, *rdata;
-       uint8_t *p;
-       char *path;
-       int len;
-       size_t nlen;
-       TALLOC_CTX *frame = talloc_stackframe();
-       NTSTATUS status;
+       struct tevent_req *req = NULL, *subreq = NULL;
+       struct cli_qpathinfo_basic_state *state = NULL;
 
-       path = talloc_strdup(frame, name);
-       if (!path) {
-               TALLOC_FREE(frame);
-               return NT_STATUS_NO_MEMORY;
+       req = tevent_req_create(mem_ctx, &state,
+                               struct cli_qpathinfo_basic_state);
+       if (req == NULL) {
+               return NULL;
        }
-       /* cleanup */
-
-       len = strlen(path);
-       if ( path[len-1] == '\\' || path[len-1] == '/') {
-               path[len-1] = '\0';
+       subreq = cli_qpathinfo_send(state, ev, cli, fname,
+                                   SMB_QUERY_FILE_BASIC_INFO,
+                                   36, cli->max_xmit);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
        }
-       nlen = 2*(strlen(path)+1);
+       tevent_req_set_callback(subreq, cli_qpathinfo_basic_done, req);
+       return req;
+}
 
-       param = TALLOC_ARRAY(frame, uint8_t, 6+nlen+2);
-       if (!param) {
-               TALLOC_FREE(frame);
-               return NT_STATUS_NO_MEMORY;
+static void cli_qpathinfo_basic_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct cli_qpathinfo_basic_state *state = tevent_req_data(
+               req, struct cli_qpathinfo_basic_state);
+       NTSTATUS status;
+
+       status = cli_qpathinfo_recv(subreq, state, &state->data,
+                                   &state->num_data);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               tevent_req_nterror(req, status);
+               return;
        }
-       p = param;
-       memset(param, '\0', 6);
+       tevent_req_done(req);
+}
 
-       SSVAL(setup, 0, TRANSACT2_QPATHINFO);
-       SSVAL(p, 0, SMB_QUERY_FILE_BASIC_INFO);
-       p += 6;
-       p += clistr_push(cli, p, path, nlen, STR_TERMINATE);
-       param_len = PTR_DIFF(p, param);
+NTSTATUS cli_qpathinfo_basic_recv(struct tevent_req *req,
+                                 SMB_STRUCT_STAT *sbuf, uint32 *attributes)
+{
+       struct cli_qpathinfo_basic_state *state = tevent_req_data(
+               req, struct cli_qpathinfo_basic_state);
+       NTSTATUS status;
 
-       status = cli_trans(talloc_tos(), cli, SMBtrans2, NULL, -1, 0, 0,
-                          setup, 1, 0,
-                          param, param_len, 2,
-                          NULL, 0, cli->max_xmit,
-                          NULL, 0, NULL,
-                          NULL, 0, NULL,
-                          &rdata, 36, &rdata_len);
-       if (!NT_STATUS_IS_OK(status)) {
-               TALLOC_FREE(frame);
+       if (tevent_req_is_nterror(req, &status)) {
                return status;
        }
 
-       sbuf->st_ex_atime = interpret_long_date((char *)rdata+8);
-       sbuf->st_ex_mtime = interpret_long_date((char *)rdata+16);
-       sbuf->st_ex_ctime = interpret_long_date((char *)rdata+24);
-
-       *attributes = IVAL( rdata, 32 );
+       sbuf->st_ex_atime = interpret_long_date((char *)state->data+8);
+       sbuf->st_ex_mtime = interpret_long_date((char *)state->data+16);
+       sbuf->st_ex_ctime = interpret_long_date((char *)state->data+24);
+       *attributes = IVAL(state->data, 32);
+       return NT_STATUS_OK;
+}
 
-       TALLOC_FREE(rdata);
+NTSTATUS cli_qpathinfo_basic(struct cli_state *cli, const char *name,
+                            SMB_STRUCT_STAT *sbuf, uint32 *attributes)
+{
+       TALLOC_CTX *frame = talloc_stackframe();
+       struct event_context *ev;
+       struct tevent_req *req;
+       NTSTATUS status = NT_STATUS_NO_MEMORY;
 
-       return NT_STATUS_OK;
+       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_qpathinfo_basic_send(frame, ev, cli, name);
+       if (req == NULL) {
+               goto fail;
+       }
+       if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+               goto fail;
+       }
+       status = cli_qpathinfo_basic_recv(req, sbuf, attributes);
+ fail:
+       TALLOC_FREE(frame);
+       if (!NT_STATUS_IS_OK(status)) {
+               cli_set_error(cli, status);
+       }
+       return status;
 }
 
 /****************************************************************************