dbox-save.c revision 26a8b7deb3a5b6f26f9c4d71538e1248f680e4be
/* Copyright (C) 2005 Timo Sirainen */
#include "lib.h"
#include "array.h"
#include "ioloop.h"
#include "istream.h"
#include "hex-dec.h"
#include "write-full.h"
#include "ostream.h"
#include "seq-range-array.h"
#include "index-mail.h"
#include "dbox-uidlist.h"
#include "dbox-keywords.h"
#include "dbox-sync.h"
#include "dbox-storage.h"
#include <stddef.h>
struct dbox_save_context {
struct mail_save_context ctx;
struct dbox_mailbox *mbox;
struct mail_index_transaction *trans;
struct dbox_uidlist_append_ctx *append_ctx;
struct mail_index_sync_ctx *index_sync_ctx;
/* updated for each appended mail: */
unsigned int failed:1;
unsigned int finished:1;
};
static int
const struct mail_keywords *keywords,
{
int ret = 0;
/* Get a list of all new keywords. Using seq_range is the easiest
way to do this and should be pretty fast too. */
t_push();
/* check if it's already in the file */
continue;
}
/* add it. if it already exists, it's handled internally. */
}
/* now, write them to file */
if (count > 0) {
ret = -1;
count = 0;
}
/* write the new keywords to file_keywords */
for (i = 0; i < count; i++) {
unsigned int kw;
&file_idx)) {
/* it should have been found */
i_unreached();
continue;
}
}
}
}
t_pop();
return ret;
}
const char *from_envelope __attr_unused__,
struct mail_save_context **ctx_r)
{
struct dbox_transaction_context *t =
(struct dbox_transaction_context *)_t;
struct dbox_mail_header hdr;
enum mail_flags save_flags;
char buf[128];
int ret;
return -1;
}
if (ret > 0) {
return -1;
}
}
}
/* get the size of the mail to be saved, if possible */
return -1;
}
t_push();
/* uidlist must be locked while we're reading or modifying
file's header */
t_pop();
return -1;
}
/* write keywords to the file */
t_pop();
return -1;
}
}
/* append mail header. UID and mail size are written later. */
/* write keywords */
if (file_keywords != NULL) {
unsigned char *keyword_string;
/* string should be filled with NULs and '1' now.
Change NULs to '0'. */
for (i = 0; i < size; i++) {
if (keyword_string[i] == '\0')
keyword_string[i] = '0';
}
}
/* fill rest of the header with '0' characters */
}
/* add to index */
}
NULL);
}
i_unreached();
if (t->first_saved_mail_seq == 0)
t_pop();
}
{
return -1;
"Not enough disk space");
} else {
"o_stream_send_istream(%s) failed: %m",
}
return -1;
}
return 0;
}
{
struct dbox_mail_header hdr;
/* Make sure the file ends here (we could have been overwriting
some existing aborted mail). In case we failed, truncate the
file to the size before writing. */
"ftruncate(%s) failed: %m",
}
}
/* write mail size to header */
offsetof(struct dbox_mail_header,
mail_size_hex)) < 0) {
"pwrite_full(%s) failed: %m",
}
}
return -1;
return 0;
}
{
(void)dbox_save_finish(_ctx);
}
{
struct dbox_transaction_context *t =
struct dbox_mail_header hdr;
struct mail_index_view *view;
const struct mail_index_header *idx_hdr;
int ret;
/* uidlist locking is done before index locking. */
return -1;
}
/* update UIDs */
file_seq);
offsetof(struct dbox_mail_header,
uid_hex)) < 0) {
"pwrite_full(%s) failed: %m",
return -1;
}
}
/* lock index lock before dropping uidlist lock in _append_commit() */
return -1;
}
return -1;
}
/* index was fully synced. keep it that way. */
}
return 0;
}
{
}
{
}