summaryrefslogtreecommitdiffstats
path: root/src/lib-storage/index/imapc/imapc-storage.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib-storage/index/imapc/imapc-storage.h')
-rw-r--r--src/lib-storage/index/imapc/imapc-storage.h268
1 files changed, 268 insertions, 0 deletions
diff --git a/src/lib-storage/index/imapc/imapc-storage.h b/src/lib-storage/index/imapc/imapc-storage.h
new file mode 100644
index 0000000..e02c568
--- /dev/null
+++ b/src/lib-storage/index/imapc/imapc-storage.h
@@ -0,0 +1,268 @@
+#ifndef IMAPC_STORAGE_H
+#define IMAPC_STORAGE_H
+
+#include "index-storage.h"
+#include "imapc-settings.h"
+#include "imapc-client.h"
+
+#define IMAPC_STORAGE_NAME "imapc"
+/* storage_name separator */
+#define IMAPC_LIST_STORAGE_NAME_ESCAPE_CHAR '%'
+/* fs_name separator */
+#define IMAPC_LIST_FS_NAME_ESCAPE_CHAR '%'
+/* vname separator */
+#define IMAPC_LIST_VNAME_ESCAPE_CHAR '~'
+
+struct imap_arg;
+struct imapc_untagged_reply;
+struct imapc_command_reply;
+struct imapc_mailbox;
+struct imapc_storage_client;
+
+typedef void imapc_storage_callback_t(const struct imapc_untagged_reply *reply,
+ struct imapc_storage_client *client);
+typedef void imapc_mailbox_callback_t(const struct imapc_untagged_reply *reply,
+ struct imapc_mailbox *mbox);
+
+struct imapc_storage_event_callback {
+ char *name;
+ imapc_storage_callback_t *callback;
+};
+
+struct imapc_mailbox_event_callback {
+ const char *name;
+ imapc_mailbox_callback_t *callback;
+};
+
+#define IMAPC_HAS_FEATURE(mstorage, feature) \
+ (((mstorage)->set->parsed_features & feature) != 0)
+#define IMAPC_BOX_HAS_FEATURE(mbox, feature) \
+ (((mbox)->storage->set->parsed_features & feature) != 0)
+
+struct imapc_namespace {
+ const char *prefix;
+ char separator;
+ enum mail_namespace_type type;
+};
+
+struct imapc_storage_client {
+ int refcount;
+
+ /* either one of these may not be available: */
+ struct imapc_storage *_storage;
+ struct imapc_mailbox_list *_list;
+
+ struct imapc_client *client;
+
+ ARRAY(struct imapc_storage_event_callback) untagged_callbacks;
+
+ /* IMAPC_COMMAND_STATE_OK if no auth failure (yet), otherwise result to
+ the LOGIN/AUTHENTICATE command. */
+ enum imapc_command_state auth_failed_state;
+ char *auth_failed_reason;
+
+ /* Authentication reply was received (success or failure) */
+ bool auth_returned:1;
+ bool destroying:1;
+};
+
+struct imapc_storage {
+ struct mail_storage storage;
+ const struct imapc_settings *set;
+
+ struct ioloop *root_ioloop;
+ struct imapc_storage_client *client;
+
+ struct imapc_mailbox *cur_status_box;
+ struct mailbox_status *cur_status;
+ unsigned int reopen_count;
+
+ ARRAY(struct imapc_namespace) remote_namespaces;
+
+ bool namespaces_requested:1;
+};
+
+struct imapc_mail_cache {
+ uint32_t uid;
+
+ /* either fd != -1 or buf != NULL */
+ int fd;
+ buffer_t *buf;
+};
+
+struct imapc_fetch_request {
+ ARRAY(struct imapc_mail *) mails;
+};
+
+struct imapc_untagged_fetch_ctx {
+ pool_t pool;
+
+ /* keywords, flags, guid, modseq and fetch_uid may or may not be
+ received with an untagged fetch response */
+ ARRAY_TYPE(const_string) keywords;
+ /* Is set if have_flags is TRUE */
+ enum mail_flags flags;
+ const char *guid;
+ uint64_t modseq;
+ uint32_t fetch_uid;
+
+ /* uid is generated locally based on the remote MSN or fetch_uid */
+ uint32_t uid;
+
+ bool have_gmail_labels:1;
+ bool have_flags:1;
+};
+
+struct imapc_copy_request {
+ struct imapc_save_context *sctx;
+ struct seqset_builder *uidset_builder;
+};
+
+struct imapc_mailbox {
+ struct mailbox box;
+ struct imapc_storage *storage;
+ struct imapc_client_mailbox *client_box;
+ enum imapc_capability capabilities;
+
+ struct mail_index_transaction *delayed_sync_trans;
+ struct mail_index_view *sync_view, *delayed_sync_view;
+ struct mail_cache_view *delayed_sync_cache_view;
+ struct mail_cache_transaction_ctx *delayed_sync_cache_trans;
+ struct timeout *to_idle_check, *to_idle_delay;
+
+ ARRAY(struct imapc_fetch_request *) fetch_requests;
+ ARRAY(struct imapc_untagged_fetch_ctx *) untagged_fetch_contexts;
+ /* if non-empty, contains the latest FETCH command we're going to be
+ sending soon (but still waiting to see if we can increase its
+ UID range) */
+ string_t *pending_fetch_cmd;
+ /* if non-empty, contains the latest COPY command we're going to be
+ sending soon. */
+ string_t *pending_copy_cmd;
+ char *copy_dest_box;
+ struct imapc_fetch_request *pending_fetch_request;
+ struct imapc_copy_request *pending_copy_request;
+ struct timeout *to_pending_fetch_send;
+
+ ARRAY(struct imapc_mailbox_event_callback) untagged_callbacks;
+ ARRAY(struct imapc_mailbox_event_callback) resp_text_callbacks;
+
+ enum mail_flags permanent_flags;
+ uint32_t highest_nonrecent_uid;
+
+ ARRAY(uint64_t) rseq_modseqs;
+ ARRAY_TYPE(seq_range) delayed_expunged_uids;
+ ARRAY_TYPE(seq_range) copy_rollback_expunge_uids;
+ uint32_t sync_uid_validity;
+ uint32_t sync_uid_next;
+ uint64_t sync_highestmodseq;
+ uint32_t sync_fetch_first_uid;
+ uint32_t sync_next_lseq;
+ uint32_t sync_next_rseq;
+ uint32_t exists_count;
+ uint32_t min_append_uid;
+ char *sync_gmail_pop3_search_tag;
+
+ /* keep the previous fetched message body cached,
+ mainly for partial IMAP fetches */
+ struct imapc_mail_cache prev_mail_cache;
+
+ uint32_t prev_skipped_rseq, prev_skipped_uid;
+ struct imapc_sync_context *sync_ctx;
+
+ const char *guid_fetch_field_name;
+ struct imapc_search_context *search_ctx;
+
+ bool selecting:1;
+ bool syncing:1;
+ bool initial_sync_done:1;
+ bool selected:1;
+ bool exists_received:1;
+ bool state_fetching_uid1:1;
+ bool state_fetched_success:1;
+ bool rollback_pending:1;
+ bool delayed_untagged_exists:1;
+};
+
+struct imapc_simple_context {
+ struct imapc_storage_client *client;
+ int ret;
+};
+
+#define IMAPC_STORAGE(s) container_of(s, struct imapc_storage, storage)
+#define IMAPC_MAILBOX(s) container_of(s, struct imapc_mailbox, box)
+
+int imapc_storage_client_create(struct mail_namespace *ns,
+ const struct imapc_settings *imapc_set,
+ const struct mail_storage_settings *mail_set,
+ struct imapc_storage_client **client_r,
+ const char **error_r);
+void imapc_storage_client_unref(struct imapc_storage_client **client);
+bool imapc_storage_client_handle_auth_failure(struct imapc_storage_client *client);
+
+struct mail_save_context *
+imapc_save_alloc(struct mailbox_transaction_context *_t);
+int imapc_save_begin(struct mail_save_context *ctx, struct istream *input);
+int imapc_save_continue(struct mail_save_context *ctx);
+int imapc_save_finish(struct mail_save_context *ctx);
+void imapc_save_cancel(struct mail_save_context *ctx);
+int imapc_copy(struct mail_save_context *ctx, struct mail *mail);
+
+int imapc_transaction_save_commit(struct mailbox_transaction_context *t);
+int imapc_transaction_save_commit_pre(struct mail_save_context *ctx);
+void imapc_transaction_save_commit_post(struct mail_save_context *ctx,
+ struct mail_index_transaction_commit_result *result);
+void imapc_transaction_save_rollback(struct mail_save_context *ctx);
+
+void imapc_mailbox_run(struct imapc_mailbox *mbox);
+void imapc_mailbox_run_nofetch(struct imapc_mailbox *mbox);
+void imapc_mail_cache_free(struct imapc_mail_cache *cache);
+int imapc_mailbox_select(struct imapc_mailbox *mbox);
+void imap_mailbox_select_finish(struct imapc_mailbox *mbox);
+
+bool imapc_mailbox_has_modseqs(struct imapc_mailbox *mbox);
+bool imapc_resp_text_code_parse(const char *str, enum mail_error *error_r);
+bool imapc_mail_error_to_resp_text_code(enum mail_error error, const char **str_r);
+void imapc_copy_error_from_reply(struct imapc_storage *storage,
+ enum mail_error default_error,
+ const struct imapc_command_reply *reply);
+void imapc_simple_context_init(struct imapc_simple_context *sctx,
+ struct imapc_storage_client *client);
+void imapc_simple_run(struct imapc_simple_context *sctx,
+ struct imapc_command **cmd);
+void imapc_simple_callback(const struct imapc_command_reply *reply,
+ void *context);
+int imapc_mailbox_commit_delayed_trans(struct imapc_mailbox *mbox,
+ bool force, bool *changes_r);
+bool imapc_mailbox_name_equals(struct imapc_mailbox *mbox,
+ const char *remote_name);
+void imapc_mailbox_noop(struct imapc_mailbox *mbox);
+void imapc_mailbox_set_corrupted(struct imapc_mailbox *mbox,
+ const char *reason, ...) ATTR_FORMAT(2, 3);
+const char *imapc_mailbox_get_remote_name(struct imapc_mailbox *mbox);
+
+void imapc_storage_client_register_untagged(struct imapc_storage_client *client,
+ const char *name,
+ imapc_storage_callback_t *callback);
+void imapc_storage_client_unregister_untagged(struct imapc_storage_client *client,
+ const char *name);
+void imapc_mailbox_register_untagged(struct imapc_mailbox *mbox,
+ const char *name,
+ imapc_mailbox_callback_t *callback);
+void imapc_mailbox_register_resp_text(struct imapc_mailbox *mbox,
+ const char *key,
+ imapc_mailbox_callback_t *callback);
+
+void imapc_mailbox_register_callbacks(struct imapc_mailbox *mbox);
+
+struct mail_index_view *
+imapc_mailbox_get_sync_view(struct imapc_mailbox *mbox);
+
+void imapc_untagged_fetch_ctx_free(struct imapc_untagged_fetch_ctx **_ctx);
+void imapc_untagged_fetch_update_flags(struct imapc_mailbox *mbox,
+ struct imapc_untagged_fetch_ctx *ctx,
+ struct mail_index_view *view,
+ uint32_t lseq);
+bool imapc_mailbox_fetch_state(struct imapc_mailbox *mbox, uint32_t first_uid);
+
+#endif