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