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