Mercurial > dovecot > core-2.2
view src/lib-dict/dict.c @ 3879:928229f8b3e6 HEAD
deinit, unref, destroy, close, free, etc. functions now take a pointer to
their data pointer, and set it to NULL. This makes double-frees less likely
to cause security holes.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 14 Jan 2006 20:47:20 +0200 |
parents | 55df57c028d4 |
children | 6fabe878c46d |
line wrap: on
line source
/* Copyright (C) 2005 Timo Sirainen */ #include "lib.h" #include "array.h" #include "dict-sql.h" #include "dict-private.h" static array_t ARRAY_DEFINE(dict_classes, struct dict *); static struct dict *dict_class_lookup(const char *name) { struct dict *const *dicts; unsigned int i, count; dicts = array_get(&dict_classes, &count); for (i = 0; i < count; i++) { if (strcmp(dicts[i]->name, name) == 0) return dicts[i]; } return NULL; } void dict_class_register(struct dict *dict_class) { if (!array_is_created(&dict_classes)) ARRAY_CREATE(&dict_classes, default_pool, struct dict *, 8); if (dict_class_lookup(dict_class->name) != NULL) { i_fatal("dict_class_register(%s): Already registered", dict_class->name); } array_append(&dict_classes, &dict_class, 1); } void dict_class_unregister(struct dict *dict_class) { struct dict *const *dicts; unsigned int i, count; dicts = array_get(&dict_classes, &count); for (i = 0; i < count; i++) { if (dicts[i] == dict_class) { array_delete(&dict_classes, i, 1); break; } } i_assert(i < count); if (array_count(&dict_classes) == 0) array_free(&dict_classes); } struct dict *dict_init(const char *uri) { struct dict *dict; const char *p; p = strchr(uri, ':'); if (p == NULL) { i_error("URI is missing ':': %s", uri); return NULL; } t_push(); dict = dict_class_lookup(t_strdup_until(uri, p)); t_pop(); if (dict == NULL) return NULL; return dict->v.init(dict, p+1); } void dict_deinit(struct dict **_dict) { struct dict *dict = *_dict; *_dict = NULL; dict->v.deinit(dict); } int dict_lookup(struct dict *dict, pool_t pool, const char *key, const char **value_r) { return dict->v.lookup(dict, pool, key, value_r); } struct dict_iterate_context * dict_iterate_init(struct dict *dict, const char *path, bool recurse) { return dict->v.iterate_init(dict, path, recurse); } int dict_iterate(struct dict_iterate_context *ctx, const char **key_r, const char **value_r) { return ctx->dict->v.iterate(ctx, key_r, value_r); } void dict_iterate_deinit(struct dict_iterate_context *ctx) { ctx->dict->v.iterate_deinit(ctx); } struct dict_transaction_context *dict_transaction_begin(struct dict *dict) { return dict->v.transaction_init(dict); } int dict_transaction_commit(struct dict_transaction_context *ctx) { return ctx->dict->v.transaction_commit(ctx); } void dict_transaction_rollback(struct dict_transaction_context *ctx) { ctx->dict->v.transaction_rollback(ctx); } void dict_set(struct dict_transaction_context *ctx, const char *key, const char *value) { ctx->dict->v.set(ctx, key, value); } void dict_atomic_inc(struct dict_transaction_context *ctx, const char *key, long long diff) { ctx->dict->v.atomic_inc(ctx, key, diff); }