mail-search.c revision 4139bd30500732466acf4ff1134950788248ec55
76b43e4417bab52e913da39b5f5bc2a130d3f149Timo Sirainen/* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenmailbox_uidset_change(struct mail_search_arg *arg, struct mailbox *box,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen const ARRAY_TYPE(seq_range) *search_saved_uidset)
5363a534097c170ef9cccbdde5ca802f581f5eb7Timo Sirainen unsigned int i, count;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen if (arg->value.str != NULL && strcmp(arg->value.str, "$") == 0) {
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* SEARCHRES: Replace with saved uidset */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen array_append_array(&arg->value.seqset, search_saved_uidset);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen /* make a copy of the UIDs */
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen /* empty set, keep it */
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen memcpy(uids, array_idx(&arg->value.seqset, 0), sizeof(*uids) * count);
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen /* put them back to the range as sequences */
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen for (i = 0; i < count; i++) {
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen mailbox_get_seq_range(box, uids[i].seq1, uids[i].seq2,
f0569d9fbb25c8437760be69f194595a841ad711Timo Sirainen /* make sure the last message is in the range */
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainen seq_range_array_add(&arg->value.seqset, 0, seq2);
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainenmail_search_args_init_sub(struct mail_search_arg *args,
12d34ab79772e0748a1daef30fa749dfe3036608Timo Sirainen const ARRAY_TYPE(seq_range) *search_saved_uidset)
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* modseq with keyword */
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen mail_search_args_init_sub(args->value.subargs, box,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenvoid mail_search_args_init(struct mail_search_args *args,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen const ARRAY_TYPE(seq_range) *search_saved_uidset)
9aa52288a4b53186d81b0ec9afa7d9e0a8ee8753Timo Sirainen mail_search_args_init_sub(args->args, box, change_uidsets,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainenstatic void mail_search_args_deinit_sub(struct mail_search_args *args,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen mailbox_keywords_free(args->box, &arg->value.keywords);
821984ecb6c90696f35c32a8dc4c8a60f9e98f99Timo Sirainen mail_search_args_deinit_sub(args, arg->value.subargs);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenvoid mail_search_args_deinit(struct mail_search_args *args)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen mail_search_args_deinit_sub(args, args->args);
197ad81605dc0f6d2ebc9ad99994db5ca6d76699Timo Sirainenstatic void mail_search_args_seq2uid_sub(struct mail_search_args *args,
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 mail_search_args_seq2uid_sub(args, arg->value.subargs,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenvoid mail_search_args_seq2uid(struct mail_search_args *args)
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen mail_search_args_seq2uid_sub(args, args->args, &uids);
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenvoid mail_search_args_ref(struct mail_search_args *args)
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainenvoid mail_search_args_unref(struct mail_search_args **_args)
7f773564b94e6054a40d3785cb63c29f1e4d4deeTimo Sirainenvoid mail_search_args_reset(struct mail_search_arg *args, bool full_reset)
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen if (args->type == SEARCH_OR || args->type == SEARCH_SUB)
dda2c506c8fc8ac2f88272de4523ded42baa0aa0Timo Sirainen mail_search_args_reset(args->value.subargs, full_reset);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void search_arg_foreach(struct mail_search_arg *arg,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* sublist of conditions */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen search_arg_foreach(subarg, callback, context);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* didn't match */
d371507847d62ba311b4bcc23d18f45c3d0f1a38Timo Sirainen /* OR-list of conditions */
08b30498acefc69e223baf7eda6429be98cc3a10Timo Sirainen search_arg_foreach(subarg, callback, context);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* matched */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen /* just a single condition */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint mail_search_args_foreach(struct mail_search_arg *args,
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen /* didn't match */
92139717fd109c34692670df54d157d8c4df9b71Timo Sirainensearch_arg_analyze(struct mail_search_arg *arg, buffer_t *headers,
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen buffer_append(headers, &date_hdr, sizeof(const char *));
1cd97699af9c77d8f5920832ec3374884544fd68Timo Sirainen sizeof(const char *));
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainenconst char *const *
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainenmail_search_args_analyze(struct mail_search_arg *args,
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen *have_headers = *have_body = have_text = FALSE;
bf301a34ffbfd049be583094019b2644884b6d0bTimo Sirainen headers = buffer_create_dynamic(pool_datastack_create(), 128);
58eb2cb24dbeadd94500670acad7ceb1c8b0d9b4Timo Sirainen search_arg_analyze(args, headers, have_body, &have_text);
84e1634acc701d14e358e27f1beff5ad74f5004aTimo Sirainen *have_headers = have_text || headers->used != 0;
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen buffer_append(headers, &null, sizeof(const char *));
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainenmail_search_keywords_merge(struct mail_keywords **_kw1,
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen struct mail_keywords *kw1 = *_kw1, *kw2 = *_kw2;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen unsigned int i, j;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen t_array_init(&new_indexes, kw1->count + kw2->count + 1);
1e76a5b92f9d82d557f81f080f3dfad1c9d8f200Timo Sirainen array_append(&new_indexes, kw1->idx, kw1->count);
b5e6f6f27c1461f0f9f202615eeb738a645188c3Timo Sirainen /* don't add duplicates */
6843896c40bee4f9b6680ca7ced598c446e9f999Timo Sirainen new_kw = mail_index_keywords_create_from_indexes(kw1->index,
eddd9bf1a1369aea4a2715f6be1137da6d17d293Timo Sirainenmail_search_args_simplify_sub(struct mail_search_arg *args, bool parent_and)
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;
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 .. */
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen if ((args->type == SEARCH_SUB && parent_and) ||
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen /* p and (q and ..) == p and q and ..
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen p or (q or ..) == p or q or .. */
91dca97b367c54a139c268b56a0c67f564bd9197Timo Sirainen if (args->type == SEARCH_SUB || args->type == SEARCH_OR) {
bb10ebcf076c959c752f583746d83805d7686df8Timo Sirainen mail_search_args_simplify_sub(args->value.subargs,
313fe89df4d91cd0cd7f3558dc6d7fd21ad39eeeTimo Sirainen /* merge all flags arguments */
8d80659e504ffb34bb0c6a633184fece35751b18Timo Sirainen if (args->type == SEARCH_FLAGS && !args->not && parent_and) {
abe8230dd1dd37d7ccf0163100e934bb5e658c20Timo Sirainen } else if (args->type == SEARCH_FLAGS && args->not &&
!parent_and) {