{
}
+static void search_set_failed(struct index_search_context *ctx)
+{
+ if (ctx->failed)
+ return;
+
+ /* remember the first failure */
+ mail_storage_last_error_push(ctx->box->storage);
+ ctx->failed = TRUE;
+}
+
+static void search_cur_mail_failed(struct index_search_context *ctx)
+{
+ switch (mailbox_get_last_mail_error(ctx->cur_mail->box)) {
+ case MAIL_ERROR_EXPUNGED:
+ ctx->mail_ctx.seen_lost_data = TRUE;
+ break;
+ case MAIL_ERROR_NOTPOSSIBLE:
+ /* lookup_abort hit */
+ break;
+ default:
+ search_set_failed(ctx);
+ break;
+ }
+}
+
static void search_init_arg(struct mail_search_arg *arg,
struct index_search_context *ctx)
{
if (strcmp(box->vname, arg->value.str) == 0)
return 1;
if (mail_get_special(ctx->cur_mail, MAIL_FETCH_MAILBOX_NAME,
- &str) < 0)
+ &str) < 0) {
+ search_cur_mail_failed(ctx);
return -1;
+ }
if (strcasecmp(str, "INBOX") == 0)
return strcasecmp(arg->value.str, "INBOX") == 0;
if (imap_match(arg->initialized.mailbox_glob, box->vname) == IMAP_MATCH_YES)
return 1;
if (mail_get_special(ctx->cur_mail, MAIL_FETCH_MAILBOX_NAME,
- &str) < 0)
+ &str) < 0) {
+ search_cur_mail_failed(ctx);
return -1;
+ }
return imap_match(arg->initialized.mailbox_glob, str) == IMAP_MATCH_YES;
default:
return -1;
have_tz_offset = FALSE; tz_offset = 0; date = (time_t)-1;
switch (arg->value.date_type) {
case MAIL_SEARCH_DATE_TYPE_SENT:
- if (mail_get_date(ctx->cur_mail, &date, &tz_offset) < 0)
+ if (mail_get_date(ctx->cur_mail, &date, &tz_offset) < 0) {
+ search_cur_mail_failed(ctx);
return -1;
+ }
have_tz_offset = TRUE;
break;
case MAIL_SEARCH_DATE_TYPE_RECEIVED:
- if (mail_get_received_date(ctx->cur_mail, &date) < 0)
+ if (mail_get_received_date(ctx->cur_mail, &date) < 0) {
+ search_cur_mail_failed(ctx);
return -1;
+ }
break;
case MAIL_SEARCH_DATE_TYPE_SAVED:
- if (mail_get_save_date(ctx->cur_mail, &date) < 0)
+ if (mail_get_save_date(ctx->cur_mail, &date) < 0) {
+ search_cur_mail_failed(ctx);
return -1;
+ }
break;
}
/* sizes */
case SEARCH_SMALLER:
case SEARCH_LARGER:
- if (mail_get_virtual_size(ctx->cur_mail, &virtual_size) < 0)
+ if (mail_get_virtual_size(ctx->cur_mail, &virtual_size) < 0) {
+ search_cur_mail_failed(ctx);
return -1;
+ }
if (arg->type == SEARCH_SMALLER)
return virtual_size < arg->value.size;
return virtual_size > arg->value.size;
case SEARCH_GUID:
- if (mail_get_special(ctx->cur_mail, MAIL_FETCH_GUID, &str) < 0)
+ if (mail_get_special(ctx->cur_mail, MAIL_FETCH_GUID, &str) < 0) {
+ search_cur_mail_failed(ctx);
return -1;
+ }
return strcmp(str, arg->value.str) == 0;
case SEARCH_REAL_UID: {
struct mail *real_mail;
- if (mail_get_backend_mail(ctx->cur_mail, &real_mail) < 0)
+ if (mail_get_backend_mail(ctx->cur_mail, &real_mail) < 0) {
+ search_cur_mail_failed(ctx);
return -1;
+ }
return seq_range_exists(&arg->value.seqset, real_mail->uid);
}
default:
hdr_ctx.index_ctx = ctx;
/* hdr_ctx.imail is different from imail for mails in
virtual mailboxes */
- if (mail_get_backend_mail(ctx->cur_mail, &real_mail) < 0)
+ if (mail_get_backend_mail(ctx->cur_mail, &real_mail) < 0) {
+ search_cur_mail_failed(ctx);
return -1;
+ }
hdr_ctx.imail = (struct index_mail *)real_mail;
hdr_ctx.custom_header = TRUE;
hdr_ctx.args = args;
i_assert(*headers != NULL);
if (mail_get_header_stream(ctx->cur_mail, headers_ctx,
- &input) < 0)
+ &input) < 0) {
+ search_cur_mail_failed(ctx);
failed = TRUE;
- else {
+ } else {
message_parse_header(input, NULL, hdr_parser_flags,
search_header, &hdr_ctx);
}
ret = have_body ?
mail_get_stream_because(ctx->cur_mail, NULL, NULL, "search", &input) :
mail_get_hdr_stream_because(ctx->cur_mail, NULL, "search", &input);
- if (ret < 0)
+ if (ret < 0) {
+ search_cur_mail_failed(ctx);
failed = TRUE;
- else {
+ } else {
hdr_ctx.parse_headers =
index_mail_want_parse_headers(hdr_ctx.imail);
if (hdr_ctx.parse_headers) {
i_stream_get_name(input),
i_stream_get_error(input));
failed = TRUE;
+ search_set_failed(ctx);
}
}
}
/* we didn't search headers. */
struct message_size hdr_size;
- if (mail_get_stream_because(ctx->cur_mail, &hdr_size, NULL, "search", &input) < 0)
+ if (mail_get_stream_because(ctx->cur_mail, &hdr_size, NULL, "search", &input) < 0) {
+ search_cur_mail_failed(ctx);
return -1;
+ }
i_stream_seek(input, hdr_size.physical_size);
}
mail_search_args_reset(ctx->mail_ctx.args->args, TRUE);
if (args->have_inthreads) {
if (mail_thread_init(t->box, NULL, &ctx->thread_ctx) < 0)
- ctx->failed = TRUE;
+ search_set_failed(ctx);
if (search_build_inthreads(ctx, args->args) < 0)
- ctx->failed = TRUE;
+ search_set_failed(ctx);
}
if (sort_program != NULL) {
imail->search_mail = FALSE;
mail_free(mailp);
}
+
+ if (ctx->failed)
+ mail_storage_last_error_pop(ctx->box->storage);
array_free(&ctx->mails);
i_free(ctx);
return ret;
static void search_match_finish(struct index_search_context *ctx, int match)
{
- if (ctx->cur_mail->expunged)
- ctx->mail_ctx.seen_lost_data = TRUE;
-
if (match == 0 &&
search_has_static_nonmatches(ctx->mail_ctx.args->args)) {
/* if there are saved search results remember
returning the messages. */
ctx->sorted = TRUE;
index_sort_list_finish(_ctx->sort_program);
- if (ctx->failed)
- return FALSE;
}
/* everything searched at this point already. just returning