The branch, master has been updated
       via  c69b1ed s3: Properly print binary values "net cache"
       via  1a91fe9 s3: Add gencache_iterate_blobs
       via  62afdb9 s3: Convert gencache_get_data_blob to gencache_parse
       via  9843103 s3: Add gencache_parse
      from  ce55d7c Revert "s4:netcmd/drs.py - use "objectClass" for 
discovering the server and it's NTDS settings object"

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


- Log -----------------------------------------------------------------
commit c69b1edcb9a4b41055f82007d223ef18dc04a1d2
Author: Volker Lendecke <v...@samba.org>
Date:   Sun Nov 28 13:14:38 2010 +0100

    s3: Properly print binary values "net cache"
    
    Autobuild-User: Volker Lendecke <vlen...@samba.org>
    Autobuild-Date: Sun Nov 28 15:03:26 CET 2010 on sn-devel-104

commit 1a91fe90b6a1f50c641ce4d778f49ce4c121b9dd
Author: Volker Lendecke <v...@samba.org>
Date:   Sat Nov 27 15:48:21 2010 +0100

    s3: Add gencache_iterate_blobs

commit 62afdb9cc056da4ba7a873e6bce00b4f2c32f4a4
Author: Volker Lendecke <v...@samba.org>
Date:   Sat Nov 27 11:36:52 2010 +0100

    s3: Convert gencache_get_data_blob to gencache_parse

commit 9843103b7d2a13b1b8a45b3a1d958700bbf1bcfc
Author: Volker Lendecke <v...@samba.org>
Date:   Sat Nov 27 00:40:25 2010 +0100

    s3: Add gencache_parse

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

Summary of changes:
 source3/include/proto.h   |    7 +
 source3/lib/gencache.c    |  298 +++++++++++++++++++++++++++-----------------
 source3/utils/net_cache.c |   28 +++-
 3 files changed, 211 insertions(+), 122 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index d199d1e..9f00e6d 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -548,10 +548,17 @@ void pull_file_id_24(char *buf, struct file_id *id);
 bool gencache_set(const char *keystr, const char *value, time_t timeout);
 bool gencache_del(const char *keystr);
 bool gencache_get(const char *keystr, char **valstr, time_t *timeout);
+bool gencache_parse(const char *keystr,
+                   void (*parser)(time_t timeout, DATA_BLOB blob,
+                                  void *private_data),
+                   void *private_data);
 bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob,
                            time_t *timeout, bool *was_expired);
 bool gencache_stabilize(void);
 bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob, time_t 
timeout);
+void gencache_iterate_blobs(void (*fn)(const char *key, DATA_BLOB value,
+                                      time_t timeout, void *private_data),
+                           void *private_data, const char *pattern);
 void gencache_iterate(void (*fn)(const char* key, const char *value, time_t 
timeout, void* dptr),
                       void* data, const char* keystr_pattern);
 
diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c
index 8d2ddb2..db0b179 100644
--- a/source3/lib/gencache.c
+++ b/source3/lib/gencache.c
@@ -274,6 +274,10 @@ static bool gencache_pull_timeout(char *val, time_t *pres, 
char **pendptr)
        time_t res;
        char *endptr;
 
+       if (val == NULL) {
+               return false;
+       }
+
        res = strtol(val, &endptr, 10);
 
        if ((endptr == NULL) || (*endptr != '/')) {
@@ -289,69 +293,124 @@ static bool gencache_pull_timeout(char *val, time_t 
*pres, char **pendptr)
        return true;
 }
 
-/**
- * Get existing entry from the cache file.
- *
- * @param keystr string that represents a key of this entry
- * @param blob DATA_BLOB that is filled with entry's blob
- * @param timeout pointer to a time_t that is filled with entry's
- *        timeout
- *
- * @retval true when entry is successfuly fetched
- * @retval False for failure
- **/
+struct gencache_parse_state {
+       void (*parser)(time_t timeout, DATA_BLOB blob, void *private_data);
+       void *private_data;
+};
 
-bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob,
-                           time_t *timeout, bool *was_expired)
+static int gencache_parse_fn(TDB_DATA key, TDB_DATA data, void *private_data)
 {
-       TDB_DATA databuf;
+       struct gencache_parse_state *state;
+       DATA_BLOB blob;
        time_t t;
        char *endptr;
-       bool expired = false;
+       bool ret;
 
-       if (keystr == NULL) {
-               goto fail;
+       if (data.dptr == NULL) {
+               return -1;
+       }
+       ret = gencache_pull_timeout((char *)data.dptr, &t, &endptr);
+       if (!ret) {
+               return -1;
        }
+       state = (struct gencache_parse_state *)private_data;
+       blob = data_blob_const(
+               endptr+1, data.dsize - PTR_DIFF(endptr+1, data.dptr));
+       state->parser(t, blob, state->private_data);
+       return 0;
+}
+
+bool gencache_parse(const char *keystr,
+                   void (*parser)(time_t timeout, DATA_BLOB blob,
+                                  void *private_data),
+                   void *private_data)
+{
+       struct gencache_parse_state state;
+       TDB_DATA key;
+       int ret;
 
+       if (keystr == NULL) {
+               return false;
+       }
        if (tdb_data_cmp(string_term_tdb_data(keystr),
                         last_stabilize_key()) == 0) {
-               DEBUG(10, ("Can't get %s as a key\n", keystr));
-               goto fail;
+               return false;
        }
-
        if (!gencache_init()) {
-               goto fail;
+               return false;
        }
 
-       databuf = tdb_fetch_bystring(cache_notrans, keystr);
+       key = string_term_tdb_data(keystr);
+       state.parser = parser;
+       state.private_data = private_data;
 
-       if (databuf.dptr == NULL) {
-               databuf = tdb_fetch_bystring(cache, keystr);
+       ret = tdb_parse_record(cache_notrans, key, gencache_parse_fn, &state);
+       if (ret != -1) {
+               return true;
        }
+       ret = tdb_parse_record(cache, key, gencache_parse_fn, &state);
+       return (ret != -1);
+}
 
-       if (databuf.dptr == NULL) {
-               DEBUG(10, ("Cache entry with key = %s couldn't be found \n",
-                          keystr));
-               goto fail;
-       }
+struct gencache_get_data_blob_state {
+       DATA_BLOB *blob;
+       time_t timeout;
+       bool result;
+};
 
-       if (!gencache_pull_timeout((char *)databuf.dptr, &t, &endptr)) {
-               SAFE_FREE(databuf.dptr);
-               goto fail;
+static void gencache_get_data_blob_parser(time_t timeout, DATA_BLOB blob,
+                                         void *private_data)
+{
+       struct gencache_get_data_blob_state *state =
+               (struct gencache_get_data_blob_state *)private_data;
+
+       if (timeout == 0) {
+               state->result = false;
+               return;
        }
+       state->timeout = timeout;
 
-       DEBUG(10, ("Returning %s cache entry: key = %s, value = %s, "
-                  "timeout = %s", t > time(NULL) ? "valid" :
-                  "expired", keystr, endptr+1, ctime(&t)));
+       if (state->blob == NULL) {
+               state->result = true;
+               return;
+       }
 
-       if (t == 0) {
-               /* Deleted */
-               SAFE_FREE(databuf.dptr);
-               goto fail;
+       *state->blob = data_blob(blob.data, blob.length);
+       if (state->blob->data == NULL) {
+               state->result = false;
+               return;
        }
+       state->result = true;
+}
+
+/**
+ * Get existing entry from the cache file.
+ *
+ * @param keystr string that represents a key of this entry
+ * @param blob DATA_BLOB that is filled with entry's blob
+ * @param timeout pointer to a time_t that is filled with entry's
+ *        timeout
+ *
+ * @retval true when entry is successfuly fetched
+ * @retval False for failure
+ **/
+
+bool gencache_get_data_blob(const char *keystr, DATA_BLOB *blob,
+                           time_t *timeout, bool *was_expired)
+{
+       struct gencache_get_data_blob_state state;
+       bool expired = false;
 
-       if (t <= time(NULL)) {
+       state.result = false;
+       state.blob = blob;
 
+       if (!gencache_parse(keystr, gencache_get_data_blob_parser, &state)) {
+               goto fail;
+       }
+       if (!state.result) {
+               goto fail;
+       }
+       if (state.timeout <= time(NULL)) {
                /*
                 * We're expired, delete the entry. We can't use gencache_del
                 * here, because that uses gencache_get_data_blob for checking
@@ -359,28 +418,11 @@ bool gencache_get_data_blob(const char *keystr, DATA_BLOB 
*blob,
                 * directly store an empty value with 0 timeout.
                 */
                gencache_set(keystr, "", 0);
-
-               SAFE_FREE(databuf.dptr);
-
                expired = true;
                goto fail;
        }
-
-       if (blob != NULL) {
-               *blob = data_blob(
-                       endptr+1,
-                       databuf.dsize - PTR_DIFF(endptr+1, databuf.dptr));
-               if (blob->data == NULL) {
-                       SAFE_FREE(databuf.dptr);
-                       DEBUG(0, ("memdup failed\n"));
-                       goto fail;
-               }
-       }
-
-       SAFE_FREE(databuf.dptr);
-
        if (timeout) {
-               *timeout = t;
+               *timeout = state.timeout;
        }
 
        return True;
@@ -593,42 +635,27 @@ bool gencache_set(const char *keystr, const char *value, 
time_t timeout)
        return gencache_set_data_blob(keystr, &blob, timeout);
 }
 
-/**
- * Iterate through all entries which key matches to specified pattern
- *
- * @param fn pointer to the function that will be supplied with each single
- *        matching cache entry (key, value and timeout) as an arguments
- * @param data void pointer to an arbitrary data that is passed directly to 
the fn
- *        function on each call
- * @param keystr_pattern pattern the existing entries' keys are matched to
- *
- **/
-
-struct gencache_iterate_state {
-       void (*fn)(const char *key, const char *value, time_t timeout,
-                  void *priv);
+struct gencache_iterate_blobs_state {
+       void (*fn)(const char *key, DATA_BLOB value,
+                  time_t timeout, void *private_data);
        const char *pattern;
-       void *priv;
+       void *private_data;
        bool in_persistent;
 };
 
-static int gencache_iterate_fn(struct tdb_context *tdb, TDB_DATA key,
-                              TDB_DATA value, void *priv)
+static int gencache_iterate_blobs_fn(struct tdb_context *tdb, TDB_DATA key,
+                                    TDB_DATA data, void *priv)
 {
-       struct gencache_iterate_state *state =
-               (struct gencache_iterate_state *)priv;
+       struct gencache_iterate_blobs_state *state =
+               (struct gencache_iterate_blobs_state *)priv;
        char *keystr;
        char *free_key = NULL;
-       char *valstr;
-       char *free_val = NULL;
-       unsigned long u;
        time_t timeout;
-       char *timeout_endp;
+       char *endptr;
 
        if (tdb_data_cmp(key, last_stabilize_key()) == 0) {
                return 0;
        }
-
        if (state->in_persistent && tdb_exists(cache_notrans, key)) {
                return 0;
        }
@@ -641,62 +668,103 @@ static int gencache_iterate_fn(struct tdb_context *tdb, 
TDB_DATA key,
                free_key = keystr;
        }
 
-       if ((value.dptr == NULL) || (value.dsize <= TIMEOUT_LEN)) {
+       if (!gencache_pull_timeout((char *)data.dptr, &timeout, &endptr)) {
                goto done;
        }
+       endptr += 1;
 
        if (fnmatch(state->pattern, keystr, 0) != 0) {
                goto done;
        }
 
-       if (value.dptr[value.dsize-1] == '\0') {
-               valstr = (char *)value.dptr;
-       } else {
-               /* ensure 0-termination */
-               valstr = SMB_STRNDUP((char *)value.dptr, value.dsize);
-               free_val = valstr;
-       }
-
-       u = strtoul(valstr, &timeout_endp, 10);
-
-       if ((*timeout_endp != '/') || ((timeout_endp-valstr) != TIMEOUT_LEN)) {
-               goto done;
-       }
-
-       timeout = u;
-       timeout_endp += 1;
+       DEBUG(10, ("Calling function with arguments (key=%s, timeout=%s)\n",
+                  keystr, ctime(&timeout)));
 
-       DEBUG(10, ("Calling function with arguments "
-                  "(key = %s, value = %s, timeout = %s)\n",
-                  keystr, timeout_endp, ctime(&timeout)));
-       state->fn(keystr, timeout_endp, timeout, state->priv);
+       state->fn(keystr,
+                 data_blob_const(endptr,
+                                 data.dsize - PTR_DIFF(endptr, data.dptr)),
+                 timeout, state->private_data);
 
  done:
        SAFE_FREE(free_key);
-       SAFE_FREE(free_val);
        return 0;
 }
 
-void gencache_iterate(void (*fn)(const char* key, const char *value, time_t 
timeout, void* dptr),
-                      void* data, const char* keystr_pattern)
+void gencache_iterate_blobs(void (*fn)(const char *key, DATA_BLOB value,
+                                      time_t timeout, void *private_data),
+                           void *private_data, const char *pattern)
 {
-       struct gencache_iterate_state state;
+       struct gencache_iterate_blobs_state state;
 
-       if ((fn == NULL) || (keystr_pattern == NULL)) {
+       if ((fn == NULL) || (pattern == NULL) || !gencache_init()) {
                return;
        }
 
-       if (!gencache_init()) return;
-
-       DEBUG(5, ("Searching cache keys with pattern %s\n", keystr_pattern));
+       DEBUG(5, ("Searching cache keys with pattern %s\n", pattern));
 
        state.fn = fn;
-       state.pattern = keystr_pattern;
-       state.priv = data;
+       state.pattern = pattern;
+       state.private_data = private_data;
 
        state.in_persistent = false;
-       tdb_traverse(cache_notrans, gencache_iterate_fn, &state);
+       tdb_traverse(cache_notrans, gencache_iterate_blobs_fn, &state);
 
        state.in_persistent = true;
-       tdb_traverse(cache, gencache_iterate_fn, &state);
+       tdb_traverse(cache, gencache_iterate_blobs_fn, &state);
+}
+
+/**
+ * Iterate through all entries which key matches to specified pattern
+ *
+ * @param fn pointer to the function that will be supplied with each single
+ *        matching cache entry (key, value and timeout) as an arguments
+ * @param data void pointer to an arbitrary data that is passed directly to 
the fn
+ *        function on each call
+ * @param keystr_pattern pattern the existing entries' keys are matched to
+ *
+ **/
+
+struct gencache_iterate_state {
+       void (*fn)(const char *key, const char *value, time_t timeout,
+                  void *priv);
+       void *private_data;
+};
+
+static void gencache_iterate_fn(const char *key, DATA_BLOB value,
+                               time_t timeout, void *private_data)
+{
+       struct gencache_iterate_state *state =
+               (struct gencache_iterate_state *)private_data;
+       char *valstr;
+       char *free_val = NULL;
+
+       if (value.data[value.length-1] == '\0') {
+               valstr = (char *)value.data;
+       } else {
+               /* ensure 0-termination */
+               valstr = SMB_STRNDUP((char *)value.data, value.length);
+               free_val = valstr;
+       }
+
+       DEBUG(10, ("Calling function with arguments "
+                  "(key = %s, value = %s, timeout = %s)\n",
+                  key, valstr, ctime(&timeout)));
+
+       state->fn(key, valstr, timeout, state->private_data);
+
+       SAFE_FREE(free_val);
+}
+
+void gencache_iterate(void (*fn)(const char *key, const char *value,
+                                time_t timeout, void *dptr),
+                      void *private_data, const char *pattern)
+{
+       struct gencache_iterate_state state;
+
+       if (fn == NULL) {
+               return;
+       }
+       state.fn = fn;
+       state.private_data = private_data;
+       gencache_iterate_blobs(gencache_iterate_fn, &state, pattern);
 }
diff --git a/source3/utils/net_cache.c b/source3/utils/net_cache.c
index 4339094..88aff4e 100644
--- a/source3/utils/net_cache.c
+++ b/source3/utils/net_cache.c
@@ -33,11 +33,13 @@
  * (print_cache_entry) and to flush it (delete_cache_entry).
  * Both of them are defined by first arg of gencache_iterate() routine.
  */
-static void print_cache_entry(const char* keystr, const char* datastr,
+static void print_cache_entry(const char* keystr, DATA_BLOB value,
                               const time_t timeout, void* dptr)
 {
        char *timeout_str;
        char *alloc_str = NULL;
+       const char *datastr;
+       char *datastr_free = NULL;
        time_t now_t = time(NULL);
        struct tm timeout_tm, now_tm;
        struct tm *ptimeout_tm, *pnow_tm;
@@ -69,6 +71,18 @@ static void print_cache_entry(const char* keystr, const 
char* datastr,
                timeout_str = alloc_str;
        }
 
+       datastr = (char *)value.data;
+
+       if ((value.length > 0) && (value.data[value.length-1] != '\0')) {
+               datastr_free = talloc_asprintf(
+                       talloc_tos(), "<binary length %d>",
+                       (int)value.length);
+               datastr = datastr_free;
+               if (datastr == NULL) {
+                       datastr = "<binary>";
+               }
+       }
+
        d_printf(_("Key: %s\t Timeout: %s\t Value: %s  %s\n"), keystr,
                 timeout_str, datastr, timeout > now_t ? "": _("(expired)"));
 
@@ -218,7 +232,7 @@ static int net_cache_del(struct net_context *c, int argc, 
const char **argv)
 static int net_cache_get(struct net_context *c, int argc, const char **argv)
 {
        const char* keystr = argv[0];
-       char* valuestr = NULL;
+       DATA_BLOB value;
        time_t timeout;
 
        if (argc < 1 || c->display_usage) {
@@ -228,9 +242,9 @@ static int net_cache_get(struct net_context *c, int argc, 
const char **argv)
                return -1;
        }
 
-       if (gencache_get(keystr, &valuestr, &timeout)) {
-               print_cache_entry(keystr, valuestr, timeout, NULL);
-               SAFE_FREE(valuestr);
+       if (gencache_get_data_blob(keystr, &value, &timeout, NULL)) {
+               print_cache_entry(keystr, value, timeout, NULL);
+               SAFE_FREE(value.data);
                return 0;
        }
 
@@ -258,7 +272,7 @@ static int net_cache_search(struct net_context *c, int 
argc, const char **argv)
        }
 
        pattern = argv[0];
-       gencache_iterate(print_cache_entry, NULL, pattern);
+       gencache_iterate_blobs(print_cache_entry, NULL, pattern);
        return 0;
 }
 
@@ -282,7 +296,7 @@ static int net_cache_list(struct net_context *c, int argc, 
const char **argv)
                         _("List all cache entries."));
                return 0;
        }
-       gencache_iterate(print_cache_entry, NULL, pattern);
+       gencache_iterate_blobs(print_cache_entry, NULL, pattern);
        return 0;
 }
 


-- 
Samba Shared Repository

Reply via email to