[dovecot-cvs] dovecot/src/lib-storage/index/maildir maildir-mail.c,
1.21, 1.22 maildir-save.c, 1.67, 1.68 maildir-storage.h, 1.46, 1.47
tss-movial at dovecot.org
tss-movial at dovecot.org
Mon Mar 6 21:05:12 EET 2006
Update of /var/lib/cvs/dovecot/src/lib-storage/index/maildir
In directory talvi:/tmp/cvs-serv23804/lib-storage/index/maildir
Modified Files:
maildir-mail.c maildir-save.c maildir-storage.h
Log Message:
Support accessing saved mails that haven't been committed yet (fixes quota for maildir).
Index: maildir-mail.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/maildir/maildir-mail.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- maildir-mail.c 6 Mar 2006 16:42:10 -0000 1.21
+++ maildir-mail.c 6 Mar 2006 19:05:09 -0000 1.22
@@ -42,18 +42,25 @@
}
static struct istream *
-maildir_open_mail(struct maildir_mailbox *mbox, uint32_t uid, bool *deleted)
+maildir_open_mail(struct maildir_mailbox *mbox, struct mail *mail,
+ bool *deleted_r)
{
- int fd;
+ const char *path;
+ int fd = -1;
- *deleted = FALSE;
+ *deleted_r = FALSE;
- fd = -1;
- if (maildir_file_do(mbox, uid, do_open, &fd) < 0)
- return NULL;
+ if (mail->uid != 0) {
+ if (maildir_file_do(mbox, mail->uid, do_open, &fd) < 0)
+ return NULL;
+ } else {
+ path = maildir_save_file_get_path(mail->transaction, mail->seq);
+ if (do_open(mbox, path, &fd) <= 0)
+ return NULL;
+ }
if (fd == -1) {
- *deleted = TRUE;
+ *deleted_r = TRUE;
return NULL;
}
@@ -72,6 +79,7 @@
struct maildir_mailbox *mbox = (struct maildir_mailbox *)mail->ibox;
struct index_mail_data *data = &mail->data;
struct stat st;
+ const char *path;
int fd;
(void)index_mail_get_received_date(_mail);
@@ -92,9 +100,14 @@
"fstat(maildir) failed: %m");
return (time_t)-1;
}
- } else {
+ } else if (_mail->uid != 0) {
if (maildir_file_do(mbox, _mail->uid, do_stat, &st) <= 0)
return (time_t)-1;
+ } else {
+ path = maildir_save_file_get_path(_mail->transaction,
+ _mail->seq);
+ if (do_stat(mbox, path, &st) <= 0)
+ return (time_t)-1;
}
data->received_date = st.st_mtime;
@@ -121,9 +134,15 @@
return data->virtual_size;
}
- fname = maildir_uidlist_lookup(mbox->uidlist, _mail->uid, &flags);
- if (fname == NULL)
- return (uoff_t)-1;
+ if (_mail->uid != 0) {
+ fname = maildir_uidlist_lookup(mbox->uidlist, _mail->uid,
+ &flags);
+ if (fname == NULL)
+ return (uoff_t)-1;
+ } else {
+ fname = maildir_save_file_get_path(_mail->transaction,
+ _mail->seq);
+ }
/* size can be included in filename */
p = strstr(fname, MAILDIR_EXTRA_SEP_S MAILDIR_EXTRA_VIRTUAL_SIZE "=");
@@ -156,8 +175,13 @@
const char *fname, *end;
if (field == MAIL_FETCH_UIDL_FILE_NAME) {
- fname = maildir_uidlist_lookup(mbox->uidlist,
- _mail->uid, &flags);
+ if (_mail->uid != 0) {
+ fname = maildir_uidlist_lookup(mbox->uidlist,
+ _mail->uid, &flags);
+ } else {
+ fname = maildir_save_file_get_path(_mail->transaction,
+ _mail->seq);
+ }
end = strchr(fname, MAILDIR_INFO_SEP);
return end == NULL ? fname : t_strdup_until(fname, end);
}
@@ -179,9 +203,15 @@
if (size != (uoff_t)-1)
return size;
- fname = maildir_uidlist_lookup(mbox->uidlist, _mail->uid, &flags);
- if (fname == NULL)
- return (uoff_t)-1;
+ if (_mail->uid != 0) {
+ fname = maildir_uidlist_lookup(mbox->uidlist, _mail->uid,
+ &flags);
+ if (fname == NULL)
+ return (uoff_t)-1;
+ } else {
+ fname = maildir_save_file_get_path(_mail->transaction,
+ _mail->seq);
+ }
/* size can be included in filename */
p = strstr(fname, MAILDIR_EXTRA_SEP_S MAILDIR_EXTRA_FILE_SIZE "=");
@@ -199,8 +229,14 @@
}
if (size == (uoff_t)-1) {
- if (maildir_file_do(mbox, _mail->uid, do_stat, &st) <= 0)
- return (uoff_t)-1;
+ if (_mail->uid != 0) {
+ if (maildir_file_do(mbox, _mail->uid,
+ do_stat, &st) <= 0)
+ return (uoff_t)-1;
+ } else {
+ if (do_stat(mbox, fname, &st) <= 0)
+ return (uoff_t)-1;
+ }
size = st.st_size;
}
@@ -208,7 +244,6 @@
&size, sizeof(size));
data->physical_size = size;
return size;
-
}
static struct istream *maildir_mail_get_stream(struct mail *_mail,
@@ -221,7 +256,7 @@
bool deleted;
if (data->stream == NULL) {
- data->stream = maildir_open_mail(mbox, _mail->uid, &deleted);
+ data->stream = maildir_open_mail(mbox, _mail, &deleted);
if (data->stream == NULL) {
_mail->expunged = deleted;
return NULL;
Index: maildir-save.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/maildir/maildir-save.c,v
retrieving revision 1.67
retrieving revision 1.68
diff -u -d -r1.67 -r1.68
--- maildir-save.c 6 Mar 2006 18:16:12 -0000 1.67
+++ maildir-save.c 6 Mar 2006 19:05:09 -0000 1.68
@@ -36,7 +36,7 @@
struct maildir_index_sync_context *sync_ctx;
const char *tmpdir, *newdir, *curdir;
- struct maildir_filename *files;
+ struct maildir_filename *files, **files_tail;
buffer_t *keywords_buffer;
array_t ARRAY_DEFINE(keywords_array, unsigned int);
@@ -45,10 +45,11 @@
struct ostream *output;
int fd;
time_t received_date;
- uint32_t seq;
+ uint32_t first_seq, seq;
unsigned int synced:1;
unsigned int failed:1;
+ unsigned int moving:1;
unsigned int finished:1;
};
@@ -103,6 +104,7 @@
ctx->pool = pool;
ctx->mbox = mbox;
ctx->trans = t->ictx.trans;
+ ctx->files_tail = &ctx->files;
ctx->tmpdir = p_strconcat(pool, mbox->path, "/tmp", NULL);
ctx->newdir = p_strconcat(pool, mbox->path, "/new", NULL);
@@ -125,6 +127,17 @@
struct maildir_mailbox *mbox = (struct maildir_mailbox *)t->ictx.ibox;
struct maildir_filename *mf;
+ if (!ctx->synced && want_mail) {
+ /* we could support adding the missing mails to index, but
+ currently there's no need. */
+ i_assert(ctx->files == NULL);
+
+ if (maildir_storage_sync_force(mbox) < 0)
+ ctx->failed = TRUE;
+ else
+ ctx->synced = TRUE;
+ }
+
/* 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/. */
@@ -132,10 +145,13 @@
mf = p_malloc(ctx->pool, sizeof(*mf) +
sizeof(unsigned int) * (keywords == NULL ? 0 :
keywords->count));
- mf->next = ctx->files;
mf->basename = p_strdup(ctx->pool, base_fname);
mf->flags = flags;
- ctx->files = mf;
+
+ if (*ctx->files_tail != NULL)
+ (*ctx->files_tail)->next = mf;
+ *ctx->files_tail = mf;
+ ctx->files_tail = &mf->next;
if (keywords != NULL) {
i_assert(sizeof(keywords->idx[0]) == sizeof(unsigned int));
@@ -146,13 +162,6 @@
sizeof(unsigned int) * keywords->count);
}
- if (!ctx->synced && want_mail) {
- if (maildir_storage_sync_force(mbox) < 0)
- ctx->failed = TRUE;
- else
- ctx->synced = TRUE;
- }
-
if (ctx->synced) {
/* insert into index */
mail_index_append(ctx->trans, 0, &ctx->seq);
@@ -162,6 +171,11 @@
mail_index_update_keywords(ctx->trans, ctx->seq,
MODIFY_REPLACE, keywords);
}
+
+ if (ctx->first_seq == 0) {
+ ctx->first_seq = ctx->seq;
+ i_assert(ctx->files->next == NULL);
+ }
} else {
ctx->seq = 0;
}
@@ -169,6 +183,65 @@
return ctx->seq;
}
+static const char *
+maildir_get_updated_filename(struct maildir_save_context *ctx,
+ struct maildir_filename *mf)
+{
+ if (mf->keywords_count == 0) {
+ if ((mf->flags & MAIL_FLAGS_MASK) == MAIL_RECENT)
+ return NULL;
+ return maildir_filename_set_flags(NULL, mf->basename,
+ mf->flags & MAIL_FLAGS_MASK,
+ NULL);
+ }
+
+ buffer_update_const_data(ctx->keywords_buffer, mf + 1,
+ mf->keywords_count * sizeof(unsigned int));
+ return maildir_filename_set_flags(
+ maildir_sync_get_keywords_sync_ctx(ctx->sync_ctx),
+ mf->basename, mf->flags & MAIL_FLAGS_MASK,
+ &ctx->keywords_array);
+}
+
+static const char *maildir_mf_get_path(struct maildir_save_context *ctx,
+ struct maildir_filename *mf)
+{
+ const char *fname;
+
+ if (!ctx->moving && (mf->flags & MAILDIR_SAVE_FLAG_HARDLINK) == 0) {
+ /* file is still in tmp/ */
+ return t_strdup_printf("%s/%s", ctx->tmpdir, mf->basename);
+ }
+
+ /* already moved to new/ or cur/ */
+ fname = maildir_get_updated_filename(ctx, mf);
+ if (fname == NULL)
+ return t_strdup_printf("%s/%s", ctx->newdir, mf->basename);
+ else
+ return t_strdup_printf("%s/%s", ctx->curdir, fname);
+}
+
+const char *maildir_save_file_get_path(struct mailbox_transaction_context *_t,
+ uint32_t seq)
+{
+ struct maildir_transaction_context *t =
+ (struct maildir_transaction_context *)_t;
+ struct maildir_save_context *ctx = t->save_ctx;
+ struct maildir_filename *mf;
+
+ i_assert(seq >= ctx->first_seq);
+
+ seq -= ctx->first_seq;
+ mf = ctx->files;
+ while (seq > 0) {
+ mf = mf->next;
+ i_assert(mf != NULL);
+ seq--;
+ }
+
+ return maildir_mf_get_path(ctx, mf);
+}
+
int maildir_save_init(struct mailbox_transaction_context *_t,
enum mail_flags flags, struct mail_keywords *keywords,
time_t received_date, int timezone_offset __attr_unused__,
@@ -328,32 +401,11 @@
(void)maildir_save_finish(_ctx, NULL);
}
-static const char *
-maildir_get_updated_filename(struct maildir_save_context *ctx,
- struct maildir_filename *mf)
-{
- if (mf->keywords_count == 0) {
- if ((mf->flags & MAIL_FLAGS_MASK) == MAIL_RECENT)
- return NULL;
- return maildir_filename_set_flags(NULL, mf->basename,
- mf->flags & MAIL_FLAGS_MASK,
- NULL);
- }
-
- buffer_update_const_data(ctx->keywords_buffer, mf + 1,
- mf->keywords_count * sizeof(unsigned int));
- return maildir_filename_set_flags(
- maildir_sync_get_keywords_sync_ctx(ctx->sync_ctx),
- mf->basename, mf->flags & MAIL_FLAGS_MASK,
- &ctx->keywords_array);
-}
-
static void
maildir_transaction_unlink_copied_files(struct maildir_save_context *ctx,
struct maildir_filename *pos)
{
struct maildir_filename *mf;
- const char *path, *dest;
/* try to unlink the mails already moved */
for (mf = ctx->files; mf != pos; mf = mf->next) {
@@ -361,14 +413,7 @@
continue;
t_push();
- dest = maildir_get_updated_filename(ctx, mf);
- if (dest != NULL)
- path = t_strdup_printf("%s/%s", ctx->curdir, dest);
- else {
- path = t_strdup_printf("%s/%s",
- ctx->newdir, mf->basename);
- }
- (void)unlink(path);
+ (void)unlink(maildir_mf_get_path(ctx, mf));
t_pop();
}
ctx->files = pos;
@@ -410,6 +455,7 @@
/* move them into new/ and/or cur/ */
ret = 0;
+ ctx->moving = TRUE;
for (mf = ctx->files; mf != NULL && ret == 0; mf = mf->next) {
t_push();
dest = maildir_get_updated_filename(ctx, mf);
Index: maildir-storage.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/maildir/maildir-storage.h,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -d -r1.46 -r1.47
--- maildir-storage.h 6 Mar 2006 18:16:12 -0000 1.46
+++ maildir-storage.h 6 Mar 2006 19:05:09 -0000 1.47
@@ -129,6 +129,8 @@
uint32_t maildir_save_add(struct maildir_transaction_context *t,
const char *base_fname, enum mail_flags flags,
struct mail_keywords *keywords, bool want_mail);
+const char *maildir_save_file_get_path(struct mailbox_transaction_context *t,
+ uint32_t seq);
int maildir_transaction_save_commit_pre(struct maildir_save_context *ctx);
void maildir_transaction_save_commit_post(struct maildir_save_context *ctx);
More information about the dovecot-cvs
mailing list