static int virtual_mail_get_save_date(struct mail *mail, time_t *date_r) { struct virtual_mail *vmail = (struct virtual_mail *)mail; if (virtual_mail_handle_lost(vmail) < 0) return -1; if (mail_get_save_date(vmail->backend_mail, date_r) < 0) { virtual_box_copy_error(mail->box, vmail->backend_mail->box); return -1; } return 0; }
static int index_mailbox_get_first_save_date(struct mailbox *box, struct mailbox_metadata *metadata_r) { const struct mail_index_header *hdr; struct mailbox_transaction_context *t; struct mail *mail; uint32_t seq; int ret = -1; hdr = mail_index_get_header(box->view); if (hdr->messages_count == 0) { metadata_r->first_save_date = (time_t)-1; return 0; } t = mailbox_transaction_begin(box, 0, __func__); mail = mail_alloc(t, 0, NULL); for (seq = 1; seq <= hdr->messages_count; seq++) { mail_set_seq(mail, seq); if (mail_get_save_date(mail, &metadata_r->first_save_date) == 0) { ret = 0; break; } if (mailbox_get_last_mail_error(box) != MAIL_ERROR_EXPUNGED) { /* failed */ break; } } mail_free(&mail); (void)mailbox_transaction_commit(&t); if (seq > hdr->messages_count) { /* all messages were expunged after all */ metadata_r->first_save_date = (time_t)-1; return 0; } return ret; }
/* Returns >0 = matched, 0 = not matched, -1 = unknown */ static int search_arg_match_cached(struct index_search_context *ctx, struct mail_search_arg *arg) { const char *str; struct tm *tm; uoff_t virtual_size; time_t date; int tz_offset; bool have_tz_offset; switch (arg->type) { /* internal dates */ case SEARCH_BEFORE: case SEARCH_ON: case SEARCH_SINCE: 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->mail, &date, &tz_offset) < 0) return -1; have_tz_offset = TRUE; break; case MAIL_SEARCH_DATE_TYPE_RECEIVED: if (mail_get_received_date(ctx->mail, &date) < 0) return -1; break; case MAIL_SEARCH_DATE_TYPE_SAVED: if (mail_get_save_date(ctx->mail, &date) < 0) return -1; break; } if ((arg->value.search_flags & MAIL_SEARCH_ARG_FLAG_USE_TZ) == 0) { if (!have_tz_offset) { tm = localtime(&date); tz_offset = utc_offset(tm, date); } date += tz_offset * 60; } switch (arg->type) { case SEARCH_BEFORE: return date < arg->value.time; case SEARCH_ON: return date >= arg->value.time && date < arg->value.time + 3600*24; case SEARCH_SINCE: return date >= arg->value.time; default: /* unreachable */ break; } /* sizes */ case SEARCH_SMALLER: case SEARCH_LARGER: if (mail_get_virtual_size(ctx->mail, &virtual_size) < 0) return -1; if (arg->type == SEARCH_SMALLER) return virtual_size < arg->value.size; else return virtual_size > arg->value.size; case SEARCH_GUID: if (mail_get_special(ctx->mail, MAIL_FETCH_GUID, &str) < 0) return -1; return strcmp(str, arg->value.str) == 0; default: return -1; } }