Mercurial > dovecot > core-2.2
view src/lib-storage/index/index-attribute.c @ 15272:ca10d2e8d8e3
lib-storage: Moved mail attribute dict to struct mail_storage.
This also means that index_storage_destroy() must always be called, so
removed now unnecessary mail_storage.destroy=NULL checks.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 29 Oct 2012 14:50:11 +0200 |
parents | a436e4a7503b |
children | 4c84efce3a94 |
line wrap: on
line source
/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */ #include "lib.h" #include "dict.h" #include "index-storage.h" struct index_storage_attribute_iter { struct mailbox_attribute_iter iter; struct dict_iterate_context *diter; char *prefix; unsigned int prefix_len; bool dict_disabled; }; static int index_storage_get_dict(struct mailbox *box, struct dict **dict_r, const char **mailbox_prefix_r) { struct mail_storage *storage = box->storage; struct mailbox_metadata metadata; const char *error; if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID, &metadata) < 0) return -1; *mailbox_prefix_r = guid_128_to_string(metadata.guid); if (storage->_attr_dict != NULL) { *dict_r = storage->_attr_dict; return 0; } if (*storage->set->mail_attribute_dict == '\0') { mail_storage_set_error(storage, MAIL_ERROR_NOTPOSSIBLE, "Mailbox attributes not enabled"); return -1; } if (storage->attr_dict_failed) { mail_storage_set_internal_error(storage); return -1; } if (dict_init(storage->set->mail_attribute_dict, DICT_DATA_TYPE_STRING, storage->user->username, storage->user->set->base_dir, &storage->_attr_dict, &error) < 0) { mail_storage_set_critical(storage, "mail_attribute_dict: dict_init(%s) failed: %s", storage->set->mail_attribute_dict, error); storage->attr_dict_failed = TRUE; return -1; } *dict_r = storage->_attr_dict; return 0; } static const char * key_get_prefixed(enum mail_attribute_type type, const char *mailbox_prefix, const char *key) { switch (type) { case MAIL_ATTRIBUTE_TYPE_PRIVATE: return t_strconcat(DICT_PATH_PRIVATE, mailbox_prefix, "/", key, NULL); case MAIL_ATTRIBUTE_TYPE_SHARED: return t_strconcat(DICT_PATH_SHARED, mailbox_prefix, "/", key, NULL); } i_unreached(); } int index_storage_attribute_set(struct mailbox *box, enum mail_attribute_type type, const char *key, const char *value) { struct dict_transaction_context *dtrans; struct dict *dict; const char *mailbox_prefix; if (index_storage_get_dict(box, &dict, &mailbox_prefix) < 0) return -1; T_BEGIN { key = key_get_prefixed(type, mailbox_prefix, key); dtrans = dict_transaction_begin(dict); if (value != NULL) dict_set(dtrans, key, value); else dict_unset(dtrans, key); } T_END; if (dict_transaction_commit(&dtrans) < 0) { mail_storage_set_internal_error(box->storage); return -1; } return 0; } int index_storage_attribute_get(struct mailbox *box, enum mail_attribute_type type, const char *key, const char **value_r) { struct dict *dict; const char *mailbox_prefix; int ret; if (index_storage_get_dict(box, &dict, &mailbox_prefix) < 0) return -1; ret = dict_lookup(dict, pool_datastack_create(), key_get_prefixed(type, mailbox_prefix, key), value_r); if (ret < 0) { mail_storage_set_internal_error(box->storage); return -1; } if (ret == 0) *value_r = NULL; return ret; } struct mailbox_attribute_iter * index_storage_attribute_iter_init(struct mailbox *box, enum mail_attribute_type type, const char *prefix) { struct index_storage_attribute_iter *iter; struct dict *dict; const char *mailbox_prefix; iter = i_new(struct index_storage_attribute_iter, 1); iter->iter.box = box; if (index_storage_get_dict(box, &dict, &mailbox_prefix) < 0) { if (mailbox_get_last_mail_error(box) == MAIL_ERROR_NOTPOSSIBLE) iter->dict_disabled = TRUE; } else { iter->prefix = i_strdup(key_get_prefixed(type, mailbox_prefix, prefix)); iter->prefix_len = strlen(iter->prefix); iter->diter = dict_iterate_init(dict, iter->prefix, DICT_ITERATE_FLAG_RECURSE | DICT_ITERATE_FLAG_NO_VALUE); } return &iter->iter; } const char * index_storage_attribute_iter_next(struct mailbox_attribute_iter *_iter) { struct index_storage_attribute_iter *iter = (struct index_storage_attribute_iter *)_iter; const char *key, *value; if (iter->diter == NULL || !dict_iterate(iter->diter, &key, &value)) return NULL; i_assert(strncmp(key, iter->prefix, iter->prefix_len) == 0); key += iter->prefix_len; return key; } int index_storage_attribute_iter_deinit(struct mailbox_attribute_iter *_iter) { struct index_storage_attribute_iter *iter = (struct index_storage_attribute_iter *)_iter; int ret; if (iter->diter == NULL) { ret = iter->dict_disabled ? 0 : -1; } else { if ((ret = dict_iterate_deinit(&iter->diter)) < 0) mail_storage_set_internal_error(_iter->box->storage); } i_free(iter->prefix); i_free(iter); return ret; }