Mercurial > dovecot > core-2.2
view src/lib-dict/dict-cdb.c @ 22325:e01bc3015b2f
lib-index: Check .log.2 rotation only when syncing
Instead of also whenever appending transactions to .log file. This
shouldn't change the behavior much, and it's needed for the following
change to work correctly.
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Tue, 11 Jul 2017 15:33:56 +0300 |
parents | af8d96508fad |
children | cb108f786fb4 |
line wrap: on
line source
/* Copyright (c) 2013-2017 Dovecot authors, see the included COPYING file */ #include "lib.h" #ifdef BUILD_CDB #include "dict-private.h" #include <string.h> #include <cdb.h> #include <unistd.h> #include <fcntl.h> #define CDB_WITH_NULL 1 #define CDB_WITHOUT_NULL 2 struct cdb_dict { struct dict dict; struct cdb cdb; char *path; int fd, flag; }; static void cdb_dict_deinit(struct dict *_dict); static int cdb_dict_init(struct dict *driver, const char *uri, const struct dict_settings *set ATTR_UNUSED, struct dict **dict_r, const char **error_r) { struct cdb_dict *dict; dict = i_new(struct cdb_dict, 1); dict->dict = *driver; dict->path = i_strdup(uri); dict->flag = CDB_WITH_NULL | CDB_WITHOUT_NULL; /* initialize cdb to 0 (unallocated) */ memset(&dict->cdb, 0, sizeof(struct cdb)); dict->fd = open(dict->path, O_RDONLY); if (dict->fd == -1) { *error_r = t_strdup_printf("open(%s) failed: %m", dict->path); cdb_dict_deinit(&dict->dict); return -1; } #ifdef TINYCDB_VERSION if (cdb_init(&dict->cdb, dict->fd) < 0) { *error_r = t_strdup_printf("cdb_init(%s) failed: %m", dict->path); cdb_dict_deinit(&dict->dict); return -1; } #else cdb_init(&dict->cdb, dict->fd); #endif *dict_r = &dict->dict; return 0; } static void cdb_dict_deinit(struct dict *_dict) { struct cdb_dict *dict = (struct cdb_dict *)_dict; /* we can safely deinit unallocated cdb */ cdb_free(&dict->cdb); if (dict->fd != -1) { if (close(dict->fd) < 0) i_error("close(%s) failed: %m", dict->path); } i_free(dict->path); i_free(dict); } static int cdb_dict_lookup(struct dict *_dict, pool_t pool, const char *key, const char **value_r) { struct cdb_dict *dict = (struct cdb_dict *)_dict; unsigned datalen; int ret = 0; char *data; /* keys and values may be null terminated... */ if ((dict->flag & CDB_WITH_NULL) != 0) { ret = cdb_find(&dict->cdb, key, (unsigned)strlen(key)+1); if (ret > 0) dict->flag &= ~CDB_WITHOUT_NULL; } /* ...or not */ if (ret == 0 && (dict->flag & CDB_WITHOUT_NULL) != 0) { ret = cdb_find(&dict->cdb, key, (unsigned)strlen(key)); if (ret > 0) dict->flag &= ~CDB_WITH_NULL; } if (ret <= 0) { *value_r = NULL; /* something bad with db */ if (ret < 0) { i_error("cdb_find(%s) failed: %m", dict->path); return -1; } /* found nothing */ return 0; } datalen = cdb_datalen(&dict->cdb); data = p_malloc(pool, datalen + 1); if (cdb_read(&dict->cdb, data, datalen, cdb_datapos(&dict->cdb)) < 0) { i_error("cdb_read(%s) failed: %m", dict->path); return -1; } *value_r = data; return 1; } struct dict dict_driver_cdb = { .name = "cdb", { .init = cdb_dict_init, .deinit = cdb_dict_deinit, .lookup = cdb_dict_lookup, } }; #endif