mail-search.c revision 78f8407de32c9a51f2db00f4edb466f4279fa456
5f5870385cff47efd2f58e7892f251cf13761528Timo Sirainen/* Copyright (c) 2002-2015 Dovecot authors, see the included COPYING file */
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "lib.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "array.h"
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen#include "imap-match.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "mail-index.h"
c0a87e5f3316a57e6f915882fa1951d0fbb74a61Timo Sirainen#include "mail-storage.h"
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen#include "mail-namespace.h"
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen#include "mail-search-build.h"
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen#include "mail-search.h"
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic void
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainenmailbox_uidset_change(struct mail_search_arg *arg, struct mailbox *box,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const ARRAY_TYPE(seq_range) *search_saved_uidset)
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen{
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct seq_range *uids;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen unsigned int i, count;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen uint32_t seq1, seq2;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen if (arg->value.str != NULL && strcmp(arg->value.str, "$") == 0) {
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen /* SEARCHRES: Replace with saved uidset */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen array_clear(&arg->value.seqset);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (search_saved_uidset == NULL ||
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen !array_is_created(search_saved_uidset))
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen array_append_array(&arg->value.seqset, search_saved_uidset);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen return;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen arg->type = SEARCH_SEQSET;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* make a copy of the UIDs */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen count = array_count(&arg->value.seqset);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (count == 0) {
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen /* empty set, keep it */
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen return;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen }
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen uids = t_new(struct seq_range, count);
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen memcpy(uids, array_idx(&arg->value.seqset, 0), sizeof(*uids) * count);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen /* put them back to the range as sequences */
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen array_clear(&arg->value.seqset);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen for (i = 0; i < count; i++) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen mailbox_get_seq_range(box, uids[i].seq1, uids[i].seq2,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen &seq1, &seq2);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (seq1 != 0) {
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen seq_range_array_add_range(&arg->value.seqset,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen seq1, seq2);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (uids[i].seq2 == (uint32_t)-1) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen /* make sure the last message is in the range */
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen mailbox_get_seq_range(box, 1, (uint32_t)-1,
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen &seq1, &seq2);
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen seq_range_array_add(&arg->value.seqset, seq2);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen }
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen }
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid mail_search_arg_init(struct mail_search_args *args,
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen struct mail_search_arg *arg,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen bool change_uidsets,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen const ARRAY_TYPE(seq_range) *search_saved_uidset)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen{
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen struct mail_search_args *thread_args;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen const char *keywords[2];
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen for (; arg != NULL; arg = arg->next) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen switch (arg->type) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen case SEARCH_UIDSET:
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (change_uidsets) T_BEGIN {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen mailbox_uidset_change(arg, args->box,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen search_saved_uidset);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen } T_END;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen break;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen case SEARCH_MODSEQ:
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (arg->value.str == NULL)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen break;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen /* modseq with keyword */
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen case SEARCH_KEYWORDS:
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen keywords[0] = arg->value.str;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen keywords[1] = NULL;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen i_assert(arg->initialized.keywords == NULL);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen arg->initialized.keywords =
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen mailbox_keywords_create_valid(args->box,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen keywords);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen break;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen case SEARCH_MAILBOX_GLOB: {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen struct mail_namespace *ns =
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen mailbox_get_namespace(args->box);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen arg->initialized.mailbox_glob =
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen imap_match_init(default_pool, arg->value.str,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen TRUE, mail_namespace_get_sep(ns));
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen break;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen case SEARCH_INTHREAD:
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen thread_args = arg->initialized.search_args;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (thread_args == NULL) {
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen arg->initialized.search_args = thread_args =
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen p_new(args->pool,
0fd246126fece57712566c725d6353f255f5fcfaTimo Sirainen struct mail_search_args, 1);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen thread_args->pool = args->pool;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen thread_args->args = arg->value.subargs;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen thread_args->simplified = TRUE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* simplification should have unnested all
d0ef8bc2b961a68dd0f75662c2160bd296b9476bTimo Sirainen inthreads, so we'll assume that
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen have_inthreads=FALSE */
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen thread_args->refcount++;
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen thread_args->box = args->box;
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen /* fall through */
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen case SEARCH_SUB:
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen case SEARCH_OR:
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen mail_search_arg_init(args, arg->value.subargs,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen change_uidsets,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen search_saved_uidset);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen default:
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen break;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
d54ab8987e482a8df250615b44f41fa040c38741Timo Sirainenvoid mail_search_args_init(struct mail_search_args *args,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct mailbox *box, bool change_uidsets,
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen const ARRAY_TYPE(seq_range) *search_saved_uidset)
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen{
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen i_assert(args->init_refcount <= args->refcount);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (args->init_refcount++ > 0) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_assert(args->box == box);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen args->box = box;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (!args->simplified)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen mail_search_args_simplify(args);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen mail_search_arg_init(args, args->args, change_uidsets,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen search_saved_uidset);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid mail_search_arg_deinit(struct mail_search_arg *arg)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen for (; arg != NULL; arg = arg->next) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen switch (arg->type) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_MODSEQ:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_KEYWORDS:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (arg->initialized.keywords == NULL)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen mailbox_keywords_unref(&arg->initialized.keywords);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen case SEARCH_MAILBOX_GLOB:
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (arg->initialized.mailbox_glob == NULL)
c4b376dd6e0c423006d7ac83a39253bcaf8e7c47Timo Sirainen break;
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen imap_match_deinit(&arg->initialized.mailbox_glob);
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen break;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen case SEARCH_INTHREAD:
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen i_assert(arg->initialized.search_args->refcount > 0);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen if (arg->value.search_result != NULL) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen mailbox_search_result_free(
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen &arg->value.search_result);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen }
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen arg->initialized.search_args->refcount--;
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen arg->initialized.search_args->box = NULL;
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainen /* fall through */
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen case SEARCH_SUB:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_OR:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen mail_search_arg_deinit(arg->value.subargs);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen default:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen }
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen}
a5e89374cb2fb2cad575fee6c3b33a9487ab9b3aTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenvoid mail_search_args_deinit(struct mail_search_args *args)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen{
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (--args->init_refcount > 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen mail_search_arg_deinit(args->args);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen args->box = NULL;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen}
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic void mail_search_args_seq2uid_sub(struct mail_search_args *args,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct mail_search_arg *arg,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ARRAY_TYPE(seq_range) *uids)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen for (; arg != NULL; arg = arg->next) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen switch (arg->type) {
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen case SEARCH_SEQSET:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen array_clear(uids);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen mailbox_get_uid_range(args->box,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen &arg->value.seqset, uids);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen /* replace sequences with UIDs in the existing array.
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen this way it's possible to switch between uidsets and
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen seqsets constantly without leaking memory */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen arg->type = SEARCH_UIDSET;
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen array_clear(&arg->value.seqset);
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen array_append_array(&arg->value.seqset, uids);
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen break;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_SUB:
bc93929cdd9000ca560a5f42a27f50ab307f1efbTimo Sirainen case SEARCH_OR:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_INTHREAD:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen mail_search_args_seq2uid_sub(args, arg->value.subargs,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen uids);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen break;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen default:
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen break;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
d54ab8987e482a8df250615b44f41fa040c38741Timo Sirainen}
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
f210ec6b25f80d06419921e9231465bb114ee971Timo Sirainenvoid mail_search_args_seq2uid(struct mail_search_args *args)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen T_BEGIN {
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen ARRAY_TYPE(seq_range) uids;
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen t_array_init(&uids, 128);
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen mail_search_args_seq2uid_sub(args, args->args, &uids);
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen } T_END;
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen}
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainenvoid mail_search_args_ref(struct mail_search_args *args)
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen{
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen i_assert(args->refcount > 0);
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen args->refcount++;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainenvoid mail_search_args_unref(struct mail_search_args **_args)
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen{
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen struct mail_search_args *args = *_args;
437a8b0fe254057b0c1f1723d689bafa91cae2abTimo Sirainen
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen i_assert(args->refcount > 0);
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen *_args = NULL;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen if (--args->refcount > 0) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_assert(args->init_refcount <= args->refcount);
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen return;
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen }
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen i_assert(args->init_refcount <= 1);
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen if (args->init_refcount == 1)
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen mail_search_args_deinit(args);
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen pool_unref(&args->pool);
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen}
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainenstatic struct mail_search_arg *
eef4ba0cc3e78f8c26804c1c9251a76580a41f0cTimo Sirainenmail_search_arg_dup_one(pool_t pool, const struct mail_search_arg *arg)
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen{
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainen struct mail_search_arg *new_arg;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen new_arg = p_new(pool, struct mail_search_arg, 1);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen new_arg->type = arg->type;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen new_arg->match_not = arg->match_not;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen new_arg->match_always = arg->match_always;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen new_arg->nonmatch_always = arg->nonmatch_always;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen new_arg->fuzzy = arg->fuzzy;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen new_arg->value.search_flags = arg->value.search_flags;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen switch (arg->type) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_INTHREAD:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen new_arg->value.thread_type = arg->value.thread_type;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* fall through */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_OR:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_SUB:
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen new_arg->value.subargs =
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen mail_search_arg_dup(pool, arg->value.subargs);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_ALL:
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen break;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_SEQSET:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_UIDSET:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_REAL_UID:
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen p_array_init(&new_arg->value.seqset, pool,
f4616f1875297fb2f583d913c0f01b075bdecd5bTimo Sirainen array_count(&arg->value.seqset));
bd1b2615928a1e8be190cb0405754f0aec8cac2fTimo Sirainen array_append_array(&new_arg->value.seqset, &arg->value.seqset);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen break;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen case SEARCH_FLAGS:
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen new_arg->value.flags = arg->value.flags;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen case SEARCH_BEFORE:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_ON:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_SINCE:
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen new_arg->value.time = arg->value.time;
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen new_arg->value.date_type = arg->value.date_type;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen break;
c63c3c4d548416914b8c6734fe18dd69bb900775Timo Sirainen case SEARCH_SMALLER:
94f90df2cfb7587bb5af432b2ba065d1c364e1f7Timo Sirainen case SEARCH_LARGER:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen new_arg->value.size = arg->value.size;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen break;
3852872e6954b7132e637294132005e86b8ebd4aTimo Sirainen case SEARCH_HEADER:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_HEADER_ADDRESS:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_HEADER_COMPRESS_LWSP:
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen new_arg->hdr_field_name = p_strdup(pool, arg->hdr_field_name);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* fall through */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_KEYWORDS:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_BODY:
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen case SEARCH_TEXT:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_GUID:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_MAILBOX:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_MAILBOX_GUID:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_MAILBOX_GLOB:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen new_arg->value.str = p_strdup(pool, arg->value.str);
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen break;
ecdce39e5ef4b62eefa9f5818f17d153fd5d710aTimo Sirainen case SEARCH_MODSEQ:
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen new_arg->value.modseq =
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen p_new(pool, struct mail_search_modseq, 1);
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen *new_arg->value.modseq = *arg->value.modseq;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen break;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen }
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen return new_arg;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainenstruct mail_search_arg *
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainenmail_search_arg_dup(pool_t pool, const struct mail_search_arg *arg)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct mail_search_arg *new_arg = NULL, **dest = &new_arg;
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen for (; arg != NULL; arg = arg->next) {
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen *dest = mail_search_arg_dup_one(pool, arg);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen dest = &(*dest)->next;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return new_arg;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
88dc563319efecd6e68bad16b0d92672da05584aTimo Sirainenstruct mail_search_args *
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainenmail_search_args_dup(const struct mail_search_args *args)
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen{
6d41944c73171cdb64b0a00bff368d212452e924Timo Sirainen struct mail_search_args *new_args;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen new_args = mail_search_build_init();
fde0b1793a2842da00eaa105d5e13fec465f0443Timo Sirainen new_args->simplified = args->simplified;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen new_args->have_inthreads = args->have_inthreads;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen new_args->args = mail_search_arg_dup(new_args->pool, args->args);
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen return new_args;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen}
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainenvoid mail_search_args_reset(struct mail_search_arg *args, bool full_reset)
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen{
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen while (args != NULL) {
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen if (args->type == SEARCH_OR || args->type == SEARCH_SUB)
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen mail_search_args_reset(args->value.subargs, full_reset);
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen if (args->match_always) {
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen if (!full_reset)
fd14806f879f6cd4f023750e0c4cac27a7f94fbbTimo Sirainen args->result = 1;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen else {
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen args->match_always = FALSE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen args->result = -1;
fde0b1793a2842da00eaa105d5e13fec465f0443Timo Sirainen }
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen } else if (args->nonmatch_always) {
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen if (!full_reset)
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen args->result = 0;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen else {
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen args->nonmatch_always = FALSE;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen args->result = -1;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen }
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen } else {
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen args->result = -1;
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen }
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen args = args->next;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen}
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainenstatic void search_arg_foreach(struct mail_search_arg *arg,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen mail_search_foreach_callback_t *callback,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen void *context)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen{
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen struct mail_search_arg *subarg;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (arg->result != -1)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen return;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (arg->type == SEARCH_SUB) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen /* sublist of conditions */
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen i_assert(arg->value.subargs != NULL);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen arg->result = 1;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen subarg = arg->value.subargs;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen while (subarg != NULL) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (subarg->result == -1)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen search_arg_foreach(subarg, callback, context);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (subarg->result == -1)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen arg->result = -1;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen else if (subarg->result == 0) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen /* didn't match */
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen arg->result = 0;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen break;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen subarg = subarg->next;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (arg->match_not && arg->result != -1)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen arg->result = !arg->result;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen } else if (arg->type == SEARCH_OR) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen /* OR-list of conditions */
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen i_assert(arg->value.subargs != NULL);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen subarg = arg->value.subargs;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen arg->result = 0;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen while (subarg != NULL) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (subarg->result == -1)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen search_arg_foreach(subarg, callback, context);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (subarg->result == -1)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen arg->result = -1;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen else if (subarg->result > 0) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen /* matched */
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen arg->result = 1;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen break;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen subarg = subarg->next;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (arg->match_not && arg->result != -1)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen arg->result = !arg->result;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen } else {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen /* just a single condition */
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen callback(arg, context);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen}
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen#undef mail_search_args_foreach
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainenint mail_search_args_foreach(struct mail_search_arg *args,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen mail_search_foreach_callback_t *callback,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen void *context)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen{
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen int result;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen result = 1;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen for (; args != NULL; args = args->next) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen search_arg_foreach(args, callback, context);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (args->result == 0) {
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen /* didn't match */
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen return 0;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (args->result == -1)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen result = -1;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen return result;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen}
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainenstatic void
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainensearch_arg_analyze(struct mail_search_arg *arg, buffer_t *headers,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen bool *have_body, bool *have_text)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen{
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen static const char *date_hdr = "Date";
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen struct mail_search_arg *subarg;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen if (arg->result != -1)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen return;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen switch (arg->type) {
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen case SEARCH_OR:
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen case SEARCH_SUB:
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen subarg = arg->value.subargs;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen while (subarg != NULL) {
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen if (subarg->result == -1) {
a0c453a8edaec90fb0d945c874de0b1845bc7d7eTimo Sirainen search_arg_analyze(subarg, headers,
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen have_body, have_text);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen subarg = subarg->next;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen }
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen break;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen case SEARCH_BEFORE:
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen case SEARCH_ON:
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen case SEARCH_SINCE:
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen if (arg->value.date_type == MAIL_SEARCH_DATE_TYPE_SENT)
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen buffer_append(headers, &date_hdr, sizeof(const char *));
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen break;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen case SEARCH_HEADER:
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen case SEARCH_HEADER_ADDRESS:
fda168427e1950518acd6d600f1a10a29a5baef0Timo Sirainen case SEARCH_HEADER_COMPRESS_LWSP:
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen buffer_append(headers, &arg->hdr_field_name,
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen sizeof(const char *));
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen break;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen case SEARCH_BODY:
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen *have_body = TRUE;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen break;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen case SEARCH_TEXT:
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen *have_text = TRUE;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen *have_body = TRUE;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen break;
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen default:
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen break;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen }
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen}
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainenconst char *const *
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainenmail_search_args_analyze(struct mail_search_arg *args,
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen bool *have_headers, bool *have_body)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen{
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen const char *null = NULL;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen buffer_t *headers;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen bool have_text;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen *have_headers = *have_body = have_text = FALSE;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen headers = buffer_create_dynamic(pool_datastack_create(), 128);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen for (; args != NULL; args = args->next)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen search_arg_analyze(args, headers, have_body, &have_text);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen *have_headers = have_text || headers->used != 0;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (headers->used == 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return NULL;
a7061727e8f1378228f110b23d816329d39ce82bTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen buffer_append(headers, &null, sizeof(const char *));
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen return buffer_get_data(headers, NULL);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen}
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainenstatic bool
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainenmail_search_args_match_mailbox_arg(const struct mail_search_arg *arg,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen const char *vname, char sep)
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen{
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen const struct mail_search_arg *subarg;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen bool ret;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen switch (arg->type) {
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen case SEARCH_OR:
96308127e006bb3b1108093bcf4cc1fd9481cb7aTimo Sirainen subarg = arg->value.subargs;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen for (; subarg != NULL; subarg = subarg->next) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (mail_search_args_match_mailbox_arg(subarg,
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen vname, sep))
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen return TRUE;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen return FALSE;
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen case SEARCH_SUB:
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen case SEARCH_INTHREAD:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen subarg = arg->value.subargs;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen for (; subarg != NULL; subarg = subarg->next) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (!mail_search_args_match_mailbox_arg(subarg,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen vname, sep))
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return FALSE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return TRUE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_MAILBOX:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ret = strcmp(arg->value.str, vname) == 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return ret != arg->match_not;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_MAILBOX_GLOB: {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen T_BEGIN {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen struct imap_match_glob *glob;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen glob = imap_match_init(pool_datastack_create(),
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen arg->value.str, TRUE, sep);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen ret = imap_match(glob, vname) == IMAP_MATCH_YES;
1b0cfbf3cc77a670b92fff5c30f7b1eb17a63ab1Timo Sirainen } T_END;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen return ret != arg->match_not;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
083c67ac280fb4930a280ce1f76fb27a1637e818Timo Sirainen default:
083c67ac280fb4930a280ce1f76fb27a1637e818Timo Sirainen break;
083c67ac280fb4930a280ce1f76fb27a1637e818Timo Sirainen }
083c67ac280fb4930a280ce1f76fb27a1637e818Timo Sirainen return TRUE;
083c67ac280fb4930a280ce1f76fb27a1637e818Timo Sirainen}
083c67ac280fb4930a280ce1f76fb27a1637e818Timo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenbool mail_search_args_match_mailbox(struct mail_search_args *args,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const char *vname, char sep)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const struct mail_search_arg *arg;
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen
85a4ae7e8df7ea45a7665828e5edf48a5fc85730Timo Sirainen if (!args->simplified)
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen mail_search_args_simplify(args);
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen for (arg = args->args; arg != NULL; arg = arg->next) {
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen if (!mail_search_args_match_mailbox_arg(arg, vname, sep))
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen return FALSE;
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen }
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen return TRUE;
a0475b241a56220714d96a41f11a174c11a48bfaTimo Sirainen}
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen
20eafc2a848865ce7bf5e8c609e3b0bbd9077ec2Timo Sirainenbool mail_search_arg_one_equals(const struct mail_search_arg *arg1,
20eafc2a848865ce7bf5e8c609e3b0bbd9077ec2Timo Sirainen const struct mail_search_arg *arg2)
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen{
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen if (arg1->type != arg2->type ||
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen arg1->match_not != arg2->match_not ||
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen arg1->fuzzy != arg2->fuzzy ||
20eafc2a848865ce7bf5e8c609e3b0bbd9077ec2Timo Sirainen arg1->value.search_flags != arg2->value.search_flags)
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen return FALSE;
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen switch (arg1->type) {
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen case SEARCH_OR:
a0475b241a56220714d96a41f11a174c11a48bfaTimo Sirainen case SEARCH_SUB:
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen return mail_search_arg_equals(arg1->value.subargs,
ceae1acc3e3022c6b5fe52a4a34890dffdbcb77fTimo Sirainen arg2->value.subargs);
a0475b241a56220714d96a41f11a174c11a48bfaTimo Sirainen
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen case SEARCH_ALL:
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen return TRUE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_SEQSET:
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen /* sequences may point to different messages at different times,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen never assume they match */
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen return FALSE;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen case SEARCH_UIDSET:
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen return array_cmp(&arg1->value.seqset, &arg2->value.seqset);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_REAL_UID:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return array_cmp(&arg1->value.seqset, &arg2->value.seqset);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_FLAGS:
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen return arg1->value.flags == arg2->value.flags;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen case SEARCH_KEYWORDS:
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen return strcasecmp(arg1->value.str, arg2->value.str);
421d30619384e72a27e2a5d13ff6525aff4d17feTimo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen case SEARCH_BEFORE:
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen case SEARCH_ON:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_SINCE:
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen return arg1->value.time == arg2->value.time &&
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen arg1->value.date_type == arg2->value.date_type;
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen case SEARCH_SMALLER:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_LARGER:
64b61cd24d630223478ccbe1934b9f60f0881f59Timo Sirainen return arg1->value.size == arg2->value.size;
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen case SEARCH_HEADER:
2793e3bd31d212d6506686aa70773e13d9d98195Timo Sirainen case SEARCH_HEADER_ADDRESS:
e726bf74fcc8d24f4c9d0d83217b3db4314d9d1fTimo Sirainen case SEARCH_HEADER_COMPRESS_LWSP:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (strcasecmp(arg1->hdr_field_name, arg2->hdr_field_name) != 0)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return FALSE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* fall through */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_BODY:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_TEXT:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_GUID:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_MAILBOX:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_MAILBOX_GUID:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_MAILBOX_GLOB:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen /* don't bother doing case-insensitive comparison. it must not
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen be done for guid/mailbox, and for others we should support
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen full i18n case-insensitivity (or the active comparator
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen in future). */
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return strcmp(arg1->value.str, arg2->value.str) == 0;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_MODSEQ: {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const struct mail_search_modseq *m1 = arg1->value.modseq;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const struct mail_search_modseq *m2 = arg2->value.modseq;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return m1->modseq == m2->modseq &&
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen m1->type == m2->type;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen case SEARCH_INTHREAD:
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (arg1->value.thread_type != arg2->value.thread_type)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return FALSE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return mail_search_args_equal(arg1->initialized.search_args,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen arg2->initialized.search_args);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_unreached();
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return FALSE;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenbool mail_search_arg_equals(const struct mail_search_arg *arg1,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const struct mail_search_arg *arg2)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen while (arg1 != NULL && arg2 != NULL) {
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen if (!mail_search_arg_one_equals(arg1, arg2))
e51bfe0db17f1a2e44932d0d6d3958ae409a8bcfTimo Sirainen return FALSE;
e51bfe0db17f1a2e44932d0d6d3958ae409a8bcfTimo Sirainen arg1 = arg1->next;
e51bfe0db17f1a2e44932d0d6d3958ae409a8bcfTimo Sirainen arg2 = arg2->next;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen }
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen return arg1 == NULL && arg2 == NULL;
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenbool mail_search_args_equal(const struct mail_search_args *args1,
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen const struct mail_search_args *args2)
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen{
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_assert(args1->simplified == args2->simplified);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen i_assert(args1->box == args2->box);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen
e726bf74fcc8d24f4c9d0d83217b3db4314d9d1fTimo Sirainen return mail_search_arg_equals(args1->args, args2->args);
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainen}
e726bf74fcc8d24f4c9d0d83217b3db4314d9d1fTimo Sirainen
8d587838c414c48a331f0b54cd7ffd97e5024abdTimo Sirainenstatic void
e726bf74fcc8d24f4c9d0d83217b3db4314d9d1fTimo Sirainenmail_search_args_result_serialize_arg(const struct mail_search_arg *arg,
d3380f13cb3e398bb5e7acbd4d04582397f62ec2Timo Sirainen buffer_t *dest)
d3380f13cb3e398bb5e7acbd4d04582397f62ec2Timo Sirainen{
d3380f13cb3e398bb5e7acbd4d04582397f62ec2Timo Sirainen const struct mail_search_arg *subarg;
d3380f13cb3e398bb5e7acbd4d04582397f62ec2Timo Sirainen
d3380f13cb3e398bb5e7acbd4d04582397f62ec2Timo Sirainen buffer_append_c(dest, arg->result < 0 ? 0xff : arg->result);
d3380f13cb3e398bb5e7acbd4d04582397f62ec2Timo Sirainen
d3380f13cb3e398bb5e7acbd4d04582397f62ec2Timo Sirainen switch (arg->type) {
case SEARCH_OR:
case SEARCH_SUB:
case SEARCH_INTHREAD:
subarg = arg->value.subargs;
for (; subarg != NULL; subarg = subarg->next)
mail_search_args_result_serialize_arg(subarg, dest);
default:
break;
}
}
void mail_search_args_result_serialize(const struct mail_search_args *args,
buffer_t *dest)
{
const struct mail_search_arg *arg;
for (arg = args->args; arg != NULL; arg = arg->next)
mail_search_args_result_serialize_arg(arg, dest);
}
static void
mail_search_args_result_deserialize_arg(struct mail_search_arg *arg,
const unsigned char **data,
size_t *size)
{
struct mail_search_arg *subarg;
i_assert(*size > 0);
arg->result = **data == 0xff ? -1 : **data;
*data += 1; *size -= 1;
switch (arg->type) {
case SEARCH_OR:
case SEARCH_SUB:
case SEARCH_INTHREAD:
subarg = arg->value.subargs;
for (; subarg != NULL; subarg = subarg->next) {
mail_search_args_result_deserialize_arg(subarg,
data, size);
}
default:
break;
}
}
void mail_search_args_result_deserialize(struct mail_search_args *args,
const unsigned char *data, size_t size)
{
struct mail_search_arg *arg;
for (arg = args->args; arg != NULL; arg = arg->next)
mail_search_args_result_deserialize_arg(arg, &data, &size);
}