svn commit: samba r24733 - in branches: SAMBA_3_2/source/lib SAMBA_3_2/source/torture SAMBA_3_2_0/source/lib SAMBA_3_2_0/source/torture

gd at samba.org gd at samba.org
Tue Aug 28 12:40:03 GMT 2007


Author: gd
Date: 2007-08-28 12:40:01 +0000 (Tue, 28 Aug 2007)
New Revision: 24733

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=24733

Log:
Add support for storing DATA_BLOBs in gencache.tdb (including torturetest).

Mimir, please have a look. DATA_BLOBs will now just show up as "DATA_BLOB"
values with "net cache list".

Guenther


Modified:
   branches/SAMBA_3_2/source/lib/gencache.c
   branches/SAMBA_3_2/source/torture/torture.c
   branches/SAMBA_3_2_0/source/lib/gencache.c
   branches/SAMBA_3_2_0/source/torture/torture.c


Changeset:
Modified: branches/SAMBA_3_2/source/lib/gencache.c
===================================================================
--- branches/SAMBA_3_2/source/lib/gencache.c	2007-08-28 09:57:47 UTC (rev 24732)
+++ branches/SAMBA_3_2/source/lib/gencache.c	2007-08-28 12:40:01 UTC (rev 24733)
@@ -28,6 +28,8 @@
 #define TIMEOUT_LEN 12
 #define CACHE_DATA_FMT	"%12u/%s"
 #define READ_CACHE_DATA_FMT_TEMPLATE "%%12u/%%%us"
+#define BLOB_TYPE "DATA_BLOB"
+#define BLOB_TYPE_LEN 9
 
 static TDB_CONTEXT *cache;
 static BOOL cache_readonly;
@@ -243,8 +245,163 @@
 	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 expired pointer to a BOOL that indicates whether the entry is expired
+ *
+ * @retval true when entry is successfuly fetched
+ * @retval False for failure
+ **/
 
+BOOL gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, BOOL *expired)
+{
+	TDB_DATA databuf;
+	time_t t;
+	char *blob_type;
+	unsigned char *buf = NULL;
+	BOOL ret = False;
+	fstring valstr;
+	int buflen = 0, len = 0, blob_len = 0;
+	unsigned char *blob_buf = NULL;
+
+	/* fail completely if get null pointers passed */
+	SMB_ASSERT(keystr);
+
+	if (!gencache_init()) {
+		return False;
+	}
+
+	databuf = tdb_fetch_bystring(cache, keystr);
+	if (!databuf.dptr) {
+		DEBUG(10,("Cache entry with key = %s couldn't be found\n",
+			  keystr));
+		return False;
+	}
+
+	buf = (unsigned char *)databuf.dptr;
+	buflen = databuf.dsize;
+
+	len += tdb_unpack(buf+len, buflen-len, "fB",
+			  &valstr,
+			  &blob_len, &blob_buf);
+	if (len == -1) {
+		goto out;
+	}
+
+	t = strtol(valstr, &blob_type, 10);
+
+	if (strcmp(blob_type+1, BLOB_TYPE) != 0) {
+		goto out;
+	}
+
+	DEBUG(10,("Returning %s cache entry: key = %s, "
+		  "timeout = %s", t > time(NULL) ? "valid" :
+		  "expired", keystr, ctime(&t)));
+
+	if (t <= time(NULL)) {
+		/* We're expired */
+		if (expired) {
+			*expired = True;
+		}
+	}
+
+	if (blob) {
+		*blob = data_blob(blob_buf, blob_len);
+		if (!blob->data) {
+			goto out;
+		}
+	}
+
+	ret = True;
+ out:
+	SAFE_FREE(blob_buf);
+	SAFE_FREE(databuf.dptr);
+
+	return ret;
+}
+
 /**
+ * Set an entry in the cache file. If there's no such
+ * one, then add it.
+ *
+ * @param keystr string that represents a key of this entry
+ * @param blob DATA_BLOB value being cached
+ * @param timeout time when the value is expired
+ *
+ * @retval true when entry is successfuly stored
+ * @retval false on failure
+ **/
+
+BOOL gencache_set_data_blob(const char *keystr, DATA_BLOB *blob, time_t timeout)
+{
+	BOOL ret = False;
+	int tdb_ret;
+	TDB_DATA databuf;
+	char *valstr = NULL;
+	unsigned char *buf = NULL;
+	int len = 0, buflen = 0;
+
+	/* fail completely if get null pointers passed */
+	SMB_ASSERT(keystr && blob);
+
+	if (!gencache_init()) {
+		return False;
+	}
+
+	if (cache_readonly) {
+		return False;
+	}
+
+	asprintf(&valstr, "%12u/%s", (int)timeout, BLOB_TYPE);
+	if (!valstr) {
+		return False;
+	}
+
+ again:
+	len = 0;
+
+	len += tdb_pack(buf+len, buflen-len, "fB",
+			valstr,
+			blob->length, blob->data);
+
+	if (len == -1) {
+		goto out;
+	}
+
+	if (buflen < len) {
+		SAFE_FREE(buf);
+		buf = SMB_MALLOC_ARRAY(unsigned char, len);
+		if (!buf) {
+			goto out;
+		}
+		buflen = len;
+		goto again;
+	}
+
+	databuf = make_tdb_data(buf, len);
+
+	DEBUG(10,("Adding cache entry with key = %s; "
+		  "blob size = %d and timeout = %s"
+		  "(%d seconds %s)\n", keystr, (int)databuf.dsize,
+		  ctime(&timeout), (int)(timeout - time(NULL)),
+		  timeout > time(NULL) ? "ahead" : "in the past"));
+
+	tdb_ret = tdb_store_bystring(cache, keystr, databuf, 0);
+	if (tdb_ret == 0) {
+		ret = True;
+	}
+
+ out:
+	SAFE_FREE(valstr);
+	SAFE_FREE(buf);
+
+	return ret;
+}
+
+/**
  * Iterate through all entries which key matches to specified pattern
  *
  * @param fn pointer to the function that will be supplied with each single

Modified: branches/SAMBA_3_2/source/torture/torture.c
===================================================================
--- branches/SAMBA_3_2/source/torture/torture.c	2007-08-28 09:57:47 UTC (rev 24732)
+++ branches/SAMBA_3_2/source/torture/torture.c	2007-08-28 12:40:01 UTC (rev 24733)
@@ -4820,6 +4820,7 @@
 {
 	char *val;
 	time_t tm;
+	DATA_BLOB blob;
 
 	if (!gencache_init()) {
 		d_printf("%s: gencache_init() failed\n", __location__);
@@ -4861,6 +4862,46 @@
 		return False;
 	}
 
+	blob = data_blob_string_const("bar");
+	tm = time(NULL);
+
+	if (!gencache_set_data_blob("foo", &blob, tm)) {
+		d_printf("%s: gencache_set_data_blob() failed\n", __location__);
+		return False;
+	}
+
+	data_blob_free(&blob);
+
+	if (!gencache_get_data_blob("foo", &blob, NULL)) {
+		d_printf("%s: gencache_get_data_blob() failed\n", __location__);
+		return False;
+	}
+
+	if (strcmp((const char *)blob.data, "bar") != 0) {
+		d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
+			 __location__, (const char *)blob.data, "bar");
+		data_blob_free(&blob);
+		return False;
+	}
+
+	data_blob_free(&blob);
+
+	if (!gencache_del("foo")) {
+		d_printf("%s: gencache_del() failed\n", __location__);
+		return False;
+	}
+	if (gencache_del("foo")) {
+		d_printf("%s: second gencache_del() succeeded\n",
+			 __location__);
+		return False;
+	}
+
+	if (gencache_get_data_blob("foo", &blob, NULL)) {
+		d_printf("%s: gencache_get_data_blob() on deleted entry "
+			 "succeeded\n", __location__);
+		return False;
+	}
+
 	if (!gencache_shutdown()) {
 		d_printf("%s: gencache_shutdown() failed\n", __location__);
 		return False;

Modified: branches/SAMBA_3_2_0/source/lib/gencache.c
===================================================================
--- branches/SAMBA_3_2_0/source/lib/gencache.c	2007-08-28 09:57:47 UTC (rev 24732)
+++ branches/SAMBA_3_2_0/source/lib/gencache.c	2007-08-28 12:40:01 UTC (rev 24733)
@@ -28,6 +28,8 @@
 #define TIMEOUT_LEN 12
 #define CACHE_DATA_FMT	"%12u/%s"
 #define READ_CACHE_DATA_FMT_TEMPLATE "%%12u/%%%us"
+#define BLOB_TYPE "DATA_BLOB"
+#define BLOB_TYPE_LEN 9
 
 static TDB_CONTEXT *cache;
 static BOOL cache_readonly;
@@ -243,8 +245,163 @@
 	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 expired pointer to a BOOL that indicates whether the entry is expired
+ *
+ * @retval true when entry is successfuly fetched
+ * @retval False for failure
+ **/
 
+BOOL gencache_get_data_blob(const char *keystr, DATA_BLOB *blob, BOOL *expired)
+{
+	TDB_DATA databuf;
+	time_t t;
+	char *blob_type;
+	unsigned char *buf = NULL;
+	BOOL ret = False;
+	fstring valstr;
+	int buflen = 0, len = 0, blob_len = 0;
+	unsigned char *blob_buf = NULL;
+
+	/* fail completely if get null pointers passed */
+	SMB_ASSERT(keystr);
+
+	if (!gencache_init()) {
+		return False;
+	}
+
+	databuf = tdb_fetch_bystring(cache, keystr);
+	if (!databuf.dptr) {
+		DEBUG(10,("Cache entry with key = %s couldn't be found\n",
+			  keystr));
+		return False;
+	}
+
+	buf = (unsigned char *)databuf.dptr;
+	buflen = databuf.dsize;
+
+	len += tdb_unpack(buf+len, buflen-len, "fB",
+			  &valstr,
+			  &blob_len, &blob_buf);
+	if (len == -1) {
+		goto out;
+	}
+
+	t = strtol(valstr, &blob_type, 10);
+
+	if (strcmp(blob_type+1, BLOB_TYPE) != 0) {
+		goto out;
+	}
+
+	DEBUG(10,("Returning %s cache entry: key = %s, "
+		  "timeout = %s", t > time(NULL) ? "valid" :
+		  "expired", keystr, ctime(&t)));
+
+	if (t <= time(NULL)) {
+		/* We're expired */
+		if (expired) {
+			*expired = True;
+		}
+	}
+
+	if (blob) {
+		*blob = data_blob(blob_buf, blob_len);
+		if (!blob->data) {
+			goto out;
+		}
+	}
+
+	ret = True;
+ out:
+	SAFE_FREE(blob_buf);
+	SAFE_FREE(databuf.dptr);
+
+	return ret;
+}
+
 /**
+ * Set an entry in the cache file. If there's no such
+ * one, then add it.
+ *
+ * @param keystr string that represents a key of this entry
+ * @param blob DATA_BLOB value being cached
+ * @param timeout time when the value is expired
+ *
+ * @retval true when entry is successfuly stored
+ * @retval false on failure
+ **/
+
+BOOL gencache_set_data_blob(const char *keystr, DATA_BLOB *blob, time_t timeout)
+{
+	BOOL ret = False;
+	int tdb_ret;
+	TDB_DATA databuf;
+	char *valstr = NULL;
+	unsigned char *buf = NULL;
+	int len = 0, buflen = 0;
+
+	/* fail completely if get null pointers passed */
+	SMB_ASSERT(keystr && blob);
+
+	if (!gencache_init()) {
+		return False;
+	}
+
+	if (cache_readonly) {
+		return False;
+	}
+
+	asprintf(&valstr, "%12u/%s", (int)timeout, BLOB_TYPE);
+	if (!valstr) {
+		return False;
+	}
+
+ again:
+	len = 0;
+
+	len += tdb_pack(buf+len, buflen-len, "fB",
+			valstr,
+			blob->length, blob->data);
+
+	if (len == -1) {
+		goto out;
+	}
+
+	if (buflen < len) {
+		SAFE_FREE(buf);
+		buf = SMB_MALLOC_ARRAY(unsigned char, len);
+		if (!buf) {
+			goto out;
+		}
+		buflen = len;
+		goto again;
+	}
+
+	databuf = make_tdb_data(buf, len);
+
+	DEBUG(10,("Adding cache entry with key = %s; "
+		  "blob size = %d and timeout = %s"
+		  "(%d seconds %s)\n", keystr, (int)databuf.dsize,
+		  ctime(&timeout), (int)(timeout - time(NULL)),
+		  timeout > time(NULL) ? "ahead" : "in the past"));
+
+	tdb_ret = tdb_store_bystring(cache, keystr, databuf, 0);
+	if (tdb_ret == 0) {
+		ret = True;
+	}
+
+ out:
+	SAFE_FREE(valstr);
+	SAFE_FREE(buf);
+
+	return ret;
+}
+
+/**
  * Iterate through all entries which key matches to specified pattern
  *
  * @param fn pointer to the function that will be supplied with each single

Modified: branches/SAMBA_3_2_0/source/torture/torture.c
===================================================================
--- branches/SAMBA_3_2_0/source/torture/torture.c	2007-08-28 09:57:47 UTC (rev 24732)
+++ branches/SAMBA_3_2_0/source/torture/torture.c	2007-08-28 12:40:01 UTC (rev 24733)
@@ -4820,6 +4820,7 @@
 {
 	char *val;
 	time_t tm;
+	DATA_BLOB blob;
 
 	if (!gencache_init()) {
 		d_printf("%s: gencache_init() failed\n", __location__);
@@ -4861,6 +4862,46 @@
 		return False;
 	}
 
+	blob = data_blob_string_const("bar");
+	tm = time(NULL);
+
+	if (!gencache_set_data_blob("foo", &blob, tm)) {
+		d_printf("%s: gencache_set_data_blob() failed\n", __location__);
+		return False;
+	}
+
+	data_blob_free(&blob);
+
+	if (!gencache_get_data_blob("foo", &blob, NULL)) {
+		d_printf("%s: gencache_get_data_blob() failed\n", __location__);
+		return False;
+	}
+
+	if (strcmp((const char *)blob.data, "bar") != 0) {
+		d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
+			 __location__, (const char *)blob.data, "bar");
+		data_blob_free(&blob);
+		return False;
+	}
+
+	data_blob_free(&blob);
+
+	if (!gencache_del("foo")) {
+		d_printf("%s: gencache_del() failed\n", __location__);
+		return False;
+	}
+	if (gencache_del("foo")) {
+		d_printf("%s: second gencache_del() succeeded\n",
+			 __location__);
+		return False;
+	}
+
+	if (gencache_get_data_blob("foo", &blob, NULL)) {
+		d_printf("%s: gencache_get_data_blob() on deleted entry "
+			 "succeeded\n", __location__);
+		return False;
+	}
+
 	if (!gencache_shutdown()) {
 		d_printf("%s: gencache_shutdown() failed\n", __location__);
 		return False;



More information about the samba-cvs mailing list