maildir-save.c revision 04126bd4b437b99b1450bd7e68b3401c03159395
/* 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 index_mailbox *ibox;
struct mail_index_transaction *trans;
struct index_mail mail;
struct maildir_filename *files;
int fd;
unsigned int save_crlf:1;
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 struct mail_full_flags *flags,
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;
enum mail_flags mail_flags;
t_push();
t->save_ctx = maildir_transaction_save_init(t);
/* create a new file in tmp/ directory */
&path);
t_pop();
}
fname++;
/*FIXME:if (!index_mailbox_fix_keywords(ibox, &mail_flags,
flags->keywords,
flags->keywords_count))
return FALSE;*/
/* 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 */
// FIXME: set keywords
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_uidlist_sync_ctx *sync_ctx;
struct maildir_filename *mf;
const char *fname;
int ret = 0;
if (ret <= 0) {
/* error or timeout - our transaction is broken */
return -1;
}
/* move them into new/ */
(void)maildir_uidlist_sync_deinit(sync_ctx);
return -1;
}
}
if (maildir_uidlist_sync_deinit(sync_ctx) < 0) {
return -1;
}
return ret;
}
{
struct maildir_filename *mf;
t_push();
/* clean up the temp files */
str_truncate(str, 0);
}
t_pop();
}