1 #ifndef INDEX_MAIL_H 2 #define INDEX_MAIL_H 3 4 #include "message-size.h" 5 #include "mail-cache.h" 6 #include "mail-storage-private.h" 7 8 enum index_cache_field { 9 /* fixed size fields */ 10 MAIL_CACHE_FLAGS = 0, 11 MAIL_CACHE_SENT_DATE, 12 MAIL_CACHE_RECEIVED_DATE, 13 MAIL_CACHE_SAVE_DATE, 14 MAIL_CACHE_VIRTUAL_FULL_SIZE, 15 MAIL_CACHE_PHYSICAL_FULL_SIZE, 16 17 /* variable sized field */ 18 MAIL_CACHE_IMAP_BODY, 19 MAIL_CACHE_IMAP_BODYSTRUCTURE, 20 MAIL_CACHE_IMAP_ENVELOPE, 21 MAIL_CACHE_POP3_UIDL, 22 MAIL_CACHE_POP3_ORDER, 23 MAIL_CACHE_GUID, 24 MAIL_CACHE_MESSAGE_PARTS, 25 MAIL_CACHE_BINARY_PARTS, 26 MAIL_CACHE_BODY_SNIPPET, 27 28 MAIL_INDEX_CACHE_FIELD_COUNT 29 }; 30 extern struct mail_cache_field 31 global_cache_fields[MAIL_INDEX_CACHE_FIELD_COUNT]; 32 33 #define IMAP_BODY_PLAIN_7BIT_ASCII \ 34 "\"text\" \"plain\" (\"charset\" \"us-ascii\") NIL NIL \"7bit\"" 35 36 enum mail_cache_record_flag { 37 /* If binary flags are set, it's not checked whether mail is 38 missing CRs. So this flag may be set as an optimization for 39 regular non-binary mails as well if it's known that it contains 40 valid CR+LF line breaks. */ 41 MAIL_CACHE_FLAG_BINARY_HEADER = 0x0001, 42 MAIL_CACHE_FLAG_BINARY_BODY = 0x0002, 43 44 /* Mail header or body is known to contain NUL characters. */ 45 MAIL_CACHE_FLAG_HAS_NULS = 0x0004, 46 /* Mail header or body is known to not contain NUL characters. */ 47 MAIL_CACHE_FLAG_HAS_NO_NULS = 0x0020, 48 /* obsolete _HAS_NO_NULS flag, which was being set incorrectly */ 49 MAIL_CACHE_FLAG_HAS_NO_NULS_BROKEN = 0x0008, 50 51 /* BODY is IMAP_BODY_PLAIN_7BIT_ASCII and rest of BODYSTRUCTURE 52 fields are NIL */ 53 MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII = 0x0010 54 }; 55 56 enum index_mail_access_part { 57 READ_HDR = 0x01, 58 READ_BODY = 0x02, 59 PARSE_HDR = 0x04, 60 PARSE_BODY = 0x08 61 }; 62 63 struct mail_sent_date { 64 uint32_t time; 65 int32_t timezone; 66 }; 67 68 struct index_mail_line { 69 unsigned int field_idx; 70 uint32_t start_pos, end_pos; 71 uint32_t line_num; 72 }; 73 74 struct message_header_line; 75 76 struct index_mail_data { 77 time_t date, received_date, save_date; 78 uoff_t virtual_size, physical_size; 79 80 struct mail_sent_date sent_date; 81 struct index_mail_line parse_line; 82 uint32_t parse_line_num; 83 84 struct message_part *parts; 85 struct message_binary_part *bin_parts; 86 const char *envelope, *body, *bodystructure, *guid, *filename; 87 const char *from_envelope, *body_snippet; 88 struct message_part_envelope *envelope_data; 89 90 uint32_t seq; 91 uint32_t cache_flags; 92 uint64_t modseq, pvt_modseq; 93 enum index_mail_access_part access_part; 94 /* dont_cache_fields overrides cache_fields */ 95 enum mail_fetch_field cache_fetch_fields, dont_cache_fetch_fields; 96 unsigned int dont_cache_field_idx; 97 enum mail_fetch_field wanted_fields; 98 struct mailbox_header_lookup_ctx *wanted_headers; 99 100 buffer_t *search_results; 101 102 struct istream *stream, *filter_stream; 103 struct tee_istream *tee_stream; 104 struct message_size hdr_size, body_size; 105 struct istream *parser_input; 106 struct message_parser_ctx *parser_ctx; 107 int parsing_count; 108 ARRAY_TYPE(keywords) keywords; 109 ARRAY_TYPE(keyword_indexes) keyword_indexes; 110 111 bool initialized:1; 112 bool save_sent_date:1; 113 bool sent_date_parsed:1; 114 bool save_envelope:1; 115 bool save_bodystructure_header:1; 116 bool save_bodystructure_body:1; 117 bool save_message_parts:1; 118 bool save_body_snippet:1; 119 bool stream_has_only_header:1; 120 bool parsed_bodystructure:1; 121 bool parsed_bodystructure_header:1; 122 bool hdr_size_set:1; 123 bool body_size_set:1; 124 bool messageparts_saved_to_cache:1; 125 bool header_parsed:1; 126 bool no_caching:1; 127 bool forced_no_caching:1; 128 bool istream_error_logged:1; 129 bool destroying_stream:1; 130 bool initialized_wrapper_stream:1; 131 bool destroy_callback_set:1; 132 bool prefetch_sent:1; 133 bool header_parser_initialized:1; 134 /* virtual_size and physical_size may not match the stream size. 135 Try to avoid trusting them too much. */ 136 bool inexact_total_sizes:1; 137 }; 138 139 struct index_mail { 140 struct mail_private mail; 141 struct index_mail_data data; 142 struct index_mailbox_context *ibox; 143 144 int pop3_state; 145 146 /* per-mail variables, here for performance reasons: */ 147 uint32_t header_seq; 148 string_t *header_data; 149 ARRAY(struct index_mail_line) header_lines; 150 #define HEADER_MATCH_FLAG_FOUND 1 151 #define HEADER_MATCH_SKIP_COUNT 2 152 #define HEADER_MATCH_USABLE(mail, num) \ 153 ((num & ~1U) == (mail)->header_match_value) 154 ARRAY(uint8_t) header_match; 155 ARRAY(unsigned int) header_match_lines; 156 uint8_t header_match_value; 157 158 bool pop3_state_set:1; 159 /* close() is being called from mail_free() */ 160 bool freeing:1; 161 }; 162 163 #define INDEX_MAIL(s) container_of(s, struct index_mail, mail.mail) 164 165 struct mail * 166 index_mail_alloc(struct mailbox_transaction_context *t, 167 enum mail_fetch_field wanted_fields, 168 struct mailbox_header_lookup_ctx *wanted_headers); 169 void index_mail_init(struct index_mail *mail, 170 struct mailbox_transaction_context *_t, 171 enum mail_fetch_field wanted_fields, 172 struct mailbox_header_lookup_ctx *_wanted_headers, 173 struct pool *mail_pool, 174 struct pool *data_pool); 175 176 void index_mail_set_seq(struct mail *mail, uint32_t seq, bool saving); 177 bool index_mail_set_uid(struct mail *mail, uint32_t uid); 178 void index_mail_set_uid_cache_updates(struct mail *mail, bool set); 179 bool index_mail_prefetch(struct mail *mail); 180 void index_mail_add_temp_wanted_fields(struct mail *mail, 181 enum mail_fetch_field fields, 182 struct mailbox_header_lookup_ctx *headers); 183 void index_mail_update_access_parts_pre(struct mail *mail); 184 void index_mail_update_access_parts_post(struct mail *_mail); 185 void index_mail_close(struct mail *mail); 186 void index_mail_close_streams(struct index_mail *mail); 187 void index_mail_free(struct mail *mail); 188 void index_mail_set_message_parts_corrupted(struct mail *mail, const char *error); 189 190 bool index_mail_want_parse_headers(struct index_mail *mail); 191 void index_mail_parse_header_init(struct index_mail *mail, 192 struct mailbox_header_lookup_ctx *headers) 193 ATTR_NULL(2); 194 void index_mail_parse_header(struct message_part *part, 195 struct message_header_line *hdr, 196 struct index_mail *mail) ATTR_NULL(1); 197 int index_mail_parse_headers(struct index_mail *mail, 198 struct mailbox_header_lookup_ctx *headers, 199 const char *reason) 200 ATTR_NULL(2); 201 void index_mail_parse_header_deinit(struct index_mail *mail); 202 /* Same as index_mail_parse_headers(), but assume that the stream is 203 already opened. */ 204 int index_mail_parse_headers_internal(struct index_mail *mail, 205 struct mailbox_header_lookup_ctx *headers) 206 ATTR_NULL(2); 207 int index_mail_headers_get_envelope(struct index_mail *mail); 208 209 int index_mail_get_first_header(struct mail *_mail, const char *field, 210 bool decode_to_utf8, const char **value_r); 211 int index_mail_get_headers(struct mail *_mail, const char *field, 212 bool decode_to_utf8, const char *const **value_r); 213 int index_mail_get_header_stream(struct mail *_mail, 214 struct mailbox_header_lookup_ctx *headers, 215 struct istream **stream_r); 216 void index_mail_set_read_buffer_size(struct mail *mail, struct istream *input); 217 218 enum mail_flags index_mail_get_flags(struct mail *_mail); 219 uint64_t index_mail_get_modseq(struct mail *_mail); 220 uint64_t index_mail_get_pvt_modseq(struct mail *_mail); 221 const char *const *index_mail_get_keywords(struct mail *_mail); 222 const ARRAY_TYPE(keyword_indexes) * 223 index_mail_get_keyword_indexes(struct mail *_mail); 224 int index_mail_get_parts(struct mail *_mail, struct message_part **parts_r); 225 int index_mail_get_received_date(struct mail *_mail, time_t *date_r); 226 int index_mail_get_save_date(struct mail *_mail, time_t *date_r); 227 int index_mail_get_date(struct mail *_mail, time_t *date_r, int *timezone_r); 228 int index_mail_get_virtual_size(struct mail *mail, uoff_t *size_r); 229 int index_mail_get_physical_size(struct mail *mail, uoff_t *size_r); 230 int index_mail_init_stream(struct index_mail *mail, 231 struct message_size *hdr_size, 232 struct message_size *body_size, 233 struct istream **stream_r) ATTR_NULL(2, 3); 234 int index_mail_get_binary_stream(struct mail *_mail, 235 const struct message_part *part, 236 bool include_hdr, uoff_t *size_r, 237 unsigned int *body_lines_r, bool *binary_r, 238 struct istream **stream_r); 239 int index_mail_get_special(struct mail *_mail, enum mail_fetch_field field, 240 const char **value_r); 241 int index_mail_get_backend_mail(struct mail *mail, struct mail **real_mail_r); 242 243 void index_mail_update_flags(struct mail *mail, enum modify_type modify_type, 244 enum mail_flags flags); 245 void index_mail_update_keywords(struct mail *mail, enum modify_type modify_type, 246 struct mail_keywords *keywords); 247 void index_mail_update_modseq(struct mail *mail, uint64_t min_modseq); 248 void index_mail_update_pvt_modseq(struct mail *mail, uint64_t min_pvt_modseq); 249 void index_mail_expunge(struct mail *mail); 250 int index_mail_precache(struct mail *mail); 251 void index_mail_set_cache_corrupted(struct mail *mail, 252 enum mail_fetch_field field, 253 const char *reason); 254 int index_mail_opened(struct mail *mail, struct istream **stream); 255 int index_mail_stream_check_failure(struct index_mail *mail); 256 void index_mail_stream_log_failure_for(struct index_mail *mail, 257 struct istream *input); 258 void index_mail_refresh_expunged(struct mail *mail); 259 struct index_mail *index_mail_get_index_mail(struct mail *mail); 260 261 bool index_mail_get_cached_uoff_t(struct index_mail *mail, 262 enum index_cache_field field, uoff_t *size_r); 263 bool index_mail_get_cached_virtual_size(struct index_mail *mail, 264 uoff_t *size_r); 265 bool index_mail_get_cached_body(struct index_mail *mail, const char **value_r); 266 bool index_mail_get_cached_bodystructure(struct index_mail *mail, 267 const char **value_r); 268 const uint32_t *index_mail_get_vsize_extension(struct mail *_mail); 269 270 bool index_mail_want_cache(struct index_mail *mail, enum index_cache_field field); 271 void index_mail_cache_add(struct index_mail *mail, enum index_cache_field field, 272 const void *data, size_t data_size); 273 void index_mail_cache_add_idx(struct index_mail *mail, unsigned int field_idx, 274 const void *data, size_t data_size); 275 276 void index_mail_cache_pop3_data(struct mail *_mail, 277 const char *uidl, uint32_t order); 278 279 struct istream *index_mail_cache_parse_init(struct mail *mail, 280 struct istream *input); 281 void index_mail_cache_parse_continue(struct mail *mail); 282 void index_mail_cache_parse_deinit(struct mail *mail, time_t received_date, 283 bool success); 284 285 int index_mail_cache_lookup_field(struct index_mail *mail, buffer_t *buf, 286 unsigned int field_idx); 287 void index_mail_save_finish(struct mail_save_context *ctx); 288 289 const char *index_mail_cache_reason(struct mail *mail, const char *reason); 290 291 #endif 292