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;

Reply via email to