From: Timo Sirainen Date: Mon, 6 Dec 2010 03:53:30 +0000 (+0000) Subject: lib-storage: Unvirtualized mailbox_header_lookup_*() X-Git-Tag: 2.1.alpha1~438 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a4f09749814b93e8ad3ec8a0dc18885b874d6f8c;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Unvirtualized mailbox_header_lookup_*() --- diff --git a/src/lib-storage/Makefile.am b/src/lib-storage/Makefile.am index 0c2c0ad52a..0eb81f66db 100644 --- a/src/lib-storage/Makefile.am +++ b/src/lib-storage/Makefile.am @@ -35,6 +35,7 @@ libstorage_la_SOURCES = \ mail-thread.c \ mail-user.c \ mailbox-get.c \ + mailbox-header.c \ mailbox-keywords.c \ mailbox-list.c \ mailbox-search-result.c \ diff --git a/src/lib-storage/index/cydir/cydir-storage.c b/src/lib-storage/index/cydir/cydir-storage.c index 684d6c0bbc..c5bac64f93 100644 --- a/src/lib-storage/index/cydir/cydir-storage.c +++ b/src/lib-storage/index/cydir/cydir-storage.c @@ -157,8 +157,6 @@ struct mailbox cydir_mailbox = { index_transaction_rollback, NULL, index_mail_alloc, - index_header_lookup_init, - index_header_lookup_deinit, index_storage_search_init, index_storage_search_deinit, index_storage_search_next_nonblock, diff --git a/src/lib-storage/index/dbox-multi/mdbox-storage.c b/src/lib-storage/index/dbox-multi/mdbox-storage.c index fbedfa5778..9d19e28807 100644 --- a/src/lib-storage/index/dbox-multi/mdbox-storage.c +++ b/src/lib-storage/index/dbox-multi/mdbox-storage.c @@ -416,8 +416,6 @@ struct mailbox mdbox_mailbox = { index_transaction_rollback, NULL, dbox_mail_alloc, - index_header_lookup_init, - index_header_lookup_deinit, index_storage_search_init, index_storage_search_deinit, index_storage_search_next_nonblock, diff --git a/src/lib-storage/index/dbox-single/sdbox-storage.c b/src/lib-storage/index/dbox-single/sdbox-storage.c index fd59e748ae..4cc3ea0ebf 100644 --- a/src/lib-storage/index/dbox-single/sdbox-storage.c +++ b/src/lib-storage/index/dbox-single/sdbox-storage.c @@ -383,8 +383,6 @@ struct mailbox sdbox_mailbox = { index_transaction_rollback, NULL, dbox_mail_alloc, - index_header_lookup_init, - index_header_lookup_deinit, index_storage_search_init, index_storage_search_deinit, index_storage_search_next_nonblock, diff --git a/src/lib-storage/index/index-mail-headers.c b/src/lib-storage/index/index-mail-headers.c index ee02145dd3..15e33082ce 100644 --- a/src/lib-storage/index/index-mail-headers.c +++ b/src/lib-storage/index/index-mail-headers.c @@ -15,17 +15,6 @@ #include "index-storage.h" #include "index-mail.h" -#include - -struct index_header_lookup_ctx { - struct mailbox_header_lookup_ctx ctx; - pool_t pool; - - unsigned int count; - unsigned int *idx; - const char **name; -}; - static const enum message_header_parser_flags hdr_parser_flags = MESSAGE_HEADER_PARSER_FLAG_SKIP_INITIAL_LWSP | MESSAGE_HEADER_PARSER_FLAG_DROP_CR; @@ -194,10 +183,8 @@ static void index_mail_parse_header_register_all_wanted(struct index_mail *mail) } void index_mail_parse_header_init(struct index_mail *mail, - struct mailbox_header_lookup_ctx *_headers) + struct mailbox_header_lookup_ctx *headers) { - struct index_header_lookup_ctx *headers = - (struct index_header_lookup_ctx *)_headers; const uint8_t *match; unsigned int i, field_idx, match_count; @@ -801,20 +788,18 @@ static void header_cache_callback(struct message_header_line *hdr, } int index_mail_get_header_stream(struct mail *_mail, - struct mailbox_header_lookup_ctx *_headers, + struct mailbox_header_lookup_ctx *headers, struct istream **stream_r) { struct index_mail *mail = (struct index_mail *)_mail; - struct index_header_lookup_ctx *headers = - (struct index_header_lookup_ctx *)_headers; struct istream *input; string_t *dest; - i_assert(_headers->box == _mail->box); + i_assert(headers->box == _mail->box); if (mail->data.save_bodystructure_header) { /* we have to parse the header. */ - if (index_mail_parse_headers(mail, _headers) < 0) + if (index_mail_parse_headers(mail, headers) < 0) return -1; } @@ -840,7 +825,7 @@ int index_mail_get_header_stream(struct mail *_mail, if (mail->data.filter_stream != NULL) i_stream_destroy(&mail->data.filter_stream); - index_mail_parse_header_init(mail, _headers); + index_mail_parse_header_init(mail, headers); mail->data.filter_stream = i_stream_create_header_filter(mail->data.stream, HEADER_FILTER_INCLUDE | @@ -850,73 +835,3 @@ int index_mail_get_header_stream(struct mail *_mail, *stream_r = mail->data.filter_stream; return 0; } - -static struct mailbox_header_lookup_ctx * -index_header_lookup_init_real(struct mailbox *box, const char *const headers[]) -{ - struct mail_cache_field *fields, header_field = { - NULL, 0, MAIL_CACHE_FIELD_HEADER, 0, - MAIL_CACHE_DECISION_TEMP - }; - struct index_header_lookup_ctx *ctx; - const char *const *name; - const char **sorted_headers; - pool_t pool; - unsigned int i, count; - - i_assert(*headers != NULL); - - for (count = 0, name = headers; *name != NULL; name++) - count++; - - /* @UNSAFE: headers need to be sorted for filter stream. */ - sorted_headers = t_new(const char *, count); - memcpy(sorted_headers, headers, count * sizeof(*sorted_headers)); - qsort(sorted_headers, count, sizeof(*sorted_headers), i_strcasecmp_p); - headers = sorted_headers; - - /* @UNSAFE */ - fields = t_new(struct mail_cache_field, count); - for (i = 0; i < count; i++) { - header_field.name = t_strconcat("hdr.", headers[i], NULL); - fields[i] = header_field; - } - mail_cache_register_fields(box->cache, fields, count); - - pool = pool_alloconly_create("index_header_lookup_ctx", 1024); - ctx = p_new(pool, struct index_header_lookup_ctx, 1); - ctx->ctx.box = box; - ctx->ctx.refcount = 1; - ctx->pool = pool; - ctx->count = count; - - ctx->idx = p_new(pool, unsigned int, count); - ctx->name = p_new(pool, const char *, count + 1); - - /* @UNSAFE */ - for (i = 0; i < count; i++) { - ctx->idx[i] = fields[i].idx; - ctx->name[i] = p_strdup(pool, headers[i]); - } - ctx->ctx.headers = ctx->name; - return &ctx->ctx; -} - -struct mailbox_header_lookup_ctx * -index_header_lookup_init(struct mailbox *box, const char *const headers[]) -{ - struct mailbox_header_lookup_ctx *ctx; - - T_BEGIN { - ctx = index_header_lookup_init_real(box, headers); - } T_END; - return ctx; -} - -void index_header_lookup_deinit(struct mailbox_header_lookup_ctx *_ctx) -{ - struct index_header_lookup_ctx *ctx = - (struct index_header_lookup_ctx *)_ctx; - - pool_unref(&ctx->pool); -} diff --git a/src/lib-storage/index/index-mail.c b/src/lib-storage/index/index-mail.c index fed8523de8..5a411e771f 100644 --- a/src/lib-storage/index/index-mail.c +++ b/src/lib-storage/index/index-mail.c @@ -1121,10 +1121,8 @@ index_mail_alloc(struct mailbox_transaction_context *t, void index_mail_init(struct index_mail *mail, struct mailbox_transaction_context *t, enum mail_fetch_field wanted_fields, - struct mailbox_header_lookup_ctx *_wanted_headers) + struct mailbox_header_lookup_ctx *wanted_headers) { - struct index_header_lookup_ctx *wanted_headers = - (struct index_header_lookup_ctx *)_wanted_headers; const struct mail_index_header *hdr; array_create(&mail->mail.module_contexts, mail->mail.pool, @@ -1134,7 +1132,7 @@ void index_mail_init(struct index_mail *mail, mail->mail.mail.box = t->box; mail->mail.mail.transaction = t; mail->mail.wanted_fields = wanted_fields; - mail->mail.wanted_headers = _wanted_headers; + mail->mail.wanted_headers = wanted_headers; hdr = mail_index_get_header(t->box->view); mail->uid_validity = hdr->uid_validity; @@ -1145,7 +1143,7 @@ void index_mail_init(struct index_mail *mail, mail->wanted_fields = wanted_fields; if (wanted_headers != NULL) { mail->wanted_headers = wanted_headers; - mailbox_header_lookup_ref(_wanted_headers); + mailbox_header_lookup_ref(wanted_headers); } } diff --git a/src/lib-storage/index/index-mail.h b/src/lib-storage/index/index-mail.h index a6f9eab4aa..6c4f2bb0af 100644 --- a/src/lib-storage/index/index-mail.h +++ b/src/lib-storage/index/index-mail.h @@ -123,7 +123,7 @@ struct index_mail { uint32_t uid_validity; enum mail_fetch_field wanted_fields; - struct index_header_lookup_ctx *wanted_headers; + struct mailbox_header_lookup_ctx *wanted_headers; int pop3_state; diff --git a/src/lib-storage/index/index-storage.h b/src/lib-storage/index/index-storage.h index 4c75819ebc..e55d351661 100644 --- a/src/lib-storage/index/index-storage.h +++ b/src/lib-storage/index/index-storage.h @@ -109,10 +109,6 @@ void index_storage_get_status(struct mailbox *box, enum mailbox_status_items items, struct mailbox_status *status_r); -struct mailbox_header_lookup_ctx * -index_header_lookup_init(struct mailbox *box, const char *const headers[]); -void index_header_lookup_deinit(struct mailbox_header_lookup_ctx *ctx); - struct mail_search_context * index_storage_search_init(struct mailbox_transaction_context *t, struct mail_search_args *args, diff --git a/src/lib-storage/index/maildir/maildir-storage.c b/src/lib-storage/index/maildir/maildir-storage.c index bb56fab11d..ef361b17b0 100644 --- a/src/lib-storage/index/maildir/maildir-storage.c +++ b/src/lib-storage/index/maildir/maildir-storage.c @@ -657,8 +657,6 @@ struct mailbox maildir_mailbox = { index_transaction_rollback, maildir_get_private_flags_mask, index_mail_alloc, - index_header_lookup_init, - index_header_lookup_deinit, index_storage_search_init, index_storage_search_deinit, index_storage_search_next_nonblock, diff --git a/src/lib-storage/index/mbox/mbox-storage.c b/src/lib-storage/index/mbox/mbox-storage.c index 71345e9c16..eeafdbeb0a 100644 --- a/src/lib-storage/index/mbox/mbox-storage.c +++ b/src/lib-storage/index/mbox/mbox-storage.c @@ -761,8 +761,6 @@ struct mailbox mbox_mailbox = { mbox_transaction_rollback, NULL, index_mail_alloc, - index_header_lookup_init, - index_header_lookup_deinit, index_storage_search_init, index_storage_search_deinit, index_storage_search_next_nonblock, diff --git a/src/lib-storage/index/raw/raw-storage.c b/src/lib-storage/index/raw/raw-storage.c index ffcdd6a457..1e2836bce6 100644 --- a/src/lib-storage/index/raw/raw-storage.c +++ b/src/lib-storage/index/raw/raw-storage.c @@ -157,8 +157,6 @@ struct mailbox raw_mailbox = { index_transaction_rollback, NULL, index_mail_alloc, - index_header_lookup_init, - index_header_lookup_deinit, index_storage_search_init, index_storage_search_deinit, index_storage_search_next_nonblock, diff --git a/src/lib-storage/mail-storage-private.h b/src/lib-storage/mail-storage-private.h index 79c6686ef6..61e132a554 100644 --- a/src/lib-storage/mail-storage-private.h +++ b/src/lib-storage/mail-storage-private.h @@ -158,11 +158,6 @@ struct mailbox_vfuncs { enum mail_fetch_field wanted_fields, struct mailbox_header_lookup_ctx *wanted_headers); - struct mailbox_header_lookup_ctx * - (*header_lookup_init)(struct mailbox *box, - const char *const headers[]); - void (*header_lookup_deinit)(struct mailbox_header_lookup_ctx *ctx); - struct mail_search_context * (*search_init)(struct mailbox_transaction_context *t, struct mail_search_args *args, @@ -426,8 +421,12 @@ struct mailbox_sync_context { struct mailbox_header_lookup_ctx { struct mailbox *box; - const char *const *headers; + pool_t pool; int refcount; + + unsigned int count; + const char *const *name; + unsigned int *idx; }; /* Modules should use do "my_id = mail_storage_module_id++" and diff --git a/src/lib-storage/mail-storage.c b/src/lib-storage/mail-storage.c index 1c4442ef6d..052fd7bdf7 100644 --- a/src/lib-storage/mail-storage.c +++ b/src/lib-storage/mail-storage.c @@ -1013,31 +1013,6 @@ void mailbox_notify_changes_stop(struct mailbox *box) mailbox_notify_changes(box, 0, NULL, NULL); } -struct mailbox_header_lookup_ctx * -mailbox_header_lookup_init(struct mailbox *box, const char *const headers[]) -{ - return box->v.header_lookup_init(box, headers); -} - -void mailbox_header_lookup_ref(struct mailbox_header_lookup_ctx *ctx) -{ - i_assert(ctx->refcount > 0); - ctx->refcount++; -} - -void mailbox_header_lookup_unref(struct mailbox_header_lookup_ctx **_ctx) -{ - struct mailbox_header_lookup_ctx *ctx = *_ctx; - - *_ctx = NULL; - - i_assert(ctx->refcount > 0); - if (--ctx->refcount > 0) - return; - - ctx->box->v.header_lookup_deinit(ctx); -} - struct mail_search_context * mailbox_search_init(struct mailbox_transaction_context *t, struct mail_search_args *args, diff --git a/src/lib-storage/mailbox-header.c b/src/lib-storage/mailbox-header.c new file mode 100644 index 0000000000..ea58acef76 --- /dev/null +++ b/src/lib-storage/mailbox-header.c @@ -0,0 +1,89 @@ +/* Copyright (c) 2003-2010 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "mail-cache.h" +#include "mail-storage-private.h" + +#include + +static struct mailbox_header_lookup_ctx * +mailbox_header_lookup_init_real(struct mailbox *box, + const char *const headers[]) +{ + struct mail_cache_field *fields, header_field = { + NULL, 0, MAIL_CACHE_FIELD_HEADER, 0, + MAIL_CACHE_DECISION_TEMP + }; + struct mailbox_header_lookup_ctx *ctx; + const char *const *name; + const char **sorted_headers, **dest_name; + pool_t pool; + unsigned int i, count; + + i_assert(*headers != NULL); + + for (count = 0, name = headers; *name != NULL; name++) + count++; + + /* @UNSAFE: headers need to be sorted for filter stream. */ + sorted_headers = t_new(const char *, count); + memcpy(sorted_headers, headers, count * sizeof(*sorted_headers)); + qsort(sorted_headers, count, sizeof(*sorted_headers), i_strcasecmp_p); + headers = sorted_headers; + + /* @UNSAFE */ + fields = t_new(struct mail_cache_field, count); + for (i = 0; i < count; i++) { + header_field.name = t_strconcat("hdr.", headers[i], NULL); + fields[i] = header_field; + } + mail_cache_register_fields(box->cache, fields, count); + + pool = pool_alloconly_create("mailbox_header_lookup_ctx", 1024); + ctx = p_new(pool, struct mailbox_header_lookup_ctx, 1); + ctx->box = box; + ctx->refcount = 1; + ctx->pool = pool; + ctx->count = count; + + ctx->idx = p_new(pool, unsigned int, count); + + /* @UNSAFE */ + dest_name = p_new(pool, const char *, count + 1); + for (i = 0; i < count; i++) { + ctx->idx[i] = fields[i].idx; + dest_name[i] = p_strdup(pool, headers[i]); + } + ctx->name = dest_name; + return ctx; +} + +struct mailbox_header_lookup_ctx * +mailbox_header_lookup_init(struct mailbox *box, const char *const headers[]) +{ + struct mailbox_header_lookup_ctx *ctx; + + T_BEGIN { + ctx = mailbox_header_lookup_init_real(box, headers); + } T_END; + return ctx; +} + +void mailbox_header_lookup_ref(struct mailbox_header_lookup_ctx *ctx) +{ + i_assert(ctx->refcount > 0); + ctx->refcount++; +} + +void mailbox_header_lookup_unref(struct mailbox_header_lookup_ctx **_ctx) +{ + struct mailbox_header_lookup_ctx *ctx = *_ctx; + + *_ctx = NULL; + + i_assert(ctx->refcount > 0); + if (--ctx->refcount > 0) + return; + + pool_unref(&ctx->pool); +} diff --git a/src/lib-storage/test-mailbox.c b/src/lib-storage/test-mailbox.c index fefcdd0019..d2f0cf4e16 100644 --- a/src/lib-storage/test-mailbox.c +++ b/src/lib-storage/test-mailbox.c @@ -138,24 +138,6 @@ test_mailbox_transaction_commit(struct mailbox_transaction_context *t, return 0; } -static struct mailbox_header_lookup_ctx * -test_mailbox_header_lookup_init(struct mailbox *box, - const char *const headers[]) -{ - struct mailbox_header_lookup_ctx *ctx; - - ctx = i_new(struct mailbox_header_lookup_ctx, 1); - ctx->box = box; - ctx->headers = headers; /* now exactly right, but .. */ - return ctx; -} - -static void -test_mailbox_header_lookup_deinit(struct mailbox_header_lookup_ctx *ctx) -{ - i_free(ctx); -} - static struct mail_search_context * test_mailbox_search_init(struct mailbox_transaction_context *t, struct mail_search_args *args, @@ -267,8 +249,6 @@ struct mailbox test_mailbox = { test_mailbox_transaction_rollback, NULL, test_mailbox_mail_alloc, - test_mailbox_header_lookup_init, - test_mailbox_header_lookup_deinit, test_mailbox_search_init, test_mailbox_search_deinit, test_mailbox_search_next_nonblock, diff --git a/src/plugins/virtual/virtual-mail.c b/src/plugins/virtual/virtual-mail.c index 5c8deb0eb8..9543df8aad 100644 --- a/src/plugins/virtual/virtual-mail.c +++ b/src/plugins/virtual/virtual-mail.c @@ -97,7 +97,7 @@ virtual_mail_set_backend_mail(struct mail *mail, backend_headers = vmail->wanted_headers == NULL ? NULL : mailbox_header_lookup_init(bbox->box, - vmail->wanted_headers->headers); + vmail->wanted_headers->name); vmail->backend_mail = mail_alloc(backend_trans, vmail->wanted_fields, backend_headers); if (backend_headers != NULL) @@ -301,7 +301,7 @@ virtual_mail_get_header_stream(struct mail *mail, return -1; backend_headers = mailbox_header_lookup_init(vmail->backend_mail->box, - headers->headers); + headers->name); ret = mail_get_header_stream(vmail->backend_mail, backend_headers, stream_r); mailbox_header_lookup_unref(&backend_headers); diff --git a/src/plugins/virtual/virtual-storage.c b/src/plugins/virtual/virtual-storage.c index b57c5ee135..8cd9830bfb 100644 --- a/src/plugins/virtual/virtual-storage.c +++ b/src/plugins/virtual/virtual-storage.c @@ -530,8 +530,6 @@ struct mailbox virtual_mailbox = { virtual_transaction_rollback, NULL, virtual_mail_alloc, - index_header_lookup_init, - index_header_lookup_deinit, virtual_search_init, virtual_search_deinit, virtual_search_next_nonblock,