*/
#include "includes.h"
+#include "system/filesys.h"
+#include "system/glob.h"
+#include "util_tdb.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_TDB
return false;
}
first_try = false;
- DEBUG(0, ("gencache_init: tdb_check(%s) failed - retry after CLEAR_IF_FIRST\n",
+ DEBUG(0, ("gencache_init: tdb_check(%s) failed - retry after truncate\n",
cache_fname));
- cache = tdb_open_log(cache_fname, 0, TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH, open_flags, 0644);
- if (cache) {
- tdb_close(cache);
- cache = NULL;
- goto again;
- }
+ truncate(cache_fname, 0);
+ goto again;
}
}
static TDB_DATA last_stabilize_key(void)
{
TDB_DATA result;
- result.dptr = (uint8_t *)"@LAST_STABILIZED";
+ result.dptr = discard_const_p(uint8_t, "@LAST_STABILIZED");
result.dsize = 17;
return result;
}
*/
last_stabilize = 0;
- databuf = tdb_fetch(cache_notrans, last_stabilize_key());
+ databuf = tdb_fetch_compat(cache_notrans, last_stabilize_key());
if ((databuf.dptr != NULL)
&& (databuf.dptr[databuf.dsize-1] == '\0')) {
last_stabilize = atoi((char *)databuf.dptr);
time_t res;
char *endptr;
+ if (val == NULL) {
+ return false;
+ }
+
res = strtol(val, &endptr, 10);
if ((endptr == NULL) || (*endptr != '/')) {
state.private_data = private_data;
ret = tdb_parse_record(cache_notrans, key, gencache_parse_fn, &state);
- if (ret != -1) {
+ if (ret == 0) {
return true;
}
ret = tdb_parse_record(cache, key, gencache_parse_fn, &state);
- return (ret != -1);
+ return (ret == 0);
}
struct gencache_get_data_blob_state {
if (was_expired != NULL) {
*was_expired = expired;
}
+ if (state.result && state.blob) {
+ data_blob_free(state.blob);
+ }
return false;
}
}
res = tdb_transaction_start_nonblock(cache);
- if (res == -1) {
-
- if (tdb_error(cache) == TDB_ERR_NOLOCK) {
+ if (res != 0) {
+ if (tdb_error(cache) == TDB_ERR_NOLOCK)
+ {
/*
* Someone else already does the stabilize,
* this does not have to be done twice
}
DEBUG(10, ("Could not start transaction on gencache.tdb: "
- "%s\n", tdb_errorstr(cache)));
+ "%s\n", tdb_errorstr_compat(cache)));
return false;
}
res = tdb_transaction_start(cache_notrans);
- if (res == -1) {
+ if (res != 0) {
tdb_transaction_cancel(cache);
DEBUG(10, ("Could not start transaction on "
"gencache_notrans.tdb: %s\n",
- tdb_errorstr(cache_notrans)));
+ tdb_errorstr_compat(cache_notrans)));
return false;
}
state.written = false;
res = tdb_traverse(cache_notrans, stabilize_fn, &state);
- if ((res == -1) || state.error) {
- if ((tdb_transaction_cancel(cache_notrans) == -1)
- || (tdb_transaction_cancel(cache) == -1)) {
- smb_panic("tdb_transaction_cancel failed\n");
- }
+ if ((res < 0) || state.error) {
+ tdb_transaction_cancel(cache_notrans);
+ tdb_transaction_cancel(cache);
return false;
}
if (!state.written) {
- if ((tdb_transaction_cancel(cache_notrans) == -1)
- || (tdb_transaction_cancel(cache) == -1)) {
- smb_panic("tdb_transaction_cancel failed\n");
- }
+ tdb_transaction_cancel(cache_notrans);
+ tdb_transaction_cancel(cache);
return true;
}
res = tdb_transaction_commit(cache);
- if (res == -1) {
+ if (res != 0) {
DEBUG(10, ("tdb_transaction_commit on gencache.tdb failed: "
- "%s\n", tdb_errorstr(cache)));
- if (tdb_transaction_cancel(cache_notrans) == -1) {
- smb_panic("tdb_transaction_cancel failed\n");
- }
+ "%s\n", tdb_errorstr_compat(cache)));
+ tdb_transaction_cancel(cache_notrans);
return false;
}
res = tdb_transaction_commit(cache_notrans);
- if (res == -1) {
+ if (res != 0) {
DEBUG(10, ("tdb_transaction_commit on gencache.tdb failed: "
- "%s\n", tdb_errorstr(cache)));
+ "%s\n", tdb_errorstr_compat(cache)));
return false;
}
}
if ((timeout < time(NULL)) || (val.dsize == 0)) {
res = tdb_delete(cache, key);
- if ((res == -1) && (tdb_error(cache) == TDB_ERR_NOEXIST)) {
+ if ((res != 0) && (tdb_error(cache) == TDB_ERR_NOEXIST)) {
res = 0;
} else {
state->written = true;
}
}
- if (res == -1) {
+ if (res != 0) {
DEBUG(10, ("Transfer to gencache.tdb failed: %s\n",
- tdb_errorstr(cache)));
+ tdb_errorstr_compat(cache)));
state->error = true;
return -1;
}
- if (tdb_delete(cache_notrans, key) == -1) {
+ if (tdb_delete(cache_notrans, key) != 0) {
DEBUG(10, ("tdb_delete from gencache_notrans.tdb failed: "
- "%s\n", tdb_errorstr(cache_notrans)));
+ "%s\n", tdb_errorstr_compat(cache_notrans)));
state->error = true;
return -1;
}
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;
}
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);
}