summaryrefslogtreecommitdiffstats
path: root/src/lib-storage/index/index-mail.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:51:24 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:51:24 +0000
commitf7548d6d28c313cf80e6f3ef89aed16a19815df1 (patch)
treea3f6f2a3f247293bee59ecd28e8cd8ceb6ca064a /src/lib-storage/index/index-mail.h
parentInitial commit. (diff)
downloaddovecot-f7548d6d28c313cf80e6f3ef89aed16a19815df1.tar.xz
dovecot-f7548d6d28c313cf80e6f3ef89aed16a19815df1.zip
Adding upstream version 1:2.3.19.1+dfsg1.upstream/1%2.3.19.1+dfsg1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/lib-storage/index/index-mail.h')
-rw-r--r--src/lib-storage/index/index-mail.h292
1 files changed, 292 insertions, 0 deletions
diff --git a/src/lib-storage/index/index-mail.h b/src/lib-storage/index/index-mail.h
new file mode 100644
index 0000000..74107d2
--- /dev/null
+++ b/src/lib-storage/index/index-mail.h
@@ -0,0 +1,292 @@
+#ifndef INDEX_MAIL_H
+#define INDEX_MAIL_H
+
+#include "message-size.h"
+#include "mail-cache.h"
+#include "mail-storage-private.h"
+
+enum index_cache_field {
+ /* fixed size fields */
+ MAIL_CACHE_FLAGS = 0,
+ MAIL_CACHE_SENT_DATE,
+ MAIL_CACHE_RECEIVED_DATE,
+ MAIL_CACHE_SAVE_DATE,
+ MAIL_CACHE_VIRTUAL_FULL_SIZE,
+ MAIL_CACHE_PHYSICAL_FULL_SIZE,
+
+ /* variable sized field */
+ MAIL_CACHE_IMAP_BODY,
+ MAIL_CACHE_IMAP_BODYSTRUCTURE,
+ MAIL_CACHE_IMAP_ENVELOPE,
+ MAIL_CACHE_POP3_UIDL,
+ MAIL_CACHE_POP3_ORDER,
+ MAIL_CACHE_GUID,
+ MAIL_CACHE_MESSAGE_PARTS,
+ MAIL_CACHE_BINARY_PARTS,
+ MAIL_CACHE_BODY_SNIPPET,
+
+ MAIL_INDEX_CACHE_FIELD_COUNT
+};
+extern struct mail_cache_field
+ global_cache_fields[MAIL_INDEX_CACHE_FIELD_COUNT];
+
+#define IMAP_BODY_PLAIN_7BIT_ASCII \
+ "\"text\" \"plain\" (\"charset\" \"us-ascii\") NIL NIL \"7bit\""
+
+enum mail_cache_record_flag {
+ /* If binary flags are set, it's not checked whether mail is
+ missing CRs. So this flag may be set as an optimization for
+ regular non-binary mails as well if it's known that it contains
+ valid CR+LF line breaks. */
+ MAIL_CACHE_FLAG_BINARY_HEADER = 0x0001,
+ MAIL_CACHE_FLAG_BINARY_BODY = 0x0002,
+
+ /* Mail header or body is known to contain NUL characters. */
+ MAIL_CACHE_FLAG_HAS_NULS = 0x0004,
+ /* Mail header or body is known to not contain NUL characters. */
+ MAIL_CACHE_FLAG_HAS_NO_NULS = 0x0020,
+ /* obsolete _HAS_NO_NULS flag, which was being set incorrectly */
+ MAIL_CACHE_FLAG_HAS_NO_NULS_BROKEN = 0x0008,
+
+ /* BODY is IMAP_BODY_PLAIN_7BIT_ASCII and rest of BODYSTRUCTURE
+ fields are NIL */
+ MAIL_CACHE_FLAG_TEXT_PLAIN_7BIT_ASCII = 0x0010
+};
+
+enum index_mail_access_part {
+ READ_HDR = 0x01,
+ READ_BODY = 0x02,
+ PARSE_HDR = 0x04,
+ PARSE_BODY = 0x08
+};
+
+struct mail_sent_date {
+ uint32_t time;
+ int32_t timezone;
+};
+
+struct index_mail_line {
+ unsigned int field_idx;
+ uint32_t start_pos, end_pos;
+ uint32_t line_num;
+};
+
+struct message_header_line;
+
+struct index_mail_data {
+ time_t date, received_date, save_date;
+ uoff_t virtual_size, physical_size;
+
+ struct mail_sent_date sent_date;
+ struct index_mail_line parse_line;
+ uint32_t parse_line_num;
+
+ struct message_part *parts;
+ struct message_binary_part *bin_parts;
+ const char *envelope, *body, *bodystructure, *guid, *filename;
+ const char *from_envelope, *body_snippet;
+ struct message_part_envelope *envelope_data;
+
+ uint32_t cache_flags;
+ uint64_t modseq, pvt_modseq;
+ enum index_mail_access_part access_part;
+ const char *access_reason_code;
+ /* dont_cache_fields overrides cache_fields */
+ enum mail_fetch_field cache_fetch_fields, dont_cache_fetch_fields;
+ unsigned int dont_cache_field_idx;
+ enum mail_fetch_field wanted_fields;
+ struct mailbox_header_lookup_ctx *wanted_headers;
+
+ buffer_t *search_results;
+
+ struct istream *stream, *filter_stream;
+ struct tee_istream *tee_stream;
+ struct message_size hdr_size, body_size;
+ struct istream *parser_input;
+ struct message_parser_ctx *parser_ctx;
+ int parsing_count;
+ ARRAY_TYPE(keywords) keywords;
+ ARRAY_TYPE(keyword_indexes) keyword_indexes;
+
+ bool initialized:1;
+ bool save_sent_date:1;
+ bool sent_date_parsed:1;
+ bool save_envelope:1;
+ bool save_bodystructure_header:1;
+ bool save_bodystructure_body:1;
+ bool save_message_parts:1;
+ bool save_body_snippet:1;
+ bool stream_has_only_header:1;
+ bool parsed_bodystructure:1;
+ bool parsed_bodystructure_header:1;
+ bool hdr_size_set:1;
+ bool body_size_set:1;
+ bool messageparts_saved_to_cache:1;
+ bool header_parsed:1;
+ bool no_caching:1;
+ bool forced_no_caching:1;
+ bool istream_error_logged:1;
+ bool destroying_stream:1;
+ bool initialized_wrapper_stream:1;
+ bool destroy_callback_set:1;
+ bool prefetch_sent:1;
+ bool header_parser_initialized:1;
+ /* virtual_size and physical_size may not match the stream size.
+ Try to avoid trusting them too much. */
+ bool inexact_total_sizes:1;
+};
+
+struct index_mail {
+ struct mail_private mail;
+ struct index_mail_data data;
+ struct index_mailbox_context *ibox;
+
+ int pop3_state;
+
+ /* per-mail variables, here for performance reasons: */
+ uint32_t header_seq;
+ string_t *header_data;
+ ARRAY(struct index_mail_line) header_lines;
+#define HEADER_MATCH_FLAG_FOUND 1
+#define HEADER_MATCH_SKIP_COUNT 2
+#define HEADER_MATCH_USABLE(mail, num) \
+ ((num & ~1U) == (mail)->header_match_value)
+ ARRAY(uint8_t) header_match;
+ ARRAY(unsigned int) header_match_lines;
+ uint8_t header_match_value;
+
+ bool pop3_state_set:1;
+ /* close() is being called from mail_free() */
+ bool freeing:1;
+};
+
+#define INDEX_MAIL(s) container_of(s, struct index_mail, mail.mail)
+
+struct mail *
+index_mail_alloc(struct mailbox_transaction_context *t,
+ enum mail_fetch_field wanted_fields,
+ struct mailbox_header_lookup_ctx *wanted_headers);
+void index_mail_init(struct index_mail *mail,
+ struct mailbox_transaction_context *_t,
+ enum mail_fetch_field wanted_fields,
+ struct mailbox_header_lookup_ctx *_wanted_headers,
+ struct pool *mail_pool,
+ struct pool *data_pool);
+
+void index_mail_set_seq(struct mail *mail, uint32_t seq, bool saving);
+bool index_mail_set_uid(struct mail *mail, uint32_t uid);
+void index_mail_set_uid_cache_updates(struct mail *mail, bool set);
+bool index_mail_prefetch(struct mail *mail);
+void index_mail_add_temp_wanted_fields(struct mail *mail,
+ enum mail_fetch_field fields,
+ struct mailbox_header_lookup_ctx *headers);
+void index_mail_update_access_parts_pre(struct mail *mail);
+void index_mail_update_access_parts_post(struct mail *_mail);
+void index_mail_close(struct mail *mail);
+void index_mail_close_streams(struct index_mail *mail);
+void index_mail_free(struct mail *mail);
+void index_mail_set_message_parts_corrupted(struct mail *mail, const char *error);
+
+bool index_mail_want_parse_headers(struct index_mail *mail);
+void index_mail_parse_header_init(struct index_mail *mail,
+ struct mailbox_header_lookup_ctx *headers)
+ ATTR_NULL(2);
+void index_mail_parse_header(struct message_part *part,
+ struct message_header_line *hdr,
+ struct index_mail *mail) ATTR_NULL(1);
+int index_mail_parse_headers(struct index_mail *mail,
+ struct mailbox_header_lookup_ctx *headers,
+ const char *reason)
+ ATTR_NULL(2);
+void index_mail_parse_header_deinit(struct index_mail *mail);
+/* Same as index_mail_parse_headers(), but assume that the stream is
+ already opened. */
+int index_mail_parse_headers_internal(struct index_mail *mail,
+ struct mailbox_header_lookup_ctx *headers)
+ ATTR_NULL(2);
+int index_mail_headers_get_envelope(struct index_mail *mail);
+void index_mail_parts_reset(struct index_mail *mail);
+
+int index_mail_get_first_header(struct mail *_mail, const char *field,
+ bool decode_to_utf8, const char **value_r);
+int index_mail_get_headers(struct mail *_mail, const char *field,
+ bool decode_to_utf8, const char *const **value_r);
+int index_mail_get_header_stream(struct mail *_mail,
+ struct mailbox_header_lookup_ctx *headers,
+ struct istream **stream_r);
+void index_mail_set_read_buffer_size(struct mail *mail, struct istream *input);
+
+enum mail_flags index_mail_get_flags(struct mail *_mail);
+uint64_t index_mail_get_modseq(struct mail *_mail);
+uint64_t index_mail_get_pvt_modseq(struct mail *_mail);
+const char *const *index_mail_get_keywords(struct mail *_mail);
+const ARRAY_TYPE(keyword_indexes) *
+index_mail_get_keyword_indexes(struct mail *_mail);
+int index_mail_get_parts(struct mail *_mail, struct message_part **parts_r);
+int index_mail_get_received_date(struct mail *_mail, time_t *date_r);
+int index_mail_get_save_date(struct mail *_mail, time_t *date_r);
+int index_mail_get_date(struct mail *_mail, time_t *date_r, int *timezone_r);
+int index_mail_get_virtual_size(struct mail *mail, uoff_t *size_r);
+int index_mail_get_physical_size(struct mail *mail, uoff_t *size_r);
+int index_mail_init_stream(struct index_mail *mail,
+ struct message_size *hdr_size,
+ struct message_size *body_size,
+ struct istream **stream_r) ATTR_NULL(2, 3);
+int index_mail_get_binary_stream(struct mail *_mail,
+ const struct message_part *part,
+ bool include_hdr, uoff_t *size_r,
+ unsigned int *body_lines_r, bool *binary_r,
+ struct istream **stream_r);
+int index_mail_get_special(struct mail *_mail, enum mail_fetch_field field,
+ const char **value_r);
+int index_mail_get_backend_mail(struct mail *mail, struct mail **real_mail_r);
+
+void index_mail_update_flags(struct mail *mail, enum modify_type modify_type,
+ enum mail_flags flags);
+void index_mail_update_keywords(struct mail *mail, enum modify_type modify_type,
+ struct mail_keywords *keywords);
+void index_mail_update_modseq(struct mail *mail, uint64_t min_modseq);
+void index_mail_update_pvt_modseq(struct mail *mail, uint64_t min_pvt_modseq);
+void index_mail_expunge(struct mail *mail);
+int index_mail_precache(struct mail *mail);
+void index_mail_set_cache_corrupted(struct mail *mail,
+ enum mail_fetch_field field,
+ const char *reason);
+int index_mail_opened(struct mail *mail, struct istream **stream);
+int index_mail_stream_check_failure(struct index_mail *mail);
+void index_mail_stream_log_failure_for(struct index_mail *mail,
+ struct istream *input);
+void index_mail_refresh_expunged(struct mail *mail);
+struct index_mail *index_mail_get_index_mail(struct mail *mail);
+
+bool index_mail_get_cached_uoff_t(struct index_mail *mail,
+ enum index_cache_field field, uoff_t *size_r);
+bool index_mail_get_cached_virtual_size(struct index_mail *mail,
+ uoff_t *size_r);
+bool index_mail_get_cached_body(struct index_mail *mail, const char **value_r);
+bool index_mail_get_cached_bodystructure(struct index_mail *mail,
+ const char **value_r);
+const uint32_t *index_mail_get_vsize_extension(struct mail *_mail);
+
+bool index_mail_want_cache(struct index_mail *mail, enum index_cache_field field);
+void index_mail_cache_add(struct index_mail *mail, enum index_cache_field field,
+ const void *data, size_t data_size);
+void index_mail_cache_add_idx(struct index_mail *mail, unsigned int field_idx,
+ const void *data, size_t data_size);
+
+void index_mail_cache_pop3_data(struct mail *_mail,
+ const char *uidl, uint32_t order);
+
+struct istream *index_mail_cache_parse_init(struct mail *mail,
+ struct istream *input);
+void index_mail_cache_parse_continue(struct mail *mail);
+void index_mail_cache_parse_deinit(struct mail *mail, time_t received_date,
+ bool success);
+
+int index_mail_cache_lookup_field(struct index_mail *mail, buffer_t *buf,
+ unsigned int field_idx);
+void index_mail_save_finish(struct mail_save_context *ctx);
+
+const char *index_mail_cache_reason(struct mail *mail, const char *reason);
+
+#endif