static void maildir_sync_index_update_ext_header(struct maildir_index_sync_context *ctx) { struct maildir_mailbox *mbox = ctx->mbox; const char *cur_path; const void *data; size_t data_size; struct stat st; cur_path = t_strconcat(mailbox_get_path(&mbox->box), "/cur", NULL); if (ctx->update_maildir_hdr_cur && stat(cur_path, &st) == 0) { if ((time_t)mbox->maildir_hdr.cur_check_time < st.st_mtime) mbox->maildir_hdr.cur_check_time = st.st_mtime; mbox->maildir_hdr.cur_mtime = st.st_mtime; mbox->maildir_hdr.cur_mtime_nsecs = ST_MTIME_NSEC(st); } mail_index_get_header_ext(mbox->box.view, mbox->maildir_ext_id, &data, &data_size); if (data_size != sizeof(mbox->maildir_hdr) || maildir_index_header_has_changed(data, &mbox->maildir_hdr)) { mail_index_update_header_ext(ctx->trans, mbox->maildir_ext_id, 0, &mbox->maildir_hdr, sizeof(mbox->maildir_hdr)); } }
static void mdbox_map_get_ext_hdr(struct mdbox_map *map, struct mail_index_view *view, struct mdbox_map_mail_index_header *hdr_r) { const void *data; size_t data_size; mail_index_get_header_ext(view, map->map_ext_id, &data, &data_size); memset(hdr_r, 0, sizeof(*hdr_r)); memcpy(hdr_r, data, I_MIN(data_size, sizeof(*hdr_r))); }
bool mailbox_list_index_need_refresh(struct mailbox_list_index *ilist, struct mail_index_view *view) { const struct mailbox_list_index_header *hdr; const void *data; size_t size; if (!ilist->has_backing_store) return FALSE; mail_index_get_header_ext(view, ilist->ext_id, &data, &size); hdr = data; return hdr != NULL && hdr->refresh_flag != 0; }
void index_pop3_uidl_update_exists_finish(struct mailbox_transaction_context *trans) { struct mail_index_view *view; struct mailbox_index_pop3_uidl uidl; const void *data; size_t size; bool seen_all_msgs; if (trans->highest_pop3_uidl_uid == 0) return; /* First check that we actually looked at UIDL for all messages. Otherwise we can't say for sure if the newest messages had UIDLs. */ if (trans->prev_pop3_uidl_tracking_seq != mail_index_view_get_messages_count(trans->view)) return; /* Just to be sure: Refresh the index and check again. POP3 keeps transactions open for duration of the entire session. Maybe another process already added new mails (and already updated this header). This check is racy, but normally UIDLs aren't added after migration so it's a bit questionable if it's even worth having this check in there. */ view = mail_index_view_open(trans->box->index); seen_all_msgs = mail_index_refresh(trans->box->index) == 0 && trans->prev_pop3_uidl_tracking_seq == mail_index_view_get_messages_count(view); mail_index_view_close(&view); if (!seen_all_msgs) return; /* check if we have already the same header */ mail_index_get_header_ext(trans->view, trans->box->pop3_uidl_hdr_ext_id, &data, &size); if (size >= sizeof(uidl)) { memcpy(&uidl, data, size); if (trans->highest_pop3_uidl_uid == uidl.max_uid_with_pop3_uidl) return; } index_pop3_uidl_set_max_uid(trans->box, trans->itrans, trans->highest_pop3_uidl_uid); }
static int get_metadata_virtual_size(struct mailbox *box, struct mailbox_metadata *metadata_r) { struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box); struct index_vsize_header vsize_hdr; struct mailbox_status status; const void *data; size_t size; int ret; mailbox_get_open_status(box, STATUS_MESSAGES | STATUS_UIDNEXT, &status); mail_index_get_header_ext(box->view, ibox->vsize_hdr_ext_id, &data, &size); if (size == sizeof(vsize_hdr)) memcpy(&vsize_hdr, data, sizeof(vsize_hdr)); else { if (size != 0) { mail_storage_set_critical(box->storage, "vsize-hdr has invalid size: %"PRIuSIZE_T, size); } memset(&vsize_hdr, 0, sizeof(vsize_hdr)); } if (vsize_hdr.highest_uid + 1 == status.uidnext && vsize_hdr.message_count == status.messages) { /* up to date */ metadata_r->virtual_size = vsize_hdr.vsize; return 0; } if (vsize_hdr.highest_uid >= status.uidnext) { mail_storage_set_critical(box->storage, "vsize-hdr has invalid highest-uid (%u >= %u)", vsize_hdr.highest_uid, status.uidnext); memset(&vsize_hdr, 0, sizeof(vsize_hdr)); } ret = virtual_size_add_new(box, &vsize_hdr); metadata_r->virtual_size = vsize_hdr.vsize; return ret; }
int sdbox_read_header(struct sdbox_mailbox *mbox, struct sdbox_index_header *hdr, bool log_error, bool *need_resize_r) { struct mail_index_view *view; const void *data; size_t data_size; int ret = 0; i_assert(mbox->box.opened); view = mail_index_view_open(mbox->box.index); mail_index_get_header_ext(view, mbox->hdr_ext_id, &data, &data_size); if (data_size < SDBOX_INDEX_HEADER_MIN_SIZE && (!mbox->box.creating || data_size != 0)) { if (log_error) { mail_storage_set_critical( &mbox->storage->storage.storage, "sdbox %s: Invalid dbox header size", mailbox_get_path(&mbox->box)); } ret = -1; } else { memset(hdr, 0, sizeof(*hdr)); memcpy(hdr, data, I_MIN(data_size, sizeof(*hdr))); if (guid_128_is_empty(hdr->mailbox_guid)) ret = -1; else { /* data is valid. remember it in case mailbox is being reset */ mail_index_set_ext_init_data(mbox->box.index, mbox->hdr_ext_id, hdr, sizeof(*hdr)); } } mail_index_view_close(&view); *need_resize_r = data_size < sizeof(*hdr); return ret; }
bool index_pop3_uidl_can_exist(struct mail *mail) { struct mailbox_index_pop3_uidl uidl; const void *data; size_t size; /* We'll assume that if the header exists, it's up-to-date. normally UIDLs are set only during migration, so this value never changes. Also even if it does, it becomes out-of-date only when the mailbox is modified with old Dovecot versions. To fix that we'd have to add and keep updating "max tracked uid" in this header for every saved mail, which isn't worth it. */ mail_index_get_header_ext(mail->transaction->view, mail->box->pop3_uidl_hdr_ext_id, &data, &size); if (size < sizeof(uidl)) { /* this header isn't set yet */ return TRUE; } memcpy(&uidl, data, size); return mail->uid <= uidl.max_uid_with_pop3_uidl; }
int mdbox_read_header(struct mdbox_mailbox *mbox, struct mdbox_index_header *hdr, bool *need_resize_r) { const void *data; size_t data_size; i_assert(mbox->box.opened); mail_index_get_header_ext(mbox->box.view, mbox->hdr_ext_id, &data, &data_size); if (data_size < MDBOX_INDEX_HEADER_MIN_SIZE && (!mbox->creating || data_size != 0)) { mail_storage_set_critical(&mbox->storage->storage.storage, "mdbox %s: Invalid dbox header size: %"PRIuSIZE_T, mailbox_get_path(&mbox->box), data_size); mdbox_storage_set_corrupted(mbox->storage); return -1; } memset(hdr, 0, sizeof(*hdr)); memcpy(hdr, data, I_MIN(data_size, sizeof(*hdr))); *need_resize_r = data_size < sizeof(*hdr); return 0; }
static void index_storage_get_status_virtual_size(struct mailbox *box, struct mailbox_status *status_r) { struct index_mailbox_context *ibox = INDEX_STORAGE_CONTEXT(box); struct index_vsize_header vsize_hdr; const void *data; size_t size; mail_index_get_header_ext(box->view, ibox->vsize_hdr_ext_id, &data, &size); if (size == sizeof(vsize_hdr)) memcpy(&vsize_hdr, data, sizeof(vsize_hdr)); else { if (size != 0) { mail_storage_set_critical(box->storage, "vsize-hdr has invalid size: %"PRIuSIZE_T, size); } memset(&vsize_hdr, 0, sizeof(vsize_hdr)); } if (vsize_hdr.highest_uid + 1 == status_r->uidnext && vsize_hdr.message_count == status_r->messages) { /* up to date */ status_r->virtual_size = vsize_hdr.vsize; return; } if (vsize_hdr.highest_uid >= status_r->uidnext) { mail_storage_set_critical(box->storage, "vsize-hdr has invalid highest-uid (%u >= %u)", vsize_hdr.highest_uid, status_r->uidnext); memset(&vsize_hdr, 0, sizeof(vsize_hdr)); } index_storage_virtual_size_add_new(box, &vsize_hdr); status_r->virtual_size = vsize_hdr.vsize; }