index-search.c revision 013a0e03309a4a77552f6e8dd46d06c3d3f60f53
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch/* Copyright (c) 2002-2011 Dovecot authors, see the included COPYING file */
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic void search_parse_msgset_args(unsigned int messages_count,
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic void search_none(struct mail_search_arg *arg ATTR_UNUSED,
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic void search_init_arg(struct mail_search_arg *arg,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (mailbox_get_metadata(ctx->box, MAILBOX_METADATA_GUID,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* result will be unknown */
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen match = strcmp(mail_guid_128_to_string(metadata.guid),
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic void search_seqset_arg(struct mail_search_arg *arg,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (seq_range_exists(&arg->value.seqset, ctx->mail_ctx.seq))
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic int search_arg_match_keywords(struct index_search_context *ctx,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch ARRAY_TYPE(keyword_indexes) keyword_indexes_arr;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const struct mail_keywords *search_kws = arg->value.keywords;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const unsigned int *keyword_indexes;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch unsigned int i, j, count;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch mail_index_lookup_keywords(ctx->view, ctx->mail_ctx.seq,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch keyword_indexes = array_get(&keyword_indexes_arr, &count);
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen /* there probably aren't many keywords, so O(n*m) for now */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch for (j = 0; j < count; j++) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch/* Returns >0 = matched, 0 = not matched, -1 = unknown */
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic int search_arg_match_index(struct index_search_context *ctx,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return seq_range_exists(&arg->value.seqset, rec->uid);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* recent flag shouldn't be set, but indexes from v1.0.x
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch may contain it. */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return (flags & arg->value.flags) == arg->value.flags;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch modseq = mail_index_modseq_lookup_flags(ctx->view,
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen modseq = mail_index_modseq_lookup_keywords(ctx->view,
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic void search_index_arg(struct mail_search_arg *arg,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch rec = mail_index_lookup(ctx->view, ctx->mail_ctx.seq);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch switch (search_arg_match_index(ctx, arg, rec)) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* unknown */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch/* Returns >0 = matched, 0 = not matched, -1 = unknown */
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic int search_arg_match_mailbox(struct index_search_context *ctx,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const char *str;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (mail_get_special(ctx->cur_mail, MAIL_FETCH_MAILBOX_NAME,
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen return strcasecmp(arg->value.str, "INBOX") == 0;
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen if (mail_get_special(ctx->cur_mail, MAIL_FETCH_MAILBOX_NAME,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch return imap_match(arg->value.mailbox_glob, str) == IMAP_MATCH_YES;
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic void search_mailbox_arg(struct mail_search_arg *arg,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* unknown */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch/* Returns >0 = matched, 0 = not matched, -1 = unknown */
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic int search_arg_match_cached(struct index_search_context *ctx,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const char *str;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* internal dates */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch have_tz_offset = FALSE; tz_offset = 0; date = (time_t)-1;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (mail_get_date(ctx->cur_mail, &date, &tz_offset) < 0)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (mail_get_received_date(ctx->cur_mail, &date) < 0)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (mail_get_save_date(ctx->cur_mail, &date) < 0)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* unreachable */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (mail_get_virtual_size(ctx->cur_mail, &virtual_size) < 0)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (mail_get_special(ctx->cur_mail, MAIL_FETCH_GUID, &str) < 0)
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic void search_cached_arg(struct mail_search_arg *arg,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* unknown */
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic int search_sent(enum mail_search_arg_type type, time_t search_time,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch const unsigned char *sent_value, size_t sent_value_len)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* NOTE: RFC-3501 specifies that timezone is ignored
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch in searches. sent_time is returned as UTC, so change it. */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (!message_date_parse(sent_value, sent_value_len,
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainenmsg_search_arg_context(struct mail_search_arg *arg)
50a6d26bd9041f44b4cad0c0357c0c604c132cc8Stephan Bosch arg->context = message_search_init(arg->value.str, flags);
7384b4e78eaab44693c985192276e31322155e32Stephan Boschstatic void compress_lwsp(string_t *dest, const unsigned char *src,
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch unsigned int src_len)
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch unsigned int i;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch for (i = 0; i < src_len; i++) {
50a6d26bd9041f44b4cad0c0357c0c604c132cc8Stephan Boschstatic void search_header_arg(struct mail_search_arg *arg,
50a6d26bd9041f44b4cad0c0357c0c604c132cc8Stephan Bosch struct message_search_context *msg_search_ctx;
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen /* first check that the field name matches to argument. */
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen if (arg->value.date_type != MAIL_SEARCH_DATE_TYPE_SENT)
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen /* date is handled differently than others */
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen if (strcasecmp(ctx->hdr->name, "Date") == 0) {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch if (strcasecmp(ctx->hdr->name, arg->hdr_field_name) != 0)
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen /* we're just testing existence of the field. always matches. */
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen /* We're searching only for values, so drop header name and middle
65c0e43da8cfc730eeb4634f8aa384081bbfa4e7Timo Sirainen parts. We use header searching so that MIME words will be decoded. */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* simple match */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* we have to match against normalized address */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch addr = message_address_parse(pool_datastack_create(),
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch hdr.value_len = hdr.full_value_len = str_len(str);
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch /* convert LWSP to single spaces */
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch compress_lwsp(str, hdr.full_value, hdr.full_value_len);
i_unreached();
} T_END;
if (ret > 0)
case SEARCH_BEFORE:
case SEARCH_ON:
case SEARCH_SINCE:
case SEARCH_HEADER:
case SEARCH_HEADER_ADDRESS:
int ret;
case SEARCH_BODY:
case SEARCH_TEXT:
const char *const *headers;
int ret;
(!have_body ||
&input) < 0)
} else if (have_headers) {
if (failed) {
if (have_body)
if (have_headers) {
return ret;
unsigned int count;
if (count > 0) {
if (!match_not)
unsigned int count;
*seq2_r = 0;
if (!match_not) {
*seq2_r = 0;
case SEARCH_SUB:
case SEARCH_OR:
case SEARCH_SEQSET:
if (min_seq1 == 0) {
case SEARCH_SUB:
case SEARCH_OR:
case SEARCH_SEQSET:
if (uid_lowwater == 0)
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return FALSE;
unsigned int messages_count,
if (messages_count == 0) {
int ret = 0;
return ret;
int ret = 0;
&thread_uids) < 0)
return ret;
int ret = 0;
case SEARCH_OR:
case SEARCH_SUB:
case SEARCH_INTHREAD:
return ret;
const char *header;
*wanted_fields_r = 0;
case MAIL_SORT_ARRIVAL:
case MAIL_SORT_CC:
case MAIL_SORT_DATE:
case MAIL_SORT_FROM:
case MAIL_SORT_SIZE:
case MAIL_SORT_SUBJECT:
case MAIL_SORT_TO:
struct mail_search_context *
int ret;
return ret;
int ret;
if (ret < 0)
return ret;
case SEARCH_OR:
case SEARCH_SUB:
return FALSE;
return TRUE;
case SEARCH_SEQSET:
case SEARCH_FLAGS:
case SEARCH_KEYWORDS:
case SEARCH_MODSEQ:
case SEARCH_INTHREAD:
case SEARCH_ALL:
case SEARCH_UIDSET:
case SEARCH_BEFORE:
case SEARCH_ON:
case SEARCH_SINCE:
case SEARCH_SMALLER:
case SEARCH_LARGER:
case SEARCH_HEADER:
case SEARCH_HEADER_ADDRESS:
case SEARCH_BODY:
case SEARCH_TEXT:
case SEARCH_GUID:
case SEARCH_MAILBOX:
case SEARCH_MAILBOX_GUID:
case SEARCH_MAILBOX_GLOB:
return TRUE;
return FALSE;
return TRUE;
return FALSE;
if (match == 0 &&
for (i = 0; i < n && ret < 0; i++) {
return ret;
float percentage;
T_BEGIN {
const char *text;
} T_END;
unsigned long long guess_cost;
long long usecs;
bool ret;
return FALSE;
if (usecs < 0) {
return TRUE;
if (ret)
return ret;
int match;
T_BEGIN {
} T_END;
if (match < 0) {
if (match != 0)
unsigned int count;
return NULL;
return mail;
unsigned int count;
int ret = 0;
if (ret <= 0)
if (ret == 0) {
int ret;
return ret > 0;
int ret;
return ret;
int ret;
if (ret == 0) {
return FALSE;
if (ret < 0)
return FALSE;
return TRUE;
if (ret == 0) {
return FALSE;
return FALSE;
return FALSE;
return TRUE;
int ret;
ret = 0;
uid))
ret = 0;
if (ret != 0)
return ret != 0;