From: Timo Sirainen Date: Sun, 21 Mar 2010 15:08:36 +0000 (+0200) Subject: dbox: Don't write save-date to metadata, use file's ctime as fallback. X-Git-Tag: 2.0.beta4~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b8d314c6355009ad0b9e332b6acecdfac5cc8891;p=thirdparty%2Fdovecot%2Fcore.git dbox: Don't write save-date to metadata, use file's ctime as fallback. Copying must change the save-date, so it couldn't work well in metadata. --HG-- branch : HEAD --- diff --git a/src/lib-storage/index/dbox-common/dbox-file.c b/src/lib-storage/index/dbox-common/dbox-file.c index a1845dbc1c..05687d85a4 100644 --- a/src/lib-storage/index/dbox-common/dbox-file.c +++ b/src/lib-storage/index/dbox-common/dbox-file.c @@ -219,6 +219,42 @@ int dbox_file_open_primary(struct dbox_file *file, bool *notfound_r) return dbox_file_open_full(file, FALSE, notfound_r); } +int dbox_file_stat(struct dbox_file *file, struct stat *st_r) +{ + const char *path; + bool alt = FALSE; + + if (dbox_file_is_open(file)) { + if (fstat(file->fd, st_r) < 0) { + mail_storage_set_critical(&file->storage->storage, + "fstat(%s) failed: %m", file->cur_path); + return -1; + } + return 0; + } + + /* try the primary path first */ + path = file->primary_path; + while (stat(path, st_r) < 0) { + if (errno != ENOENT) { + mail_storage_set_critical(&file->storage->storage, + "stat(%s) failed: %m", path); + return -1; + } + + if (file->alt_path == NULL || alt) { + /* not found */ + return -1; + } + + /* try the alternative path */ + path = file->alt_path; + alt = TRUE; + } + file->cur_path = path; + return 0; +} + int dbox_file_header_write(struct dbox_file *file, struct ostream *output) { string_t *hdr; diff --git a/src/lib-storage/index/dbox-common/dbox-file.h b/src/lib-storage/index/dbox-common/dbox-file.h index 2607f01cd6..8fefa95c95 100644 --- a/src/lib-storage/index/dbox-common/dbox-file.h +++ b/src/lib-storage/index/dbox-common/dbox-file.h @@ -39,8 +39,6 @@ enum dbox_metadata_key { DBOX_METADATA_POP3_UIDL = 'P', /* Received UNIX timestamp in hex */ DBOX_METADATA_RECEIVED_TIME = 'R', - /* Saved UNIX timestamp in hex */ - DBOX_METADATA_SAVE_TIME = 'S', /* Physical message size in hex. Necessary only if it differs from the dbox_message_header.message_size_hex, for example because the message is compressed. */ @@ -59,6 +57,7 @@ enum dbox_metadata_key { DBOX_METADATA_OLDV1_EXPUNGED = 'E', DBOX_METADATA_OLDV1_FLAGS = 'F', DBOX_METADATA_OLDV1_KEYWORDS = 'K', + DBOX_METADATA_OLDV1_SAVE_TIME = 'S', DBOX_METADATA_OLDV1_SPACE = ' ' }; @@ -134,6 +133,10 @@ int dbox_file_open_primary(struct dbox_file *file, bool *notfound_r); /* Close the file handle from the file, but don't free it. */ void dbox_file_close(struct dbox_file *file); +/* fstat() or stat() the file. If file is already deleted, fails with + errno=ENOENT. */ +int dbox_file_stat(struct dbox_file *file, struct stat *st_r); + /* Try to lock the dbox file. Returns 1 if ok, 0 if already locked by someone else, -1 if error. */ int dbox_file_try_lock(struct dbox_file *file); diff --git a/src/lib-storage/index/dbox-common/dbox-mail.c b/src/lib-storage/index/dbox-common/dbox-mail.c index 938da26e11..4f249df535 100644 --- a/src/lib-storage/index/dbox-common/dbox-mail.c +++ b/src/lib-storage/index/dbox-common/dbox-mail.c @@ -140,29 +140,17 @@ int dbox_mail_get_save_date(struct mail *_mail, time_t *date_r) struct index_mail_data *data = &mail->imail.data; struct dbox_file *file; struct stat st; - const char *value; if (index_mail_get_save_date(_mail, date_r) == 0) return 0; - if (dbox_mail_metadata_read(mail, &file) < 0) + mail->imail.mail.stats_fstat_lookup_count++; + if (dbox_file_stat(file, &st) < 0) { + if (errno == ENOENT) + mail_set_expunged(_mail); return -1; - - value = dbox_file_metadata_get(file, DBOX_METADATA_SAVE_TIME); - data->save_date = value == NULL ? 0 : strtoul(value, NULL, 16); - - if (data->save_date == 0) { - /* missing / corrupted save time - use the file's ctime */ - i_assert(dbox_file_is_open(file)); - mail->imail.mail.stats_fstat_lookup_count++; - if (fstat(file->fd, &st) < 0) { - mail_storage_set_critical(_mail->box->storage, - "fstat(%s) failed: %m", file->cur_path); - return -1; - } - data->save_date = st.st_ctime; } - *date_r = data->save_date; + *date_r = data->save_date = st.st_ctime; return 0; } diff --git a/src/lib-storage/index/dbox-common/dbox-save.c b/src/lib-storage/index/dbox-common/dbox-save.c index 836c5a87f7..b210bfe874 100644 --- a/src/lib-storage/index/dbox-common/dbox-save.c +++ b/src/lib-storage/index/dbox-common/dbox-save.c @@ -125,8 +125,6 @@ void dbox_save_write_metadata(struct mail_save_context *ctx, } str_printfa(str, "%c%lx\n", DBOX_METADATA_RECEIVED_TIME, (unsigned long)ctx->received_date); - str_printfa(str, "%c%lx\n", DBOX_METADATA_SAVE_TIME, - (unsigned long)ioloop_time); if (mail_get_virtual_size(ctx->dest_mail, &vsize) < 0) i_unreached(); str_printfa(str, "%c%llx\n", DBOX_METADATA_VIRTUAL_SIZE, diff --git a/src/lib-storage/index/dbox-single/sdbox-save.c b/src/lib-storage/index/dbox-single/sdbox-save.c index 70afc590da..ca1d2a0bd1 100644 --- a/src/lib-storage/index/dbox-single/sdbox-save.c +++ b/src/lib-storage/index/dbox-single/sdbox-save.c @@ -129,6 +129,14 @@ static int dbox_save_finish_write(struct mail_save_context *_ctx) if (ctx->ctx.dbox_output == NULL) return -1; + if (_ctx->save_date != (time_t)-1) { + /* we can't change ctime, but we can add the date to cache */ + struct index_mail *mail = (struct index_mail *)_ctx->dest_mail; + uint32_t t = _ctx->save_date; + + index_mail_cache_add(mail, MAIL_CACHE_SAVE_DATE, &t, sizeof(t)); + } + index_mail_cache_parse_deinit(_ctx->dest_mail, _ctx->received_date, !ctx->ctx.failed);