Lines Matching refs:mail
18 #include "mail-cache.h"
19 #include "mail-index-modseq.h"
21 #include "istream-mail.h"
22 #include "index-mail.h"
72 static void index_mail_init_data(struct index_mail *mail);
73 static int index_mail_parse_body(struct index_mail *mail,
75 static int index_mail_write_body_snippet(struct index_mail *mail);
77 int index_mail_cache_lookup_field(struct index_mail *mail, buffer_t *buf,
82 ret = mail_cache_lookup_field(mail->mail.mail.transaction->cache_view,
83 buf, mail->data.seq, field_idx);
85 mail->mail.mail.transaction->stats.cache_hit_count++;
89 static int get_serialized_parts(struct index_mail *mail, buffer_t **part_buf_r)
92 mail->ibox->cache_fields[MAIL_CACHE_MESSAGE_PARTS].idx;
95 return index_mail_cache_lookup_field(mail, *part_buf_r, field_idx);
98 static struct message_part *get_unserialized_parts(struct index_mail *mail)
104 if (get_serialized_parts(mail, &part_buf) <= 0)
107 parts = message_part_deserialize(mail->mail.data_pool, part_buf->data,
110 mail_set_mail_cache_corrupted(&mail->mail.mail,
130 static bool get_cached_parts(struct index_mail *mail)
135 part = get_unserialized_parts(mail);
142 mail->mail.mail.has_nuls = TRUE;
143 mail->mail.mail.has_no_nuls = FALSE;
145 mail->mail.mail.has_nuls = FALSE;
146 mail->mail.mail.has_no_nuls = TRUE;
149 mail->data.parts = part;
153 void index_mail_set_message_parts_corrupted(struct mail *mail, const char *error)
158 if (get_serialized_parts(INDEX_MAIL(mail), &part_buf) <= 0)
163 mail_set_cache_corrupted(mail,
169 static bool index_mail_get_fixed_field(struct index_mail *mail,
173 const unsigned int field_idx = mail->ibox->cache_fields[field].idx;
178 if (index_mail_cache_lookup_field(mail, &buf, field_idx) <= 0)
187 bool index_mail_get_cached_uoff_t(struct index_mail *mail,
190 return index_mail_get_fixed_field(mail, field,
194 static bool index_mail_get_pvt(struct mail *_mail)
196 struct mail_private *mail = (struct mail_private *)_mail;
198 if (mail->seq_pvt != 0)
205 /* mail is still being saved, it has no private flags yet */
212 &mail->seq_pvt))
213 mail->seq_pvt = 0;
214 return mail->seq_pvt != 0;
217 enum mail_flags index_mail_get_flags(struct mail *_mail)
219 struct mail_private *mail = (struct mail_private *)_mail;
235 mail->seq_pvt);
241 uint64_t index_mail_get_modseq(struct mail *_mail)
243 struct index_mail *mail = INDEX_MAIL(_mail);
245 if (mail->data.modseq != 0)
246 return mail->data.modseq;
249 mail->data.modseq =
251 return mail->data.modseq;
254 uint64_t index_mail_get_pvt_modseq(struct mail *_mail)
256 struct index_mail *mail = INDEX_MAIL(_mail);
258 if (mail->data.pvt_modseq != 0)
259 return mail->data.pvt_modseq;
266 mail->data.pvt_modseq =
269 return mail->data.pvt_modseq;
272 const char *const *index_mail_get_keywords(struct mail *_mail)
274 struct index_mail *mail = INDEX_MAIL(_mail);
275 struct index_mail_data *data = &mail->data;
286 names = array_get(mail->ibox->keyword_names, &names_count);
287 p_array_init(&data->keywords, mail->mail.data_pool, count + 1);
302 index_mail_get_keyword_indexes(struct mail *_mail)
304 struct index_mail *mail = INDEX_MAIL(_mail);
305 struct index_mail_data *data = &mail->data;
308 p_array_init(&data->keyword_indexes, mail->mail.data_pool, 32);
310 mail->data.seq,
316 int index_mail_get_parts(struct mail *_mail, struct message_part **parts_r)
318 struct index_mail *mail = INDEX_MAIL(_mail);
319 struct index_mail_data *data = &mail->data;
322 if (data->parts != NULL || get_cached_parts(mail)) {
330 if (index_mail_parse_headers(mail, NULL, reason) < 0)
337 if (index_mail_parse_body(mail, 0) < 0)
345 int index_mail_get_received_date(struct mail *_mail, time_t *date_r)
347 struct index_mail *mail = INDEX_MAIL(_mail);
348 struct index_mail_data *data = &mail->data;
354 if (index_mail_get_fixed_field(mail, MAIL_CACHE_RECEIVED_DATE,
363 int index_mail_get_save_date(struct mail *_mail, time_t *date_r)
365 struct index_mail *mail = INDEX_MAIL(_mail);
366 struct index_mail_data *data = &mail->data;
372 if (index_mail_get_fixed_field(mail, MAIL_CACHE_SAVE_DATE,
381 static int index_mail_cache_sent_date(struct index_mail *mail)
383 struct index_mail_data *data = &mail->data;
391 if ((ret = mail_get_first_header(&mail->mail.mail, "Date", &str)) < 0)
403 index_mail_cache_add(mail, MAIL_CACHE_SENT_DATE,
408 int index_mail_get_date(struct mail *_mail, time_t *date_r, int *timezone_r)
410 struct index_mail *mail = INDEX_MAIL(_mail);
411 struct index_mail_data *data = &mail->data;
421 if (index_mail_get_fixed_field(mail, MAIL_CACHE_SENT_DATE,
425 if (index_mail_cache_sent_date(mail) < 0)
433 static bool get_cached_msgpart_sizes(struct index_mail *mail)
435 struct index_mail_data *data = &mail->data;
438 (void)get_cached_parts(mail);
454 const uint32_t *index_mail_get_vsize_extension(struct mail *_mail)
456 struct index_mail *mail = INDEX_MAIL(_mail);
465 mail->data.virtual_size = (*vsize)-1;
470 bool index_mail_get_cached_virtual_size(struct index_mail *mail, uoff_t *size_r)
472 struct index_mail_data *data = &mail->data;
473 struct mail *_mail = &mail->mail.mail;
482 if (index_mail_get_cached_uoff_t(mail,
487 if (!get_cached_msgpart_sizes(mail))
512 static void index_mail_get_cached_body_size(struct index_mail *mail)
514 struct index_mail_data *data = &mail->data;
523 if (!index_mail_get_cached_virtual_size(mail, &tmp))
527 enum mail_lookup_abort old_abort = mail->mail.mail.lookup_abort;
531 if (mail->mail.mail.lookup_abort < MAIL_LOOKUP_ABORT_READ_MAIL)
532 mail->mail.mail.lookup_abort = MAIL_LOOKUP_ABORT_READ_MAIL;
533 if (mail_get_physical_size(&mail->mail.mail, &tmp) == 0) {
535 (void)index_mail_get_cached_virtual_size(mail, &tmp);
537 mail->mail.mail.lookup_abort = old_abort;
541 int index_mail_get_virtual_size(struct mail *_mail, uoff_t *size_r)
543 struct index_mail *mail = INDEX_MAIL(_mail);
544 struct index_mail_data *data = &mail->data;
549 if (index_mail_get_cached_virtual_size(mail, size_r))
563 int index_mail_get_physical_size(struct mail *_mail, uoff_t *size_r)
565 struct index_mail *mail = INDEX_MAIL(_mail);
566 struct index_mail_data *data = &mail->data;
571 if (index_mail_get_cached_uoff_t(mail,
576 (void)get_cached_msgpart_sizes(mail);
582 void index_mail_cache_add(struct index_mail *mail, enum index_cache_field field,
585 index_mail_cache_add_idx(mail, mail->ibox->cache_fields[field].idx,
589 void index_mail_cache_add_idx(struct index_mail *mail, unsigned int field_idx,
592 struct mail *_mail = &mail->mail.mail;
604 if (!mail->data.no_caching &&
605 mail->data.dont_cache_field_idx != field_idx &&
619 static bool want_plain_bodystructure_cached(struct index_mail *mail)
622 mail->ibox->cache_fields[MAIL_CACHE_IMAP_BODY].idx;
624 mail->ibox->cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
625 struct mail *_mail = &mail->mail.mail;
627 if ((mail->data.wanted_fields & (MAIL_FETCH_IMAP_BODY |
640 static void index_mail_body_parsed_cache_flags(struct index_mail *mail)
642 struct mail *_mail = &mail->mail.mail;
643 struct index_mail_data *data = &mail->data;
648 cache_flags_idx = mail->ibox->cache_fields[MAIL_CACHE_FLAGS].idx;
654 (want_cached || want_plain_bodystructure_cached(mail))) {
684 index_mail_cache_add_idx(mail, cache_flags_idx,
690 static void index_mail_body_parsed_cache_message_parts(struct index_mail *mail)
692 struct mail *_mail = &mail->mail.mail;
693 struct index_mail_data *data = &mail->data;
695 mail->ibox->cache_fields[MAIL_CACHE_MESSAGE_PARTS].idx;
722 message_part_serialize(mail->data.parts, buffer);
723 index_mail_cache_add_idx(mail, cache_field,
731 index_mail_body_parsed_cache_bodystructure(struct index_mail *mail,
734 struct mail *_mail = &mail->mail.mail;
735 struct index_mail_data *data = &mail->data;
737 mail->ibox->cache_fields[MAIL_CACHE_MESSAGE_PARTS].idx;
739 mail->ibox->cache_fields[MAIL_CACHE_IMAP_BODY].idx;
741 mail->ibox->cache_fields[MAIL_CACHE_IMAP_BODYSTRUCTURE].idx;
777 str = str_new(mail->mail.data_pool, 128);
781 index_mail_cache_add(mail, MAIL_CACHE_IMAP_BODYSTRUCTURE,
809 str = str_new(mail->mail.data_pool, 128);
813 index_mail_cache_add(mail, MAIL_CACHE_IMAP_BODY,
818 bool index_mail_want_cache(struct index_mail *mail, enum index_cache_field field)
820 struct mail *_mail = &mail->mail.mail;
847 if ((mail->data.dont_cache_fetch_fields & fetch_field) != 0)
854 cache_field = mail->ibox->cache_fields[field].idx;
855 if ((mail->data.cache_fetch_fields & fetch_field) != 0) {
864 static void index_mail_save_finish_make_snippet(struct index_mail *mail)
866 if (mail->data.save_body_snippet) {
867 if (index_mail_write_body_snippet(mail) < 0)
869 mail->data.save_body_snippet = FALSE;
872 if (mail->data.body_snippet != NULL &&
873 index_mail_want_cache(mail, MAIL_CACHE_BODY_SNIPPET)) {
874 index_mail_cache_add(mail, MAIL_CACHE_BODY_SNIPPET,
875 mail->data.body_snippet,
876 strlen(mail->data.body_snippet)+1);
880 static void index_mail_cache_sizes(struct index_mail *mail)
882 struct mail *_mail = &mail->mail.mail;
894 sizes[0] = mail->data.virtual_size;
895 sizes[1] = mail->data.physical_size;
911 we store vsize for every +4GB-1 mail to cache because
925 index_mail_want_cache(mail, size_fields[i])) {
926 index_mail_cache_add(mail, size_fields[i],
932 static void index_mail_cache_dates(struct index_mail *mail)
942 dates[0] = mail->data.received_date;
943 dates[1] = mail->mail.mail.saving ? ioloop_time :
944 mail->data.save_date;
948 index_mail_want_cache(mail, date_fields[i])) {
950 index_mail_cache_add(mail, date_fields[i],
955 if (mail->data.sent_date_parsed &&
956 index_mail_want_cache(mail, MAIL_CACHE_SENT_DATE))
957 (void)index_mail_cache_sent_date(mail);
1012 static int index_mail_write_body_snippet(struct index_mail *mail)
1020 i_assert(mail->data.parsed_bodystructure);
1022 part = index_mail_find_first_text_mime_part(mail->data.parts);
1024 mail->data.body_snippet = BODY_SNIPPET_ALGO_V1;
1028 old_offset = mail->data.stream == NULL ? 0 : mail->data.stream->v_offset;
1029 const char *reason = index_mail_cache_reason(&mail->mail.mail, "snippet");
1030 if (mail_get_stream_because(&mail->mail.mail, NULL, NULL, reason, &input) < 0)
1032 i_assert(mail->data.stream != NULL);
1038 str = str_new(mail->mail.data_pool, 128);
1042 mail->data.body_snippet = str_c(str);
1045 i_stream_seek(mail->data.stream, old_offset);
1050 index_mail_parse_body_finish(struct index_mail *mail,
1053 struct istream *parser_input = mail->data.parser_input;
1058 ret = message_parser_deinit_from_parts(&mail->data.parser_ctx,
1059 &mail->data.parts, &error) < 0 ? 0 : 1;
1061 mail->data.parser_input = NULL;
1063 ret = message_parser_deinit_from_parts(&mail->data.parser_ctx,
1064 &mail->data.parts, &error) < 0 ? 0 : 1;
1080 index_mail_stream_log_failure_for(mail, parser_input);
1088 index_mail_set_message_parts_corrupted(&mail->mail.mail, error);
1090 mail->data.parts = NULL;
1091 mail->data.parsed_bodystructure = FALSE;
1092 if (mail->data.save_bodystructure_body)
1093 mail->data.save_bodystructure_header = TRUE;
1096 if (mail->data.save_bodystructure_body) {
1097 mail->data.parsed_bodystructure = TRUE;
1098 mail->data.save_bodystructure_header = FALSE;
1099 mail->data.save_bodystructure_body = FALSE;
1100 i_assert(mail->data.parts != NULL);
1103 if (mail->data.no_caching) {
1110 (void)get_cached_msgpart_sizes(mail);
1112 index_mail_body_parsed_cache_flags(mail);
1113 index_mail_body_parsed_cache_message_parts(mail);
1114 index_mail_body_parsed_cache_bodystructure(mail, field);
1115 index_mail_cache_sizes(mail);
1116 index_mail_cache_dates(mail);
1120 static void index_mail_stream_log_failure(struct index_mail *mail)
1122 index_mail_stream_log_failure_for(mail, mail->data.stream);
1125 int index_mail_stream_check_failure(struct index_mail *mail)
1127 if (mail->data.stream->stream_errno == 0)
1129 index_mail_stream_log_failure(mail);
1133 void index_mail_refresh_expunged(struct mail *mail)
1135 mail_index_refresh(mail->box->index);
1136 if (mail_index_is_expunged(mail->transaction->view, mail->seq))
1137 mail_set_expunged(mail);
1140 void index_mail_stream_log_failure_for(struct index_mail *mail,
1143 struct mail *_mail = &mail->mail.mail;
1148 /* was the mail just expunged? we could get here especially if
1158 mail->mail.get_stream_reason == NULL ? "" :
1159 mail->mail.get_stream_reason);
1162 static int index_mail_parse_body(struct index_mail *mail,
1165 struct index_mail_data *data = &mail->data;
1180 mail->mail.data_pool);
1185 ret = index_mail_stream_check_failure(mail);
1186 if (index_mail_parse_body_finish(mail, field, TRUE) < 0)
1193 static void index_mail_stream_destroy_callback(struct index_mail *mail)
1195 i_assert(mail->data.destroying_stream);
1197 mail->data.destroying_stream = FALSE;
1200 void index_mail_set_read_buffer_size(struct mail *_mail, struct istream *input)
1202 struct index_mail *mail = INDEX_MAIL(_mail);
1206 block_size = (mail->data.access_part & (READ_BODY | PARSE_BODY)) != 0 ?
1211 int index_mail_init_stream(struct index_mail *mail,
1216 struct mail *_mail = &mail->mail.mail;
1217 struct index_mail_data *data = &mail->data;
1223 mail->mail.get_stream_reason != NULL &&
1224 mail->mail.get_stream_reason[0] != '\0') {
1225 i_debug("Mailbox %s: Opened mail UID=%u because: %s",
1227 mail->mail.get_stream_reason);
1245 index_mail_stream_destroy_callback, mail);
1249 (void)get_cached_msgpart_sizes(mail);
1255 (void)get_cached_parts(mail);
1256 if (index_mail_parse_headers(mail, NULL, "parse header") < 0)
1262 index_mail_stream_log_failure(mail);
1275 index_mail_get_cached_body_size(mail);
1280 if (index_mail_parse_body(mail, 0) < 0)
1286 index_mail_stream_log_failure(mail);
1302 ret = index_mail_stream_check_failure(mail);
1311 static int index_mail_parse_bodystructure(struct index_mail *mail,
1314 struct index_mail_data *data = &mail->data;
1320 index_mail_body_parsed_cache_bodystructure(mail, field);
1327 index_mail_cache_reason(&mail->mail.mail, "bodystructure");
1330 (void)get_cached_parts(mail);
1331 if (index_mail_parse_headers(mail, NULL, reason) < 0) {
1338 if (index_mail_parse_body(mail, field) < 0)
1348 str = str_new(mail->mail.data_pool, 128);
1355 str = str_new(mail->mail.data_pool, 128);
1362 if (index_mail_write_body_snippet(mail) < 0)
1365 if (index_mail_want_cache(mail, MAIL_CACHE_BODY_SNIPPET))
1366 index_mail_cache_add(mail, MAIL_CACHE_BODY_SNIPPET,
1367 mail->data.body_snippet,
1368 strlen(mail->data.body_snippet) + 1);
1380 index_mail_get_plain_bodystructure(struct index_mail *mail, string_t *str,
1384 mail->data.parts->body_size.virtual_size,
1385 mail->data.parts->body_size.lines);
1391 index_mail_fetch_body_snippet(struct index_mail *mail, const char **value_r)
1393 const struct mail_cache_field *cache_fields = mail->ibox->cache_fields;
1398 mail->data.cache_fetch_fields |= MAIL_FETCH_BODY_SNIPPET;
1399 if (mail->data.body_snippet == NULL) {
1400 str = str_new(mail->mail.data_pool, 128);
1401 if (index_mail_cache_lookup_field(mail, str, cache_field) > 0 &&
1403 mail->data.body_snippet = str_c(str);
1405 if (mail->data.body_snippet != NULL) {
1406 *value_r = mail->data.body_snippet;
1412 mail->data.save_body_snippet = TRUE;
1413 if (index_mail_parse_bodystructure(mail, MAIL_CACHE_BODY_SNIPPET) < 0)
1415 i_assert(mail->data.body_snippet != NULL);
1416 *value_r = mail->data.body_snippet;
1420 bool index_mail_get_cached_body(struct index_mail *mail, const char **value_r)
1422 const struct mail_cache_field *cache_fields = mail->ibox->cache_fields;
1427 struct index_mail_data *data = &mail->data;
1436 str = str_new(mail->mail.data_pool, 128);
1438 get_cached_parts(mail)) {
1439 index_mail_get_plain_bodystructure(mail, str, FALSE);
1445 if (index_mail_cache_lookup_field(mail, str, body_cache_field) > 0) {
1450 if (index_mail_cache_lookup_field(mail, str, bodystructure_cache_field) > 0) {
1452 p_strdup(mail->mail.data_pool, str_c(str));
1458 mail_set_cache_corrupted(&mail->mail.mail,
1472 bool index_mail_get_cached_bodystructure(struct index_mail *mail,
1475 const struct mail_cache_field *cache_fields = mail->ibox->cache_fields;
1478 struct index_mail_data *data = &mail->data;
1486 str = str_new(mail->mail.data_pool, 128);
1488 get_cached_parts(mail)) {
1489 index_mail_get_plain_bodystructure(mail, str, TRUE);
1493 if (index_mail_cache_lookup_field(mail, str, bodystructure_cache_field) > 0) {
1502 int index_mail_get_special(struct mail *_mail,
1505 struct index_mail *mail = INDEX_MAIL(_mail);
1506 struct index_mail_data *data = &mail->data;
1510 if (index_mail_get_cached_body(mail, value_r))
1515 if (index_mail_parse_bodystructure(mail, MAIL_CACHE_IMAP_BODY) < 0)
1521 if (index_mail_get_cached_bodystructure(mail, value_r))
1524 if (index_mail_parse_bodystructure(mail, MAIL_CACHE_IMAP_BODYSTRUCTURE) < 0)
1531 if (index_mail_headers_get_envelope(mail) < 0)
1541 return index_mail_fetch_body_snippet(mail, value_r);
1559 int index_mail_get_backend_mail(struct mail *mail,
1560 struct mail **real_mail_r)
1562 *real_mail_r = mail;
1566 struct mail *
1571 struct index_mail *mail;
1574 pool = pool_alloconly_create("mail", 2048);
1575 mail = p_new(pool, struct index_mail, 1);
1576 mail->mail.pool = pool;
1578 index_mail_init(mail, t, wanted_fields, wanted_headers);
1579 return &mail->mail.mail;
1582 static void index_mail_init_event(struct mail *mail)
1584 mail->event = event_create(mail->box->event);
1585 event_add_category(mail->event, &event_category_mail);
1588 void index_mail_init(struct index_mail *mail,
1593 array_create(&mail->mail.module_contexts, mail->mail.pool,
1596 mail->mail.v = *t->box->mail_vfuncs;
1597 mail->mail.mail.box = t->box;
1598 mail->mail.mail.transaction = t;
1599 index_mail_init_event(&mail->mail.mail);
1601 mail->mail.data_pool = pool_alloconly_create("index_mail", 16384);
1602 mail->ibox = INDEX_STORAGE_CONTEXT(t->box);
1603 mail->mail.wanted_fields = wanted_fields;
1605 mail->mail.wanted_headers = wanted_headers;
1608 index_mail_init_data(mail);
1611 static void index_mail_close_streams_full(struct index_mail *mail, bool closing)
1613 struct index_mail_data *data = &mail->data;
1619 index_mail_set_message_parts_corrupted(&mail->mail.mail, error);
1620 mail->data.parser_input = NULL;
1621 if (mail->data.save_bodystructure_body)
1622 mail->data.save_bodystructure_header = TRUE;
1631 allowed to have references until the mail is closed
1637 /* there must be no references to the mail when the
1638 mail is being closed. */
1641 else if (mail->data.destroying_stream) {
1651 void index_mail_close_streams(struct index_mail *mail)
1653 index_mail_close_streams_full(mail, FALSE);
1656 static void index_mail_init_data(struct index_mail *mail)
1658 struct index_mail_data *data = &mail->data;
1667 data->wanted_fields = mail->mail.wanted_fields;
1668 if (mail->mail.wanted_headers != NULL) {
1669 data->wanted_headers = mail->mail.wanted_headers;
1674 static void index_mail_reset_data(struct index_mail *mail)
1676 i_zero(&mail->data);
1677 p_clear(mail->mail.data_pool);
1679 index_mail_init_data(mail);
1681 mail->mail.mail.seq = 0;
1682 mail->mail.mail.uid = 0;
1683 mail->mail.seq_pvt = 0;
1684 mail->mail.mail.expunged = FALSE;
1685 mail->mail.mail.has_nuls = FALSE;
1686 mail->mail.mail.has_no_nuls = FALSE;
1687 mail->mail.mail.saving = FALSE;
1688 mail->mail.mail.mail_stream_opened = FALSE;
1689 mail->mail.mail.mail_metadata_accessed = FALSE;
1692 void index_mail_close(struct mail *_mail)
1694 struct index_mail *mail = INDEX_MAIL(_mail);
1696 if (mail->mail.mail.seq == 0) {
1706 /* make sure old mail isn't visible in the event anymore even if it's
1709 index_mail_init_event(&mail->mail.mail);
1716 if (mail->mail.mail.uid != 0) {
1717 index_mail_cache_sizes(mail);
1718 index_mail_cache_dates(mail);
1721 index_mail_close_streams_full(mail, TRUE);
1722 /* Notify cache that the mail is no longer open. This mainly helps
1727 mailbox_header_lookup_unref(&mail->data.wanted_headers);
1728 if (!mail->freeing)
1729 index_mail_reset_data(mail);
1732 static void check_envelope(struct index_mail *mail)
1734 struct mail *_mail = &mail->mail.mail;
1736 mail->ibox->cache_fields[MAIL_CACHE_IMAP_ENVELOPE].idx;
1739 if ((mail->data.access_part & PARSE_HDR) != 0) {
1740 mail->data.save_envelope = TRUE;
1757 mail->data.access_part |= PARSE_HDR;
1758 mail->data.save_envelope = TRUE;
1761 void index_mail_update_access_parts_pre(struct mail *_mail)
1763 struct index_mail *mail = INDEX_MAIL(_mail);
1764 struct index_mail_data *data = &mail->data;
1766 const struct mail_cache_field *cache_fields = mail->ibox->cache_fields;
1781 (void)index_mail_get_fixed_field(mail, MAIL_CACHE_FLAGS,
1811 check_envelope(mail);
1880 void index_mail_update_access_parts_post(struct mail *_mail)
1882 struct index_mail *mail = INDEX_MAIL(_mail);
1883 struct index_mail_data *data = &mail->data;
1894 first mail. */
1912 void index_mail_set_seq(struct mail *_mail, uint32_t seq, bool saving)
1914 struct index_mail *mail = INDEX_MAIL(_mail);
1916 if (mail->data.seq == seq) {
1919 /* we started saving a mail, aborted it, and now we're saving
1920 another mail with the same sequence. make sure the mail
1924 mail->mail.v.close(&mail->mail.mail);
1926 mail->data.seq = seq;
1927 mail->mail.mail.seq = seq;
1928 mail->mail.mail.saving = saving;
1930 &mail->mail.mail.uid);
1938 mail_set_expunged(&mail->mail.mail);
1942 if (!mail->search_mail) {
1947 index_mail_update_access_parts_*() after we know the mail is
1950 mail->data.initialized = TRUE;
1953 bool index_mail_prefetch(struct mail *_mail)
1955 struct index_mail *mail = INDEX_MAIL(_mail);
1967 if (mail->data.access_part == 0) {
1972 if (mail->data.stream == NULL) {
1974 if (mail->data.stream == NULL)
1979 fd = i_stream_get_fd(mail->data.stream);
1981 if ((mail->data.access_part & (READ_BODY | PARSE_BODY)) != 0)
1987 i_stream_get_name(mail->data.stream));
1989 mail->data.prefetch_sent = TRUE;
1992 return !mail->data.prefetch_sent;
1995 bool index_mail_set_uid(struct mail *_mail, uint32_t uid)
1997 struct index_mail *mail = INDEX_MAIL(_mail);
2004 mail->mail.v.close(&mail->mail.mail);
2005 mail->mail.mail.uid = uid;
2006 mail_set_expunged(&mail->mail.mail);
2011 void index_mail_add_temp_wanted_fields(struct mail *_mail,
2015 struct index_mail *mail = INDEX_MAIL(_mail);
2016 struct index_mail_data *data = &mail->data;
2055 void index_mail_set_uid_cache_updates(struct mail *_mail, bool set)
2057 struct index_mail *mail = INDEX_MAIL(_mail);
2059 mail->data.no_caching = set || mail->data.forced_no_caching;
2062 void index_mail_free(struct mail *_mail)
2064 struct index_mail *mail = INDEX_MAIL(_mail);
2066 /* make sure mailbox_search_*() users don't try to free the mail
2068 i_assert(!mail->search_mail);
2070 mail->freeing = TRUE;
2071 mail->mail.v.close(_mail);
2076 buffer_free(&mail->header_data);
2077 if (array_is_created(&mail->header_lines))
2078 array_free(&mail->header_lines);
2079 if (array_is_created(&mail->header_match))
2080 array_free(&mail->header_match);
2081 if (array_is_created(&mail->header_match_lines))
2082 array_free(&mail->header_match_lines);
2084 mailbox_header_lookup_unref(&mail->data.wanted_headers);
2085 mailbox_header_lookup_unref(&mail->mail.wanted_headers);
2087 pool_unref(&mail->mail.data_pool);
2088 pool_unref(&mail->mail.pool);
2091 void index_mail_cache_parse_continue(struct mail *_mail)
2093 struct index_mail *mail = INDEX_MAIL(_mail);
2096 while (message_parser_parse_next_block(mail->data.parser_ctx,
2101 if (!mail->data.header_parsed) {
2102 index_mail_parse_header(block.part, block.hdr, mail);
2104 mail->data.header_parsed = TRUE;
2106 message_part_data_parse_from_header(mail->mail.data_pool,
2112 void index_mail_cache_parse_deinit(struct mail *_mail, time_t received_date,
2115 struct index_mail *mail = INDEX_MAIL(_mail);
2118 /* we're going to delete this mail anyway,
2120 mail->data.no_caching = TRUE;
2121 mail->data.forced_no_caching = TRUE;
2123 if (mail->data.parser_ctx == NULL) {
2132 if (mail->data.received_date == (time_t)-1)
2133 mail->data.received_date = received_date;
2134 if (mail->data.save_date == (time_t)-1) {
2138 mail->data.save_date = ioloop_time;
2141 (void)index_mail_parse_body_finish(mail, 0, success);
2145 index_mail_update_pvt_flags(struct mail *_mail, enum modify_type modify_type,
2148 struct mail_private *mail = (struct mail_private *)_mail;
2158 rec = mail_index_lookup(_mail->transaction->view_pvt, mail->seq_pvt);
2172 void index_mail_update_flags(struct mail *_mail, enum modify_type modify_type,
2175 struct mail_private *mail = (struct mail_private *)_mail;
2188 mail->seq_pvt,
2208 void index_mail_update_keywords(struct mail *mail, enum modify_type modify_type,
2211 struct index_mail *imail = INDEX_MAIL(mail);
2220 array is allocated from mail's memory pool. */
2225 mail_index_update_keywords(mail->transaction->itrans, mail->seq,
2229 void index_mail_update_modseq(struct mail *mail, uint64_t min_modseq)
2231 mail_index_update_modseq(mail->transaction->itrans, mail->seq,
2235 void index_mail_update_pvt_modseq(struct mail *mail, uint64_t min_pvt_modseq)
2237 if (mail->box->view_pvt == NULL)
2239 index_transaction_init_pvt(mail->transaction);
2240 mail_index_update_modseq(mail->transaction->itrans_pvt, mail->seq,
2244 void index_mail_expunge(struct mail *mail)
2246 enum mail_lookup_abort old_abort = mail->lookup_abort;
2250 mail->lookup_abort = MAIL_LOOKUP_ABORT_NOT_IN_CACHE;
2251 if (mail_get_special(mail, MAIL_FETCH_GUID, &value) < 0)
2252 mail_index_expunge(mail->transaction->itrans, mail->seq);
2255 mail_index_expunge_guid(mail->transaction->itrans,
2256 mail->seq, guid_128);
2258 mail->lookup_abort = old_abort;
2261 static void index_mail_parse(struct mail *mail, bool parse_body)
2263 struct index_mail *imail = INDEX_MAIL(mail);
2274 void index_mail_precache(struct mail *mail)
2276 struct index_mail *imail = INDEX_MAIL(mail);
2282 if (mail_cache_field_exists_any(mail->transaction->cache_view,
2283 mail->seq)) {
2284 /* already cached this mail (we should get here only if FTS
2291 index_mail_parse(mail, (cache & MAIL_FETCH_STREAM_BODY) != 0);
2293 (void)mail_get_received_date(mail, &date);
2295 (void)mail_get_save_date(mail, &date);
2297 (void)mail_get_virtual_size(mail, &size);
2299 (void)mail_get_physical_size(mail, &size);
2301 (void)mail_get_special(mail, MAIL_FETCH_UIDL_BACKEND, &str);
2303 (void)mail_get_special(mail, MAIL_FETCH_POP3_ORDER, &str);
2305 (void)mail_get_special(mail, MAIL_FETCH_GUID, &str);
2309 index_mail_reset_vsize_ext(struct mail *mail)
2313 struct mail_index_view *view = mail->transaction->view;
2314 if (mail_index_map_get_ext_idx(view->map, mail->box->mail_vsize_ext_id,
2316 mail_index_update_ext(mail->transaction->itrans, mail->seq,
2317 mail->box->mail_vsize_ext_id, &vsize, NULL);
2321 void index_mail_set_cache_corrupted(struct mail *mail,
2325 struct index_mail *imail = INDEX_MAIL(mail);
2337 index_mail_reset_vsize_ext(mail);
2344 index_mail_reset_vsize_ext(mail);
2365 mail_cache_transaction_reset(mail->transaction->cache_trans);
2369 if (mail->saving) {
2370 mail_set_critical(mail,
2371 "BUG: Broken %s found while saving a new mail: %s",
2374 mail_set_mail_cache_corrupted(mail,
2376 field_name, mail->box->vname);
2378 mail_set_mail_cache_corrupted(mail,
2380 field_name, mail->box->vname, reason);
2384 int index_mail_opened(struct mail *mail ATTR_UNUSED,
2399 p_strdup(imail->mail.data_pool, ctx->data.from_envelope);
2403 const char *index_mail_cache_reason(struct mail *mail, const char *reason)
2406 mail_cache_get_missing_reason(mail->transaction->cache_view, mail->seq);