[dovecot-cvs] dovecot/src/lib-storage/index/mbox mbox-save.c,1.31,1.32 mbox-storage.c,1.33,1.34 mbox-storage.h,1.13,1.14
cras at procontrol.fi
cras at procontrol.fi
Wed Jan 22 21:23:30 EET 2003
- Previous message: [dovecot-cvs] dovecot/src/lib-storage/index index-copy.c,1.26,1.27 index-fetch.c,1.41,1.42 index-messageset.c,1.13,1.14 index-messageset.h,1.6,1.7 index-save.c,1.23,1.24 index-storage.h,1.29,1.30 index-update-flags.c,1.18,1.19
- Next message: [dovecot-cvs] dovecot/src/lib-storage/index/maildir maildir-copy.c,1.19,1.20 maildir-save.c,1.15,1.16 maildir-storage.c,1.23,1.24 maildir-storage.h,1.11,1.12
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /home/cvs/dovecot/src/lib-storage/index/mbox
In directory danu:/tmp/cvs-serv16040/src/lib-storage/index/mbox
Modified Files:
mbox-save.c mbox-storage.c mbox-storage.h
Log Message:
Support for MULTIAPPEND extension. COPY now behaves like spec says - if it
fails, none of the messages are copied. maildir_copy_with_hardlinks didn't
actually work.
Index: mbox-save.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-save.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -d -r1.31 -r1.32
--- mbox-save.c 20 Jan 2003 14:52:52 -0000 1.31
+++ mbox-save.c 22 Jan 2003 19:23:28 -0000 1.32
@@ -14,68 +14,82 @@
#include <sys/stat.h>
#include <netdb.h>
+struct mail_save_context {
+ pool_t pool;
+
+ struct index_mailbox *ibox;
+ int transaction;
+
+ struct ostream *output;
+ uoff_t sync_offset;
+};
+
static char my_hostdomain[256] = "";
-static int write_error(struct mail_storage *storage, const char *mbox_path)
+static int write_error(struct mail_save_context *ctx)
{
- if (errno == ENOSPC)
- mail_storage_set_error(storage, "Not enough disk space");
- else {
- mail_storage_set_critical(storage,
- "Error writing to mbox file %s: %m", mbox_path);
+ if (errno == ENOSPC) {
+ mail_storage_set_error(ctx->ibox->box.storage,
+ "Not enough disk space");
+ } else {
+ mail_storage_set_critical(ctx->ibox->box.storage,
+ "Error writing to mbox file %s: %m",
+ ctx->ibox->index->mailbox_path);
}
return FALSE;
}
-static int mbox_seek_to_end(struct mail_storage *storage, int fd,
- const char *mbox_path, off_t *pos)
+static int mbox_seek_to_end(struct mail_save_context *ctx, off_t *offset)
{
struct stat st;
char ch;
+ int fd;
+ fd = ctx->ibox->index->mbox_fd;
if (fstat(fd, &st) < 0) {
- mail_storage_set_critical(storage,
- "fstat() failed for mbox file %s: %m", mbox_path);
+ mail_storage_set_critical(ctx->ibox->box.storage,
+ "fstat() failed for mbox file %s: %m",
+ ctx->ibox->index->mailbox_path);
return FALSE;
}
- *pos = st.st_size;
+ *offset = st.st_size;
if (st.st_size == 0)
return TRUE;
if (lseek(fd, st.st_size-1, SEEK_SET) < 0) {
- mail_storage_set_critical(storage,
- "lseek() failed for mbox file %s: %m", mbox_path);
+ mail_storage_set_critical(ctx->ibox->box.storage,
+ "lseek() failed for mbox file %s: %m",
+ ctx->ibox->index->mailbox_path);
return FALSE;
}
if (read(fd, &ch, 1) != 1) {
- mail_storage_set_critical(storage,
- "read() failed for mbox file %s: %m", mbox_path);
+ mail_storage_set_critical(ctx->ibox->box.storage,
+ "read() failed for mbox file %s: %m",
+ ctx->ibox->index->mailbox_path);
return FALSE;
}
if (ch != '\n') {
if (write_full(fd, "\n", 1) < 0)
- return write_error(storage, mbox_path);
- *pos += 1;
+ return write_error(ctx);
+ *offset += 1;
}
return TRUE;
}
-static int mbox_append_lf(struct mail_storage *storage, struct ostream *output,
- const char *mbox_path)
+static int mbox_append_lf(struct mail_save_context *ctx)
{
- if (o_stream_send(output, "\n", 1) < 0)
- return write_error(storage, mbox_path);
+ if (o_stream_send(ctx->output, "\n", 1) < 0)
+ return write_error(ctx);
return TRUE;
}
-static int write_from_line(struct mail_storage *storage, struct ostream *output,
- const char *mbox_path, time_t internal_date)
+static int write_from_line(struct mail_save_context *ctx, time_t received_date)
{
const char *sender, *line, *name;
@@ -94,19 +108,19 @@
strocpy(my_hostdomain, name, sizeof(my_hostdomain));
}
- sender = t_strconcat(storage->user, "@", my_hostdomain, NULL);
+ sender = t_strconcat(ctx->ibox->box.storage->user, "@",
+ my_hostdomain, NULL);
/* save in local timezone, no matter what it was given with */
- line = mbox_from_create(sender, internal_date);
+ line = mbox_from_create(sender, received_date);
- if (o_stream_send_str(output, line) < 0)
- return write_error(storage, mbox_path);
+ if (o_stream_send_str(ctx->output, line) < 0)
+ return write_error(ctx);
return TRUE;
}
-static int write_flags(struct mail_storage *storage, struct ostream *output,
- const char *mbox_path,
+static int write_flags(struct mail_save_context *ctx,
const struct mail_full_flags *full_flags)
{
enum mail_flags flags = full_flags->flags;
@@ -118,8 +132,8 @@
return TRUE;
if (flags & MAIL_SEEN) {
- if (o_stream_send_str(output, "Status: R\n") < 0)
- return write_error(storage, mbox_path);
+ if (o_stream_send_str(ctx->output, "Status: R\n") < 0)
+ return write_error(ctx);
}
if (flags & (MAIL_ANSWERED|MAIL_DRAFT|MAIL_FLAGGED|MAIL_DELETED)) {
@@ -130,100 +144,134 @@
(flags & MAIL_DELETED) ? "T" : "",
"\n", NULL);
- if (o_stream_send_str(output, str) < 0)
- return write_error(storage, mbox_path);
+ if (o_stream_send_str(ctx->output, str) < 0)
+ return write_error(ctx);
}
if (flags & MAIL_CUSTOM_FLAGS_MASK) {
- if (o_stream_send_str(output, "X-Keywords:") < 0)
- return write_error(storage, mbox_path);
+ if (o_stream_send_str(ctx->output, "X-Keywords:") < 0)
+ return write_error(ctx);
field = 1 << MAIL_CUSTOM_FLAG_1_BIT;
for (i = 0; i < full_flags->custom_flags_count; i++) {
const char *custom_flag = full_flags->custom_flags[i];
if ((flags & field) && custom_flag != NULL) {
- if (o_stream_send(output, " ", 1) < 0)
- return write_error(storage, mbox_path);
+ if (o_stream_send(ctx->output, " ", 1) < 0)
+ return write_error(ctx);
- if (o_stream_send_str(output, custom_flag) < 0)
- return write_error(storage, mbox_path);
+ if (o_stream_send_str(ctx->output,
+ custom_flag) < 0)
+ return write_error(ctx);
}
field <<= 1;
}
- if (o_stream_send(output, "\n", 1) < 0)
- return write_error(storage, mbox_path);
+ if (o_stream_send(ctx->output, "\n", 1) < 0)
+ return write_error(ctx);
}
return TRUE;
}
-int mbox_storage_save(struct mailbox *box, const struct mail_full_flags *flags,
- time_t internal_date,
- int timezone_offset __attr_unused__,
- struct istream *data, uoff_t data_size)
+int mbox_storage_save_next(struct mail_save_context *ctx,
+ const struct mail_full_flags *flags,
+ time_t received_date,
+ int timezone_offset __attr_unused__,
+ struct istream *data)
{
- struct index_mailbox *ibox = (struct index_mailbox *) box;
- struct mail_index *index;
enum mail_flags real_flags;
- const char *mbox_path;
- struct ostream *output;
int failed;
- off_t pos;
-
- if (box->readonly) {
- mail_storage_set_error(box->storage, "Mailbox is read-only");
- return FALSE;
- }
/* we don't need the real flag positions, easier to keep using our own.
they need to be checked/added though. */
real_flags = flags->flags;
- if (!index_mailbox_fix_custom_flags(ibox, &real_flags,
+ if (!index_mailbox_fix_custom_flags(ctx->ibox, &real_flags,
flags->custom_flags,
flags->custom_flags_count))
return FALSE;
+ t_push();
+ if (!write_from_line(ctx, received_date) ||
+ !write_flags(ctx, flags) ||
+ !index_storage_save(ctx->ibox->box.storage,
+ ctx->ibox->index->mailbox_path,
+ data, ctx->output) ||
+ !mbox_append_lf(ctx)) {
+ /* failed, truncate file back to original size.
+ output stream needs to be flushed before truncating
+ so unref() won't write anything. */
+ o_stream_flush(ctx->output);
+ if (ctx->sync_offset != (uoff_t)-1) {
+ (void)ftruncate(ctx->ibox->index->mbox_fd,
+ ctx->sync_offset);
+ ctx->sync_offset = (uoff_t)-1;
+ }
+ failed = TRUE;
+ } else {
+ if (!ctx->transaction)
+ ctx->sync_offset = ctx->output->offset;
+ failed = FALSE;
+ }
+ t_pop();
+
+ return !failed;
+}
+
+struct mail_save_context *
+mbox_storage_save_init(struct mailbox *box, int transaction)
+{
+ struct index_mailbox *ibox = (struct index_mailbox *) box;
+ struct mail_save_context *ctx;
+ pool_t pool;
+
+ if (box->readonly) {
+ mail_storage_set_error(box->storage, "Mailbox is read-only");
+ return NULL;
+ }
+
if (!index_storage_sync_and_lock(ibox, FALSE, MAIL_LOCK_EXCLUSIVE))
- return FALSE;
+ return NULL;
- index = ibox->index;
- mbox_path = index->mailbox_path;
- if (!mbox_seek_to_end(box->storage, index->mbox_fd, mbox_path, &pos))
+ pool = pool_alloconly_create("mail_save_context", 2048);
+ ctx = p_new(pool, struct mail_save_context, 1);
+ ctx->pool = pool;
+ ctx->ibox = ibox;
+ ctx->transaction = transaction;
+
+ if (!mbox_seek_to_end(ctx, &ctx->sync_offset)) {
+ pool_unref(pool);
+ return NULL;
+ }
+
+ ctx->output = o_stream_create_file(ibox->index->mbox_fd,
+ ctx->pool, 4096, 0, FALSE);
+ o_stream_set_blocking(ctx->output, 60000, NULL, NULL);
+ return ctx;
+}
+
+int mbox_storage_save_deinit(struct mail_save_context *ctx, int rollback)
+{
+ int failed = FALSE;
+
+ if (!index_storage_lock(ctx->ibox, MAIL_LOCK_UNLOCK))
failed = TRUE;
- else {
- failed = FALSE;
- t_push();
- output = o_stream_create_file(index->mbox_fd,
- data_stack_pool, 4096,
- 0, FALSE);
- o_stream_set_blocking(output, 60000, NULL, NULL);
+ if (o_stream_flush(ctx->output) < 0)
+ failed = TRUE;
+ o_stream_unref(ctx->output);
- if (!write_from_line(box->storage, output, mbox_path,
- internal_date) ||
- !write_flags(box->storage, output, mbox_path, flags) ||
- !index_storage_save(box->storage, mbox_path,
- data, output, data_size) ||
- !mbox_append_lf(box->storage, output, mbox_path)) {
- /* failed, truncate file back to original size.
- output stream needs to be flushed before truncating
- so unref() won't write anything. */
- o_stream_flush(output);
- (void)ftruncate(index->mbox_fd, pos);
+ if (rollback && ctx->sync_offset != (uoff_t)-1) {
+ if (ftruncate(ctx->ibox->index->mbox_fd,
+ ctx->sync_offset) < 0) {
+ mail_storage_set_critical(ctx->ibox->box.storage,
+ "ftruncate(%s) failed: %m",
+ ctx->ibox->index->mailbox_path);
failed = TRUE;
}
- o_stream_unref(output);
- t_pop();
- }
-
- /* kludgy.. for copying inside same mailbox. */
- if (!ibox->delay_save_unlocking) {
- if (!index_storage_lock(ibox, MAIL_LOCK_UNLOCK))
- return FALSE;
}
+ pool_unref(ctx->pool);
return !failed;
}
Index: mbox-storage.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-storage.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -d -r1.33 -r1.34
--- mbox-storage.c 21 Jan 2003 18:33:06 -0000 1.33
+++ mbox-storage.c 22 Jan 2003 19:23:28 -0000 1.34
@@ -630,7 +630,9 @@
index_storage_search_init,
index_storage_search_deinit,
index_storage_search_next,
- mbox_storage_save,
+ mbox_storage_save_init,
+ mbox_storage_save_deinit,
+ mbox_storage_save_next,
mail_storage_is_inconsistency_error,
FALSE,
Index: mbox-storage.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-storage/index/mbox/mbox-storage.h,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- mbox-storage.h 20 Jan 2003 14:52:52 -0000 1.13
+++ mbox-storage.h 22 Jan 2003 19:23:28 -0000 1.14
@@ -5,9 +5,14 @@
int mbox_storage_copy(struct mailbox *box, struct mailbox *destbox,
const char *messageset, int uidset);
-int mbox_storage_save(struct mailbox *box, const struct mail_full_flags *flags,
- time_t internal_date, int timezone_offset,
- struct istream *data, uoff_t data_size);
+
+struct mail_save_context *
+mbox_storage_save_init(struct mailbox *box, int transaction);
+int mbox_storage_save_deinit(struct mail_save_context *ctx, int rollback);
+int mbox_storage_save_next(struct mail_save_context *ctx,
+ const struct mail_full_flags *flags,
+ time_t received_date, int timezone_offset,
+ struct istream *data);
int mbox_find_mailboxes(struct mail_storage *storage, const char *mask,
mailbox_list_callback_t callback, void *context);
- Previous message: [dovecot-cvs] dovecot/src/lib-storage/index index-copy.c,1.26,1.27 index-fetch.c,1.41,1.42 index-messageset.c,1.13,1.14 index-messageset.h,1.6,1.7 index-save.c,1.23,1.24 index-storage.h,1.29,1.30 index-update-flags.c,1.18,1.19
- Next message: [dovecot-cvs] dovecot/src/lib-storage/index/maildir maildir-copy.c,1.19,1.20 maildir-save.c,1.15,1.16 maildir-storage.c,1.23,1.24 maildir-storage.h,1.11,1.12
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the dovecot-cvs
mailing list