1 #ifndef IMAPC_STORAGE_H 2 #define IMAPC_STORAGE_H 3 4 #include "index-storage.h" 5 #include "imapc-settings.h" 6 #include "imapc-client.h" 7 8 #define IMAPC_STORAGE_NAME "imapc" 9 /* storage_name separator */ 10 #define IMAPC_LIST_STORAGE_NAME_ESCAPE_CHAR '%' 11 /* fs_name separator */ 12 #define IMAPC_LIST_FS_NAME_ESCAPE_CHAR '%' 13 /* vname separator */ 14 #define IMAPC_LIST_VNAME_ESCAPE_CHAR '~' 15 16 struct imap_arg; 17 struct imapc_untagged_reply; 18 struct imapc_command_reply; 19 struct imapc_mailbox; 20 struct imapc_storage_client; 21 22 typedef void imapc_storage_callback_t(const struct imapc_untagged_reply *reply, 23 struct imapc_storage_client *client); 24 typedef void imapc_mailbox_callback_t(const struct imapc_untagged_reply *reply, 25 struct imapc_mailbox *mbox); 26 27 struct imapc_storage_event_callback { 28 char *name; 29 imapc_storage_callback_t *callback; 30 }; 31 32 struct imapc_mailbox_event_callback { 33 const char *name; 34 imapc_mailbox_callback_t *callback; 35 }; 36 37 #define IMAPC_HAS_FEATURE(mstorage, feature) \ 38 (((mstorage)->set->parsed_features & feature) != 0) 39 #define IMAPC_BOX_HAS_FEATURE(mbox, feature) \ 40 (((mbox)->storage->set->parsed_features & feature) != 0) 41 42 struct imapc_namespace { 43 const char *prefix; 44 char separator; 45 enum mail_namespace_type type; 46 }; 47 48 struct imapc_storage_client { 49 int refcount; 50 51 /* either one of these may not be available: */ 52 struct imapc_storage *_storage; 53 struct imapc_mailbox_list *_list; 54 55 struct imapc_client *client; 56 57 ARRAY(struct imapc_storage_event_callback) untagged_callbacks; 58 59 /* IMAPC_COMMAND_STATE_OK if no auth failure (yet), otherwise result to 60 the LOGIN/AUTHENTICATE command. */ 61 enum imapc_command_state auth_failed_state; 62 char *auth_failed_reason; 63 64 /* Authentication reply was received (success or failure) */ 65 bool auth_returned:1; 66 bool destroying:1; 67 }; 68 69 struct imapc_storage { 70 struct mail_storage storage; 71 const struct imapc_settings *set; 72 73 struct ioloop *root_ioloop; 74 struct imapc_storage_client *client; 75 76 struct imapc_mailbox *cur_status_box; 77 struct mailbox_status *cur_status; 78 unsigned int reopen_count; 79 80 ARRAY(struct imapc_namespace) remote_namespaces; 81 82 bool namespaces_requested:1; 83 }; 84 85 struct imapc_mail_cache { 86 uint32_t uid; 87 88 /* either fd != -1 or buf != NULL */ 89 int fd; 90 buffer_t *buf; 91 }; 92 93 struct imapc_fetch_request { 94 ARRAY(struct imapc_mail *) mails; 95 }; 96 97 struct imapc_mailbox { 98 struct mailbox box; 99 struct imapc_storage *storage; 100 struct imapc_client_mailbox *client_box; 101 enum imapc_capability capabilities; 102 103 struct mail_index_transaction *delayed_sync_trans; 104 struct mail_index_view *sync_view, *delayed_sync_view; 105 struct mail_cache_view *delayed_sync_cache_view; 106 struct mail_cache_transaction_ctx *delayed_sync_cache_trans; 107 struct timeout *to_idle_check, *to_idle_delay; 108 109 ARRAY(struct imapc_fetch_request *) fetch_requests; 110 /* if non-empty, contains the latest FETCH command we're going to be 111 sending soon (but still waiting to see if we can increase its 112 UID range) */ 113 string_t *pending_fetch_cmd; 114 struct imapc_fetch_request *pending_fetch_request; 115 struct timeout *to_pending_fetch_send; 116 117 ARRAY(struct imapc_mailbox_event_callback) untagged_callbacks; 118 ARRAY(struct imapc_mailbox_event_callback) resp_text_callbacks; 119 120 enum mail_flags permanent_flags; 121 uint32_t highest_nonrecent_uid; 122 123 ARRAY(uint64_t) rseq_modseqs; 124 ARRAY_TYPE(seq_range) delayed_expunged_uids; 125 uint32_t sync_uid_validity; 126 uint32_t sync_uid_next; 127 uint64_t sync_highestmodseq; 128 uint32_t sync_fetch_first_uid; 129 uint32_t sync_next_lseq; 130 uint32_t sync_next_rseq; 131 uint32_t exists_count; 132 uint32_t min_append_uid; 133 char *sync_gmail_pop3_search_tag; 134 135 /* keep the previous fetched message body cached, 136 mainly for partial IMAP fetches */ 137 struct imapc_mail_cache prev_mail_cache; 138 139 uint32_t prev_skipped_rseq, prev_skipped_uid; 140 struct imapc_sync_context *sync_ctx; 141 142 const char *guid_fetch_field_name; 143 struct imapc_search_context *search_ctx; 144 145 bool selecting:1; 146 bool syncing:1; 147 bool initial_sync_done:1; 148 bool selected:1; 149 bool exists_received:1; 150 bool state_fetching_uid1:1; 151 bool state_fetched_success:1; 152 }; 153 154 struct imapc_simple_context { 155 struct imapc_storage_client *client; 156 int ret; 157 }; 158 159 #define IMAPC_STORAGE(s) container_of(s, struct imapc_storage, storage) 160 #define IMAPC_MAILBOX(s) container_of(s, struct imapc_mailbox, box) 161 162 int imapc_storage_client_create(struct mail_namespace *ns, 163 const struct imapc_settings *imapc_set, 164 const struct mail_storage_settings *mail_set, 165 struct imapc_storage_client **client_r, 166 const char **error_r); 167 void imapc_storage_client_unref(struct imapc_storage_client **client); 168 bool imapc_storage_client_handle_auth_failure(struct imapc_storage_client *client); 169 170 struct mail_save_context * 171 imapc_save_alloc(struct mailbox_transaction_context *_t); 172 int imapc_save_begin(struct mail_save_context *ctx, struct istream *input); 173 int imapc_save_continue(struct mail_save_context *ctx); 174 int imapc_save_finish(struct mail_save_context *ctx); 175 void imapc_save_cancel(struct mail_save_context *ctx); 176 int imapc_copy(struct mail_save_context *ctx, struct mail *mail); 177 178 int imapc_transaction_save_commit_pre(struct mail_save_context *ctx); 179 void imapc_transaction_save_commit_post(struct mail_save_context *ctx, 180 struct mail_index_transaction_commit_result *result); 181 void imapc_transaction_save_rollback(struct mail_save_context *ctx); 182 183 void imapc_mailbox_run(struct imapc_mailbox *mbox); 184 void imapc_mailbox_run_nofetch(struct imapc_mailbox *mbox); 185 void imapc_mail_cache_free(struct imapc_mail_cache *cache); 186 int imapc_mailbox_select(struct imapc_mailbox *mbox); 187 void imap_mailbox_select_finish(struct imapc_mailbox *mbox); 188 189 bool imapc_mailbox_has_modseqs(struct imapc_mailbox *mbox); 190 bool imapc_resp_text_code_parse(const char *str, enum mail_error *error_r); 191 bool imapc_mail_error_to_resp_text_code(enum mail_error error, const char **str_r); 192 void imapc_copy_error_from_reply(struct imapc_storage *storage, 193 enum mail_error default_error, 194 const struct imapc_command_reply *reply); 195 void imapc_simple_context_init(struct imapc_simple_context *sctx, 196 struct imapc_storage_client *client); 197 void imapc_simple_run(struct imapc_simple_context *sctx, 198 struct imapc_command **cmd); 199 void imapc_simple_callback(const struct imapc_command_reply *reply, 200 void *context); 201 int imapc_mailbox_commit_delayed_trans(struct imapc_mailbox *mbox, 202 bool force, bool *changes_r); 203 bool imapc_mailbox_name_equals(struct imapc_mailbox *mbox, 204 const char *remote_name); 205 void imapc_mailbox_noop(struct imapc_mailbox *mbox); 206 void imapc_mailbox_set_corrupted(struct imapc_mailbox *mbox, 207 const char *reason, ...) ATTR_FORMAT(2, 3); 208 const char *imapc_mailbox_get_remote_name(struct imapc_mailbox *mbox); 209 210 void imapc_storage_client_register_untagged(struct imapc_storage_client *client, 211 const char *name, 212 imapc_storage_callback_t *callback); 213 void imapc_storage_client_unregister_untagged(struct imapc_storage_client *client, 214 const char *name); 215 void imapc_mailbox_register_untagged(struct imapc_mailbox *mbox, 216 const char *name, 217 imapc_mailbox_callback_t *callback); 218 void imapc_mailbox_register_resp_text(struct imapc_mailbox *mbox, 219 const char *key, 220 imapc_mailbox_callback_t *callback); 221 222 void imapc_mailbox_register_callbacks(struct imapc_mailbox *mbox); 223 224 #endif 225