s3: Convert cli_qpathinfo_streams to cli_qpathinfo_send
authorVolker Lendecke <vl@samba.org>
Mon, 26 Jul 2010 08:35:15 +0000 (10:35 +0200)
committerVolker Lendecke <vl@samba.org>
Mon, 26 Jul 2010 21:01:38 +0000 (23:01 +0200)
source3/client/client.c
source3/include/proto.h
source3/libsmb/clirap.c

index efe733e7f40220995ba5436e890166bfdc2066ee..cd41699da31b6923571253667259a96873388a9f 100644 (file)
@@ -1598,10 +1598,11 @@ static int do_allinfo(const char *name)
 
        d_printf("attributes: %s\n", attr_str(talloc_tos(), mode));
 
-       if (!cli_qpathinfo_streams(cli, name, talloc_tos(), &num_streams,
-                                  &streams)) {
-               d_printf("%s getting streams for %s\n",
-                        cli_errstr(cli),name);
+       status = cli_qpathinfo_streams(cli, name, talloc_tos(), &num_streams,
+                                      &streams);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_printf("%s getting streams for %s\n", nt_errstr(status),
+                        name);
                return false;
        }
 
index 03b2277fd5eeb3a20ec709f06747792c467f98dc..16110f2cdef176004871ab014bf54eb77176912f 100644 (file)
@@ -2683,10 +2683,18 @@ NTSTATUS cli_qpathinfo2(struct cli_state *cli, const char *fname,
                        struct timespec *change_time,
                        SMB_OFF_T *size, uint16 *mode,
                        SMB_INO_T *ino);
-bool cli_qpathinfo_streams(struct cli_state *cli, const char *fname,
-                          TALLOC_CTX *mem_ctx,
-                          unsigned int *pnum_streams,
-                          struct stream_struct **pstreams);
+struct tevent_req *cli_qpathinfo_streams_send(TALLOC_CTX *mem_ctx,
+                                             struct tevent_context *ev,
+                                             struct cli_state *cli,
+                                             const char *fname);
+NTSTATUS cli_qpathinfo_streams_recv(struct tevent_req *req,
+                                   TALLOC_CTX *mem_ctx,
+                                   unsigned int *pnum_streams,
+                                   struct stream_struct **pstreams);
+NTSTATUS cli_qpathinfo_streams(struct cli_state *cli, const char *fname,
+                              TALLOC_CTX *mem_ctx,
+                              unsigned int *pnum_streams,
+                              struct stream_struct **pstreams);
 bool cli_qfilename(struct cli_state *cli, uint16_t fnum, char *name, size_t namelen);
 bool cli_qfileinfo(struct cli_state *cli, uint16_t fnum,
                   uint16 *mode, SMB_OFF_T *size,
index f94c16d55f9f40cb321a71771301574adc5edb0a..56d637597355f442053cfbaf63a5627dc4e9b38f 100644 (file)
@@ -905,58 +905,109 @@ static bool parse_streams_blob(TALLOC_CTX *mem_ctx, const uint8_t *data,
                               unsigned int *pnum_streams,
                               struct stream_struct **pstreams);
 
-bool cli_qpathinfo_streams(struct cli_state *cli, const char *fname,
-                          TALLOC_CTX *mem_ctx,
-                          unsigned int *pnum_streams,
-                          struct stream_struct **pstreams)
+struct cli_qpathinfo_streams_state {
+       uint32_t num_data;
+       uint8_t *data;
+};
+
+static void cli_qpathinfo_streams_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_qpathinfo_streams_send(TALLOC_CTX *mem_ctx,
+                                             struct tevent_context *ev,
+                                             struct cli_state *cli,
+                                             const char *fname)
 {
-       unsigned int data_len = 0;
-       unsigned int param_len = 0;
-       uint16 setup = TRANSACT2_QPATHINFO;
-       char *param;
-       char *rparam=NULL, *rdata=NULL;
-       char *p;
-       size_t namelen = 2*(strlen(fname)+1);
-       bool ret;
+       struct tevent_req *req = NULL, *subreq = NULL;
+       struct cli_qpathinfo_streams_state *state = NULL;
 
-       param = SMB_MALLOC_ARRAY(char, 6+namelen+2);
-       if (param == NULL) {
-               return false;
+       req = tevent_req_create(mem_ctx, &state,
+                               struct cli_qpathinfo_streams_state);
+       if (req == NULL) {
+               return NULL;
        }
-       p = param;
-       memset(p, 0, 6);
-       SSVAL(p, 0, SMB_FILE_STREAM_INFORMATION);
-       p += 6;
-       p += clistr_push(cli, p, fname, namelen, STR_TERMINATE);
+       subreq = cli_qpathinfo_send(state, ev, cli, fname,
+                                   SMB_FILE_STREAM_INFORMATION,
+                                   0, cli->max_xmit);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, cli_qpathinfo_streams_done, req);
+       return req;
+}
 
-       param_len = PTR_DIFF(p, param);
+static void cli_qpathinfo_streams_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       struct cli_qpathinfo_streams_state *state = tevent_req_data(
+               req, struct cli_qpathinfo_streams_state);
+       NTSTATUS status;
 
-       if (!cli_send_trans(cli, SMBtrans2,
-                            NULL,                     /* name */
-                            -1, 0,                    /* fid, flags */
-                            &setup, 1, 0,             /* setup, len, max */
-                            param, param_len, 10,     /* param, len, max */
-                            NULL, data_len, cli->max_xmit /* data, len, max */
-                           )) {
-               return false;
+       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;
        }
+       tevent_req_done(req);
+}
 
-       if (!cli_receive_trans(cli, SMBtrans2,
-                               &rparam, &param_len,
-                               &rdata, &data_len)) {
-               return false;
-       }
+NTSTATUS cli_qpathinfo_streams_recv(struct tevent_req *req,
+                                   TALLOC_CTX *mem_ctx,
+                                   unsigned int *pnum_streams,
+                                   struct stream_struct **pstreams)
+{
+       struct cli_qpathinfo_streams_state *state = tevent_req_data(
+                req, struct cli_qpathinfo_streams_state);
+        NTSTATUS status;
 
-       if (!rdata) {
-               SAFE_FREE(rparam);
-               return false;
+       if (tevent_req_is_nterror(req, &status)) {
+               return status;
+       }
+       if (!parse_streams_blob(mem_ctx, state->data, state->num_data,
+                               pnum_streams, pstreams)) {
+               return NT_STATUS_INVALID_NETWORK_RESPONSE;
        }
+       return NT_STATUS_OK;
+}
 
-       ret = parse_streams_blob(mem_ctx, (uint8_t *)rdata, data_len,
-                                pnum_streams, pstreams);
-       SAFE_FREE(rdata);
-       SAFE_FREE(rparam);
-       return ret;
+NTSTATUS cli_qpathinfo_streams(struct cli_state *cli, const char *fname,
+                              TALLOC_CTX *mem_ctx,
+                              unsigned int *pnum_streams,
+                              struct stream_struct **pstreams)
+{
+       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_qpathinfo_streams_send(frame, ev, cli, fname);
+       if (req == NULL) {
+               goto fail;
+       }
+       if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+               goto fail;
+       }
+       status = cli_qpathinfo_streams_recv(req, mem_ctx, pnum_streams,
+                                           pstreams);
+ fail:
+       TALLOC_FREE(frame);
+       if (!NT_STATUS_IS_OK(status)) {
+               cli_set_error(cli, status);
+       }
+       return status;
 }
 
 static bool parse_streams_blob(TALLOC_CTX *mem_ctx, const uint8_t *rdata,