mail-search.c revision 1db237d245d90dfa71d1968a7eb13e344eacb22e
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen/* Copyright (c) 2002-2017 Dovecot authors, see the included COPYING file */
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainenmailbox_uidset_change(struct mail_search_arg *arg, struct mailbox *box,
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen const ARRAY_TYPE(seq_range) *search_saved_uidset)
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen unsigned int i, count;
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen if (arg->value.str != NULL && strcmp(arg->value.str, "$") == 0) {
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen /* SEARCHRES: Replace with saved uidset */
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen array_append_array(&arg->value.seqset, search_saved_uidset);
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen /* make a copy of the UIDs */
8fd00f8716a931e84f33e29c8d3c579ebd718411Timo Sirainen /* empty set, keep it */
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen memcpy(uids, array_idx(&arg->value.seqset, 0), sizeof(*uids) * count);
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen /* put them back to the range as sequences */
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen for (i = 0; i < count; i++) {
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen mailbox_get_seq_range(box, uids[i].seq1, uids[i].seq2,
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen /* make sure the last message is in the range */
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen seq_range_array_add(&arg->value.seqset, seq2);
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainenvoid mail_search_arg_init(struct mail_search_args *args,
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen const ARRAY_TYPE(seq_range) *search_saved_uidset)
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen /* modseq with keyword */
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen /* simplification should have unnested all
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen inthreads, so we'll assume that
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen have_inthreads=FALSE */
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen /* fall through */
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen mail_search_arg_init(args, arg->value.subargs,
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainenvoid mail_search_args_init(struct mail_search_args *args,
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen const ARRAY_TYPE(seq_range) *search_saved_uidset)
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen i_assert(args->init_refcount <= args->refcount);
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen mail_search_arg_init(args, args->args, change_uidsets,
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainenvoid mail_search_arg_deinit(struct mail_search_arg *arg)
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainenvoid mail_search_arg_one_deinit(struct mail_search_arg *arg)
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen mailbox_keywords_unref(&arg->initialized.keywords);
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen imap_match_deinit(&arg->initialized.mailbox_glob);
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen i_assert(arg->initialized.search_args->refcount > 0);
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen mailbox_search_result_free(&arg->value.search_result);
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen /* fall through */
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainenvoid mail_search_args_deinit(struct mail_search_args *args)
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainenstatic void mail_search_args_seq2uid_sub(struct mail_search_args *args,
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen /* replace sequences with UIDs in the existing array.
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen this way it's possible to switch between uidsets and
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen seqsets constantly without leaking memory */
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen mail_search_args_seq2uid_sub(args, arg->value.subargs,
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainenvoid mail_search_args_seq2uid(struct mail_search_args *args)
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen mail_search_args_seq2uid_sub(args, args->args, &uids);
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainenvoid mail_search_args_ref(struct mail_search_args *args)
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainenvoid mail_search_args_unref(struct mail_search_args **_args)
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainen i_assert(args->init_refcount <= args->refcount);
e8bdf1be00aec45d0c6dd72ad9c8be02a3dfc778Timo Sirainenmail_search_arg_dup_one(pool_t pool, const struct mail_search_arg *arg)
65d89650662f7f1681a3431c585bfc9721a85149Timo Sirainen new_arg = p_new(pool, struct mail_search_arg, 1);
65d89650662f7f1681a3431c585bfc9721a85149Timo Sirainen new_arg->nonmatch_always = arg->nonmatch_always;
65d89650662f7f1681a3431c585bfc9721a85149Timo Sirainen new_arg->value.search_flags = arg->value.search_flags;
65d89650662f7f1681a3431c585bfc9721a85149Timo Sirainen new_arg->value.thread_type = arg->value.thread_type;
65d89650662f7f1681a3431c585bfc9721a85149Timo Sirainen /* fall through */
65d89650662f7f1681a3431c585bfc9721a85149Timo Sirainen mail_search_arg_dup(pool, arg->value.subargs);
65d89650662f7f1681a3431c585bfc9721a85149Timo Sirainen array_append_array(&new_arg->value.seqset, &arg->value.seqset);
65d89650662f7f1681a3431c585bfc9721a85149Timo Sirainen new_arg->value.date_type = arg->value.date_type;
65d89650662f7f1681a3431c585bfc9721a85149Timo Sirainen new_arg->hdr_field_name = p_strdup(pool, arg->hdr_field_name);
65d89650662f7f1681a3431c585bfc9721a85149Timo Sirainen /* fall through */
case SEARCH_GUID:
case SEARCH_MAILBOX:
case SEARCH_MAILBOX_GUID:
case SEARCH_MAILBOX_GLOB:
case SEARCH_MODSEQ:
case SEARCH_MIMEPART:
return new_arg;
struct mail_search_arg *
return new_arg;
struct mail_search_args *
return new_args;
if (!full_reset)
if (!full_reset)
void *context)
void *context)
int result;
return result;
case SEARCH_OR:
case SEARCH_SUB:
case SEARCH_BEFORE:
case SEARCH_ON:
case SEARCH_SINCE:
case SEARCH_HEADER:
case SEARCH_HEADER_ADDRESS:
case SEARCH_BODY:
case SEARCH_TEXT:
bool have_text;
return NULL;
bool ret;
case SEARCH_OR:
return TRUE;
return FALSE;
case SEARCH_SUB:
case SEARCH_INTHREAD:
return FALSE;
return TRUE;
case SEARCH_MAILBOX:
case SEARCH_MAILBOX_GLOB: {
T_BEGIN {
} T_END;
return TRUE;
return FALSE;
return TRUE;
return FALSE;
case SEARCH_OR:
case SEARCH_SUB:
case SEARCH_ALL:
return TRUE;
case SEARCH_SEQSET:
return FALSE;
case SEARCH_UIDSET:
case SEARCH_REAL_UID:
case SEARCH_FLAGS:
case SEARCH_KEYWORDS:
case SEARCH_BEFORE:
case SEARCH_ON:
case SEARCH_SINCE:
case SEARCH_SMALLER:
case SEARCH_LARGER:
case SEARCH_HEADER:
case SEARCH_HEADER_ADDRESS:
return FALSE;
case SEARCH_BODY:
case SEARCH_TEXT:
case SEARCH_GUID:
case SEARCH_MAILBOX:
case SEARCH_MAILBOX_GUID:
case SEARCH_MAILBOX_GLOB:
case SEARCH_MODSEQ: {
case SEARCH_INTHREAD:
return FALSE;
case SEARCH_MIMEPART:
i_unreached();
return FALSE;
return FALSE;
case SEARCH_OR:
case SEARCH_SUB:
case SEARCH_INTHREAD:
const unsigned char **data,
case SEARCH_OR:
case SEARCH_SUB:
case SEARCH_INTHREAD: