summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2010-11-27 00:40:25 +0100
committerVolker Lendecke <vlendec@samba.org>2010-11-28 14:19:19 +0100
commit9843103b7d2a13b1b8a45b3a1d958700bbf1bcfc (patch)
tree9338e2e5f68cd6d87d98e888d35bbccda4db5200
parentce55d7c9f0c0720f765f549f9b2617cb9a3d2299 (diff)
downloadsamba-9843103b7d2a13b1b8a45b3a1d958700bbf1bcfc.tar.gz
samba-9843103b7d2a13b1b8a45b3a1d958700bbf1bcfc.tar.bz2
samba-9843103b7d2a13b1b8a45b3a1d958700bbf1bcfc.zip
s3: Add gencache_parse
-rw-r--r--source3/include/proto.h4
-rw-r--r--source3/lib/gencache.c59
2 files changed, 63 insertions, 0 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index d199d1e3df..0af158c537 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -548,6 +548,10 @@ 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);
diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c
index 8d2ddb2387..fa8dcb02f9 100644
--- a/source3/lib/gencache.c
+++ b/source3/lib/gencache.c
@@ -289,6 +289,65 @@ static bool gencache_pull_timeout(char *val, time_t *pres, char **pendptr)
return true;
}
+struct gencache_parse_state {
+ void (*parser)(time_t timeout, DATA_BLOB blob, void *private_data);
+ void *private_data;
+};
+
+static int gencache_parse_fn(TDB_DATA key, TDB_DATA data, void *private_data)
+{
+ struct gencache_parse_state *state;
+ DATA_BLOB blob;
+ time_t t;
+ char *endptr;
+ bool ret;
+
+ 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) {
+ return false;
+ }
+ if (!gencache_init()) {
+ return false;
+ }
+
+ key = string_term_tdb_data(keystr);
+ state.parser = parser;
+ state.private_data = private_data;
+
+ 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);
+}
+
/**
* Get existing entry from the cache file.
*