summaryrefslogtreecommitdiffstats
path: root/src/imap/imap-fetch.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/imap/imap-fetch.h')
-rw-r--r--src/imap/imap-fetch.h166
1 files changed, 166 insertions, 0 deletions
diff --git a/src/imap/imap-fetch.h b/src/imap/imap-fetch.h
new file mode 100644
index 0000000..ba8cfc8
--- /dev/null
+++ b/src/imap/imap-fetch.h
@@ -0,0 +1,166 @@
+#ifndef IMAP_FETCH_H
+#define IMAP_FETCH_H
+
+struct imap_fetch_context;
+
+enum imap_fetch_handler_flags {
+ IMAP_FETCH_HANDLER_FLAG_BUFFERED = 0x01,
+ IMAP_FETCH_HANDLER_FLAG_WANT_DEINIT = 0x02
+};
+
+/* Returns 1 = ok, 0 = client output buffer full, call again, -1 = error.
+ mail = NULL for deinit. */
+typedef int imap_fetch_handler_t(struct imap_fetch_context *ctx,
+ struct mail *mail, void *context);
+
+struct imap_fetch_init_context {
+ struct imap_fetch_context *fetch_ctx;
+ pool_t pool;
+
+ const char *name;
+ const struct imap_arg *args;
+
+ const char *error;
+};
+
+struct imap_fetch_handler {
+ const char *name;
+
+ /* Returns FALSE and sets ctx->error if arg is invalid */
+ bool (*init)(struct imap_fetch_init_context *ctx);
+};
+
+struct imap_fetch_context_handler {
+ imap_fetch_handler_t *handler;
+ void *context;
+
+ const char *name;
+ const char *nil_reply;
+
+ bool buffered:1;
+ bool want_deinit:1;
+};
+
+struct imap_fetch_qresync_args {
+ const ARRAY_TYPE(uint32_t) *qresync_sample_seqset;
+ const ARRAY_TYPE(uint32_t) *qresync_sample_uidset;
+};
+
+struct imap_fetch_state {
+ struct mailbox_transaction_context *trans;
+ struct mail_search_context *search_ctx;
+
+ struct mail *cur_mail;
+ unsigned int cur_handler;
+ const char *cur_human_name;
+ uoff_t cur_size;
+ enum mail_fetch_field cur_size_field;
+ string_t *cur_str;
+ size_t cur_str_prefix_size;
+ struct istream *cur_input;
+ bool skip_cr;
+ int (*cont_handler)(struct imap_fetch_context *ctx);
+ uint64_t *cur_stats_sizep;
+
+ bool fetching:1;
+ bool seen_flags_changed:1;
+ /* TRUE if the first FETCH parameter result hasn't yet been sent to
+ the IMAP client. Note that this doesn't affect buffered content in
+ cur_str until it gets flushed out. */
+ bool cur_first:1;
+ /* TRUE if the cur_str prefix has been flushed. More data may still
+ be added to it. */
+ bool line_partial:1;
+ bool skipped_expunged_msgs:1;
+ bool failed:1;
+};
+
+struct imap_fetch_context {
+ struct client *client;
+ pool_t ctx_pool;
+ const char *reason;
+
+ enum mail_fetch_field fetch_data;
+ ARRAY_TYPE(const_string) all_headers;
+
+ ARRAY(struct imap_fetch_context_handler) handlers;
+ unsigned int buffered_handlers_count;
+
+ ARRAY_TYPE(keywords) tmp_keywords;
+
+ struct imap_fetch_state state;
+ ARRAY_TYPE(seq_range) fetch_failed_uids;
+ unsigned int fetched_mails_count;
+
+ enum mail_error error;
+ const char *errstr;
+
+ bool initialized:1;
+ bool failures:1;
+ bool flags_have_handler:1;
+ bool flags_update_seen:1;
+ bool flags_show_only_seen_changes:1;
+ /* HEADER.FIELDS or HEADER.FIELDS.NOT is fetched */
+ bool fetch_header_fields:1;
+};
+
+void imap_fetch_handlers_register(const struct imap_fetch_handler *handlers,
+ size_t count);
+void imap_fetch_handler_unregister(const char *name);
+
+void imap_fetch_add_handler(struct imap_fetch_init_context *ctx,
+ enum imap_fetch_handler_flags flags,
+ const char *nil_reply,
+ imap_fetch_handler_t *handler, void *context)
+ ATTR_NULL(3, 5);
+#define imap_fetch_add_handler(ctx, flags, nil_reply, handler, context) \
+ imap_fetch_add_handler(ctx, flags, nil_reply - \
+ CALLBACK_TYPECHECK(handler, int (*)( \
+ struct imap_fetch_context *, struct mail *, \
+ typeof(context))), \
+ (imap_fetch_handler_t *)handler, context)
+
+int imap_fetch_att_list_parse(struct client *client, pool_t pool,
+ const struct imap_arg *list,
+ struct imap_fetch_context **fetch_ctx_r,
+ const char **client_error_r);
+
+struct imap_fetch_context *
+imap_fetch_alloc(struct client *client, pool_t pool, const char *reason);
+void imap_fetch_free(struct imap_fetch_context **ctx);
+bool imap_fetch_init_handler(struct imap_fetch_init_context *init_ctx);
+void imap_fetch_init_nofail_handler(struct imap_fetch_context *ctx,
+ bool (*init)(struct imap_fetch_init_context *));
+const struct imap_fetch_handler *imap_fetch_handler_lookup(const char *name);
+
+void imap_fetch_begin(struct imap_fetch_context *ctx, struct mailbox *box,
+ struct mail_search_args *search_args);
+int imap_fetch_send_vanished(struct client *client, struct mailbox *box,
+ const struct mail_search_args *search_args,
+ const struct imap_fetch_qresync_args *qresync_args);
+/* Returns 1 if finished, 0 if more data is needed, -1 if error.
+ When 0 is returned, line_partial=TRUE if literal is open and must be
+ finished before anything else to client. */
+int imap_fetch_more(struct imap_fetch_context *ctx,
+ struct client_command_context *cmd);
+/* Like imap_fetch_more(), but don't check/update output_lock.
+ The caller must handle this itself. */
+int imap_fetch_more_no_lock_update(struct imap_fetch_context *ctx);
+int imap_fetch_end(struct imap_fetch_context *ctx);
+int imap_fetch_more(struct imap_fetch_context *ctx,
+ struct client_command_context *cmd);
+
+bool imap_fetch_flags_init(struct imap_fetch_init_context *ctx);
+bool imap_fetch_modseq_init(struct imap_fetch_init_context *ctx);
+bool imap_fetch_uid_init(struct imap_fetch_init_context *ctx);
+
+bool imap_fetch_body_section_init(struct imap_fetch_init_context *ctx);
+bool imap_fetch_rfc822_init(struct imap_fetch_init_context *ctx);
+bool imap_fetch_binary_init(struct imap_fetch_init_context *ctx);
+bool imap_fetch_preview_init(struct imap_fetch_init_context *ctx);
+bool imap_fetch_snippet_init(struct imap_fetch_init_context *ctx);
+
+void imap_fetch_handlers_init(void);
+void imap_fetch_handlers_deinit(void);
+
+#endif