mdbox-save.c revision 714c6a150480112eb1a5f309d0cc39b60613a719
/* Copyright (c) 2007-2011 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "fdatasync-path.h"
#include "hex-binary.h"
#include "hex-dec.h"
#include "str.h"
#include "istream.h"
#include "istream-crlf.h"
#include "ostream.h"
#include "write-full.h"
#include "index-mail.h"
#include "mail-copy.h"
#include "dbox-save.h"
#include "mdbox-storage.h"
#include "mdbox-map.h"
#include "mdbox-file.h"
#include "mdbox-sync.h"
#include <stdlib.h>
struct dbox_save_mail {
struct dbox_file_append_context *file_append;
};
struct mdbox_save_context {
struct dbox_save_context ctx;
struct mdbox_mailbox *mbox;
struct mdbox_sync_context *sync_ctx;
struct dbox_file_append_context *cur_file_append;
struct mdbox_map_append_context *append_ctx;
struct mdbox_map_atomic_context *atomic;
struct mdbox_map_transaction_context *map_trans;
};
static struct dbox_file *
{
struct mdbox_save_context *ctx =
(struct mdbox_save_context *)t->save_ctx;
const struct mdbox_mail_index_record *rec;
const void *data;
bool expunged;
i_unreached();
}
struct dbox_file *
{
struct mdbox_save_context *ctx =
(struct mdbox_save_context *)t->save_ctx;
unsigned int count;
/* copied mail */
}
/* saved mail */
}
struct mail_save_context *
mdbox_save_alloc(struct mailbox_transaction_context *t)
{
struct mdbox_save_context *ctx =
(struct mdbox_save_context *)t->save_ctx;
/* use the existing allocated structure */
}
return t->save_ctx;
}
{
struct dbox_save_mail *save_mail;
/* get the size of the mail to be saved, if possible */
/* we couldn't find out the exact size. fallback to non-exact,
maybe it'll give something useful. the mail size is used
only to figure out if it's causing mdbox file to grow
too large. */
}
return -1;
}
}
struct dbox_save_mail *mail)
{
struct dbox_message_header dbox_msg_hdr;
/* save the 128bit GUID to index so if the map index gets corrupted
we can still find the message */
return -1;
}
return 0;
}
{
struct dbox_save_mail *mail;
return -1;
else
} T_END;
/* if we try to read the saved mail before unlocking file,
make sure the input stream doesn't have stale data */
}
return -1;
}
return 0;
}
{
int ret;
return ret;
}
{
(void)mdbox_save_finish(_ctx);
}
static void
{
const struct mdbox_mail_index_record *old_rec;
struct mdbox_mail_index_record rec;
const struct dbox_save_mail *mails;
unsigned int i, count;
const void *data;
bool expunged;
for (i = 0; i < count; i++) {
/* message was copied. keep the existing map uid */
continue;
}
}
}
{
const struct mail_index_header *hdr;
/* make sure the map gets locked */
return -1;
}
/* assign map UIDs for newly saved messages. they're written to
transaction log immediately within this function, but the map
is left locked. */
&last_map_uid) < 0) {
return -1;
}
/* lock the mailbox after map to avoid deadlocks. */
return -1;
}
/* assign UIDs for new messages */
/* save map UIDs to mailbox index */
if (first_map_uid != 0)
/* increase map's refcount for copied mails */
return -1;
}
}
return 0;
}
{
result);
/* finish writing the mailbox APPENDs */
/* commit refcount increases for copied mails */
}
/* flush file append writes */
}
/* update the sync tail offset, everything else
was already written at this point. */
if (fdatasync_path(box_path) < 0) {
"fdatasync_path(%s) failed: %m", box_path);
}
}
}
{
}
{
struct dbox_save_mail *save_mail;
struct mdbox_mailbox *src_mbox;
struct mdbox_mail_index_record rec;
const void *data;
bool expunged;
return -1;
/* remember the map_uid so we can later increase its refcount */
/* add message to mailbox index */
}
return 0;
}