maildir-save.c revision 8153fdec343e40e2a78f5c12353e89b994b28f74
/* Copyright (C) 2002-2004 Timo Sirainen */
#include "lib.h"
#include "ioloop.h"
#include "ostream.h"
#include "ostream-crlf.h"
#include "str.h"
#include "maildir-storage.h"
#include "maildir-uidlist.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <utime.h>
struct maildir_filename {
struct maildir_filename *next;
};
struct maildir_save_context {
struct mail_save_context ctx;
struct maildir_mailbox *mbox;
struct mail_index_transaction *trans;
struct maildir_uidlist_sync_ctx *sync_ctx;
struct maildir_filename *files;
int fd;
unsigned int failed:1;
};
{
int ret;
t_push();
/* if we have flags, we'll move it to cur/ directly, because files in
new/ directory can't have flags. alternative would be to write it
in new/ and set the flags dirty in index file, but in that case
external MUAs would see wrong flags. */
ret = 0;
else {
ret = -1;
"Not enough disk space");
} else {
}
}
"unlink(%s) failed: %m", tmp_path);
}
t_pop();
return ret;
}
static struct maildir_save_context *
{
struct maildir_save_context *ctx;
return ctx;
}
struct mail_save_context *
const char *from_envelope __attr_unused__,
{
struct maildir_transaction_context *t =
(struct maildir_transaction_context *)_t;
struct maildir_save_context *ctx;
struct maildir_filename *mf;
t_push();
t->save_ctx = maildir_save_transaction_init(t);
/* create a new file in tmp/ directory */
&path);
t_pop();
}
fname++;
MAIL_STORAGE_FLAG_SAVE_CRLF) != 0 ?
flags &= ~MAIL_RECENT;
flags |= MAIL_RECENT;
/* now, we want to be able to rollback the whole append session,
so we'll just store the name of this temp file and move it later
into new/ or cur/. if dest_fname is NULL, it's moved to new/,
otherwise to cur/. */
/* insert into index */
}
t_pop();
}
{
return -1;
return -1;
}
return 0;
}
{
const char *path;
int output_errno;
/* tmp file creation failed */
return -1;
}
t_push();
/* set the received_date by modifying mtime */
"utime(%s) failed: %m", path);
}
}
/* FIXME: when saving multiple messages, we could get better
performance if we left the fd open and fsync()ed it later */
"fsync(%s) failed: %m", path);
}
"close(%s) failed: %m", path);
}
/* delete the tmp file */
"unlink(%s) failed: %m", path);
}
"Not enough disk space");
} else if (errno != 0) {
}
t_pop();
return -1;
}
return -1;
}
t_pop();
return 0;
}
{
}
struct maildir_filename *pos)
{
struct maildir_filename *mf;
t_push();
/* try to unlink the mails already moved */
str_truncate(str, 0);
else
}
t_pop();
}
{
struct maildir_index_sync_context *sync_ctx;
struct maildir_filename *mf;
const char *fname;
int ret;
return -1;
}
if (ret <= 0) {
/* error or timeout - our transaction is broken */
return -1;
}
return -1;
}
/* move them into new/ */
return -1;
}
}
return 0;
}
{
/* can't do anything anymore if we fail */
}
{
struct maildir_filename *mf;
t_push();
/* clean up the temp files */
str_truncate(str, 0);
}
t_pop();
}