mail-search.c revision 4139bd30500732466acf4ff1134950788248ec55
76b43e4417bab52e913da39b5f5bc2a130d3f149Timo Sirainen/* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "lib.h"
16f816d3f3c32ae3351834253f52ddd0212bcbf3Timo Sirainen#include "array.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "buffer.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-index.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "mail-storage.h"
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen#include "mail-search.h"
022412398e56a8f31ef111cfd7271498d64af9a9Timo Sirainen
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainenstatic void
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmailbox_uidset_change(struct mail_search_arg *arg, struct mailbox *box,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const ARRAY_TYPE(seq_range) *search_saved_uidset)
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen{
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen struct seq_range *uids;
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen unsigned int i, count;
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen uint32_t seq1, seq2;
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (arg->value.str != NULL && strcmp(arg->value.str, "$") == 0) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* SEARCHRES: Replace with saved uidset */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen array_clear(&arg->value.seqset);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (search_saved_uidset == NULL ||
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen !array_is_created(search_saved_uidset))
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen array_append_array(&arg->value.seqset, search_saved_uidset);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen arg->type = SEARCH_SEQSET;
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen /* make a copy of the UIDs */
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen count = array_count(&arg->value.seqset);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen if (count == 0) {
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen /* empty set, keep it */
2d3aac5be07b96f72cf0551fac35ac74a4f07770Timo Sirainen return;
2d3aac5be07b96f72cf0551fac35ac74a4f07770Timo Sirainen }
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen uids = t_new(struct seq_range, count);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen memcpy(uids, array_idx(&arg->value.seqset, 0), sizeof(*uids) * count);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen /* put them back to the range as sequences */
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen array_clear(&arg->value.seqset);
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen for (i = 0; i < count; i++) {
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen mailbox_get_seq_range(box, uids[i].seq1, uids[i].seq2,
a205d315b0978985ba77d871f44e4a98273612e6Timo Sirainen &seq1, &seq2);
a205d315b0978985ba77d871f44e4a98273612e6Timo Sirainen if (seq1 != 0) {
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen seq_range_array_add_range(&arg->value.seqset,
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen seq1, seq2);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen }
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen if (uids[i].seq2 == (uint32_t)-1) {
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen /* make sure the last message is in the range */
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen mailbox_get_seq_range(box, 1, (uint32_t)-1,
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen &seq1, &seq2);
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainen seq_range_array_add(&arg->value.seqset, 0, seq2);
a6a2b38d806f3ab3198160e39240a8200775e525Timo Sirainen }
a6a2b38d806f3ab3198160e39240a8200775e525Timo Sirainen }
a6a2b38d806f3ab3198160e39240a8200775e525Timo Sirainen}
fb2e0bbb7737f3223b16aa41e4b40fb0cd5f288fTimo Sirainen
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainenstatic void
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainenmail_search_args_init_sub(struct mail_search_arg *args,
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainen struct mailbox *box, bool change_uidsets,
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainen const ARRAY_TYPE(seq_range) *search_saved_uidset)
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainen{
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen const char *keywords[2];
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen for (; args != NULL; args = args->next) {
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen switch (args->type) {
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen case SEARCH_UIDSET:
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen if (change_uidsets) T_BEGIN {
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen mailbox_uidset_change(args, box,
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen search_saved_uidset);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen } T_END;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen break;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen case SEARCH_MODSEQ:
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen if (args->value.str == NULL)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen break;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* modseq with keyword */
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen case SEARCH_KEYWORDS:
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen keywords[0] = args->value.str;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen keywords[1] = NULL;
821984ecb6c90696f35c32a8dc4c8a60f9e98f99Timo Sirainen
821984ecb6c90696f35c32a8dc4c8a60f9e98f99Timo Sirainen i_assert(args->value.keywords == NULL);
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen args->value.keywords =
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen mailbox_keywords_create_valid(box, keywords);
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen break;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen case SEARCH_SUB:
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen case SEARCH_OR:
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen mail_search_args_init_sub(args->value.subargs, box,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen change_uidsets,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen search_saved_uidset);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen break;
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen default:
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen break;
e5759add4dc24b96606dccc4a989838e260f2a12Timo Sirainen }
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen }
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen}
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenvoid mail_search_args_init(struct mail_search_args *args,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct mailbox *box, bool change_uidsets,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen const ARRAY_TYPE(seq_range) *search_saved_uidset)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen{
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen args->box = box;
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen mail_search_args_init_sub(args->args, box, change_uidsets,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen search_saved_uidset);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen}
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenstatic void mail_search_args_deinit_sub(struct mail_search_args *args,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen struct mail_search_arg *arg)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen{
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen for (; arg != NULL; arg = arg->next) {
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen switch (arg->type) {
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen case SEARCH_MODSEQ:
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen case SEARCH_KEYWORDS:
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (arg->value.keywords == NULL)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen break;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen mailbox_keywords_free(args->box, &arg->value.keywords);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen break;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen case SEARCH_SUB:
821984ecb6c90696f35c32a8dc4c8a60f9e98f99Timo Sirainen case SEARCH_OR:
821984ecb6c90696f35c32a8dc4c8a60f9e98f99Timo Sirainen mail_search_args_deinit_sub(args, arg->value.subargs);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen break;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen default:
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen break;
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen }
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen}
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenvoid mail_search_args_deinit(struct mail_search_args *args)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen{
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (args->refcount > 1)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen return;
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen mail_search_args_deinit_sub(args, args->args);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen}
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
197ad81605dc0f6d2ebc9ad99994db5ca6d76699Timo Sirainenstatic void mail_search_args_seq2uid_sub(struct mail_search_args *args,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen struct mail_search_arg *arg,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen ARRAY_TYPE(seq_range) *uids)
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen{
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen for (; arg != NULL; arg = arg->next) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen switch (arg->type) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen case SEARCH_SEQSET:
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen array_clear(uids);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen mailbox_get_uid_range(args->box,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen &arg->value.seqset, uids);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen /* replace sequences with UIDs in the existing array.
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen this way it's possible to switch between uidsets and
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen seqsets constantly without leaking memory */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen arg->type = SEARCH_UIDSET;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen array_clear(&arg->value.seqset);
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen array_append_array(&arg->value.seqset, uids);
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen break;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen case SEARCH_SUB:
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen case SEARCH_OR:
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen mail_search_args_seq2uid_sub(args, arg->value.subargs,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen uids);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen break;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen default:
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen break;
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen }
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen}
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenvoid mail_search_args_seq2uid(struct mail_search_args *args)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen{
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen T_BEGIN {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen ARRAY_TYPE(seq_range) uids;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen t_array_init(&uids, 128);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen mail_search_args_seq2uid_sub(args, args->args, &uids);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen } T_END;
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen}
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenvoid mail_search_args_ref(struct mail_search_args *args)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen{
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen i_assert(args->refcount > 0);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen args->refcount++;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen}
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenvoid mail_search_args_unref(struct mail_search_args **_args)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_search_args *args = *_args;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen i_assert(args->refcount > 0);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen *_args = NULL;
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen if (--args->refcount > 0)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return;
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen mail_search_args_deinit(args);
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen pool_unref(&args->pool);
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen}
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainen
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainenvoid mail_search_args_reset(struct mail_search_arg *args, bool full_reset)
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen{
33ae95df45c9b5ec51332a6b39eb5322038686b9Timo Sirainen while (args != NULL) {
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen if (args->type == SEARCH_OR || args->type == SEARCH_SUB)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen mail_search_args_reset(args->value.subargs, full_reset);
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (!args->match_always)
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen args->result = -1;
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen else {
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen if (!full_reset)
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen args->result = 1;
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen else {
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen args->match_always = FALSE;
bf301a34ffbfd049be583094019b2644884b6d0bTimo Sirainen args->result = -1;
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen }
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen }
58eb2cb24dbeadd94500670acad7ceb1c8b0d9b4Timo Sirainen
bf301a34ffbfd049be583094019b2644884b6d0bTimo Sirainen args = args->next;
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen }
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen}
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void search_arg_foreach(struct mail_search_arg *arg,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_search_foreach_callback_t *callback,
1e76a5b92f9d82d557f81f080f3dfad1c9d8f200Timo Sirainen void *context)
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen{
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct mail_search_arg *subarg;
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (arg->result != -1)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen return;
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen if (arg->type == SEARCH_SUB) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* sublist of conditions */
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen i_assert(arg->value.subargs != NULL);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen arg->result = 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen subarg = arg->value.subargs;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen while (subarg != NULL) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (subarg->result == -1)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen search_arg_foreach(subarg, callback, context);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (subarg->result == -1)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen arg->result = -1;
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen else if (subarg->result == 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* didn't match */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen arg->result = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen subarg = subarg->next;
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (arg->not && arg->result != -1)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen arg->result = !arg->result;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else if (arg->type == SEARCH_OR) {
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen /* OR-list of conditions */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen i_assert(arg->value.subargs != NULL);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen subarg = arg->value.subargs;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen arg->result = 0;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen while (subarg != NULL) {
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen if (subarg->result == -1)
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen search_arg_foreach(subarg, callback, context);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if (subarg->result == -1)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen arg->result = -1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen else if (subarg->result > 0) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* matched */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen arg->result = 1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen break;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen subarg = subarg->next;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen }
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (arg->not && arg->result != -1)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen arg->result = !arg->result;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen } else {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* just a single condition */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen callback(arg, context);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen }
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen}
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen#undef mail_search_args_foreach
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_search_args_foreach(struct mail_search_arg *args,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_search_foreach_callback_t *callback,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen void *context)
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen{
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen int result;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen result = 1;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen for (; args != NULL; args = args->next) {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen search_arg_foreach(args, callback, context);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen if (args->result == 0) {
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen /* didn't match */
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen return 0;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen if (args->result == -1)
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen result = -1;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen }
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainen return result;
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainen}
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainen
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainenstatic void
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainensearch_arg_analyze(struct mail_search_arg *arg, buffer_t *headers,
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainen bool *have_body, bool *have_text)
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainen{
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainen static const char *date_hdr = "Date";
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainen struct mail_search_arg *subarg;
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainen
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainen if (arg->result != -1)
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainen return;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen switch (arg->type) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen case SEARCH_OR:
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen case SEARCH_SUB:
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen subarg = arg->value.subargs;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen while (subarg != NULL) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (subarg->result == -1) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen search_arg_analyze(subarg, headers,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen have_body, have_text);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen subarg = subarg->next;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen break;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen case SEARCH_SENTBEFORE:
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen case SEARCH_SENTON:
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen case SEARCH_SENTSINCE:
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen buffer_append(headers, &date_hdr, sizeof(const char *));
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen break;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen case SEARCH_HEADER:
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen case SEARCH_HEADER_ADDRESS:
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen case SEARCH_HEADER_COMPRESS_LWSP:
1cd97699af9c77d8f5920832ec3374884544fd68Timo Sirainen buffer_append(headers, &arg->hdr_field_name,
1cd97699af9c77d8f5920832ec3374884544fd68Timo Sirainen sizeof(const char *));
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen break;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen case SEARCH_BODY:
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen case SEARCH_BODY_FAST:
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen *have_body = TRUE;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen break;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen case SEARCH_TEXT:
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen case SEARCH_TEXT_FAST:
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen *have_text = TRUE;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen *have_body = TRUE;
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen break;
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen default:
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen break;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen}
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainenconst char *const *
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainenmail_search_args_analyze(struct mail_search_arg *args,
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen bool *have_headers, bool *have_body)
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen{
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen const char *null = NULL;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen buffer_t *headers;
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen bool have_text;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen *have_headers = *have_body = have_text = FALSE;
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen
bf301a34ffbfd049be583094019b2644884b6d0bTimo Sirainen headers = buffer_create_dynamic(pool_datastack_create(), 128);
51ff0538ab38def8045b3f7feb43e1e069cbe037Timo Sirainen for (; args != NULL; args = args->next)
58eb2cb24dbeadd94500670acad7ceb1c8b0d9b4Timo Sirainen search_arg_analyze(args, headers, have_body, &have_text);
bf301a34ffbfd049be583094019b2644884b6d0bTimo Sirainen
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen *have_headers = have_text || headers->used != 0;
2054222e84cb972842cc4de88e16516bef41b542Timo Sirainen
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen if (headers->used == 0 || have_text)
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen return NULL;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen buffer_append(headers, &null, sizeof(const char *));
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen return buffer_get_data(headers, NULL);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen}
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainenstatic struct mail_keywords *
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainenmail_search_keywords_merge(struct mail_keywords **_kw1,
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen struct mail_keywords **_kw2)
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen{
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen struct mail_keywords *kw1 = *_kw1, *kw2 = *_kw2;
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen struct mail_keywords *new_kw;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen
a60c1c1fca85402e6fccbf3ae0784b7179ae186cTimo Sirainen i_assert(kw1->index == kw2->index);
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen T_BEGIN {
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen ARRAY_TYPE(keyword_indexes) new_indexes;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int i, j;
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen t_array_init(&new_indexes, kw1->count + kw2->count + 1);
1e76a5b92f9d82d557f81f080f3dfad1c9d8f200Timo Sirainen array_append(&new_indexes, kw1->idx, kw1->count);
7a6b45405fb1544ac476e6eb1402a70cc1ddcdcfTimo Sirainen for (i = 0; i < kw2->count; i++) {
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen /* don't add duplicates */
d0d7fcf3ce44f26fdf34c1542a25cec644c5c4c7Timo Sirainen for (j = 0; j < kw1->count; j++) {
08fa343b3aace9343da3195686c65c5326eda207Timo Sirainen if (kw1->idx[j] == kw2->idx[i])
1cd97699af9c77d8f5920832ec3374884544fd68Timo Sirainen break;
1cd97699af9c77d8f5920832ec3374884544fd68Timo Sirainen }
1cd97699af9c77d8f5920832ec3374884544fd68Timo Sirainen if (j == kw1->count)
dc049c5e83d947aaf1b97c26ae819cc9577e0475Timo Sirainen array_append(&new_indexes, kw2->idx+i, 1);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen }
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen new_kw = mail_index_keywords_create_from_indexes(kw1->index,
1cd97699af9c77d8f5920832ec3374884544fd68Timo Sirainen &new_indexes);
33ae95df45c9b5ec51332a6b39eb5322038686b9Timo Sirainen } T_END;
33ae95df45c9b5ec51332a6b39eb5322038686b9Timo Sirainen mail_index_keywords_free(_kw1);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen mail_index_keywords_free(_kw2);
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen return new_kw;
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen}
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainenstatic void
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainenmail_search_args_simplify_sub(struct mail_search_arg *args, bool parent_and)
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen{
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen struct mail_search_arg *sub, *prev = NULL;
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen struct mail_search_arg *prev_flags_arg, *prev_not_flags_arg;
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen struct mail_search_arg *prev_kw_arg, *prev_not_kw_arg;
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen prev_flags_arg = prev_not_flags_arg = NULL;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen prev_kw_arg = prev_not_kw_arg = NULL;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen for (; args != NULL;) {
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen if (args->not && (args->type == SEARCH_SUB ||
d0d7fcf3ce44f26fdf34c1542a25cec644c5c4c7Timo Sirainen args->type == SEARCH_OR)) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* neg(p and q and ..) == neg(p) or neg(q) or ..
345212e8f61ebf14ff4f80df26df9e655eb5121eTimo Sirainen neg(p or q or ..) == neg(p) and neg(q) and .. */
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen args->type = args->type == SEARCH_SUB ?
d0d7fcf3ce44f26fdf34c1542a25cec644c5c4c7Timo Sirainen SEARCH_OR : SEARCH_SUB;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen args->not = FALSE;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen sub = args->value.subargs;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen for (; sub != NULL; sub = sub->next)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen sub->not = !sub->not;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen }
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if ((args->type == SEARCH_SUB && parent_and) ||
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen (args->type == SEARCH_OR && !parent_and)) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen /* p and (q and ..) == p and q and ..
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen p or (q or ..) == p or q or .. */
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen sub = args->value.subargs;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen for (; sub->next != NULL; sub = sub->next) ;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen sub->next = args->next;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen *args = *args->value.subargs;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen continue;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen if (args->type == SEARCH_SUB || args->type == SEARCH_OR) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen mail_search_args_simplify_sub(args->value.subargs,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen args->type == SEARCH_SUB);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen }
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* merge all flags arguments */
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen if (args->type == SEARCH_FLAGS && !args->not && parent_and) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen if (prev_flags_arg == NULL)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen prev_flags_arg = args;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen else {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen prev_flags_arg->value.flags |=
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen args->value.flags;
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen prev->next = args->next;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen args = args->next;
dc52b16795b56589923ff586e5cdd0c0f1fd5931Timo Sirainen continue;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen }
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen } else if (args->type == SEARCH_FLAGS && args->not &&
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen !parent_and) {
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen if (prev_not_flags_arg == NULL)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen prev_not_flags_arg = args;
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen else {
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen prev_not_flags_arg->value.flags |=
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen args->value.flags;
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen prev->next = args->next;
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen args = args->next;
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen continue;
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen }
19e8adccba16ff419f5675b1575358c2956dce83Timo Sirainen }
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainen
/* merge all keywords arguments */
if (args->type == SEARCH_KEYWORDS && !args->not && parent_and) {
if (prev_kw_arg == NULL)
prev_kw_arg = args;
else {
prev_kw_arg->value.keywords =
mail_search_keywords_merge(
&prev_kw_arg->value.keywords,
&args->value.keywords);
prev->next = args->next;
args = args->next;
continue;
}
} else if (args->type == SEARCH_KEYWORDS && args->not &&
!parent_and) {
if (prev_not_kw_arg == NULL)
prev_not_kw_arg = args;
else {
prev_not_kw_arg->value.keywords =
mail_search_keywords_merge(
&prev_not_kw_arg->value.keywords,
&args->value.keywords);
prev->next = args->next;
args = args->next;
continue;
}
}
prev = args;
args = args->next;
}
}
void mail_search_args_simplify(struct mail_search_arg *args)
{
mail_search_args_simplify_sub(args, TRUE);
}