keywords = mailbox_keywords_create_valid(worker->mail->box,
msg->keywords);
mail_update_keywords(worker->mail, MODIFY_REPLACE, keywords);
- mailbox_keywords_unref(worker->mail->box, &keywords);
+ mailbox_keywords_unref(&keywords);
mail_update_modseq(worker->mail, msg->modseq);
}
}
mailbox_keywords_create_valid(box, msg->keywords);
mailbox_save_set_flags(save_ctx, msg->flags, keywords);
if (keywords != NULL)
- mailbox_keywords_unref(box, &keywords);
+ mailbox_keywords_unref(&keywords);
mailbox_save_set_uid(save_ctx, msg->uid);
mailbox_save_set_save_date(save_ctx, msg->save_date);
mailbox_save_set_min_modseq(save_ctx, msg->modseq);
ret = mailbox_save_begin(&ctx->save_ctx, ctx->input);
if (keywords != NULL)
- mailbox_keywords_unref(ctx->box, &keywords);
+ mailbox_keywords_unref(&keywords);
if (ret < 0) {
/* save initialization failed */
mail_free(&mail);
if (ctx.keywords != NULL)
- mailbox_keywords_unref(client->mailbox, &ctx.keywords);
+ mailbox_keywords_unref(&ctx.keywords);
ret = mailbox_search_deinit(&search_ctx);
if (ret < 0)
else
mail_deliver_log_cache_var_expand_table(ctx);
if (kw != NULL)
- mailbox_keywords_unref(box, &kw);
+ mailbox_keywords_unref(&kw);
mail_free(&ctx->dest_mail);
if (ret < 0)
mail-storage-settings.c \
mail-thread.c \
mail-user.c \
+ mailbox-keywords.c \
mailbox-list.c \
mailbox-search-result.c \
mailbox-tree.c \
index_transaction_commit,
index_transaction_rollback,
index_transaction_set_max_modseq,
- index_keywords_create,
- index_keywords_create_from_indexes,
- index_keywords_ref,
- index_keywords_unref,
- index_keyword_is_valid,
index_storage_get_seq_range,
index_storage_get_uid_range,
index_storage_get_expunges,
index_transaction_commit,
index_transaction_rollback,
index_transaction_set_max_modseq,
- index_keywords_create,
- index_keywords_create_from_indexes,
- index_keywords_ref,
- index_keywords_unref,
- index_keyword_is_valid,
index_storage_get_seq_range,
index_storage_get_uid_range,
index_storage_get_expunges,
index_transaction_commit,
index_transaction_rollback,
index_transaction_set_max_modseq,
- index_keywords_create,
- index_keywords_create_from_indexes,
- index_keywords_ref,
- index_keywords_unref,
- index_keyword_is_valid,
index_storage_get_seq_range,
index_storage_get_uid_range,
index_storage_get_expunges,
#include "istream.h"
#include "ioloop.h"
#include "str.h"
-#include "imap-parser.h"
#include "mkdir-parents.h"
#include "mail-index-alloc-cache.h"
#include "mail-index-private.h"
return mail_index_view_is_inconsistent(box->view);
}
-bool index_keyword_is_valid(struct mailbox *box, const char *keyword,
- const char **error_r)
-{
- unsigned int i, idx;
-
- i_assert(box->opened);
-
- /* if it already exists, skip validity checks */
- if (mail_index_keyword_lookup(box->index, keyword, &idx))
- return TRUE;
-
- if (*keyword == '\0') {
- *error_r = "Empty keywords not allowed";
- return FALSE;
- }
-
- /* these are IMAP-specific restrictions, but for now IMAP is all we
- care about */
- for (i = 0; keyword[i] != '\0'; i++) {
- if (IS_ATOM_SPECIAL((unsigned char)keyword[i])) {
- *error_r = "Invalid characters in keyword";
- return FALSE;
- }
- if ((unsigned char)keyword[i] >= 0x80) {
- *error_r = "8bit characters in keyword";
- return FALSE;
- }
- }
- if (i > box->storage->set->mail_max_keyword_length) {
- *error_r = "Keyword length too long";
- return FALSE;
- }
- return TRUE;
-}
-
-static struct mail_keywords *
-index_keywords_create_skip(struct mailbox *box,
- const char *const keywords[])
-{
- ARRAY_DEFINE(valid_keywords, const char *);
- const char *error;
-
- t_array_init(&valid_keywords, 32);
- for (; *keywords != NULL; keywords++) {
- if (mailbox_keyword_is_valid(box, *keywords, &error))
- array_append(&valid_keywords, keywords, 1);
- }
- (void)array_append_space(&valid_keywords); /* NULL-terminate */
- return mail_index_keywords_create(box->index, keywords);
-}
-
-int index_keywords_create(struct mailbox *box, const char *const keywords[],
- struct mail_keywords **keywords_r, bool skip_invalid)
-{
- const char *error;
- unsigned int i;
-
- i_assert(box->opened);
-
- for (i = 0; keywords[i] != NULL; i++) {
- if (mailbox_keyword_is_valid(box, keywords[i], &error))
- continue;
-
- if (!skip_invalid) {
- mail_storage_set_error(box->storage,
- MAIL_ERROR_PARAMS, error);
- return -1;
- }
-
- /* found invalid keywords, do this the slow way */
- T_BEGIN {
- *keywords_r = index_keywords_create_skip(box, keywords);
- } T_END;
- return 0;
- }
-
- *keywords_r = mail_index_keywords_create(box->index, keywords);
- return 0;
-}
-
-struct mail_keywords *
-index_keywords_create_from_indexes(struct mailbox *box,
- const ARRAY_TYPE(keyword_indexes) *idx)
-{
- i_assert(box->opened);
-
- return mail_index_keywords_create_from_indexes(box->index, idx);
-}
-
-void index_keywords_ref(struct mail_keywords *keywords)
-{
- mail_index_keywords_ref(keywords);
-}
-
-void index_keywords_unref(struct mail_keywords *keywords)
-{
- mail_index_keywords_unref(&keywords);
-}
-
void index_save_context_free(struct mail_save_context *ctx)
{
i_free_and_null(ctx->from_envelope);
bool index_storage_allow_new_keywords(struct mailbox *box);
bool index_storage_is_inconsistent(struct mailbox *box);
-int index_keywords_create(struct mailbox *box, const char *const keywords[],
- struct mail_keywords **keywords_r, bool skip_invalid);
-struct mail_keywords *
-index_keywords_create_from_indexes(struct mailbox *box,
- const ARRAY_TYPE(keyword_indexes) *idx);
-void index_keywords_ref(struct mail_keywords *keywords);
-void index_keywords_unref(struct mail_keywords *keywords);
-bool index_keyword_is_valid(struct mailbox *box, const char *keyword,
- const char **error_r);
-
void index_mailbox_set_recent_uid(struct mailbox *box, uint32_t uid);
void index_mailbox_set_recent_seq(struct mailbox *box,
struct mail_index_view *view,
index_transaction_commit,
index_transaction_rollback,
index_transaction_set_max_modseq,
- index_keywords_create,
- index_keywords_create_from_indexes,
- index_keywords_ref,
- index_keywords_unref,
- index_keyword_is_valid,
index_storage_get_seq_range,
index_storage_get_uid_range,
index_storage_get_expunges,
mbox_transaction_commit,
mbox_transaction_rollback,
index_transaction_set_max_modseq,
- index_keywords_create,
- index_keywords_create_from_indexes,
- index_keywords_ref,
- index_keywords_unref,
- index_keyword_is_valid,
index_storage_get_seq_range,
index_storage_get_uid_range,
index_storage_get_expunges,
index_transaction_commit,
index_transaction_rollback,
index_transaction_set_max_modseq,
- index_keywords_create,
- index_keywords_create_from_indexes,
- index_keywords_ref,
- index_keywords_unref,
- index_keyword_is_valid,
index_storage_get_seq_range,
index_storage_get_uid_range,
index_storage_get_expunges,
/* keywords gets unreferenced twice: first in
mailbox_save_cancel()/_finish() and second time in
mailbox_copy(). */
- mailbox_keywords_ref(ctx->transaction->box, ctx->keywords);
+ mailbox_keywords_ref(ctx->keywords);
}
if (mail_storage_try_copy(&ctx, mail) < 0) {
case SEARCH_KEYWORDS:
if (arg->value.keywords == NULL)
break;
- mailbox_keywords_unref(args->box, &arg->value.keywords);
+ mailbox_keywords_unref(&arg->value.keywords);
break;
case SEARCH_MAILBOX_GLOB:
if (arg->value.mailbox_glob == NULL)
new_kw = mailbox_keywords_create_from_indexes(box,
&new_indexes);
} T_END;
- mailbox_keywords_unref(box, _kw1);
- mailbox_keywords_unref(box, _kw2);
+ mailbox_keywords_unref(_kw1);
+ mailbox_keywords_unref(_kw2);
return new_kw;
}
uint64_t max_modseq,
ARRAY_TYPE(seq_range) *seqs);
- int (*keywords_create)(struct mailbox *box,
- const char *const keywords[],
- struct mail_keywords **keywords_r,
- bool skip_invalid);
- struct mail_keywords *
- (*keywords_create_from_indexes)(struct mailbox *box,
- const ARRAY_TYPE(keyword_indexes) *idx);
- void (*keywords_ref)(struct mail_keywords *keywords);
- void (*keywords_unref)(struct mail_keywords *keywords);
- bool (*keyword_is_valid)(struct mailbox *box, const char *keyword,
- const char **error_r);
-
void (*get_seq_range)(struct mailbox *box, uint32_t uid1, uint32_t uid2,
uint32_t *seq1_r, uint32_t *seq2_r);
void (*get_uid_range)(struct mailbox *box,
mailbox_notify_changes(box, 0, NULL, NULL);
}
-int mailbox_keywords_create(struct mailbox *box, const char *const keywords[],
- struct mail_keywords **keywords_r)
-{
- const char *empty_keyword_list = NULL;
-
- if (keywords == NULL)
- keywords = &empty_keyword_list;
- return box->v.keywords_create(box, keywords, keywords_r, FALSE);
-}
-
-struct mail_keywords *
-mailbox_keywords_create_valid(struct mailbox *box,
- const char *const keywords[])
-{
- const char *empty_keyword_list = NULL;
- struct mail_keywords *kw;
-
- if (keywords == NULL)
- keywords = &empty_keyword_list;
- if (box->v.keywords_create(box, keywords, &kw, TRUE) < 0)
- i_unreached();
- return kw;
-}
-
-struct mail_keywords *
-mailbox_keywords_create_from_indexes(struct mailbox *box,
- const ARRAY_TYPE(keyword_indexes) *idx)
-{
- return box->v.keywords_create_from_indexes(box, idx);
-}
-
-void mailbox_keywords_ref(struct mailbox *box, struct mail_keywords *keywords)
-{
- box->v.keywords_ref(keywords);
-}
-
-void mailbox_keywords_unref(struct mailbox *box,
- struct mail_keywords **_keywords)
-{
- struct mail_keywords *keywords = *_keywords;
-
- *_keywords = NULL;
- box->v.keywords_unref(keywords);
-}
-
-bool mailbox_keyword_is_valid(struct mailbox *box, const char *keyword,
- const char **error_r)
-{
- return box->v.keyword_is_valid(box, keyword, error_r);
-}
-
void mailbox_get_seq_range(struct mailbox *box, uint32_t uid1, uint32_t uid2,
uint32_t *seq1_r, uint32_t *seq2_r)
{
ctx->flags = flags;
ctx->keywords = keywords;
if (keywords != NULL)
- mailbox_keywords_ref(ctx->transaction->box, keywords);
+ mailbox_keywords_ref(keywords);
}
void mailbox_save_copy_flags(struct mail_save_context *ctx, struct mail *mail)
*_ctx = NULL;
ret = box->v.save_finish(ctx);
if (keywords != NULL)
- mailbox_keywords_unref(box, &keywords);
+ mailbox_keywords_unref(&keywords);
return ret;
}
void mailbox_save_cancel(struct mail_save_context **_ctx)
{
struct mail_save_context *ctx = *_ctx;
- struct mailbox *box = ctx->transaction->box;
struct mail_keywords *keywords = ctx->keywords;
*_ctx = NULL;
ctx->transaction->box->v.save_cancel(ctx);
if (keywords != NULL)
- mailbox_keywords_unref(box, &keywords);
+ mailbox_keywords_unref(&keywords);
}
int mailbox_copy(struct mail_save_context **_ctx, struct mail *mail)
ret = ctx->transaction->box->v.copy(ctx, mail);
if (keywords != NULL)
- mailbox_keywords_unref(box, &keywords);
+ mailbox_keywords_unref(&keywords);
return ret;
}
struct mail_keywords *
mailbox_keywords_create_from_indexes(struct mailbox *box,
const ARRAY_TYPE(keyword_indexes) *idx);
-void mailbox_keywords_ref(struct mailbox *box, struct mail_keywords *keywords);
-void mailbox_keywords_unref(struct mailbox *box,
- struct mail_keywords **keywords);
+void mailbox_keywords_ref(struct mail_keywords *keywords);
+void mailbox_keywords_unref(struct mail_keywords **keywords);
/* Returns TRUE if keyword is valid, FALSE and error if not. */
bool mailbox_keyword_is_valid(struct mailbox *box, const char *keyword,
const char **error_r);
{
}
-static int
-test_mailbox_keywords_create(struct mailbox *box ATTR_UNUSED,
- const char *const keywords[] ATTR_UNUSED,
- struct mail_keywords **keywords_r,
- bool skip_invalid ATTR_UNUSED)
-{
- *keywords_r = i_new(struct mail_keywords, 1);
- (*keywords_r)->refcount = 1;
- return 0;
-}
-
-static struct mail_keywords *
-test_mailbox_keywords_create_from_indexes(struct mailbox *box ATTR_UNUSED,
- const ARRAY_TYPE(keyword_indexes) *idx ATTR_UNUSED)
-{
- struct mail_keywords *keywords;
-
- keywords = i_new(struct mail_keywords, 1);
- keywords->refcount++;
- return keywords;
-}
-
-static void test_mailbox_keywords_ref(struct mail_keywords *keywords)
-{
- keywords->refcount++;
-}
-
-static void test_mailbox_keywords_unref(struct mail_keywords *keywords)
-{
- if (--keywords->refcount == 0)
- i_free(keywords);
-}
-
-static bool
-test_mailbox_keyword_is_valid(struct mailbox *box ATTR_UNUSED,
- const char *keyword ATTR_UNUSED,
- const char **error_r ATTR_UNUSED)
-{
- return TRUE;
-}
-
static void
test_mailbox_get_seq_range(struct mailbox *box ATTR_UNUSED,
uint32_t uid1, uint32_t uid2,
test_mailbox_transaction_commit,
test_mailbox_transaction_rollback,
test_mailbox_transaction_set_max_modseq,
- test_mailbox_keywords_create,
- test_mailbox_keywords_create_from_indexes,
- test_mailbox_keywords_ref,
- test_mailbox_keywords_unref,
- test_mailbox_keyword_is_valid,
test_mailbox_get_seq_range,
test_mailbox_get_uid_range,
test_mailbox_get_expunged_uids,
return abox->module_ctx.super.transaction_commit(ctx, changes_r);
}
-static int
-acl_keywords_create(struct mailbox *box, const char *const keywords[],
- struct mail_keywords **keywords_r, bool skip_invalid)
-{
- struct acl_mailbox *abox = ACL_CONTEXT(box);
- int ret;
-
- ret = acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE);
- if (ret < 0) {
- if (!skip_invalid)
- return -1;
- /* we can't return failure. assume we don't have permissions. */
- ret = 0;
- }
-
- if (ret == 0) {
- /* no permission to update any flags. just return empty
- keywords list. */
- const char *null = NULL;
-
- return abox->module_ctx.super.keywords_create(box, &null,
- keywords_r,
- skip_invalid);
- }
-
- return abox->module_ctx.super.keywords_create(box, keywords,
- keywords_r, skip_invalid);
-}
-
static int acl_mailbox_open_check_acl(struct mailbox *box)
{
struct acl_mailbox *abox = ACL_CONTEXT(box);
v->delete = acl_mailbox_delete;
v->rename = acl_mailbox_rename;
v->save_begin = acl_save_begin;
- v->keywords_create = acl_keywords_create;
v->copy = acl_copy;
v->transaction_commit = acl_transaction_commit;
}
struct virtual_save_context *ctx = (struct virtual_save_context *)_ctx;
if (ctx->backend_keywords != NULL)
- mailbox_keywords_unref(ctx->backend_box, &ctx->backend_keywords);
+ mailbox_keywords_unref(&ctx->backend_keywords);
if (ctx->backend_save_ctx != NULL)
mailbox_save_cancel(&ctx->backend_save_ctx);
i_free(ctx);
virtual_transaction_commit,
virtual_transaction_rollback,
index_transaction_set_max_modseq,
- index_keywords_create,
- index_keywords_create_from_indexes,
- index_keywords_ref,
- index_keywords_unref,
- index_keyword_is_valid,
index_storage_get_seq_range,
index_storage_get_uid_range,
index_storage_get_expunges,
MODIFY_ADD : MODIFY_REMOVE;
mail_update_keywords(bbox->sync_mail,
modify_type, keywords);
- mailbox_keywords_unref(bbox->box, &keywords);
+ mailbox_keywords_unref(&keywords);
break;
case MAIL_INDEX_SYNC_TYPE_KEYWORD_RESET:
kw_names[0] = NULL;
kw_names);
mail_update_keywords(bbox->sync_mail, MODIFY_REPLACE,
keywords);
- mailbox_keywords_unref(bbox->box, &keywords);
+ mailbox_keywords_unref(&keywords);
break;
case MAIL_INDEX_SYNC_TYPE_APPEND:
i_unreached();