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