static bool maildir_expunge_is_valid_guid(struct maildir_index_sync_context *ctx, uint32_t uid, const char *filename, guid_128_t expunged_guid_128) { guid_128_t guid_128; const char *guid; if (guid_128_is_empty(expunged_guid_128)) { /* no GUID associated with expunge */ return TRUE; } T_BEGIN { guid = maildir_uidlist_lookup_ext(ctx->mbox->uidlist, uid, MAILDIR_UIDLIST_REC_EXT_GUID); if (guid == NULL) guid = t_strcut(filename, ':'); mail_generate_guid_128_hash(guid, guid_128); } T_END; if (memcmp(guid_128, expunged_guid_128, sizeof(guid_128)) == 0) return TRUE; mail_storage_set_critical(&ctx->mbox->storage->storage, "Mailbox %s: Expunged GUID mismatch for UID %u: %s vs %s", ctx->mbox->box.vname, ctx->uid, guid_128_to_string(guid_128), guid_128_to_string(expunged_guid_128)); return FALSE; }
void dbox_save_write_metadata(struct mail_save_context *_ctx, struct ostream *output, uoff_t output_msg_size, const char *orig_mailbox_name, guid_128_t guid_128) { struct dbox_save_context *ctx = (struct dbox_save_context *)_ctx; struct mail_save_data *mdata = &ctx->ctx.data; struct dbox_metadata_header metadata_hdr; const char *guid; string_t *str; uoff_t vsize; memset(&metadata_hdr, 0, sizeof(metadata_hdr)); memcpy(metadata_hdr.magic_post, DBOX_MAGIC_POST, sizeof(metadata_hdr.magic_post)); o_stream_nsend(output, &metadata_hdr, sizeof(metadata_hdr)); str = t_str_new(256); if (output_msg_size != ctx->input->v_offset) { /* a plugin changed the data written to disk, so the "message size" dbox header doesn't contain the actual "physical" message size. we need to save it as a separate metadata header. */ str_printfa(str, "%c%llx\n", DBOX_METADATA_PHYSICAL_SIZE, (unsigned long long)ctx->input->v_offset); } str_printfa(str, "%c%lx\n", DBOX_METADATA_RECEIVED_TIME, (unsigned long)mdata->received_date); if (mail_get_virtual_size(_ctx->dest_mail, &vsize) < 0) i_unreached(); str_printfa(str, "%c%llx\n", DBOX_METADATA_VIRTUAL_SIZE, (unsigned long long)vsize); if (mdata->pop3_uidl != NULL) { i_assert(strchr(mdata->pop3_uidl, '\n') == NULL); str_printfa(str, "%c%s\n", DBOX_METADATA_POP3_UIDL, mdata->pop3_uidl); } guid = mdata->guid; if (guid != NULL) mail_generate_guid_128_hash(guid, guid_128); else { guid_128_generate(guid_128); guid = guid_128_to_string(guid_128); } str_printfa(str, "%c%s\n", DBOX_METADATA_GUID, guid); if (orig_mailbox_name != NULL && strchr(orig_mailbox_name, '\r') == NULL && strchr(orig_mailbox_name, '\n') == NULL) { /* save the original mailbox name so if mailbox indexes get corrupted we can place at least some (hopefully most) of the messages to correct mailboxes. */ str_printfa(str, "%c%s\n", DBOX_METADATA_ORIG_MAILBOX, orig_mailbox_name); } dbox_attachment_save_write_metadata(_ctx, str); str_append_c(str, '\n'); o_stream_nsend(output, str_data(str), str_len(str)); }