diff options
author | Volker Lendecke <vlendec@samba.org> | 2007-01-31 12:01:52 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:17:33 -0500 |
commit | 032bd8eea89ce24ab5fdd2eb6095b8416ebde558 (patch) | |
tree | 4a95f2479b3dc0ddb852aa81d7616ef263cc7671 /source3/lib/util_tdb.c | |
parent | 8bfa9351614115ceb8bfaa6f76355ddc14ec248b (diff) | |
download | samba-032bd8eea89ce24ab5fdd2eb6095b8416ebde558.tar.gz samba-032bd8eea89ce24ab5fdd2eb6095b8416ebde558.tar.xz samba-032bd8eea89ce24ab5fdd2eb6095b8416ebde558.zip |
r21076: Two pieces of infrastructure from Samba4: An API-compatible messaging wrapper
and tdb_wrap_open.
Volker
(This used to be commit c01f164dcaf88fb7f3bed8f69b210ba8fab326d1)
Diffstat (limited to 'source3/lib/util_tdb.c')
-rw-r--r-- | source3/lib/util_tdb.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/source3/lib/util_tdb.c b/source3/lib/util_tdb.c index 4db39095a64..b559f589dc5 100644 --- a/source3/lib/util_tdb.c +++ b/source3/lib/util_tdb.c @@ -846,3 +846,101 @@ int tdb_trans_delete(struct tdb_context *tdb, TDB_DATA key) return res; } + +/* + Log tdb messages via DEBUG(). +*/ +static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, + const char *format, ...) PRINTF_ATTRIBUTE(3,4); + +static void tdb_wrap_log(TDB_CONTEXT *tdb, enum tdb_debug_level level, + const char *format, ...) +{ + va_list ap; + char *ptr = NULL; + int debuglevel = 0; + + va_start(ap, format); + vasprintf(&ptr, format, ap); + va_end(ap); + + switch (level) { + case TDB_DEBUG_FATAL: + debug_level = 0; + break; + case TDB_DEBUG_ERROR: + debuglevel = 1; + break; + case TDB_DEBUG_WARNING: + debuglevel = 2; + break; + case TDB_DEBUG_TRACE: + debuglevel = 5; + break; + default: + debuglevel = 0; + } + + if (ptr != NULL) { + const char *name = tdb_name(tdb); + DEBUG(debuglevel, ("tdb(%s): %s", name ? name : "unnamed", ptr)); + free(ptr); + } +} + +static struct tdb_wrap *tdb_list; + +/* destroy the last connection to a tdb */ +static int tdb_wrap_destructor(struct tdb_wrap *w) +{ + tdb_close(w->tdb); + DLIST_REMOVE(tdb_list, w); + return 0; +} + +/* + wrapped connection to a tdb database + to close just talloc_free() the tdb_wrap pointer + */ +struct tdb_wrap *tdb_wrap_open(TALLOC_CTX *mem_ctx, + const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode) +{ + struct tdb_wrap *w; + struct tdb_logging_context log_ctx; + log_ctx.log_fn = tdb_wrap_log; + + for (w=tdb_list;w;w=w->next) { + if (strcmp(name, w->name) == 0) { + /* + * Yes, talloc_reference is exactly what we want + * here. Otherwise we would have to implement our own + * reference counting. + */ + return talloc_reference(mem_ctx, w); + } + } + + w = talloc(mem_ctx, struct tdb_wrap); + if (w == NULL) { + return NULL; + } + + if (!(w->name = talloc_strdup(w, name))) { + talloc_free(w); + return NULL; + } + + w->tdb = tdb_open_ex(name, hash_size, tdb_flags, + open_flags, mode, &log_ctx, NULL); + if (w->tdb == NULL) { + talloc_free(w); + return NULL; + } + + talloc_set_destructor(w, tdb_wrap_destructor); + + DLIST_ADD(tdb_list, w); + + return w; +} |