Mercurial > dovecot > core-2.2
changeset 7642:077bb84e9e77 HEAD
Make mail_search_args an independent structure that can be used for multiple
separate searches.
line wrap: on
line diff
--- a/src/imap/cmd-copy.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/imap/cmd-copy.c Wed Jun 04 00:51:58 2008 +0300 @@ -28,7 +28,7 @@ static int fetch_and_copy(struct client *client, struct mailbox *destbox, struct mailbox_transaction_context *t, - struct mail_search_arg *search_args, + struct mail_search_args *search_args, const char **src_uidset_r, unsigned int *copy_count_r) { @@ -46,7 +46,7 @@ msgset_generator_init(&srcset_ctx, src_uidset); src_trans = mailbox_transaction_begin(client->mailbox, 0); - search_ctx = mailbox_search_init(src_trans, NULL, search_args, NULL); + search_ctx = mailbox_search_init(src_trans, search_args, NULL); mail = mail_alloc(src_trans, MAIL_FETCH_STREAM_HEADER | MAIL_FETCH_STREAM_BODY, NULL); @@ -90,7 +90,7 @@ struct mail_storage *storage; struct mailbox *destbox; struct mailbox_transaction_context *t; - struct mail_search_arg *search_arg; + struct mail_search_args *search_args; const char *messageset, *mailbox, *src_uidset, *msg = NULL; enum mailbox_sync_flags sync_flags = 0; enum imap_sync_flags imap_flags = 0; @@ -109,7 +109,7 @@ if (!client_verify_mailbox_name(cmd, mailbox, TRUE, FALSE)) return TRUE; - ret = imap_search_get_seqset(cmd, messageset, cmd->uid, &search_arg); + ret = imap_search_get_seqset(cmd, messageset, cmd->uid, &search_args); if (ret <= 0) return ret < 0; @@ -135,8 +135,9 @@ t = mailbox_transaction_begin(destbox, MAILBOX_TRANSACTION_FLAG_EXTERNAL | MAILBOX_TRANSACTION_FLAG_ASSIGN_UIDS); - ret = fetch_and_copy(client, destbox, t, search_arg, + ret = fetch_and_copy(client, destbox, t, search_args, &src_uidset, ©_count); + mail_search_args_unref(&search_args); if (ret <= 0) mailbox_transaction_rollback(&t);
--- a/src/imap/cmd-expunge.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/imap/cmd-expunge.c Wed Jun 04 00:51:58 2008 +0300 @@ -36,15 +36,17 @@ } static bool cmd_expunge_finish(struct client_command_context *cmd, - struct mail_search_arg *search_arg) + struct mail_search_args *search_args) { struct client *client = cmd->client; - if (imap_expunge(client->mailbox, search_arg) < 0) { + if (imap_expunge(client->mailbox, search_args->args) < 0) { client_send_storage_error(cmd, mailbox_get_storage(client->mailbox)); return TRUE; } + if (search_args != NULL) + mail_search_args_unref(&search_args); client->sync_seen_deletes = FALSE; client->sync_seen_expunges = FALSE; @@ -60,7 +62,7 @@ bool cmd_uid_expunge(struct client_command_context *cmd) { const struct imap_arg *args; - struct mail_search_arg *search_arg; + struct mail_search_args *search_args; const char *uidset; int ret; @@ -76,10 +78,10 @@ return TRUE; } - ret = imap_search_get_seqset(cmd, uidset, TRUE, &search_arg); + ret = imap_search_get_seqset(cmd, uidset, TRUE, &search_args); if (ret <= 0) return ret < 0; - return cmd_expunge_finish(cmd, search_arg); + return cmd_expunge_finish(cmd, search_args); } bool cmd_expunge(struct client_command_context *cmd)
--- a/src/imap/cmd-fetch.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/imap/cmd-fetch.c Wed Jun 04 00:51:58 2008 +0300 @@ -117,8 +117,8 @@ return FALSE; } if (ctx->send_vanished && - (ctx->search_args->next == NULL || - ctx->search_args->next->type != SEARCH_MODSEQ)) { + (ctx->search_args->args->next == NULL || + ctx->search_args->args->next->type != SEARCH_MODSEQ)) { client_send_command_error(ctx->cmd, "VANISHED used without CHANGEDSINCE"); return FALSE; @@ -175,7 +175,7 @@ struct client *client = cmd->client; struct imap_fetch_context *ctx; const struct imap_arg *args; - struct mail_search_arg *search_arg; + struct mail_search_args *search_args; const char *messageset; int ret; @@ -196,14 +196,14 @@ /* UID FETCH VANISHED needs the uidset, so convert it to sequence set later */ - ret = imap_search_get_anyset(cmd, messageset, cmd->uid, &search_arg); + ret = imap_search_get_anyset(cmd, messageset, cmd->uid, &search_args); if (ret <= 0) return ret < 0; ctx = imap_fetch_init(cmd, client->mailbox); if (ctx == NULL) return TRUE; - ctx->search_args = search_arg; + ctx->search_args = search_args; if (!fetch_parse_args(ctx, &args[1]) || (args[2].type == IMAP_ARG_LIST &&
--- a/src/imap/cmd-search.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/imap/cmd-search.c Wed Jun 04 00:51:58 2008 +0300 @@ -5,7 +5,6 @@ #include "str.h" #include "seq-range-array.h" #include "commands.h" -#include "mail-search.h" #include "mail-search-build.h" #include "imap-quote.h" #include "imap-util.h" @@ -29,7 +28,7 @@ struct mailbox_transaction_context *trans; struct mail_search_context *search_ctx; struct mail *mail; - struct mail_search_arg *sargs; + struct mail_search_args *sargs; enum search_return_options return_options; struct timeout *to; @@ -98,10 +97,10 @@ } static struct imap_search_context * -imap_search_init(struct imap_search_context *ctx, const char *charset, - struct mail_search_arg *sargs) +imap_search_init(struct imap_search_context *ctx, + struct mail_search_args *sargs) { - if (imap_search_args_have_modseq(sargs)) { + if (imap_search_args_have_modseq(sargs->args)) { ctx->return_options |= SEARCH_RETURN_MODSEQ; client_enable(ctx->cmd->client, MAILBOX_FEATURE_CONDSTORE); } @@ -109,7 +108,7 @@ ctx->box = ctx->cmd->client->mailbox; ctx->trans = mailbox_transaction_begin(ctx->box, 0); ctx->sargs = sargs; - ctx->search_ctx = mailbox_search_init(ctx->trans, charset, sargs, NULL); + ctx->search_ctx = mailbox_search_init(ctx->trans, sargs, NULL); ctx->mail = mail_alloc(ctx->trans, 0, NULL); (void)gettimeofday(&ctx->start_time, NULL); i_array_init(&ctx->result, 128); @@ -212,7 +211,8 @@ if (ctx->to != NULL) timeout_remove(&ctx->to); array_free(&ctx->result); - mail_search_args_deinit(ctx->sargs, ctx->box); + mail_search_args_deinit(ctx->sargs); + mail_search_args_unref(&ctx->sargs); ctx->cmd->context = NULL; return ret; @@ -358,7 +358,7 @@ { struct client *client = cmd->client; struct imap_search_context *ctx; - struct mail_search_arg *sargs; + struct mail_search_args *sargs; const struct imap_arg *args; enum search_return_options return_options; int ret, args_count; @@ -426,11 +426,11 @@ charset = "UTF-8"; } - ret = imap_search_args_build(cmd, args, &sargs); + ret = imap_search_args_build(cmd, args, charset, &sargs); if (ret <= 0) return ret < 0; - imap_search_init(ctx, charset, sargs); + imap_search_init(ctx, sargs); cmd->func = cmd_search_more; cmd->context = ctx;
--- a/src/imap/cmd-select.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/imap/cmd-select.c Wed Jun 04 00:51:58 2008 +0300 @@ -3,7 +3,7 @@ #include "common.h" #include "seq-range-array.h" #include "commands.h" -#include "mail-search.h" +#include "mail-search-build.h" #include "imap-messageset.h" #include "imap-fetch.h" #include "imap-sync.h" @@ -217,17 +217,18 @@ static int select_qresync(struct imap_select_context *ctx) { struct imap_fetch_context *fetch_ctx; - struct mail_search_arg *search_arg; + struct mail_search_args *search_args; - search_arg = p_new(ctx->cmd->pool, struct mail_search_arg, 1); - search_arg->type = SEARCH_UIDSET; - search_arg->value.seqset = ctx->qresync_known_uids; + search_args = mail_search_build_init(); + search_args->args = p_new(search_args->pool, struct mail_search_arg, 1); + search_args->args->type = SEARCH_UIDSET; + search_args->args->value.seqset = ctx->qresync_known_uids; fetch_ctx = imap_fetch_init(ctx->cmd, ctx->box); if (fetch_ctx == NULL) return -1; - fetch_ctx->search_args = search_arg; + fetch_ctx->search_args = search_args; fetch_ctx->send_vanished = TRUE; fetch_ctx->qresync_sample_seqset = &ctx->qresync_sample_seqset; fetch_ctx->qresync_sample_uidset = &ctx->qresync_sample_uidset;
--- a/src/imap/cmd-sort.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/imap/cmd-sort.c Wed Jun 04 00:51:58 2008 +0300 @@ -85,7 +85,7 @@ bool cmd_sort(struct client_command_context *cmd) { struct client *client = cmd->client; - struct mail_search_arg *sargs; + struct mail_search_args *sargs; enum mail_sort_type sorting[MAX_SORT_PROGRAM_SIZE]; const struct imap_arg *args; int args_count; @@ -125,11 +125,13 @@ charset = IMAP_ARG_STR(args); args++; - ret = imap_search_args_build(cmd, args, &sargs); + ret = imap_search_args_build(cmd, args, charset, &sargs); if (ret <= 0) return ret < 0; - if (imap_sort(cmd, charset, sargs, sorting) < 0) { + ret = imap_sort(cmd, sargs, sorting); + mail_search_args_unref(&sargs); + if (ret < 0) { client_send_storage_error(cmd, mailbox_get_storage(client->mailbox)); return TRUE;
--- a/src/imap/cmd-store.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/imap/cmd-store.c Wed Jun 04 00:51:58 2008 +0300 @@ -117,7 +117,7 @@ { struct client *client = cmd->client; const struct imap_arg *args; - struct mail_search_arg *search_arg; + struct mail_search_args *search_args; struct mail_search_context *search_ctx; struct mailbox_transaction_context *t; struct mail *mail; @@ -140,7 +140,7 @@ return TRUE; } ret = imap_search_get_seqset(cmd, IMAP_ARG_STR_NONULL(args), - cmd->uid, &search_arg); + cmd->uid, &search_args); if (ret <= 0) return ret < 0; @@ -154,7 +154,8 @@ if (ctx.max_modseq < (uint64_t)-1) flags |= MAILBOX_TRANSACTION_FLAG_REFRESH; t = mailbox_transaction_begin(client->mailbox, flags); - search_ctx = mailbox_search_init(t, NULL, search_arg, NULL); + search_ctx = mailbox_search_init(t, search_args, NULL); + mail_search_args_unref(&search_args); /* FIXME: UNCHANGEDSINCE should be atomic, but this requires support from mail-storage API. So for now we fake it. */
--- a/src/imap/cmd-thread.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/imap/cmd-thread.c Wed Jun 04 00:51:58 2008 +0300 @@ -10,7 +10,7 @@ { struct client *client = cmd->client; enum mail_thread_type threading; - struct mail_search_arg *sargs; + struct mail_search_args *sargs; const struct imap_arg *args; int ret, args_count; const char *charset, *str; @@ -57,11 +57,13 @@ charset = IMAP_ARG_STR(args); args++; - ret = imap_search_args_build(cmd, args, &sargs); + ret = imap_search_args_build(cmd, args, charset, &sargs); if (ret <= 0) return ret < 0; - if (imap_thread(cmd, charset, sargs, threading) < 0) { + ret = imap_thread(cmd, sargs, threading); + mail_search_args_unref(&sargs); + if (ret < 0) { client_send_storage_error(cmd, mailbox_get_storage(client->mailbox)); return TRUE;
--- a/src/imap/imap-expunge.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/imap/imap-expunge.c Wed Jun 04 00:51:58 2008 +0300 @@ -2,7 +2,7 @@ #include "common.h" #include "mail-storage.h" -#include "mail-search.h" +#include "mail-search-build.h" #include "imap-expunge.h" int imap_expunge(struct mailbox *box, struct mail_search_arg *next_search_arg) @@ -10,7 +10,7 @@ struct mail_search_context *ctx; struct mailbox_transaction_context *t; struct mail *mail; - struct mail_search_arg search_arg; + struct mail_search_args *search_args; bool expunges = FALSE; if (mailbox_is_readonly(box)) { @@ -18,15 +18,17 @@ return 0; } - memset(&search_arg, 0, sizeof(search_arg)); - search_arg.type = SEARCH_FLAGS; - search_arg.value.flags = MAIL_DELETED; - search_arg.next = next_search_arg; + search_args = mail_search_build_init(); + search_args->args = p_new(search_args->pool, struct mail_search_arg, 1); + search_args->args->type = SEARCH_FLAGS; + search_args->args->value.flags = MAIL_DELETED; + search_args->args->next = next_search_arg; /* Refresh the flags so we'll expunge all messages marked as \Deleted by any session. */ t = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_REFRESH); - ctx = mailbox_search_init(t, NULL, &search_arg, NULL); + ctx = mailbox_search_init(t, search_args, NULL); + mail_search_args_unref(&search_args); mail = mail_alloc(t, 0, NULL); while (mailbox_search_next(ctx, mail) > 0) {
--- a/src/imap/imap-expunge.h Sun Mar 16 12:10:57 2008 +0200 +++ b/src/imap/imap-expunge.h Wed Jun 04 00:51:58 2008 +0300 @@ -1,6 +1,8 @@ #ifndef IMAP_EXPUNGE_H #define IMAP_EXPUNGE_H +struct mail_search_arg; + int imap_expunge(struct mailbox *box, struct mail_search_arg *next_search_arg); #endif
--- a/src/imap/imap-fetch.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/imap/imap-fetch.c Wed Jun 04 00:51:58 2008 +0300 @@ -9,7 +9,6 @@ #include "message-send.h" #include "message-size.h" #include "imap-date.h" -#include "mail-search.h" #include "mail-search-build.h" #include "commands.h" #include "imap-fetch.h" @@ -113,14 +112,14 @@ { struct mail_search_arg *search_arg; - search_arg = p_new(ctx->cmd->pool, struct mail_search_arg, 1); + search_arg = p_new(ctx->search_args->pool, struct mail_search_arg, 1); search_arg->type = SEARCH_MODSEQ; search_arg->value.modseq = p_new(ctx->cmd->pool, struct mail_search_modseq, 1); search_arg->value.modseq->modseq = modseq; - search_arg->next = ctx->search_args->next; - ctx->search_args->next = search_arg; + search_arg->next = ctx->search_args->args->next; + ctx->search_args->args->next = search_arg; return imap_fetch_init_handler(ctx, "MODSEQ", NULL); } @@ -200,7 +199,7 @@ ARRAY_TYPE(seq_range) *expunges) { struct mailbox_transaction_context *trans; - struct mail_search_arg search_arg; + struct mail_search_args *search_args; struct mail_search_context *search_ctx; struct mail *mail; const struct seq_range *uid_range; @@ -215,14 +214,17 @@ next_uid = uid_range[0].seq1; /* search UIDs in given range */ - memset(&search_arg, 0, sizeof(search_arg)); - search_arg.type = SEARCH_UIDSET; - i_array_init(&search_arg.value.seqset, array_count(uids)); - array_append_array(&search_arg.value.seqset, uids); + search_args = mail_search_build_init(); + search_args->args = p_new(search_args->pool, struct mail_search_arg, 1); + search_args->args->type = SEARCH_UIDSET; + i_array_init(&search_args->args->value.seqset, array_count(uids)); + array_append_array(&search_args->args->value.seqset, uids); trans = mailbox_transaction_begin(ctx->box, 0); mail = mail_alloc(trans, 0, NULL); - search_ctx = mailbox_search_init(trans, NULL, &search_arg, NULL); + search_ctx = mailbox_search_init(trans, search_args, NULL); + mail_search_args_unref(&search_args); + while (mailbox_search_next(search_ctx, mail) > 0) { if (mail->uid == next_uid) { if (next_uid < uid_range[i].seq2) @@ -279,7 +281,7 @@ static int imap_fetch_send_vanished(struct imap_fetch_context *ctx) { - const struct mail_search_arg *uidarg = ctx->search_args; + const struct mail_search_arg *uidarg = ctx->search_args->args; const struct mail_search_arg *modseqarg = uidarg->next; const ARRAY_TYPE(seq_range) *uids = &uidarg->value.seqset; uint64_t modseq = modseqarg->value.modseq->modseq; @@ -352,7 +354,7 @@ mail_search_args_init(ctx->search_args, ctx->box, TRUE, &ctx->cmd->client->search_saved_uidset); ctx->search_ctx = - mailbox_search_init(ctx->trans, NULL, ctx->search_args, NULL); + mailbox_search_init(ctx->trans, ctx->search_args, NULL); return 0; }
--- a/src/imap/imap-fetch.h Sun Mar 16 12:10:57 2008 +0200 +++ b/src/imap/imap-fetch.h Wed Jun 04 00:51:58 2008 +0300 @@ -33,7 +33,7 @@ struct mailbox *box; struct mailbox_transaction_context *trans; - struct mail_search_arg *search_args; + struct mail_search_args *search_args; struct mail_search_context *search_ctx; struct mail *mail;
--- a/src/imap/imap-search.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/imap/imap-search.c Wed Jun 04 00:51:58 2008 +0300 @@ -2,7 +2,6 @@ #include "common.h" #include "mail-storage.h" -#include "mail-search.h" #include "mail-search-build.h" #include "imap-search.h" #include "imap-parser.h" @@ -37,19 +36,19 @@ } int imap_search_args_build(struct client_command_context *cmd, - const struct imap_arg *args, - struct mail_search_arg **search_args_r) + const struct imap_arg *args, const char *charset, + struct mail_search_args **search_args_r) { - struct mail_search_arg *sargs; + struct mail_search_args *sargs; const char *error; - sargs = mail_search_build_from_imap_args(cmd->pool, args, &error); - if (sargs == NULL) { + if (mail_search_build_from_imap_args(args, charset, + &sargs, &error) < 0) { client_send_command_error(cmd, error); return -1; } - if (search_args_have_searchres(sargs)) { + if (search_args_have_searchres(sargs->args)) { if (client_handle_search_save_ambiguity(cmd)) return 0; } @@ -89,51 +88,54 @@ static int imap_search_get_msgset_arg(struct client_command_context *cmd, const char *messageset, - struct mail_search_arg **arg_r, + struct mail_search_args **args_r, const char **error_r) { - struct mail_search_arg *arg; + struct mail_search_args *args; - arg = p_new(cmd->pool, struct mail_search_arg, 1); - arg->type = SEARCH_SEQSET; - p_array_init(&arg->value.seqset, cmd->pool, 16); - if (imap_messageset_parse(&arg->value.seqset, messageset) < 0 || - !msgset_is_valid(&arg->value.seqset, cmd->client->messages_count)) { + args = mail_search_build_init(); + args->args = p_new(args->pool, struct mail_search_arg, 1); + args->args->type = SEARCH_SEQSET; + p_array_init(&args->args->value.seqset, args->pool, 16); + if (imap_messageset_parse(&args->args->value.seqset, messageset) < 0 || + !msgset_is_valid(&args->args->value.seqset, + cmd->client->messages_count)) { *error_r = "Invalid messageset"; return -1; } - *arg_r = arg; + *args_r = args; return 0; } static int imap_search_get_uidset_arg(struct client_command_context *cmd, - const char *uidset, - struct mail_search_arg **arg_r, const char **error_r) + const char *uidset, struct mail_search_args **args_r, + const char **error_r) { - struct mail_search_arg *arg; + struct mail_search_args *args; - arg = p_new(cmd->pool, struct mail_search_arg, 1); - arg->type = SEARCH_UIDSET; - p_array_init(&arg->value.seqset, cmd->pool, 16); - if (imap_messageset_parse(&arg->value.seqset, uidset) < 0) { + args = mail_search_build_init(); + args->args = p_new(args->pool, struct mail_search_arg, 1); + args->args->type = SEARCH_UIDSET; + p_array_init(&args->args->value.seqset, cmd->pool, 16); + if (imap_messageset_parse(&args->args->value.seqset, uidset) < 0) { *error_r = "Invalid uidset"; return -1; } - *arg_r = arg; + *args_r = args; return 0; } int imap_search_get_seqset(struct client_command_context *cmd, const char *set, bool uid, - struct mail_search_arg **search_arg_r) + struct mail_search_args **search_args_r) { int ret; - ret = imap_search_get_anyset(cmd, set, uid, search_arg_r); + ret = imap_search_get_anyset(cmd, set, uid, search_args_r); if (ret > 0) { - mail_search_args_init(*search_arg_r, + mail_search_args_init(*search_args_r, cmd->client->mailbox, TRUE, &cmd->client->search_saved_uidset); } @@ -141,31 +143,34 @@ } static int imap_search_get_searchres(struct client_command_context *cmd, - struct mail_search_arg **search_arg_r) + struct mail_search_args **search_args_r) { - struct mail_search_arg *search_arg; + struct mail_search_args *search_args; if (client_handle_search_save_ambiguity(cmd)) return 0; - search_arg = p_new(cmd->pool, struct mail_search_arg, 1); + + search_args = mail_search_build_init(); + search_args->args = p_new(search_args->pool, struct mail_search_arg, 1); if (array_is_created(&cmd->client->search_saved_uidset)) { - search_arg->type = SEARCH_UIDSET; - p_array_init(&search_arg->value.seqset, cmd->pool, + search_args->args->type = SEARCH_UIDSET; + p_array_init(&search_args->args->value.seqset, + search_args->pool, array_count(&cmd->client->search_saved_uidset)); - array_append_array(&search_arg->value.seqset, + array_append_array(&search_args->args->value.seqset, &cmd->client->search_saved_uidset); } else { /* $ not set yet, match nothing */ - search_arg->type = SEARCH_ALL; - search_arg->not = TRUE; + search_args->args->type = SEARCH_ALL; + search_args->args->not = TRUE; } - *search_arg_r = search_arg; + *search_args_r = search_args; return 1; } int imap_search_get_anyset(struct client_command_context *cmd, const char *set, bool uid, - struct mail_search_arg **search_arg_r) + struct mail_search_args **search_args_r) { const char *error = NULL; int ret; @@ -173,12 +178,15 @@ if (strcmp(set, "$") == 0) { /* SEARCHRES extension: replace $ with the last saved search result */ - return imap_search_get_searchres(cmd, search_arg_r); + return imap_search_get_searchres(cmd, search_args_r); } - if (!uid) - ret = imap_search_get_msgset_arg(cmd, set, search_arg_r, &error); - else - ret = imap_search_get_uidset_arg(cmd, set, search_arg_r, &error); + if (!uid) { + ret = imap_search_get_msgset_arg(cmd, set, search_args_r, + &error); + } else { + ret = imap_search_get_uidset_arg(cmd, set, search_args_r, + &error); + } if (ret < 0) { client_send_command_error(cmd, error); return -1;
--- a/src/imap/imap-search.h Sun Mar 16 12:10:57 2008 +0200 +++ b/src/imap/imap-search.h Wed Jun 04 00:51:58 2008 +0300 @@ -1,6 +1,8 @@ #ifndef IMAP_SEARCH_H #define IMAP_SEARCH_H +#include "mail-search.h" + struct imap_arg; struct mailbox; struct client_command_context; @@ -9,16 +11,16 @@ arguments are invalid, 0 if we have to wait for unambiguity, 1 if we can continue. */ int imap_search_args_build(struct client_command_context *cmd, - const struct imap_arg *args, - struct mail_search_arg **search_args_r); + const struct imap_arg *args, const char *charset, + struct mail_search_args **search_args_r); /* Returns -1 if set is invalid, 0 if we have to wait for unambiguity, 1 if we can continue. */ int imap_search_get_seqset(struct client_command_context *cmd, const char *set, bool uid, - struct mail_search_arg **search_arg_r); + struct mail_search_args **search_args_r); int imap_search_get_anyset(struct client_command_context *cmd, const char *set, bool uid, - struct mail_search_arg **search_arg_r); + struct mail_search_args **search_args_r); #endif
--- a/src/imap/imap-sort.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/imap/imap-sort.c Wed Jun 04 00:51:58 2008 +0300 @@ -37,8 +37,7 @@ bool written; }; -int imap_sort(struct client_command_context *cmd, const char *charset, - struct mail_search_arg *args, +int imap_sort(struct client_command_context *cmd, struct mail_search_args *args, const enum mail_sort_type *sort_program) { struct client *client = cmd->client; @@ -82,7 +81,7 @@ mailbox_header_lookup_init(client->mailbox, wanted_headers); t = mailbox_transaction_begin(client->mailbox, 0); - search_ctx = mailbox_search_init(t, charset, args, sort_program); + search_ctx = mailbox_search_init(t, args, sort_program); str = t_str_new(STRBUF_SIZE); str_append(str, "* SORT");
--- a/src/imap/imap-sort.h Sun Mar 16 12:10:57 2008 +0200 +++ b/src/imap/imap-sort.h Wed Jun 04 00:51:58 2008 +0300 @@ -1,8 +1,7 @@ #ifndef IMAP_SORT_H #define IMAP_SORT_H -int imap_sort(struct client_command_context *cmd, const char *charset, - struct mail_search_arg *args, +int imap_sort(struct client_command_context *cmd, struct mail_search_args *args, const enum mail_sort_type *sort_program); #endif
--- a/src/imap/imap-thread.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/imap/imap-thread.c Wed Jun 04 00:51:58 2008 +0300 @@ -101,8 +101,8 @@ pool_unref(&ctx->pool); } -int imap_thread(struct client_command_context *cmd, const char *charset, - struct mail_search_arg *args, enum mail_thread_type type) +int imap_thread(struct client_command_context *cmd, + struct mail_search_args *args, enum mail_thread_type type) { static const char *wanted_headers[] = { "message-id", "in-reply-to", "references", "subject", @@ -121,7 +121,7 @@ /* initialize searching */ ctx->t = mailbox_transaction_begin(client->mailbox, 0); - ctx->search_ctx = mailbox_search_init(ctx->t, charset, args, NULL); + ctx->search_ctx = mailbox_search_init(ctx->t, args, NULL); ctx->box = client->mailbox; ctx->output = client->output;
--- a/src/imap/imap-thread.h Sun Mar 16 12:10:57 2008 +0200 +++ b/src/imap/imap-thread.h Wed Jun 04 00:51:58 2008 +0300 @@ -7,7 +7,7 @@ MAIL_THREAD_REFERENCES }; -int imap_thread(struct client_command_context *cmd, const char *charset, - struct mail_search_arg *args, enum mail_thread_type type); +int imap_thread(struct client_command_context *cmd, + struct mail_search_args *args, enum mail_thread_type type); #endif
--- a/src/lib-storage/index/index-search.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/lib-storage/index/index-search.c Wed Jun 04 00:51:58 2008 +0300 @@ -329,7 +329,7 @@ MESSAGE_SEARCH_FLAG_SKIP_HEADERS : 0; ret = message_search_init(ctx->search_pool, arg->value.str, - ctx->mail_ctx.charset, flags, + ctx->mail_ctx.args->charset, flags, &arg_ctx); if (ret > 0) { arg->context = arg_ctx; @@ -849,7 +849,7 @@ struct mail_search_context * index_storage_search_init(struct mailbox_transaction_context *_t, - const char *charset, struct mail_search_arg *args, + struct mail_search_args *args, const enum mail_sort_type *sort_program) { struct index_transaction_context *t = @@ -860,20 +860,19 @@ ctx->mail_ctx.transaction = _t; ctx->ibox = t->ibox; ctx->view = t->trans_view; - ctx->mail_ctx.charset = i_strdup(charset); ctx->mail_ctx.args = args; ctx->mail_ctx.sort_program = index_sort_program_init(_t, sort_program); array_create(&ctx->mail_ctx.module_contexts, default_pool, sizeof(void *), 5); - mail_search_args_reset(ctx->mail_ctx.args, TRUE); + mail_search_args_reset(ctx->mail_ctx.args->args, TRUE); - search_get_seqset(ctx, args); - (void)mail_search_args_foreach(args, search_init_arg, ctx); + search_get_seqset(ctx, args->args); + (void)mail_search_args_foreach(args->args, search_init_arg, ctx); /* Need to reset results for match_always cases */ - mail_search_args_reset(ctx->mail_ctx.args, FALSE); + mail_search_args_reset(ctx->mail_ctx.args->args, FALSE); return &ctx->mail_ctx; } @@ -900,8 +899,8 @@ MAIL_ERROR_PARAMS, ctx->error); } - mail_search_args_reset(ctx->mail_ctx.args, FALSE); - (void)mail_search_args_foreach(ctx->mail_ctx.args, + mail_search_args_reset(ctx->mail_ctx.args->args, FALSE); + (void)mail_search_args_foreach(ctx->mail_ctx.args->args, search_arg_deinit, NULL); if (ctx->search_pool != NULL) @@ -910,7 +909,6 @@ if (ctx->mail_ctx.sort_program != NULL) index_sort_program_deinit(&ctx->mail_ctx.sort_program); array_free(&ctx->mail_ctx.module_contexts); - i_free(ctx->mail_ctx.charset); i_free(ctx); return ret; } @@ -921,16 +919,16 @@ int ret; /* next search only from cached arguments */ - ret = mail_search_args_foreach(ctx->mail_ctx.args, + ret = mail_search_args_foreach(ctx->mail_ctx.args->args, search_cached_arg, ctx); if (ret >= 0) return ret > 0; /* open the mail file and check the rest */ - if (!search_arg_match_text(ctx->mail_ctx.args, ctx)) + if (!search_arg_match_text(ctx->mail_ctx.args->args, ctx)) return FALSE; - for (arg = ctx->mail_ctx.args; arg != NULL; arg = arg->next) { + for (arg = ctx->mail_ctx.args->args; arg != NULL; arg = arg->next) { if (arg->result != 1) return FALSE; } @@ -1005,7 +1003,7 @@ ret = search_match_next(ctx) ? 1 : 0; } T_END; - mail_search_args_reset(ctx->mail_ctx.args, FALSE); + mail_search_args_reset(ctx->mail_ctx.args->args, FALSE); if (ctx->error != NULL) ret = -1; @@ -1056,14 +1054,14 @@ ret = 0; while (_ctx->seq <= ctx->seq2) { /* check if the sequence matches */ - ret = mail_search_args_foreach(ctx->mail_ctx.args, + ret = mail_search_args_foreach(ctx->mail_ctx.args->args, search_seqset_arg, ctx); if (ret != 0) { /* check if flags/keywords match before anything else is done. mail_set_seq() can be a bit slow. */ if (!ctx->have_index_args) break; - ret = mail_search_args_foreach(ctx->mail_ctx.args, + ret = mail_search_args_foreach(ctx->mail_ctx.args->args, search_index_arg, ctx); if (ret != 0) break; @@ -1071,7 +1069,7 @@ /* doesn't, try next one */ _ctx->seq++; - mail_search_args_reset(ctx->mail_ctx.args, FALSE); + mail_search_args_reset(ctx->mail_ctx.args->args, FALSE); } return ret == 0 ? 0 : 1; }
--- a/src/lib-storage/index/index-storage.h Sun Mar 16 12:10:57 2008 +0200 +++ b/src/lib-storage/index/index-storage.h Wed Jun 04 00:51:58 2008 +0300 @@ -156,7 +156,7 @@ struct mail_search_context * index_storage_search_init(struct mailbox_transaction_context *t, - const char *charset, struct mail_search_arg *args, + struct mail_search_args *args, const enum mail_sort_type *sort_program); int index_storage_search_deinit(struct mail_search_context *ctx); int index_storage_search_next(struct mail_search_context *ctx,
--- a/src/lib-storage/mail-search-build.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/lib-storage/mail-search-build.c Wed Jun 04 00:51:58 2008 +0300 @@ -5,7 +5,6 @@ #include "imap-date.h" #include "imap-parser.h" #include "imap-messageset.h" -#include "mail-search.h" #include "mail-search-build.h" #include "mail-storage.h" @@ -608,131 +607,71 @@ return FALSE; } -struct mail_search_arg * -mail_search_build_from_imap_args(pool_t pool, const struct imap_arg *args, - const char **error_r) +int mail_search_build_from_imap_args(const struct imap_arg *imap_args, + const char *charset, + struct mail_search_args **args_r, + const char **error_r) { struct search_build_data data; - struct mail_search_arg *first_sarg, **sargs; + struct mail_search_args *args; + struct mail_search_arg **sargs; - data.pool = pool; + *args_r = NULL; + *error_r = NULL; + + args = mail_search_build_init(); + args->charset = p_strdup(args->pool, charset); + + data.pool = args->pool; data.error = NULL; - first_sarg = NULL; sargs = &first_sarg; - while (args->type != IMAP_ARG_EOL) { - if (!search_arg_build(&data, &args, sargs)) { - first_sarg = NULL; - break; + sargs = &args->args; + while (imap_args->type != IMAP_ARG_EOL) { + if (!search_arg_build(&data, &imap_args, sargs)) { + pool_unref(&args->pool); + *error_r = data.error; + return -1; } sargs = &(*sargs)->next; } - *error_r = data.error; - return first_sarg; + *args_r = args; + return 0; } -static void -mailbox_uidset_change(struct mail_search_arg *arg, struct mailbox *box, - const ARRAY_TYPE(seq_range) *search_saved_uidset) +struct mail_search_args *mail_search_build_init(void) { - struct seq_range *uids; - unsigned int i, count; - uint32_t seq1, seq2; - - if (strcmp(arg->value.str, "$") == 0) { - /* SEARCHRES: Replace with saved uidset */ - array_clear(&arg->value.seqset); - if (search_saved_uidset == NULL || - !array_is_created(search_saved_uidset)) - return; - - array_append_array(&arg->value.seqset, search_saved_uidset); - return; - } - - arg->type = SEARCH_SEQSET; + struct mail_search_args *args; + pool_t pool; - /* make a copy of the UIDs */ - count = array_count(&arg->value.seqset); - if (count == 0) { - /* empty set, keep it */ - return; - } - uids = t_new(struct seq_range, count); - memcpy(uids, array_idx(&arg->value.seqset, 0), sizeof(*uids) * count); - - /* put them back to the range as sequences */ - array_clear(&arg->value.seqset); - for (i = 0; i < count; i++) { - mailbox_get_uids(box, uids[i].seq1, uids[i].seq2, &seq1, &seq2); - if (seq1 != 0) { - seq_range_array_add_range(&arg->value.seqset, - seq1, seq2); - } - if (uids[i].seq2 == (uint32_t)-1) { - /* make sure the last message is in the range */ - mailbox_get_uids(box, 1, (uint32_t)-1, &seq1, &seq2); - seq_range_array_add(&arg->value.seqset, 0, seq2); - } - } + pool = pool_alloconly_create("mail search args", 1024); + args = p_new(pool, struct mail_search_args, 1); + args->pool = pool; + args->refcount = 1; + return args; } -void mail_search_args_init(struct mail_search_arg *args, - struct mailbox *box, bool change_uidsets, - const ARRAY_TYPE(seq_range) *search_saved_uidset) +void mail_search_build_add_all(struct mail_search_args *args) { - const char *keywords[2]; + struct mail_search_arg *arg; - for (; args != NULL; args = args->next) { - switch (args->type) { - case SEARCH_UIDSET: - if (change_uidsets) T_BEGIN { - mailbox_uidset_change(args, box, - search_saved_uidset); - } T_END; - break; - case SEARCH_MODSEQ: - if (args->value.str == NULL) - break; - /* modseq with keyword */ - case SEARCH_KEYWORDS: - keywords[0] = args->value.str; - keywords[1] = NULL; + arg = p_new(args->pool, struct mail_search_arg, 1); + arg->type = SEARCH_ALL; - i_assert(args->value.keywords == NULL); - args->value.keywords = - mailbox_keywords_create_valid(box, keywords); - break; - - case SEARCH_SUB: - case SEARCH_OR: - mail_search_args_init(args->value.subargs, box, - change_uidsets, - search_saved_uidset); - break; - default: - break; - } - } + arg->next = args->args; + args->args = arg; } -void mail_search_args_deinit(struct mail_search_arg *args, - struct mailbox *box) +void mail_search_build_add_seqset(struct mail_search_args *args, + uint32_t seq1, uint32_t seq2) { - for (; args != NULL; args = args->next) { - switch (args->type) { - case SEARCH_MODSEQ: - case SEARCH_KEYWORDS: - if (args->value.keywords == NULL) - break; - mailbox_keywords_free(box, &args->value.keywords); - break; - case SEARCH_SUB: - case SEARCH_OR: - mail_search_args_deinit(args->value.subargs, box); - break; - default: - break; - } - } + struct mail_search_arg *arg; + + arg = p_new(args->pool, struct mail_search_arg, 1); + arg->type = SEARCH_SEQSET; + p_array_init(&arg->value.seqset, args->pool, 1); + seq_range_array_add_range(&arg->value.seqset, seq1, seq2); + + arg->next = args->args; + args->args = arg; }
--- a/src/lib-storage/mail-search-build.h Sun Mar 16 12:10:57 2008 +0200 +++ b/src/lib-storage/mail-search-build.h Wed Jun 04 00:51:58 2008 +0300 @@ -1,20 +1,20 @@ #ifndef MAIL_SEARCH_BUILD_H #define MAIL_SEARCH_BUILD_H +#include "mail-search.h" + struct imap_arg; struct mailbox; -struct mail_search_arg * -mail_search_build_from_imap_args(pool_t pool, const struct imap_arg *args, - const char **error_r); +struct mail_search_args *mail_search_build_init(void); -/* Allocate keywords for search arguments. If change_uidsets is TRUE, - change uidsets to seqsets. */ -void mail_search_args_init(struct mail_search_arg *args, - struct mailbox *box, bool change_uidsets, - const ARRAY_TYPE(seq_range) *search_saved_uidset); -/* Free keywords. The args can initialized afterwards again if needed. */ -void mail_search_args_deinit(struct mail_search_arg *args, - struct mailbox *box); +int mail_search_build_from_imap_args(const struct imap_arg *imap_args, + const char *charset, + struct mail_search_args **args_r, + const char **error_r); + +void mail_search_build_add_all(struct mail_search_args *args); +void mail_search_build_add_seqset(struct mail_search_args *args, + uint32_t seq1, uint32_t seq2); #endif
--- a/src/lib-storage/mail-search.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/lib-storage/mail-search.c Wed Jun 04 00:51:58 2008 +0300 @@ -4,8 +4,151 @@ #include "array.h" #include "buffer.h" #include "mail-index.h" +#include "mail-storage.h" #include "mail-search.h" +static void +mailbox_uidset_change(struct mail_search_arg *arg, struct mailbox *box, + const ARRAY_TYPE(seq_range) *search_saved_uidset) +{ + struct seq_range *uids; + unsigned int i, count; + uint32_t seq1, seq2; + + if (arg->value.str != NULL && strcmp(arg->value.str, "$") == 0) { + /* SEARCHRES: Replace with saved uidset */ + array_clear(&arg->value.seqset); + if (search_saved_uidset == NULL || + !array_is_created(search_saved_uidset)) + return; + + array_append_array(&arg->value.seqset, search_saved_uidset); + return; + } + + arg->type = SEARCH_SEQSET; + + /* make a copy of the UIDs */ + count = array_count(&arg->value.seqset); + if (count == 0) { + /* empty set, keep it */ + return; + } + uids = t_new(struct seq_range, count); + memcpy(uids, array_idx(&arg->value.seqset, 0), sizeof(*uids) * count); + + /* put them back to the range as sequences */ + array_clear(&arg->value.seqset); + for (i = 0; i < count; i++) { + mailbox_get_uids(box, uids[i].seq1, uids[i].seq2, &seq1, &seq2); + if (seq1 != 0) { + seq_range_array_add_range(&arg->value.seqset, + seq1, seq2); + } + if (uids[i].seq2 == (uint32_t)-1) { + /* make sure the last message is in the range */ + mailbox_get_uids(box, 1, (uint32_t)-1, &seq1, &seq2); + seq_range_array_add(&arg->value.seqset, 0, seq2); + } + } +} + +static void +mail_search_args_init_sub(struct mail_search_arg *args, + struct mailbox *box, bool change_uidsets, + const ARRAY_TYPE(seq_range) *search_saved_uidset) +{ + const char *keywords[2]; + + for (; args != NULL; args = args->next) { + switch (args->type) { + case SEARCH_UIDSET: + if (change_uidsets) T_BEGIN { + mailbox_uidset_change(args, box, + search_saved_uidset); + } T_END; + break; + case SEARCH_MODSEQ: + if (args->value.str == NULL) + break; + /* modseq with keyword */ + case SEARCH_KEYWORDS: + keywords[0] = args->value.str; + keywords[1] = NULL; + + i_assert(args->value.keywords == NULL); + args->value.keywords = + mailbox_keywords_create_valid(box, keywords); + break; + + case SEARCH_SUB: + case SEARCH_OR: + mail_search_args_init_sub(args->value.subargs, box, + change_uidsets, + search_saved_uidset); + break; + default: + break; + } + } +} + +void mail_search_args_init(struct mail_search_args *args, + struct mailbox *box, bool change_uidsets, + const ARRAY_TYPE(seq_range) *search_saved_uidset) +{ + args->box = box; + mail_search_args_init_sub(args->args, box, change_uidsets, + search_saved_uidset); +} + +static void mail_search_args_deinit_sub(struct mail_search_args *args, + struct mail_search_arg *arg) +{ + for (; arg != NULL; arg = arg->next) { + switch (arg->type) { + case SEARCH_MODSEQ: + case SEARCH_KEYWORDS: + if (arg->value.keywords == NULL) + break; + mailbox_keywords_free(args->box, &arg->value.keywords); + break; + case SEARCH_SUB: + case SEARCH_OR: + mail_search_args_deinit_sub(args, arg->value.subargs); + break; + default: + break; + } + } +} + +void mail_search_args_deinit(struct mail_search_args *args) +{ + mail_search_args_deinit_sub(args, args->args); +} + +void mail_search_args_ref(struct mail_search_args *args) +{ + i_assert(args->refcount > 0); + + args->refcount++; +} + +void mail_search_args_unref(struct mail_search_args **_args) +{ + struct mail_search_args *args = *_args; + + i_assert(args->refcount > 0); + + *_args = NULL; + if (--args->refcount > 0) + return; + + mail_search_args_deinit(args); + pool_unref(&args->pool); +} + void mail_search_args_reset(struct mail_search_arg *args, bool full_reset) { while (args != NULL) {
--- a/src/lib-storage/mail-search.h Sun Mar 16 12:10:57 2008 +0200 +++ b/src/lib-storage/mail-search.h Wed Jun 04 00:51:58 2008 +0300 @@ -85,6 +85,14 @@ int result; /* -1 = unknown, 0 = unmatched, 1 = matched */ }; +struct mail_search_args { + int refcount; + pool_t pool; + struct mailbox *box; + struct mail_search_arg *args; + const char *charset; +}; + #define ARG_SET_RESULT(arg, res) \ STMT_START { \ (arg)->result = !(arg)->not ? (res) : \ @@ -94,6 +102,17 @@ typedef void mail_search_foreach_callback_t(struct mail_search_arg *arg, void *context); +/* Allocate keywords for search arguments. If change_uidsets is TRUE, + change uidsets to seqsets. */ +void mail_search_args_init(struct mail_search_args *args, + struct mailbox *box, bool change_uidsets, + const ARRAY_TYPE(seq_range) *search_saved_uidset); +/* Free keywords. The args can initialized afterwards again if needed. */ +void mail_search_args_deinit(struct mail_search_args *args); + +void mail_search_args_ref(struct mail_search_args *args); +void mail_search_args_unref(struct mail_search_args **args); + /* Reset the results in search arguments. match_always is reset only if full_reset is TRUE. */ void mail_search_args_reset(struct mail_search_arg *args, bool full_reset);
--- a/src/lib-storage/mail-storage-private.h Sun Mar 16 12:10:57 2008 +0200 +++ b/src/lib-storage/mail-storage-private.h Wed Jun 04 00:51:58 2008 +0300 @@ -141,7 +141,7 @@ struct mail_search_context * (*search_init)(struct mailbox_transaction_context *t, - const char *charset, struct mail_search_arg *args, + struct mail_search_args *args, const enum mail_sort_type *sort_program); int (*search_deinit)(struct mail_search_context *ctx); int (*search_next_nonblock)(struct mail_search_context *ctx, @@ -288,8 +288,7 @@ struct mail_search_context { struct mailbox_transaction_context *transaction; - char *charset; - struct mail_search_arg *args; + struct mail_search_args *args; struct mail_search_sort_program *sort_program; uint32_t seq;
--- a/src/lib-storage/mail-storage.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/lib-storage/mail-storage.c Wed Jun 04 00:51:58 2008 +0300 @@ -631,11 +631,11 @@ struct mail_search_context * mailbox_search_init(struct mailbox_transaction_context *t, - const char *charset, struct mail_search_arg *args, + struct mail_search_args *args, const enum mail_sort_type *sort_program) { - mail_search_args_simplify(args); - return t->box->v.search_init(t, charset, args, sort_program); + mail_search_args_simplify(args->args); + return t->box->v.search_init(t, args, sort_program); } int mailbox_search_deinit(struct mail_search_context **_ctx)
--- a/src/lib-storage/mail-storage.h Sun Mar 16 12:10:57 2008 +0200 +++ b/src/lib-storage/mail-storage.h Wed Jun 04 00:51:58 2008 +0300 @@ -158,7 +158,7 @@ struct message_part; struct mail_namespace; struct mail_storage; -struct mail_search_arg; +struct mail_search_args; struct mail_keywords; struct mail_save_context; struct mailbox; @@ -376,7 +376,7 @@ returned in the requested order, otherwise from first to last. */ struct mail_search_context * mailbox_search_init(struct mailbox_transaction_context *t, - const char *charset, struct mail_search_arg *args, + struct mail_search_args *args, const enum mail_sort_type *sort_program); /* Deinitialize search request. */ int mailbox_search_deinit(struct mail_search_context **ctx);
--- a/src/plugins/convert/convert-storage.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/plugins/convert/convert-storage.c Wed Jun 04 00:51:58 2008 +0300 @@ -6,7 +6,7 @@ #include "file-dotlock.h" #include "mail-storage-private.h" #include "mail-namespace.h" -#include "mail-search.h" +#include "mail-search-build.h" #include "convert-storage.h" #include <stdio.h> @@ -35,7 +35,7 @@ struct mail_search_context *ctx; struct mailbox_transaction_context *src_trans, *dest_trans; struct mail *mail; - struct mail_search_arg search_arg; + struct mail_search_args *search_args; int ret = 0; if (mailbox_sync(srcbox, MAILBOX_SYNC_FLAG_FULL_READ, 0, NULL) < 0) { @@ -44,14 +44,16 @@ } *error_r = NULL; - memset(&search_arg, 0, sizeof(search_arg)); - search_arg.type = SEARCH_ALL; + search_args = mail_search_build_init(); + mail_search_build_add_all(search_args); src_trans = mailbox_transaction_begin(srcbox, 0); dest_trans = mailbox_transaction_begin(destbox, MAILBOX_TRANSACTION_FLAG_EXTERNAL); - ctx = mailbox_search_init(src_trans, NULL, &search_arg, NULL); + ctx = mailbox_search_init(src_trans, search_args, NULL); + mail_search_args_unref(&search_args); + mail = mail_alloc(src_trans, MAIL_FETCH_FLAGS | MAIL_FETCH_RECEIVED_DATE | MAIL_FETCH_STREAM_HEADER | MAIL_FETCH_STREAM_BODY |
--- a/src/plugins/expire/expire-tool.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/plugins/expire/expire-tool.c Wed Jun 04 00:51:58 2008 +0300 @@ -7,7 +7,7 @@ #include "lib-signals.h" #include "dict-client.h" #include "mail-index.h" -#include "mail-search.h" +#include "mail-search-build.h" #include "mail-storage.h" #include "mail-namespace.h" #include "auth-client.h" @@ -64,7 +64,7 @@ struct mailbox *box; struct mail_search_context *search_ctx; struct mailbox_transaction_context *t; - struct mail_search_arg search_arg; + struct mail_search_args *search_args; struct mail *mail; const char *ns_mailbox; time_t now, save_time; @@ -85,10 +85,6 @@ ctx->user = i_strdup(user); } - memset(&search_arg, 0, sizeof(search_arg)); - search_arg.type = SEARCH_ALL; - search_arg.next = NULL; - ns_mailbox = mailbox; ns = mail_namespace_find(ctx->ns, &ns_mailbox); if (ns == NULL) { @@ -108,8 +104,13 @@ return 0; } + search_args = mail_search_build_init(); + mail_search_build_add_all(search_args); + t = mailbox_transaction_begin(box, 0); - search_ctx = mailbox_search_init(t, NULL, &search_arg, NULL); + search_ctx = mailbox_search_init(t, search_args, NULL); + mail_search_args_unref(&search_args); + mail = mail_alloc(t, 0, NULL); now = time(NULL);
--- a/src/plugins/fts-squat/fts-backend-squat.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/plugins/fts-squat/fts-backend-squat.c Wed Jun 04 00:51:58 2008 +0300 @@ -3,7 +3,7 @@ #include "lib.h" #include "array.h" #include "mail-storage-private.h" -#include "mail-search.h" +#include "mail-search-build.h" #include "squat-trie.h" #include "fts-squat-plugin.h" @@ -110,16 +110,18 @@ { struct mailbox_transaction_context *t; struct mail_search_context *search_ctx; - struct mail_search_arg search_arg; + struct mail_search_args *search_args; struct mail *mail; int ret = 0; t = mailbox_transaction_begin(box, 0); - memset(&search_arg, 0, sizeof(search_arg)); - search_arg.type = SEARCH_ALL; + mail = mail_alloc(t, 0, NULL); - mail = mail_alloc(t, 0, NULL); - search_ctx = mailbox_search_init(t, NULL, &search_arg, NULL); + search_args = mail_search_build_init(); + mail_search_build_add_all(search_args); + search_ctx = mailbox_search_init(t, search_args, NULL); + mail_search_args_unref(&search_args); + while ((ret = mailbox_search_next(search_ctx, mail)) > 0) { /* *2 because even/odd is for body/header */ seq_range_array_add_range(uids, mail->uid * 2,
--- a/src/plugins/fts/fts-search.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/plugins/fts/fts-search.c Wed Jun 04 00:51:58 2008 +0300 @@ -86,7 +86,8 @@ /* convert key to titlecase */ key_utf8 = t_str_new(128); - if (charset_to_utf8_str(fctx->charset, CHARSET_FLAG_DECOMP_TITLECASE, + if (charset_to_utf8_str(fctx->args->charset, + CHARSET_FLAG_DECOMP_TITLECASE, key, key_utf8, &result) < 0) { /* unknown charset, can't handle this */ ret = 0; @@ -123,7 +124,7 @@ ret = fts_search_lookup_arg(fctx, fctx->best_arg, FALSE); } T_END; /* filter the rest */ - for (arg = fctx->args; arg != NULL && ret == 0; arg = arg->next) { + for (arg = fctx->args->args; arg != NULL && ret == 0; arg = arg->next) { if (arg != fctx->best_arg) { T_BEGIN { ret = fts_search_lookup_arg(fctx, arg, TRUE); @@ -196,7 +197,8 @@ { struct mail_search_arg *best_fast_arg = NULL, *best_substr_arg = NULL; - fts_search_args_find_best(fctx->args, &best_fast_arg, &best_substr_arg); + fts_search_args_find_best(fctx->args->args, &best_fast_arg, + &best_substr_arg); if (best_fast_arg != NULL && fctx->fbox->backend_fast != NULL) { /* use fast backend whenever possible */
--- a/src/plugins/fts/fts-storage.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/plugins/fts/fts-storage.c Wed Jun 04 00:51:58 2008 +0300 @@ -7,7 +7,7 @@ #include "istream.h" #include "message-parser.h" #include "message-decoder.h" -#include "mail-search.h" +#include "mail-search-build.h" #include "mail-storage-private.h" #include "fts-api-private.h" #include "fts-storage.h" @@ -25,7 +25,7 @@ struct fts_storage_build_context { struct mail_search_context *search_ctx; - struct mail_search_arg search_arg; + struct mail_search_args *search_args; struct mail *mail; struct fts_backend_build_context *build; @@ -167,6 +167,7 @@ static int fts_build_init(struct fts_search_context *fctx) { struct mailbox_transaction_context *t = fctx->t; + struct mail_search_args *search_args; struct fts_backend *backend = fctx->build_backend; struct fts_storage_build_context *ctx; struct fts_backend_build_context *build; @@ -201,15 +202,15 @@ } } + search_args = mail_search_build_init(); + mail_search_build_add_seqset(search_args, seq1, seq2); + ctx = i_new(struct fts_storage_build_context, 1); ctx->build = build; - ctx->search_arg.type = SEARCH_SEQSET; - i_array_init(&ctx->search_arg.value.seqset, 1); - seq_range_array_add_range(&ctx->search_arg.value.seqset, seq1, seq2); - ctx->headers = str_new(default_pool, 512); ctx->mail = mail_alloc(t, 0, NULL); - ctx->search_ctx = mailbox_search_init(t, NULL, &ctx->search_arg, NULL); + ctx->search_ctx = mailbox_search_init(t, search_args, NULL); + ctx->search_args = search_args; fctx->build_ctx = ctx; return 0; @@ -239,7 +240,7 @@ } str_free(&ctx->headers); - array_free(&ctx->search_arg.value.seqset); + mail_search_args_unref(&ctx->search_args); i_free(ctx); return ret; } @@ -256,7 +257,7 @@ already spent some time indexing the mailbox */ ctx->search_start_time = ioloop_timeval; } else if (box->storage->callbacks->notify_ok != NULL) { - range = array_idx(&ctx->search_arg.value.seqset, 0); + range = array_idx(&ctx->search_args->args->value.seqset, 0); percentage = (ctx->mail->seq - range->seq1) * 100.0 / (range->seq2 - range->seq1); msecs = (ioloop_timeval.tv_sec - @@ -330,21 +331,19 @@ static struct mail_search_context * fts_mailbox_search_init(struct mailbox_transaction_context *t, - const char *charset, struct mail_search_arg *args, + struct mail_search_args *args, const enum mail_sort_type *sort_program) { struct fts_mailbox *fbox = FTS_CONTEXT(t->box); struct mail_search_context *ctx; struct fts_search_context *fctx; - ctx = fbox->module_ctx.super. - search_init(t, charset, args, sort_program); + ctx = fbox->module_ctx.super.search_init(t, args, sort_program); fctx = i_new(struct fts_search_context, 1); fctx->fbox = fbox; fctx->t = t; fctx->args = args; - fctx->charset = ctx->charset; MODULE_CONTEXT_SET(ctx, fts_storage_module, fctx); if (fbox->backend_substr == NULL && fbox->backend_fast == NULL) @@ -395,7 +394,7 @@ { struct mail_search_arg *arg; - for (arg = fctx->args; arg != NULL; arg = arg->next) { + for (arg = fctx->args->args; arg != NULL; arg = arg->next) { switch (arg->type) { case SEARCH_TEXT: case SEARCH_BODY: @@ -474,7 +473,7 @@ if (ret <= 0 || wanted_seq == ctx->seq) break; wanted_seq = ctx->seq; - mail_search_args_reset(ctx->args, FALSE); + mail_search_args_reset(ctx->args->args, FALSE); } if (!use_maybe) {
--- a/src/plugins/fts/fts-storage.h Sun Mar 16 12:10:57 2008 +0200 +++ b/src/plugins/fts/fts-storage.h Wed Jun 04 00:51:58 2008 +0300 @@ -15,9 +15,8 @@ struct fts_mailbox *fbox; struct mailbox_transaction_context *t; - struct mail_search_arg *args; + struct mail_search_args *args; struct mail_search_arg *best_arg; - const char *charset; ARRAY_TYPE(seq_range) definite_seqs, maybe_seqs; unsigned int definite_idx, maybe_idx;
--- a/src/plugins/mbox-snarf/mbox-snarf-plugin.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/plugins/mbox-snarf/mbox-snarf-plugin.c Wed Jun 04 00:51:58 2008 +0300 @@ -3,7 +3,7 @@ #include "lib.h" #include "array.h" #include "home-expand.h" -#include "mail-search.h" +#include "mail-search-build.h" #include "mail-storage-private.h" #include "mailbox-list-private.h" #include "mbox-snarf-plugin.h" @@ -37,7 +37,7 @@ static int mbox_snarf(struct mailbox *srcbox, struct mailbox *destbox) { - struct mail_search_arg search_arg; + struct mail_search_args *search_args; struct mail_search_context *search_ctx; struct mailbox_transaction_context *src_trans, *dest_trans; struct mail *mail; @@ -46,13 +46,14 @@ if (mailbox_sync(srcbox, MAILBOX_SYNC_FLAG_FULL_READ, 0, NULL) < 0) return -1; - memset(&search_arg, 0, sizeof(search_arg)); - search_arg.type = SEARCH_ALL; - src_trans = mailbox_transaction_begin(srcbox, 0); dest_trans = mailbox_transaction_begin(destbox, MAILBOX_TRANSACTION_FLAG_EXTERNAL); - search_ctx = mailbox_search_init(src_trans, NULL, &search_arg, NULL); + + search_args = mail_search_build_init(); + mail_search_build_add_all(search_args); + search_ctx = mailbox_search_init(src_trans, search_args, NULL); + mail_search_args_unref(&search_args); mail = mail_alloc(src_trans, MAIL_FETCH_STREAM_HEADER | MAIL_FETCH_STREAM_BODY, NULL);
--- a/src/plugins/quota/quota-count.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/plugins/quota/quota-count.c Wed Jun 04 00:51:58 2008 +0300 @@ -2,7 +2,7 @@ #include "lib.h" #include "array.h" -#include "mail-search.h" +#include "mail-search-build.h" #include "mail-storage.h" #include "quota-private.h" @@ -13,7 +13,7 @@ struct mailbox_transaction_context *trans; struct mail_search_context *ctx; struct mail *mail; - struct mail_search_arg search_arg; + struct mail_search_args *search_args; uoff_t size; int ret = 0; @@ -27,12 +27,14 @@ return -1; } - memset(&search_arg, 0, sizeof(search_arg)); - search_arg.type = SEARCH_ALL; + trans = mailbox_transaction_begin(box, 0); + mail = mail_alloc(trans, MAIL_FETCH_PHYSICAL_SIZE, NULL); - trans = mailbox_transaction_begin(box, 0); - ctx = mailbox_search_init(trans, NULL, &search_arg, NULL); - mail = mail_alloc(trans, MAIL_FETCH_PHYSICAL_SIZE, NULL); + search_args = mail_search_build_init(); + mail_search_build_add_all(search_args); + ctx = mailbox_search_init(trans, search_args, NULL); + mail_search_args_unref(&search_args); + while (mailbox_search_next(ctx, mail) > 0) { if (mail_get_physical_size(mail, &size) == 0) *bytes_r += size;
--- a/src/plugins/quota/quota-storage.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/plugins/quota/quota-storage.c Wed Jun 04 00:51:58 2008 +0300 @@ -3,7 +3,7 @@ #include "lib.h" #include "array.h" #include "istream.h" -#include "mail-search.h" +#include "mail-search-build.h" #include "mail-storage-private.h" #include "mailbox-list-private.h" #include "quota-private.h" @@ -392,7 +392,7 @@ struct mailbox_transaction_context *t; struct quota_transaction_context *qt; struct mail *mail; - struct mail_search_arg search_arg; + struct mail_search_args *search_args; enum mail_error error; int ret; @@ -416,12 +416,13 @@ return -1; } - memset(&search_arg, 0, sizeof(search_arg)); - search_arg.type = SEARCH_ALL; - t = mailbox_transaction_begin(box, 0); qt = QUOTA_CONTEXT(t); - ctx = mailbox_search_init(t, NULL, &search_arg, NULL); + + search_args = mail_search_build_init(); + mail_search_build_add_all(search_args); + ctx = mailbox_search_init(t, search_args, NULL); + mail_search_args_unref(&search_args); mail = mail_alloc(t, 0, NULL); while (mailbox_search_next(ctx, mail) > 0)
--- a/src/plugins/trash/trash-plugin.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/plugins/trash/trash-plugin.c Wed Jun 04 00:51:58 2008 +0300 @@ -5,7 +5,7 @@ #include "istream.h" #include "home-expand.h" #include "mail-namespace.h" -#include "mail-search.h" +#include "mail-search-build.h" #include "quota-private.h" #include "quota-plugin.h" #include "trash-plugin.h" @@ -26,7 +26,6 @@ /* temporarily set while cleaning: */ struct mailbox *box; struct mailbox_transaction_context *trans; - struct mail_search_arg search_arg; struct mail_search_context *search_ctx; struct mail *mail; @@ -44,6 +43,8 @@ static int trash_clean_mailbox_open(struct trash_mailbox *trash) { + struct mail_search_args *search_args; + trash->box = mailbox_open(trash->storage, trash->name, NULL, MAILBOX_OPEN_KEEP_RECENT); if (trash->box == NULL) @@ -53,12 +54,15 @@ return -1; trash->trans = mailbox_transaction_begin(trash->box, 0); - - trash->search_ctx = mailbox_search_init(trash->trans, NULL, - &trash->search_arg, NULL); trash->mail = mail_alloc(trash->trans, MAIL_FETCH_PHYSICAL_SIZE | MAIL_FETCH_RECEIVED_DATE, NULL); + search_args = mail_search_build_init(); + mail_search_build_add_all(search_args); + trash->search_ctx = mailbox_search_init(trash->trans, + search_args, NULL); + mail_search_args_unref(&search_args); + return mailbox_search_next(trash->search_ctx, trash->mail); } @@ -259,7 +263,6 @@ trash = array_append_space(&trash_boxes); trash->name = p_strdup(config_pool, name+1); trash->priority = atoi(t_strdup_until(line, name)); - trash->search_arg.type = SEARCH_ALL; if (getenv("DEBUG") != NULL) { i_info("trash plugin: Added '%s' with priority %d",
--- a/src/pop3/client.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/pop3/client.c Wed Jun 04 00:51:58 2008 +0300 @@ -10,7 +10,7 @@ #include "var-expand.h" #include "mail-storage.h" #include "commands.h" -#include "mail-search.h" +#include "mail-search-build.h" #include "mail-namespace.h" #include <stdlib.h> @@ -47,7 +47,7 @@ static bool init_mailbox(struct client *client, const char **error_r) { - struct mail_search_arg search_arg; + struct mail_search_args *search_args; struct mailbox_transaction_context *t; struct mail_search_context *ctx; struct mailbox_status status; @@ -60,8 +60,8 @@ message_sizes_buf = buffer_create_dynamic(default_pool, 512); - memset(&search_arg, 0, sizeof(search_arg)); - search_arg.type = SEARCH_ALL; + search_args = mail_search_build_init(); + mail_search_build_add_all(search_args); for (i = 0; i < 2; i++) { expunged = FALSE; @@ -73,7 +73,7 @@ client->uid_validity = status.uidvalidity; t = mailbox_transaction_begin(client->mailbox, 0); - ctx = mailbox_search_init(t, NULL, &search_arg, NULL); + ctx = mailbox_search_init(t, search_args, NULL); client->last_seen = 0; client->total_size = 0; @@ -114,6 +114,7 @@ client->trans = t; client->message_sizes = buffer_free_without_data(&message_sizes_buf); + mail_search_args_unref(&search_args); return TRUE; } @@ -121,6 +122,7 @@ sizes, make sure they get committed. */ (void)mailbox_transaction_commit(&t); } + mail_search_args_unref(&search_args); if (expunged) { client_send_line(client,
--- a/src/pop3/commands.c Sun Mar 16 12:10:57 2008 +0200 +++ b/src/pop3/commands.c Wed Jun 04 00:51:58 2008 +0300 @@ -8,7 +8,7 @@ #include "var-expand.h" #include "message-size.h" #include "mail-storage.h" -#include "mail-search.h" +#include "mail-search-build.h" #include "capability.h" #include "commands.h" @@ -183,9 +183,24 @@ return 1; } +static struct mail_search_args * +pop3_search_build(struct client *client, uint32_t seq) +{ + struct mail_search_args *search_args; + + search_args = mail_search_build_init(); + if (seq == 0) { + mail_search_build_add_seqset(search_args, + 1, client->messages_count); + } else { + mail_search_build_add_seqset(search_args, seq, seq); + } + return search_args; +} + static bool expunge_mails(struct client *client) { - struct mail_search_arg search_arg; + struct mail_search_args *search_args; struct mail_search_context *ctx; struct mail *mail; uint32_t idx; @@ -198,13 +213,10 @@ return TRUE; } - memset(&search_arg, 0, sizeof(search_arg)); - search_arg.type = SEARCH_SEQSET; - t_array_init(&search_arg.value.seqset, 1); - seq_range_array_add_range(&search_arg.value.seqset, - 1, client->messages_count); + search_args = pop3_search_build(client, 0); + ctx = mailbox_search_init(client->trans, search_args, NULL); + mail_search_args_unref(&search_args); - ctx = mailbox_search_init(client->trans, NULL, &search_arg, NULL); mail = mail_alloc(client->trans, 0, NULL); while (mailbox_search_next(ctx, mail) > 0) { idx = mail->seq - 1; @@ -253,8 +265,6 @@ struct istream *stream; uoff_t body_lines; - struct mail_search_arg search_arg; - unsigned char last; bool cr_skipped, in_body; }; @@ -262,7 +272,6 @@ static void fetch_deinit(struct fetch_context *ctx) { (void)mailbox_search_deinit(&ctx->search_ctx); - array_free(&ctx->search_arg.value.seqset); mail_free(&ctx->mail); i_free(ctx); } @@ -367,15 +376,14 @@ static void fetch(struct client *client, unsigned int msgnum, uoff_t body_lines) { struct fetch_context *ctx; + struct mail_search_args *search_args; + + search_args = pop3_search_build(client, msgnum+1); ctx = i_new(struct fetch_context, 1); + ctx->search_ctx = mailbox_search_init(client->trans, search_args, NULL); + mail_search_args_unref(&search_args); - ctx->search_arg.type = SEARCH_SEQSET; - i_array_init(&ctx->search_arg.value.seqset, 1); - seq_range_array_add(&ctx->search_arg.value.seqset, 0, msgnum+1); - - ctx->search_ctx = mailbox_search_init(client->trans, NULL, - &ctx->search_arg, NULL); ctx->mail = mail_alloc(client->trans, MAIL_FETCH_STREAM_HEADER | MAIL_FETCH_STREAM_BODY, NULL); @@ -430,7 +438,7 @@ { struct mail_search_context *search_ctx; struct mail *mail; - struct mail_search_arg search_arg; + struct mail_search_args *search_args; client->last_seen = 0; @@ -443,14 +451,11 @@ if (enable_last_command) { /* remove all \Seen flags (as specified by RFC 1460) */ - memset(&search_arg, 0, sizeof(search_arg)); - search_arg.type = SEARCH_SEQSET; - t_array_init(&search_arg.value.seqset, 1); - seq_range_array_add_range(&search_arg.value.seqset, - 1, client->messages_count); + search_args = pop3_search_build(client, 0); + search_ctx = mailbox_search_init(client->trans, + search_args, NULL); + mail_search_args_unref(&search_args); - search_ctx = mailbox_search_init(client->trans, NULL, - &search_arg, NULL); mail = mail_alloc(client->trans, 0, NULL); while (mailbox_search_next(search_ctx, mail) > 0) mail_update_flags(mail, MODIFY_REMOVE, MAIL_SEEN); @@ -598,26 +603,21 @@ cmd_uidl_init(struct client *client, unsigned int message) { struct cmd_uidl_context *ctx; + struct mail_search_args *search_args; enum mail_fetch_field wanted_fields; + search_args = pop3_search_build(client, message); + ctx = i_new(struct cmd_uidl_context, 1); - - ctx->search_arg.type = SEARCH_SEQSET; - i_array_init(&ctx->search_arg.value.seqset, 1); - if (message == 0) { - seq_range_array_add_range(&ctx->search_arg.value.seqset, - 1, client->messages_count); - } else { - ctx->message = message; - seq_range_array_add(&ctx->search_arg.value.seqset, 0, message); - } + ctx->message = message; wanted_fields = 0; if ((uidl_keymask & UIDL_MD5) != 0) wanted_fields |= MAIL_FETCH_HEADER_MD5; - ctx->search_ctx = mailbox_search_init(client->trans, NULL, - &ctx->search_arg, NULL); + ctx->search_ctx = mailbox_search_init(client->trans, search_args, NULL); + mail_search_args_unref(&search_args); + ctx->mail = mail_alloc(client->trans, wanted_fields, NULL); if (message == 0) { client->cmd = cmd_uidl_callback;