[SCM] Samba Shared Repository - branch master updated

Volker Lendecke vlendec at samba.org
Sun Nov 28 07:04:01 MST 2010


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 <vl at samba.org>
Date:   Sun Nov 28 13:14:38 2010 +0100

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

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

    s3: Add gencache_iterate_blobs

commit 62afdb9cc056da4ba7a873e6bce00b4f2c32f4a4
Author: Volker Lendecke <vl at 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 <vl at 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


More information about the samba-cvs mailing list