dovecot-2.2: maildir: Maildir S=size fixing now works also with ...
dovecot at dovecot.org
dovecot at dovecot.org
Fri May 2 10:49:10 UTC 2014
details: http://hg.dovecot.org/dovecot-2.2/rev/a1831c9896d4
changeset: 17309:a1831c9896d4
user: Timo Sirainen <tss at iki.fi>
date: Fri May 02 13:48:36 2014 +0300
description:
maildir: Maildir S=size fixing now works also with zlib etc. plugins that modify the files.
diffstat:
src/lib-storage/index/maildir/maildir-mail.c | 53 ++++++++++++++++++++-------
1 files changed, 38 insertions(+), 15 deletions(-)
diffs (106 lines):
diff -r 9f1460682295 -r a1831c9896d4 src/lib-storage/index/maildir/maildir-mail.c
--- a/src/lib-storage/index/maildir/maildir-mail.c Fri May 02 13:36:00 2014 +0300
+++ b/src/lib-storage/index/maildir/maildir-mail.c Fri May 02 13:48:36 2014 +0300
@@ -651,8 +651,14 @@
}
}
+struct maildir_size_fix_ctx {
+ uoff_t physical_size;
+ bool wrong_key;
+};
+
static int
-do_fix_size(struct maildir_mailbox *mbox, const char *path, char *wrong_key_p)
+do_fix_size(struct maildir_mailbox *mbox, const char *path,
+ struct maildir_size_fix_ctx *ctx)
{
const char *fname, *newpath, *extra, *info, *dir;
struct stat st;
@@ -666,23 +672,26 @@
info = strchr(fname, MAILDIR_INFO_SEP);
if (info == NULL) info = "";
- if (stat(path, &st) < 0) {
- if (errno == ENOENT)
- return 0;
- mail_storage_set_critical(&mbox->storage->storage,
- "stat(%s) failed: %m", path);
- return -1;
+ if (ctx->physical_size == (uoff_t)-1) {
+ if (stat(path, &st) < 0) {
+ if (errno == ENOENT)
+ return 0;
+ mail_storage_set_critical(&mbox->storage->storage,
+ "stat(%s) failed: %m", path);
+ return -1;
+ }
+ ctx->physical_size = st.st_size;
}
newpath = t_strdup_printf("%s/%s,S=%"PRIuUOFF_T"%s", dir,
t_strdup_until(fname, extra),
- (uoff_t)st.st_size, info);
+ ctx->physical_size, info);
if (rename(path, newpath) == 0) {
mail_storage_set_critical(mbox->box.storage,
"Maildir filename has wrong %c value, "
"renamed the file from %s to %s",
- *wrong_key_p, path, newpath);
+ ctx->wrong_key, path, newpath);
return 1;
}
if (errno == ENOENT)
@@ -702,10 +711,9 @@
enum maildir_uidlist_rec_flag flags;
const char *fname;
uoff_t size;
- char wrong_key;
+ struct maildir_size_fix_ctx ctx;
- if (mbox->storage->set->maildir_broken_filename_sizes ||
- pmail->v.istream_opened != NULL) {
+ if (mbox->storage->set->maildir_broken_filename_sizes) {
/* never try to fix sizes in maildir filenames */
return;
}
@@ -715,20 +723,35 @@
if (strchr(fname, MAILDIR_EXTRA_SEP) == NULL)
return;
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.physical_size = (uoff_t)-1;
if (field == MAIL_FETCH_VIRTUAL_SIZE &&
maildir_filename_get_size(fname, MAILDIR_EXTRA_VIRTUAL_SIZE,
&size)) {
- wrong_key = 'W';
+ ctx.wrong_key = 'W';
} else if (field == MAIL_FETCH_PHYSICAL_SIZE &&
maildir_filename_get_size(fname, MAILDIR_EXTRA_FILE_SIZE,
&size)) {
- wrong_key = 'S';
+ ctx.wrong_key = 'S';
} else {
/* the broken size isn't in filename */
return;
}
- (void)maildir_file_do(mbox, mail->uid, do_fix_size, &wrong_key);
+ if (pmail->v.istream_opened != NULL) {
+ /* the mail could be e.g. compressed. get the physical size
+ the slow way by actually reading the mail. */
+ struct istream *input;
+ const struct stat *stp;
+
+ if (mail_get_stream(mail, NULL, NULL, &input) < 0)
+ return;
+ if (i_stream_stat(input, TRUE, &stp) < 0)
+ return;
+ ctx.physical_size = stp->st_size;
+ }
+
+ (void)maildir_file_do(mbox, mail->uid, do_fix_size, &ctx);
}
static void maildir_mail_set_cache_corrupted(struct mail *_mail,
More information about the dovecot-cvs
mailing list