1 #ifndef MAIL_STORAGE_PRIVATE_H
2 #define MAIL_STORAGE_PRIVATE_H
3 
4 #include "module-context.h"
5 #include "unichar.h"
6 #include "file-lock.h"
7 #include "mail-storage.h"
8 #include "mail-storage-hooks.h"
9 #include "mail-storage-settings.h"
10 #include "mailbox-attribute-private.h"
11 #include "mail-index-private.h"
12 
13 struct file_lock;
14 struct file_create_settings;
15 struct fs;
16 
17 /* Default prefix for indexes */
18 #define MAIL_INDEX_PREFIX "dovecot.index"
19 
20 /* Block size when read()ing message header. */
21 #define MAIL_READ_HDR_BLOCK_SIZE (1024*4)
22 /* Block size when read()ing message (header and) body. */
23 #define MAIL_READ_FULL_BLOCK_SIZE IO_BLOCK_SIZE
24 
25 #define MAIL_SHARED_STORAGE_NAME "shared"
26 
27 #define MAIL_STORAGE_LOST_MAILBOX_PREFIX "recovered-lost-folder-"
28 
29 enum mail_storage_list_index_rebuild_reason {
30 	/* Mailbox list index was found to be corrupted. */
31 	MAIL_STORAGE_LIST_INDEX_REBUILD_REASON_CORRUPTED,
32 	/* Mailbox list index doesn't have INBOX in an inbox=yes namespace.
33 	   Rebuild is done to verify whether the user really is an empty new
34 	   user, or if an existing user's mailbox list index was lost. Because
35 	   this is called in non-error conditions, the callback shouldn't log
36 	   any errors or warnings if it didn't find any missing mailboxes. */
37 	MAIL_STORAGE_LIST_INDEX_REBUILD_REASON_NO_INBOX,
38 	/* MAILBOX_SYNC_FLAG_FORCE_RESYNC is run. This is called only once
39 	   per list, so that doveadm force-resync '*' won't cause it to run for
40 	   every mailbox. */
41 	MAIL_STORAGE_LIST_INDEX_REBUILD_REASON_FORCE_RESYNC,
42 };
43 
44 struct mail_storage_module_register {
45 	unsigned int id;
46 };
47 
48 struct mail_module_register {
49 	unsigned int id;
50 };
51 
52 struct mail_storage_vfuncs {
53 	const struct setting_parser_info *(*get_setting_parser_info)(void);
54 
55 	struct mail_storage *(*alloc)(void);
56 	int (*create)(struct mail_storage *storage, struct mail_namespace *ns,
57 		      const char **error_r);
58 	void (*destroy)(struct mail_storage *storage);
59 	void (*add_list)(struct mail_storage *storage,
60 			 struct mailbox_list *list);
61 
62 	void (*get_list_settings)(const struct mail_namespace *ns,
63 				  struct mailbox_list_settings *set);
64 	bool (*autodetect)(const struct mail_namespace *ns,
65 			   struct mailbox_list_settings *set);
66 
67 	struct mailbox *(*mailbox_alloc)(struct mail_storage *storage,
68 					 struct mailbox_list *list,
69 					 const char *vname,
70 					 enum mailbox_flags flags);
71 	int (*purge)(struct mail_storage *storage);
72 	/* Called when mailbox list index rebuild is requested.
73 	   The callback should add any missing mailboxes to the list index.
74 	   Returns 0 on success, -1 on temporary failure that didn't properly
75 	   rebuild the index. */
76 	int (*list_index_rebuild)(struct mail_storage *storage,
77 				  enum mail_storage_list_index_rebuild_reason reason);
78 };
79 
80 union mail_storage_module_context {
81 	struct mail_storage_vfuncs super;
82 	struct mail_storage_module_register *reg;
83 };
84 
85 enum mail_storage_class_flags {
86 	/* mailboxes are files, not directories */
87 	MAIL_STORAGE_CLASS_FLAG_MAILBOX_IS_FILE	= 0x01,
88 	/* root_dir points to a unique directory */
89 	MAIL_STORAGE_CLASS_FLAG_UNIQUE_ROOT	= 0x02,
90 	/* mailbox_open_stream() is supported */
91 	MAIL_STORAGE_CLASS_FLAG_OPEN_STREAMS	= 0x04,
92 	/* never use quota for this storage (e.g. virtual mailboxes) */
93 	MAIL_STORAGE_CLASS_FLAG_NOQUOTA		= 0x08,
94 	/* Storage doesn't need a mail root directory */
95 	MAIL_STORAGE_CLASS_FLAG_NO_ROOT		= 0x10,
96 	/* Storage uses one file per message */
97 	MAIL_STORAGE_CLASS_FLAG_FILE_PER_MSG	= 0x20,
98 	/* Messages have GUIDs (always set mailbox_status.have_guids=TRUE) */
99 	MAIL_STORAGE_CLASS_FLAG_HAVE_MAIL_GUIDS	= 0x40,
100 	/* mailbox_save_set_guid() works (always set
101 	   mailbox_status.have_save_guids=TRUE) */
102 	MAIL_STORAGE_CLASS_FLAG_HAVE_MAIL_SAVE_GUIDS	= 0x80,
103 	/* message content can be unstructured binary data
104 	   (e.g. zlib plugin is allowed to compress/decompress mails) */
105 	MAIL_STORAGE_CLASS_FLAG_BINARY_DATA	= 0x100,
106 	/* Message GUIDs can only be 128bit (always set
107 	   mailbox_status.have_only_guid128) */
108 	MAIL_STORAGE_CLASS_FLAG_HAVE_MAIL_GUID128 = 0x200,
109 	/* Storage deletes all files internally - mailbox list's
110 	   delete_mailbox() shouldn't delete anything itself. */
111 	MAIL_STORAGE_CLASS_FLAG_NO_LIST_DELETES	= 0x400,
112 	/* Storage creates a secondary index */
113 	MAIL_STORAGE_CLASS_FLAG_SECONDARY_INDEX	= 0x800,
114 };
115 
116 struct mail_binary_cache {
117 	struct timeout *to;
118 	struct mailbox *box;
119 	uint32_t uid;
120 
121 	uoff_t orig_physical_pos;
122 	bool include_hdr;
123 	struct istream *input;
124 	uoff_t size;
125 };
126 
127 struct mail_storage_error {
128 	char *error_string;
129 	enum mail_error error;
130 	char *last_internal_error;
131 	bool last_error_is_internal;
132 };
133 
134 struct mail_storage {
135 	const char *name;
136 	enum mail_storage_class_flags class_flags;
137 	/* Fields that the storage backend can get by other means than parsing
138 	   the message header/body. For example the imapc backend can lookup
139 	   MAIL_FETCH_IMAP_BODYSTRUCTURE from the remote server. Adding fields
140 	   here avoids adding them to index_mail_data.access_part. */
141 	enum mail_fetch_field nonbody_access_fields;
142 	struct event_category *event_category;
143 
144         struct mail_storage_vfuncs v, *vlast;
145 
146 /* private: */
147 	pool_t pool;
148 	struct mail_storage *prev, *next;
149 	/* counting number of times mail_storage_create() has returned this
150 	   same storage. */
151 	int refcount;
152 	/* counting number of objects (e.g. mailbox) that have a pointer
153 	   to this storage. */
154 	int obj_refcount;
155 	/* Linked list of all mailboxes in the storage */
156 	struct mailbox *mailboxes;
157 	/* A "root dir" to enable storage sharing.  It is only ever used for
158 	 * uniqueness checking (via strcmp) and never used as a path. */
159 	const char *unique_root_dir;
160 
161 	/* prefix for lost mailbox */
162 	const char *lost_mailbox_prefix;
163 
164 	/* Last error set in mail_storage_set_critical(). */
165 	char *last_internal_error;
166 
167 	char *error_string;
168 	enum mail_error error;
169 	ARRAY(struct mail_storage_error) error_stack;
170 	struct event *event;
171 
172         const struct mail_storage *storage_class;
173 	struct mail_user *user;
174 	const char *temp_path_prefix;
175 	const struct mail_storage_settings *set;
176 
177 	enum mail_storage_flags flags;
178 
179 	struct mail_storage_callbacks callbacks;
180 	void *callback_context;
181 
182 	struct mail_binary_cache binary_cache;
183 	/* Filled lazily by mailbox_attribute_*() when accessing shared
184 	   attributes. */
185 	struct dict *_shared_attr_dict;
186 
187 	/* optional fs-api object for accessing mailboxes */
188 	struct fs *mailboxes_fs;
189 
190 	/* Module-specific contexts. See mail_storage_module_id. */
191 	ARRAY(union mail_storage_module_context *) module_contexts;
192 
193 	/* Failed to create shared attribute dict, don't try again */
194 	bool shared_attr_dict_failed:1;
195 	bool last_error_is_internal:1;
196 	bool rebuilding_list_index:1;
197 	bool rebuild_list_index:1;
198 };
199 
200 struct mail_attachment_part {
201 	struct message_part *part;
202 	const char *content_type, *content_disposition;
203 };
204 
205 struct virtual_mailbox_vfuncs {
206 	/* convert backend UIDs to virtual UIDs. if some backend UID doesn't
207 	   exist in mailbox, it's simply ignored */
208 	void (*get_virtual_uids)(struct mailbox *box,
209 				 struct mailbox *backend_mailbox,
210 				 const ARRAY_TYPE(seq_range) *backend_uids,
211 				 ARRAY_TYPE(seq_range) *virtual_uids_r);
212 	/* like get_virtual_uids(), but if a backend UID doesn't exist,
213 	   convert it to 0. */
214 	void (*get_virtual_uid_map)(struct mailbox *box,
215 				    struct mailbox *backend_mailbox,
216 				    const ARRAY_TYPE(seq_range) *backend_uids,
217 				    ARRAY_TYPE(uint32_t) *virtual_uids_r);
218 	void (*get_virtual_backend_boxes)(struct mailbox *box,
219 					  ARRAY_TYPE(mailboxes) *mailboxes,
220 					  bool only_with_msgs);
221 };
222 
223 struct mailbox_vfuncs {
224 	bool (*is_readonly)(struct mailbox *box);
225 
226 	int (*enable)(struct mailbox *box, enum mailbox_feature features);
227 	int (*exists)(struct mailbox *box, bool auto_boxes,
228 		      enum mailbox_existence *existence_r);
229 	int (*open)(struct mailbox *box);
230 	void (*close)(struct mailbox *box);
231 	void (*free)(struct mailbox *box);
232 
233 	int (*create_box)(struct mailbox *box,
234 			  const struct mailbox_update *update, bool directory);
235 	int (*update_box)(struct mailbox *box,
236 			  const struct mailbox_update *update);
237 	int (*delete_box)(struct mailbox *box);
238 	int (*rename_box)(struct mailbox *src, struct mailbox *dest);
239 
240 	int (*get_status)(struct mailbox *box, enum mailbox_status_items items,
241 			  struct mailbox_status *status_r);
242 	int (*get_metadata)(struct mailbox *box,
243 			    enum mailbox_metadata_items items,
244 			    struct mailbox_metadata *metadata_r);
245 	int (*set_subscribed)(struct mailbox *box, bool set);
246 
247 	int (*attribute_set)(struct mailbox_transaction_context *t,
248 			     enum mail_attribute_type type_flags,
249 			     const char *key,
250 			     const struct mail_attribute_value *value);
251 	int (*attribute_get)(struct mailbox *box,
252 			     enum mail_attribute_type type_flags,
253 			     const char *key,
254 			     struct mail_attribute_value *value_r);
255 	struct mailbox_attribute_iter *
256 		(*attribute_iter_init)(struct mailbox *box,
257 				       enum mail_attribute_type type_flags,
258 				       const char *prefix);
259 	const char *(*attribute_iter_next)(struct mailbox_attribute_iter *iter);
260 	int (*attribute_iter_deinit)(struct mailbox_attribute_iter *iter);
261 
262 	/* Lookup sync extension record and figure out if it mailbox has
263 	   changed since. Returns 1 = yes, 0 = no, -1 = error. if quick==TRUE,
264 	   return 1 if it's too costly to find out exactly. */
265 	int (*list_index_has_changed)(struct mailbox *box,
266 				      struct mail_index_view *list_view,
267 				      uint32_t seq, bool quick);
268 	/* Update the sync extension record. */
269 	void (*list_index_update_sync)(struct mailbox *box,
270 				       struct mail_index_transaction *trans,
271 				       uint32_t seq);
272 
273 	struct mailbox_sync_context *
274 		(*sync_init)(struct mailbox *box,
275 			     enum mailbox_sync_flags flags);
276 	bool (*sync_next)(struct mailbox_sync_context *ctx,
277 			  struct mailbox_sync_rec *sync_rec_r);
278 	int (*sync_deinit)(struct mailbox_sync_context *ctx,
279 			   struct mailbox_sync_status *status_r);
280 
281 	/* Called once for each expunge. Called one or more times for
282 	   flag/keyword changes. Once the sync is finished, called with
283 	   uid=0 and sync_type=0. */
284 	void (*sync_notify)(struct mailbox *box, uint32_t uid,
285 			    enum mailbox_sync_type sync_type);
286 
287 	void (*notify_changes)(struct mailbox *box);
288 
289 	struct mailbox_transaction_context *
290 		(*transaction_begin)(struct mailbox *box,
291 				     enum mailbox_transaction_flags flags,
292 				     const char *reason);
293 	int (*transaction_commit)(struct mailbox_transaction_context *t,
294 				  struct mail_transaction_commit_changes *changes_r);
295 	void (*transaction_rollback)(struct mailbox_transaction_context *t);
296 
297 	enum mail_flags (*get_private_flags_mask)(struct mailbox *box);
298 
299 	struct mail *
300 		(*mail_alloc)(struct mailbox_transaction_context *t,
301 			      enum mail_fetch_field wanted_fields,
302 			      struct mailbox_header_lookup_ctx *wanted_headers);
303 
304 	struct mail_search_context *
305 	(*search_init)(struct mailbox_transaction_context *t,
306 		       struct mail_search_args *args,
307 		       const enum mail_sort_type *sort_program,
308 		       enum mail_fetch_field wanted_fields,
309 		       struct mailbox_header_lookup_ctx *wanted_headers);
310 	int (*search_deinit)(struct mail_search_context *ctx);
311 	bool (*search_next_nonblock)(struct mail_search_context *ctx,
312 				     struct mail **mail_r, bool *tryagain_r);
313 	/* Internal search function which updates ctx->seq */
314 	bool (*search_next_update_seq)(struct mail_search_context *ctx);
315 
316 	struct mail_save_context *
317 		(*save_alloc)(struct mailbox_transaction_context *t);
318 	int (*save_begin)(struct mail_save_context *ctx, struct istream *input);
319 	int (*save_continue)(struct mail_save_context *ctx);
320 	int (*save_finish)(struct mail_save_context *ctx);
321 	void (*save_cancel)(struct mail_save_context *ctx);
322 	int (*copy)(struct mail_save_context *ctx, struct mail *mail);
323 
324 	/* Called during transaction commit/rollback if saving was done */
325 	int (*transaction_save_commit_pre)(struct mail_save_context *save_ctx);
326 	void (*transaction_save_commit_post)
327 		(struct mail_save_context *save_ctx,
328 		 struct mail_index_transaction_commit_result *result_r);
329 	void (*transaction_save_rollback)(struct mail_save_context *save_ctx);
330 
331 	bool (*is_inconsistent)(struct mailbox *box);
332 };
333 
334 union mailbox_module_context {
335         struct mailbox_vfuncs super;
336 	struct mail_storage_module_register *reg;
337 };
338 
339 struct mail_msgpart_partial_cache {
340 	uint32_t uid;
341 	uoff_t physical_start;
342 	uoff_t physical_pos, virtual_pos;
343 };
344 
345 struct mailbox_index_vsize {
346 	uint64_t vsize;
347 	uint32_t highest_uid;
348 	uint32_t message_count;
349 };
350 
351 struct mailbox_index_pop3_uidl {
352 	uint32_t max_uid_with_pop3_uidl;
353 };
354 
355 struct mailbox_index_first_saved {
356 	uint32_t uid;
357 	uint32_t timestamp;
358 };
359 
360 struct mailbox {
361 	const char *name;
362 	/* mailbox's virtual name (from mail_namespace_get_vname()) */
363 	const char *vname;
364 	struct mail_storage *storage;
365 	struct mailbox_list *list;
366 	struct event *event;
367 
368 	struct mailbox_vfuncs v, *vlast;
369 	/* virtual mailboxes: */
370 	const struct virtual_mailbox_vfuncs *virtual_vfuncs;
371 /* private: */
372 	pool_t pool;
373 	/* Linked list of all mailboxes in this storage */
374 	struct mailbox *prev, *next;
375 
376 	/* these won't be set until mailbox is opened: */
377 	struct mail_index *index;
378 	struct mail_index_view *view;
379 	struct mail_cache *cache;
380 	/* Private per-user index/view for shared mailboxes. These are synced
381 	   against the primary index and used to store per-user flags.
382 	   These are non-NULL only when mailbox has per-user flags. */
383 	struct mail_index *index_pvt;
384 	struct mail_index_view *view_pvt;
385 	/* Filled lazily by mailbox_get_permissions() */
386 	struct mailbox_permissions _perm;
387 	/* Filled lazily when mailbox is opened, use mailbox_get_path()
388 	   to access it */
389 	const char *_path;
390 	/* Filled lazily when mailbox is opened, use mailbox_get_index_path()
391 	   to access it */
392 	const char *_index_path;
393 	/* Reason for why mailbox is being accessed or NULL if unknown. */
394 	const char *reason;
395 
396 	/* default vfuncs for new struct mails. */
397 	const struct mail_vfuncs *mail_vfuncs;
398 	/* Mailbox settings, or NULL if defaults */
399 	const struct mailbox_settings *set;
400 
401 	/* If non-zero, fail mailbox_open() with this error. mailbox_alloc()
402 	   can set this to force open to fail. */
403 	enum mail_error open_error;
404 
405 	struct istream *input;
406 	const char *index_prefix;
407 	enum mailbox_flags flags;
408 	unsigned int transaction_count;
409 	unsigned int attribute_iter_count;
410 	enum mailbox_feature enabled_features;
411 	struct mail_msgpart_partial_cache partial_cache;
412 	uint32_t vsize_hdr_ext_id;
413 	uint32_t pop3_uidl_hdr_ext_id;
414 	uint32_t box_name_hdr_ext_id;
415 	uint32_t box_last_rename_stamp_ext_id;
416 	uint32_t mail_vsize_ext_id;
417 
418 	/* MAIL_RECENT flags handling */
419 	ARRAY_TYPE(seq_range) recent_flags;
420 	uint32_t recent_flags_prev_uid;
421 	uint32_t recent_flags_count;
422 
423 	struct mail_index_view *tmp_sync_view;
424 
425 	/* Mailbox notification settings: */
426 	mailbox_notify_callback_t *notify_callback;
427 	void *notify_context;
428 	struct timeout *to_notify, *to_notify_delay;
429 	struct mailbox_notify_file *notify_files;
430 
431 	/* Increased by one for each new struct mailbox. */
432 	unsigned int generation_sequence;
433 
434 	/* Saved search results */
435 	ARRAY(struct mail_search_result *) search_results;
436 
437 	/* Module-specific contexts. See mail_storage_module_id. */
438 	ARRAY(union mailbox_module_context *) module_contexts;
439 
440 	/* When FAST open flag is used, the mailbox isn't actually opened until
441 	   it's synced for the first time. */
442 	bool opened:1;
443 	/* Mailbox was deleted while we had it open. */
444 	bool mailbox_deleted:1;
445 	/* Mailbox is being created */
446 	bool creating:1;
447 	/* Mailbox is being deleted */
448 	bool deleting:1;
449 	/* Mailbox is being undeleted */
450 	bool mailbox_undeleting:1;
451 	/* Don't use MAIL_INDEX_SYNC_FLAG_DELETING_INDEX for sync flag */
452 	bool delete_sync_check:1;
453 	/* Delete mailbox only if it's empty */
454 	bool deleting_must_be_empty:1;
455 	/* The backend wants to skip checking if there are 0 messages before
456 	   calling mailbox_list.delete_mailbox() */
457 	bool delete_skip_empty_check:1;
458 	/* Mailbox was already marked as deleted within this allocation. */
459 	bool marked_deleted:1;
460 	/* TRUE if this is an INBOX for this user */
461 	bool inbox_user:1;
462 	/* TRUE if this is an INBOX for this namespace (user or shared) */
463 	bool inbox_any:1;
464 	/* When copying to this mailbox, require that mailbox_copy() uses
465 	   mailbox_save_*() to actually save a new physical copy rather than
466 	   simply incrementing a reference count (e.g. via hard link) */
467 	bool disable_reflink_copy_to:1;
468 	/* Don't allow creating any new keywords */
469 	bool disallow_new_keywords:1;
470 	/* Mailbox has been synced at least once */
471 	bool synced:1;
472 	/* Updating cache file is disabled */
473 	bool mail_cache_disabled:1;
474 	/* Update first_saved field to mailbox list index. */
475 	bool update_first_saved:1;
476 	/* mailbox_verify_create_name() only checks for mailbox_verify_name() */
477 	bool skip_create_name_restrictions:1;
478 	/* Using LAYOUT=index and mailbox is being opened with a corrupted
479 	   mailbox name. Try to revert to the previously known good name. */
480 	bool corrupted_mailbox_name:1;
481 	/* mailbox_open() returned MAIL_ERROR_NOTFOUND because the mailbox
482 	   doesn't have the LOOKUP ACL right. */
483 	bool acl_no_lookup_right:1;
484 };
485 
486 struct mail_vfuncs {
487 	void (*close)(struct mail *mail);
488 	void (*free)(struct mail *mail);
489 	void (*set_seq)(struct mail *mail, uint32_t seq, bool saving);
490 	bool (*set_uid)(struct mail *mail, uint32_t uid);
491 	void (*set_uid_cache_updates)(struct mail *mail, bool set);
492 	bool (*prefetch)(struct mail *mail);
493 	int (*precache)(struct mail *mail);
494 	void (*add_temp_wanted_fields)(struct mail *mail,
495 				       enum mail_fetch_field fields,
496 				       struct mailbox_header_lookup_ctx *headers);
497 
498 	enum mail_flags (*get_flags)(struct mail *mail);
499 	const char *const *(*get_keywords)(struct mail *mail);
500 	const ARRAY_TYPE(keyword_indexes) *
501 		(*get_keyword_indexes)(struct mail *mail);
502 	uint64_t (*get_modseq)(struct mail *mail);
503 	uint64_t (*get_pvt_modseq)(struct mail *mail);
504 
505 	int (*get_parts)(struct mail *mail,
506 			 struct message_part **parts_r);
507 	int (*get_date)(struct mail *mail, time_t *date_r, int *timezone_r);
508 	int (*get_received_date)(struct mail *mail, time_t *date_r);
509 	int (*get_save_date)(struct mail *mail, time_t *date_r);
510 	int (*get_virtual_size)(struct mail *mail, uoff_t *size_r);
511 	int (*get_physical_size)(struct mail *mail, uoff_t *size_r);
512 
513 	int (*get_first_header)(struct mail *mail, const char *field,
514 				bool decode_to_utf8, const char **value_r);
515 	int (*get_headers)(struct mail *mail, const char *field,
516 			   bool decode_to_utf8, const char *const **value_r);
517 	int (*get_header_stream)(struct mail *mail,
518 				 struct mailbox_header_lookup_ctx *headers,
519 				 struct istream **stream_r);
520 	int (*get_stream)(struct mail *mail, bool get_body,
521 			  struct message_size *hdr_size,
522 			  struct message_size *body_size,
523 			  struct istream **stream_r);
524 	int (*get_binary_stream)(struct mail *mail,
525 				 const struct message_part *part,
526 				 bool include_hdr, uoff_t *size_r,
527 				 unsigned int *lines_r, bool *binary_r,
528 				 struct istream **stream_r);
529 
530 	int (*get_special)(struct mail *mail, enum mail_fetch_field field,
531 			   const char **value_r);
532 	int (*get_backend_mail)(struct mail *mail, struct mail **real_mail_r);
533 
534 	void (*update_flags)(struct mail *mail, enum modify_type modify_type,
535 			     enum mail_flags flags);
536 	void (*update_keywords)(struct mail *mail, enum modify_type modify_type,
537 				struct mail_keywords *keywords);
538 	void (*update_modseq)(struct mail *mail, uint64_t min_modseq);
539 	void (*update_pvt_modseq)(struct mail *mail, uint64_t min_pvt_modseq);
540 	void (*update_pop3_uidl)(struct mail *mail, const char *uidl);
541 	void (*expunge)(struct mail *mail);
542 	void (*set_cache_corrupted)(struct mail *mail,
543 				    enum mail_fetch_field field,
544 				    const char *reason);
545 	int (*istream_opened)(struct mail *mail, struct istream **input);
546 };
547 
548 union mail_module_context {
549 	struct mail_vfuncs super;
550 	struct mail_module_register *reg;
551 };
552 
553 struct mail_private {
554 	struct mail mail;
555 	struct mail_vfuncs v, *vlast;
556 	/* normally NULL, but in case this is a "backend mail" for a mail
557 	   created by virtual storage, this points back to the original virtual
558 	   mail. at least mailbox_copy() bypasses the virtual storage, so this
559 	   allows mail_log plugin to log the copy operation using the original
560 	   mailbox name. */
561 	struct mail *vmail;
562 
563 	uint32_t seq_pvt;
564 
565 	/* initial wanted fields/headers, set by mail_alloc(): */
566 	enum mail_fetch_field wanted_fields;
567 	struct mailbox_header_lookup_ctx *wanted_headers;
568 
569 	pool_t pool, data_pool;
570 	ARRAY(union mail_module_context *) module_contexts;
571 
572 	const char *get_stream_reason;
573 
574 	bool autoexpunged:1;
575 	/* mail created by mailbox_search_*() */
576 	bool search_mail:1;
577 };
578 
579 struct mailbox_list_context {
580 	struct mail_storage *storage;
581 	enum mailbox_list_flags flags;
582 	bool failed;
583 };
584 
585 union mailbox_transaction_module_context {
586 	struct mail_storage_module_register *reg;
587 };
588 
589 struct mailbox_transaction_stats {
590 	unsigned long open_lookup_count;
591 	unsigned long stat_lookup_count;
592 	unsigned long fstat_lookup_count;
593 	/* number of files we've opened and read */
594 	unsigned long files_read_count;
595 	/* number of bytes we've had to read from files */
596 	unsigned long long files_read_bytes;
597 	/* number of cache lookup hits */
598 	unsigned long cache_hit_count;
599 };
600 
601 struct mail_save_private_changes {
602 	/* first saved mail is 0, second is 1, etc. we'll map these to UIDs
603 	   using struct mail_transaction_commit_changes. */
604 	unsigned int mailnum;
605 	enum mail_flags flags;
606 };
607 
608 struct mailbox_transaction_context {
609 	struct mailbox *box;
610 	enum mailbox_transaction_flags flags;
611 	char *reason;
612 
613 	union mail_index_transaction_module_context module_ctx;
614 	struct mail_index_transaction_vfuncs super;
615 	int mail_ref_count;
616 
617 	struct mail_index_transaction *itrans;
618 	struct dict_transaction_context *attr_pvt_trans, *attr_shared_trans;
619 	/* view contains all changes done within this transaction */
620 	struct mail_index_view *view;
621 
622 	/* for private index updates: */
623 	struct mail_index_transaction *itrans_pvt;
624 	struct mail_index_view *view_pvt;
625 
626 	struct mail_cache_view *cache_view;
627 	struct mail_cache_transaction_ctx *cache_trans;
628 
629 	struct mail_transaction_commit_changes *changes;
630 	ARRAY(union mailbox_transaction_module_context *) module_contexts;
631 
632 	uint32_t prev_pop3_uidl_tracking_seq;
633 	uint32_t highest_pop3_uidl_uid;
634 
635 	struct mail_save_context *save_ctx;
636 	/* number of mails saved/copied within this transaction. */
637 	unsigned int save_count;
638 	/* List of private flags added with save/copy. These are added to the
639 	   private index after committing the mails to the shared index. */
640 	ARRAY(struct mail_save_private_changes) pvt_saves;
641 
642 	/* these statistics are never reset by mail-storage API: */
643 	struct mailbox_transaction_stats stats;
644 	/* Set to TRUE to update stats_* fields */
645 	bool stats_track:1;
646 };
647 
648 union mail_search_module_context {
649 	struct mail_storage_module_register *reg;
650 };
651 
652 struct mail_search_context {
653 	struct mailbox_transaction_context *transaction;
654 
655 	struct mail_search_args *args;
656 	struct mail_search_sort_program *sort_program;
657 	enum mail_fetch_field wanted_fields;
658 	struct mailbox_header_lookup_ctx *wanted_headers;
659 	normalizer_func_t *normalizer;
660 
661 	/* if non-NULL, specifies that a search resulting is being updated.
662 	   this can be used as a search optimization: if searched message
663 	   already exists in search result, it's not necessary to check if
664 	   static data matches. */
665 	struct mail_search_result *update_result;
666 	/* add matches to these search results */
667 	ARRAY(struct mail_search_result *) results;
668 
669 	uint32_t seq;
670 	uint32_t progress_cur, progress_max;
671 
672 	ARRAY(struct mail *) mails;
673 	unsigned int unused_mail_idx;
674 	unsigned int max_mails;
675 
676 	ARRAY(union mail_search_module_context *) module_contexts;
677 
678 	bool seen_lost_data:1;
679 	bool progress_hidden:1;
680 };
681 
682 struct mail_save_data {
683 	enum mail_flags flags;
684 	enum mail_flags pvt_flags;
685 	struct mail_keywords *keywords;
686 	uint64_t min_modseq;
687 
688 	time_t received_date, save_date;
689 	int received_tz_offset;
690 
691 	uint32_t uid;
692 	char *guid, *pop3_uidl, *from_envelope;
693 	uint32_t pop3_order;
694 
695 	struct ostream *output;
696 	struct mail_save_attachment *attach;
697 };
698 
699 struct mail_save_context {
700 	struct mailbox_transaction_context *transaction;
701 	struct mail *dest_mail;
702 	/* Set during mailbox_copy(). This is useful when copying is
703 	   implemented via save, and the save_*() methods want to access the
704 	   source mail. */
705 	struct mail *copy_src_mail;
706 
707 	/* data that changes for each saved mail */
708 	struct mail_save_data data;
709 
710 	/* returns TRUE if message part is an attachment. */
711 	bool (*part_is_attachment)(struct mail_save_context *ctx,
712 				   const struct mail_attachment_part *part);
713 
714 	/* mailbox_save_alloc() called, but finish/cancel not.
715 	   the same context is usually returned by the backends for reuse. */
716 	bool unfinished:1;
717 	/* mailbox_save_finish() or mailbox_copy() is being called. */
718 	bool finishing:1;
719 	/* mail was copied or moved using saving (requires:
720 	   copying_or_moving==TRUE). */
721 	bool copying_via_save:1;
722 	/* mail is being saved, not copied. However, this is set also with
723 	   mailbox_save_using_mail() and then copying_or_moving==TRUE. */
724 	bool saving:1;
725 	/* mail is being moved - ignore quota (requires:
726 	   copying_or_moving==TRUE && saving==FALSE). */
727 	bool moving:1;
728 	/* mail is being copied or moved. However, this is set also with
729 	   mailbox_save_using_mail() and then saving==TRUE. */
730 	bool copying_or_moving:1;
731 };
732 
733 struct mailbox_sync_context {
734 	struct mailbox *box;
735 	enum mailbox_sync_flags flags;
736 	bool open_failed;
737 };
738 
739 struct mailbox_header_lookup_ctx {
740 	struct mailbox *box;
741 	pool_t pool;
742 	int refcount;
743 
744 	unsigned int count;
745 	const char *const *name;
746 	unsigned int *idx;
747 };
748 
749 /* Modules should use do "my_id = mail_storage_module_id++" and
750    use objects' module_contexts[id] for their own purposes. */
751 extern struct mail_storage_module_register mail_storage_module_register;
752 
753 /* Storage's module_id for mail_index. */
754 extern struct mail_module_register mail_module_register;
755 
756 extern struct event_category event_category_storage;
757 extern struct event_category event_category_mailbox;
758 extern struct event_category event_category_mail;
759 
760 #define MAIL_STORAGE_CONTEXT(obj) \
761 	MODULE_CONTEXT(obj, mail_storage_mail_index_module)
762 #define MAIL_STORAGE_CONTEXT_REQUIRE(obj) \
763 	MODULE_CONTEXT_REQUIRE(obj, mail_storage_mail_index_module)
764 extern MODULE_CONTEXT_DEFINE(mail_storage_mail_index_module,
765 			     &mail_index_module_register);
766 
767 void mail_storage_obj_ref(struct mail_storage *storage);
768 void mail_storage_obj_unref(struct mail_storage *storage);
769 
770 /* Set error message in storage. Critical errors are logged with i_error(),
771    but user sees only "internal error" message. */
772 void mail_storage_clear_error(struct mail_storage *storage);
773 void mail_storage_set_error(struct mail_storage *storage,
774 			    enum mail_error error, const char *string);
775 void mail_storage_set_critical(struct mail_storage *storage,
776 			       const char *fmt, ...) ATTR_FORMAT(2, 3);
777 void mailbox_set_critical(struct mailbox *box,
778 			  const char *fmt, ...) ATTR_FORMAT(2, 3);
779 void mail_set_critical(struct mail *mail,
780 		       const char *fmt, ...) ATTR_FORMAT(2, 3);
781 void mail_storage_set_internal_error(struct mail_storage *storage);
782 void mailbox_set_index_error(struct mailbox *box);
783 void mail_storage_set_index_error(struct mail_storage *storage,
784 				  struct mail_index *index);
785 bool mail_storage_set_error_from_errno(struct mail_storage *storage);
786 void mail_storage_copy_list_error(struct mail_storage *storage,
787 				  struct mailbox_list *list);
788 void mail_storage_copy_error(struct mail_storage *dest,
789 			     struct mail_storage *src);
790 /* set record in mail cache corrupted */
791 void mail_set_mail_cache_corrupted(struct mail *mail, const char *fmt, ...)
792 	ATTR_FORMAT(2, 3);
793 
794 /* Indicate mail being expunged by autoexpunge */
795 void mail_autoexpunge(struct mail *mail);
796 
797 /* Returns TRUE if everything should already be in memory after this call
798    or if prefetching is not supported, i.e. the caller shouldn't do more
799    prefetching before this message is handled. */
800 bool mail_prefetch(struct mail *mail);
801 void mail_set_aborted(struct mail *mail);
802 void mail_set_expunged(struct mail *mail);
803 void mail_set_seq_saving(struct mail *mail, uint32_t seq);
804 /* Returns true IF and only IF the mail has EITHER one of the
805    attachment keywords set. If it has both, or none, it will return FALSE. */
806 bool mail_has_attachment_keywords(struct mail *mail);
807 /* Sets attachment keywords. Returns -1 on error, 0 when no attachment(s) found,
808    and 1 if attachment was found. */
809 int mail_set_attachment_keywords(struct mail *mail);
810 
811 /* Emit mail opened events */
812 void mail_opened_event(struct mail *mail);
813 
814 /* Emit mail expunge_requested event */
815 void mail_expunge_requested_event(struct mail *mail);
816 
817 void mailbox_set_deleted(struct mailbox *box);
818 int mailbox_mark_index_deleted(struct mailbox *box, bool del);
819 /* Easy wrapper for getting mailbox's MAILBOX_LIST_PATH_TYPE_MAILBOX.
820    The mailbox must already be opened and the caller must know that the
821    storage has mailbox files (i.e. NULL/empty path is never returned). */
822 const char *mailbox_get_path(struct mailbox *box) ATTR_PURE;
823 /* Similar to mailbox_get_path() but for MAILBOX_LIST_PATH_TYPE_INDEX. */
824 const char *mailbox_get_index_path(struct mailbox *box) ATTR_PURE;
825 /* Wrapper to mailbox_list_get_path() */
826 int mailbox_get_path_to(struct mailbox *box, enum mailbox_list_path_type type,
827 			const char **path_r);
828 /* Get mailbox permissions. */
829 const struct mailbox_permissions *mailbox_get_permissions(struct mailbox *box);
830 /* Force permissions to be refreshed on next lookup */
831 void mailbox_refresh_permissions(struct mailbox *box);
832 
833 /* Open private index files for mailbox. Returns 1 if opened, 0 if there
834    are no private indexes (or flags) in this mailbox, -1 if error. */
835 int mailbox_open_index_pvt(struct mailbox *box);
836 /* Create path's directory with proper permissions. The root directory is also
837    created if necessary. Returns 1 if created, 0 if it already existed,
838    -1 if error. */
839 int mailbox_mkdir(struct mailbox *box, const char *path,
840 		  enum mailbox_list_path_type type);
841 /* Create a non-mailbox type directory for mailbox if it's missing (e.g. index).
842    Optimized for case where the directory usually exists. */
843 int mailbox_create_missing_dir(struct mailbox *box,
844 			       enum mailbox_list_path_type type);
845 /* Returns TRUE if mailbox is autocreated. */
846 bool mailbox_is_autocreated(struct mailbox *box);
847 /* Returns TRUE if mailbox is autosubscribed. */
848 bool mailbox_is_autosubscribed(struct mailbox *box);
849 
850 /* Returns -1 if error, 0 if failed with EEXIST, 1 if ok */
851 int mailbox_create_fd(struct mailbox *box, const char *path, int flags,
852 		      int *fd_r);
853 /* Create a lock file with the given path and settings. If it succeeds,
854    returns 1 and lock_r, which needs to be freed once finished with the lock.
855    If lock_set->lock_timeout_secs is reached, returns 0 and error_r. Returns
856    -1 and sets error_r on other errors. */
857 int mail_storage_lock_create(const char *lock_path,
858 			     const struct file_create_settings *lock_set,
859 			     const struct mail_storage_settings *mail_set,
860 			     struct file_lock **lock_r, const char **error_r);
861 /* Create a lock file to the mailbox with the given filename. Returns the same
862    as mail_storage_lock_create(). */
863 int mailbox_lock_file_create(struct mailbox *box, const char *lock_fname,
864 			     unsigned int lock_secs, struct file_lock **lock_r,
865 			     const char **error_r);
866 unsigned int mail_storage_get_lock_timeout(struct mail_storage *storage,
867 					   unsigned int secs);
868 void mail_storage_free_binary_cache(struct mail_storage *storage);
869 
870 enum mail_index_open_flags
871 mail_storage_settings_to_index_flags(const struct mail_storage_settings *set);
872 void mailbox_save_context_deinit(struct mail_save_context *ctx);
873 
874 /* Notify that a sync should be done. */
875 void mailbox_sync_notify(struct mailbox *box, uint32_t uid,
876 			 enum mailbox_sync_type sync_type);
877 
878 /* for unit testing */
879 int mailbox_verify_name(struct mailbox *box);
880 
881 int mail_storage_list_index_rebuild_and_set_uncorrupted(struct mail_storage *storage);
882 int mail_storage_list_index_rebuild(struct mail_storage *storage,
883 				    enum mail_storage_list_index_rebuild_reason reason);
884 
885 #endif
886