The branch, master has been updated
       via  d7c8fb2... s3: async cli_list
       via  77761d9... s3: Add cli_flush
      from  71dfa62... s3-ads: cleanup ads_keytab_list()

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit d7c8fb21bb0a29bb7227d4b242aba2f1524f6c48
Author: Volker Lendecke <v...@samba.org>
Date:   Tue Aug 10 07:44:15 2010 +0200

    s3: async cli_list

commit 77761d9adcf34a9d1cd4567422c98efac101b3f6
Author: Volker Lendecke <v...@samba.org>
Date:   Fri Aug 13 14:01:03 2010 +0200

    s3: Add cli_flush

-----------------------------------------------------------------------

Summary of changes:
 source3/include/proto.h    |   31 +-
 source3/libsmb/clifile.c   |  103 +++++
 source3/libsmb/clilist.c   | 1043 +++++++++++++++++++++++++++-----------------
 source3/torture/masktest.c |   47 ++-
 source3/torture/torture.c  |    9 +-
 5 files changed, 811 insertions(+), 422 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index 5c664eb..4f63a77 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -2070,6 +2070,8 @@ NTSTATUS cli_ntcreate(struct cli_state *cli,
                      uint16_t *pfid);
 uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2, const char *str,
                            size_t str_len, size_t *pconverted_size);
+uint8_t *smb_bytes_push_bytes(uint8_t *buf, uint8_t prefix,
+                             const uint8_t *bytes, size_t num_bytes);
 struct tevent_req *cli_open_create(TALLOC_CTX *mem_ctx,
                                   struct event_context *ev,
                                   struct cli_state *cli, const char *fname,
@@ -2334,12 +2336,22 @@ bool unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB 
*auth_data, DATA_BLOB *unwrapped_
 
 /* The following definitions come from libsmb/clilist.c  */
 
-int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
-                void (*fn)(const char *, struct file_info *, const char *,
-                           void *), void *state);
-int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
-                void (*fn)(const char *, struct file_info *, const char *,
-                           void *), void *state);
+NTSTATUS cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute,
+                     void (*fn)(const char *, struct file_info *,
+                                const char *, void *), void *state);
+NTSTATUS cli_list_trans(struct cli_state *cli, const char *mask,
+                       uint16_t attribute, int info_level,
+                       void (*fn)(const char *mnt, struct file_info *finfo,
+                                  const char *mask, void *private_data),
+                       void *private_data);
+struct tevent_req *cli_list_send(TALLOC_CTX *mem_ctx,
+                                struct tevent_context *ev,
+                                struct cli_state *cli,
+                                const char *mask,
+                                uint16_t attribute,
+                                uint16_t info_level);
+NTSTATUS cli_list_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+                      struct file_info **finfo, size_t *num_finfo);
 NTSTATUS cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
                  void (*fn)(const char *, struct file_info *, const char *,
                             void *), void *state);
@@ -2483,6 +2495,13 @@ NTSTATUS cli_qpathinfo(TALLOC_CTX *mem_ctx, struct 
cli_state *cli,
                       uint32_t max_rdata,
                       uint8_t **rdata, uint32_t *num_rdata);
 
+struct tevent_req *cli_flush_send(TALLOC_CTX *mem_ctx,
+                                 struct event_context *ev,
+                                 struct cli_state *cli,
+                                 uint16_t fnum);
+NTSTATUS cli_flush_recv(struct tevent_req *req);
+NTSTATUS cli_flush(TALLOC_CTX *mem_ctx, struct cli_state *cli, uint16_t fnum);
+
 /* The following definitions come from libsmb/clirap2.c  */
 struct rap_group_info_1;
 struct rap_user_info_1;
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 48af0cc..d6b2e31 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -91,6 +91,26 @@ uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2,
                        true, pconverted_size);
 }
 
+uint8_t *smb_bytes_push_bytes(uint8_t *buf, uint8_t prefix,
+                             const uint8_t *bytes, size_t num_bytes)
+{
+       size_t buflen;
+
+       if (buf == NULL) {
+               return NULL;
+       }
+       buflen = talloc_get_size(buf);
+
+       buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t,
+                                  buflen + 1 + num_bytes);
+       if (buf == NULL) {
+               return NULL;
+       }
+       buf[buflen] = prefix;
+       memcpy(&buf[buflen+1], bytes, num_bytes);
+       return buf;
+}
+
 /***********************************************************
  Same as smb_bytes_push_str(), but without the odd byte
  align for ucs2 (we're pushing into a param or data block).
@@ -5243,3 +5263,86 @@ NTSTATUS cli_qpathinfo(TALLOC_CTX *mem_ctx, struct 
cli_state *cli,
        }
        return status;
 }
+
+struct cli_flush_state {
+       uint16_t vwv[1];
+};
+
+static void cli_flush_done(struct tevent_req *subreq);
+
+struct tevent_req *cli_flush_send(TALLOC_CTX *mem_ctx,
+                                 struct event_context *ev,
+                                 struct cli_state *cli,
+                                 uint16_t fnum)
+{
+       struct tevent_req *req, *subreq;
+       struct cli_flush_state *state;
+
+       req = tevent_req_create(mem_ctx, &state, struct cli_flush_state);
+       if (req == NULL) {
+               return NULL;
+       }
+       SSVAL(state->vwv + 0, 0, fnum);
+
+       subreq = cli_smb_send(state, ev, cli, SMBflush, 0, 1, state->vwv,
+                             0, NULL);
+       if (tevent_req_nomem(subreq, req)) {
+               return tevent_req_post(req, ev);
+       }
+       tevent_req_set_callback(subreq, cli_flush_done, req);
+       return req;
+}
+
+static void cli_flush_done(struct tevent_req *subreq)
+{
+       struct tevent_req *req = tevent_req_callback_data(
+               subreq, struct tevent_req);
+       NTSTATUS status;
+
+       status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL);
+       TALLOC_FREE(subreq);
+       if (!NT_STATUS_IS_OK(status)) {
+               tevent_req_nterror(req, status);
+               return;
+       }
+       tevent_req_done(req);
+}
+
+NTSTATUS cli_flush_recv(struct tevent_req *req)
+{
+       return tevent_req_simple_recv_ntstatus(req);
+}
+
+NTSTATUS cli_flush(TALLOC_CTX *mem_ctx, struct cli_state *cli, uint16_t fnum)
+{
+       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_flush_send(frame, ev, cli, fnum);
+       if (req == NULL) {
+               goto fail;
+       }
+       if (!tevent_req_poll_ntstatus(req, ev, &status)) {
+               goto fail;
+       }
+       status = cli_flush_recv(req);
+ fail:
+       TALLOC_FREE(frame);
+       if (!NT_STATUS_IS_OK(status)) {
+               cli_set_error(cli, status);
+       }
+       return status;
+}
diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c
index 1a8b79b..29b16cb 100644
--- a/source3/libsmb/clilist.c
+++ b/source3/libsmb/clilist.c
@@ -227,289 +227,6 @@ static size_t interpret_long_filename(TALLOC_CTX *ctx,
 }
 
 /****************************************************************************
- Do a directory listing, calling fn on each file found.
-****************************************************************************/
-
-int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
-                void (*fn)(const char *, struct file_info *, const char *,
-                           void *), void *state)
-{
-#if 1
-       int max_matches = 1366; /* Match W2k - was 512. */
-#else
-       int max_matches = 512;
-#endif
-       int info_level;
-       char *p, *p2, *rdata_end;
-       char *mask = NULL;
-       struct file_info finfo;
-       int i;
-       char *dirlist = NULL;
-       int dirlist_len = 0;
-       int total_received = -1;
-       bool First = True;
-       int ff_searchcount=0;
-       int ff_eos=0;
-       int ff_dir_handle=0;
-       int loop_count = 0;
-       char *rparam=NULL, *rdata=NULL;
-       unsigned int param_len, data_len;
-       uint16 setup;
-       char *param;
-       uint32 resume_key = 0;
-       TALLOC_CTX *frame = talloc_stackframe();
-       DATA_BLOB last_name_raw = data_blob_null;
-
-       /* NT uses SMB_FIND_FILE_BOTH_DIRECTORY_INFO,
-          OS/2 uses SMB_FIND_EA_SIZE. Both accept SMB_FIND_INFO_STANDARD. */
-       info_level = (cli->capabilities&CAP_NT_SMBS)?
-               SMB_FIND_FILE_BOTH_DIRECTORY_INFO : SMB_FIND_INFO_STANDARD;
-
-       mask = SMB_STRDUP(Mask);
-       if (!mask) {
-               TALLOC_FREE(frame);
-               return -1;
-       }
-
-       ZERO_STRUCT(finfo);
-
-       while (ff_eos == 0) {
-               size_t nlen = 2*(strlen(mask)+1);
-
-               loop_count++;
-               if (loop_count > 200) {
-                       DEBUG(0,("Error: Looping in FIND_NEXT??\n"));
-                       break;
-               }
-
-               param = SMB_MALLOC_ARRAY(char, 12+nlen+last_name_raw.length+2);
-               if (!param) {
-                       break;
-               }
-
-               if (First) {
-                       setup = TRANSACT2_FINDFIRST;
-                       SSVAL(param,0,attribute); /* attribute */
-                       SSVAL(param,2,max_matches); /* max count */
-                       
SSVAL(param,4,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); 
/* resume required + close on end */
-                       SSVAL(param,6,info_level);
-                       SIVAL(param,8,0);
-                       p = param+12;
-                       p += clistr_push(cli, param+12, mask,
-                                        nlen, STR_TERMINATE);
-               } else {
-                       setup = TRANSACT2_FINDNEXT;
-                       SSVAL(param,0,ff_dir_handle);
-                       SSVAL(param,2,max_matches); /* max count */
-                       SSVAL(param,4,info_level);
-                       /* For W2K servers serving out FAT filesystems we 
*must* set the
-                          resume key. If it's not FAT then it's returned as 
zero. */
-                       SIVAL(param,6,resume_key); /* ff_resume_key */
-                       /* NB. *DON'T* use continue here. If you do it seems 
that W2K and bretheren
-                          can miss filenames. Use last filename continue 
instead. JRA */
-                       
SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END));
        /* resume required + close on end */
-                       p = param+12;
-                       if (last_name_raw.length) {
-                               memcpy(p, last_name_raw.data, 
last_name_raw.length);
-                               p += last_name_raw.length;
-                       } else {
-                               p += clistr_push(cli, param+12, mask,
-                                               nlen, STR_TERMINATE);
-                       }
-               }
-
-               param_len = PTR_DIFF(p, param);
-
-               if (!cli_send_trans(cli, SMBtrans2,
-                                   NULL,                   /* Name */
-                                   -1, 0,                  /* fid, flags */
-                                   &setup, 1, 0,           /* setup, length, 
max */
-                                   param, param_len, 10,   /* param, length, 
max */
-                                   NULL, 0,
-#if 0
-                                   /* w2k value. */
-                                   MIN(16384,cli->max_xmit) /* data, length, 
max. */
-#else
-                                   cli->max_xmit           /* data, length, 
max. */
-#endif
-                                   )) {
-                       SAFE_FREE(param);
-                       TALLOC_FREE(frame);
-                       break;
-               }
-
-               SAFE_FREE(param);
-
-               if (!cli_receive_trans(cli, SMBtrans2,
-                                      &rparam, &param_len,
-                                      &rdata, &data_len) &&
-                    cli_is_dos_error(cli)) {
-                       /* We need to work around a Win95 bug - sometimes
-                          it gives ERRSRV/ERRerror temprarily */
-                       uint8 eclass;
-                       uint32 ecode;
-
-                       SAFE_FREE(rdata);
-                       SAFE_FREE(rparam);
-
-                       cli_dos_error(cli, &eclass, &ecode);
-
-                       /*
-                        * OS/2 might return "no more files",
-                        * which just tells us, that searchcount is zero
-                        * in this search.
-                        * Guenter Kukkukk <li...@kukkukk.com>
-                        */
-
-                       if (eclass == ERRDOS && ecode == ERRnofiles) {
-                               ff_searchcount = 0;
-                               cli_reset_error(cli);
-                               break;
-                       }
-
-                       if (eclass != ERRSRV || ecode != ERRerror)
-                               break;
-                       smb_msleep(100);
-                       continue;
-               }
-
-                if (cli_is_error(cli) || !rdata || !rparam) {
-                       SAFE_FREE(rdata);
-                       SAFE_FREE(rparam);
-                       break;
-               }
-
-               if (total_received == -1)
-                       total_received = 0;
-
-               /* parse out some important return info */
-               p = rparam;
-               if (First) {
-                       ff_dir_handle = SVAL(p,0);
-                       ff_searchcount = SVAL(p,2);
-                       ff_eos = SVAL(p,4);
-               } else {
-                       ff_searchcount = SVAL(p,0);
-                       ff_eos = SVAL(p,2);
-               }
-
-               if (ff_searchcount == 0) {
-                       SAFE_FREE(rdata);
-                       SAFE_FREE(rparam);
-                       break;
-               }
-
-               /* point to the data bytes */
-               p = rdata;
-               rdata_end = rdata + data_len;
-
-               /* we might need the lastname for continuations */
-               for (p2=p,i=0;i<ff_searchcount && p2 < rdata_end;i++) {
-                       if ((info_level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) &&
-                                       (i == ff_searchcount-1)) {
-                               /* Last entry - fixup the last offset length. */
-                               SIVAL(p2,0,PTR_DIFF((rdata + data_len),p2));
-                       }
-                       p2 += interpret_long_filename(frame,
-                                                       cli,
-                                                       info_level,
-                                                       cli->inbuf,
-                                                       SVAL(cli->inbuf, 
smb_flg2),
-                                                       p2,
-                                                       rdata_end,
-                                                       &finfo,
-                                                       &resume_key,
-                                                       &last_name_raw);
-
-                       if (!finfo.name) {
-                               DEBUG(0,("cli_list_new: Error: unable to parse 
name from info level %d\n",
-                                       info_level));
-                               ff_eos = 1;
-                               break;
-                       }
-                       if (!First && *mask && strcsequal(finfo.name, mask)) {
-                               DEBUG(0,("Error: Looping in FIND_NEXT as name 
%s has already been seen?\n",
-                                       finfo.name));
-                               ff_eos = 1;
-                               break;
-                       }
-               }
-
-               SAFE_FREE(mask);
-               if (ff_searchcount > 0 && ff_eos == 0 && finfo.name) {
-                       mask = SMB_STRDUP(finfo.name);
-               } else {
-                       mask = SMB_STRDUP("");
-               }
-               if (!mask) {
-                       SAFE_FREE(rdata);
-                       SAFE_FREE(rparam);
-                       break;
-               }
-
-               /* grab the data for later use */
-               /* and add them to the dirlist pool */
-               dirlist = (char *)SMB_REALLOC(dirlist,dirlist_len + data_len);
-
-               if (!dirlist) {
-                       DEBUG(0,("cli_list_new: Failed to expand dirlist\n"));
-                       SAFE_FREE(rdata);
-                       SAFE_FREE(rparam);
-                       break;
-               }
-
-               memcpy(dirlist+dirlist_len,p,data_len);
-               dirlist_len += data_len;
-
-               total_received += ff_searchcount;
-
-               SAFE_FREE(rdata);
-               SAFE_FREE(rparam);
-
-               DEBUG(3,("received %d entries (eos=%d)\n",
-                        ff_searchcount,ff_eos));
-
-               if (ff_searchcount > 0)
-                       loop_count = 0;
-
-               First = False;
-       }
-
-        /* see if the server disconnected or the connection otherwise failed */
-        if (cli_is_error(cli)) {
-                total_received = -1;
-        } else {
-                /* no connection problem.  let user function add each entry */
-               rdata_end = dirlist + dirlist_len;
-                for (p=dirlist,i=0;i<total_received;i++) {
-                        p += interpret_long_filename(frame,
-                                                       cli,
-                                                       info_level,
-                                                       cli->inbuf,
-                                                       SVAL(cli->inbuf, 
smb_flg2),
-                                                       p,
-                                                       rdata_end,
-                                                       &finfo,
-                                                       NULL,
-                                                       NULL);
-                       if (!finfo.name) {
-                               DEBUG(0,("cli_list_new: unable to parse name 
from info level %d\n",
-                                       info_level));
-                               break;
-                       }
-                        fn(cli->dfs_mountpoint, &finfo, Mask, state);
-                }
-        }
-
-       /* free up the dirlist buffer and last name raw blob */
-       SAFE_FREE(dirlist);
-       data_blob_free(&last_name_raw);
-       SAFE_FREE(mask);
-       TALLOC_FREE(frame);
-       return(total_received);
-}
-
-/****************************************************************************
  Interpret a short filename structure.
  The length of the structure is returned.
 ****************************************************************************/
@@ -549,163 +266,697 @@ static bool interpret_short_filename(TALLOC_CTX *ctx,
        return true;
 }
 
-/****************************************************************************
- Do a directory listing, calling fn on each file found.
- this uses the old SMBsearch interface. It is needed for testing Samba,
- but should otherwise not be used.
-****************************************************************************/
+struct cli_list_old_state {
+       struct tevent_context *ev;
+       struct cli_state *cli;
+       uint16_t vwv[2];
+       char *mask;
+       int num_asked;
+       uint16_t attribute;
+       uint8_t search_status[23];
+       bool first;
+       bool done;
+       uint8_t *dirlist;
+};
+
+static void cli_list_old_done(struct tevent_req *subreq);
+
+static struct tevent_req *cli_list_old_send(TALLOC_CTX *mem_ctx,
+                                           struct tevent_context *ev,
+                                           struct cli_state *cli,
+                                           const char *mask,
+                                           uint16_t attribute)
+{
+       struct tevent_req *req, *subreq;
+       struct cli_list_old_state *state;


-- 
Samba Shared Repository

Reply via email to