Mercurial > dovecot > original-hg > dovecot-1.2
changeset 8580:1efbbf9d0841 HEAD
dbox: In Maildir migrations preserve POP3 UIDL from dovecot-uidlist.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Fri, 19 Dec 2008 16:24:19 +0200 |
parents | 3b16e400fa8c |
children | a920044c8775 |
files | src/lib-storage/index/dbox/dbox-file-maildir.c src/lib-storage/index/dbox/dbox-file.c src/lib-storage/index/dbox/dbox-index.c src/lib-storage/index/dbox/dbox-index.h src/lib-storage/index/dbox/dbox-sync-rebuild.c |
diffstat | 5 files changed, 78 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/dbox/dbox-file-maildir.c Fri Dec 19 13:03:51 2008 +0200 +++ b/src/lib-storage/index/dbox/dbox-file-maildir.c Fri Dec 19 16:24:19 2008 +0200 @@ -6,6 +6,7 @@ #include "dbox-storage.h" #include "../maildir/maildir-storage.h" #include "../maildir/maildir-filename.h" +#include "dbox-index.h" #include "dbox-file.h" #include "dbox-file-maildir.h" @@ -35,6 +36,29 @@ return str_c(str); } +static const char * +dbox_file_maildir_get_old_metadata(struct dbox_file *file, char key) +{ + struct dbox_index_record *rec; + const char *p, *end; + + rec = dbox_index_record_lookup(file->mbox->dbox_index, file->file_id); + if (rec == NULL) + return NULL; + + for (p = strchr(rec->data, ' '); *p != '\0'; p++) { + if (*p == ' ') { + if (p[1] == key) { + end = strchr(p+2, ' '); + return t_strdup_until(p+2, end); + } + if (p[1] == ':') + break; + } + } + return NULL; +} + const char *dbox_file_maildir_metadata_get(struct dbox_file *file, enum dbox_metadata_key key) { @@ -77,8 +101,12 @@ MAILDIR_EXTRA_VIRTUAL_SIZE, &size)) value = dec2str(size); + else + value = dbox_file_maildir_get_old_metadata(file, 'W'); break; case DBOX_METADATA_POP3_UIDL: + value = dbox_file_maildir_get_old_metadata(file, 'P'); + break; case DBOX_METADATA_EXPUNGED: case DBOX_METADATA_EXT_REF: case DBOX_METADATA_SPACE:
--- a/src/lib-storage/index/dbox/dbox-file.c Fri Dec 19 13:03:51 2008 +0200 +++ b/src/lib-storage/index/dbox/dbox-file.c Fri Dec 19 16:24:19 2008 +0200 @@ -141,10 +141,11 @@ rec = dbox_index_record_lookup(mbox->dbox_index, file_id); if (rec != NULL && rec->status == DBOX_INDEX_FILE_STATUS_MAILDIR) { - /* data contains <uid> <filename> */ + /* data contains <uid> [<fields>] :<filename> */ *maildir_file_r = TRUE; - p = strchr(rec->data, ' '); - return i_strdup_printf("%s", p + 1); + p = strstr(rec->data, " :"); + i_assert(p != NULL); + return i_strdup_printf("%s", p + 2); } return i_strdup_printf(DBOX_MAIL_FILE_MULTI_FORMAT, file_id);
--- a/src/lib-storage/index/dbox/dbox-index.c Fri Dec 19 13:03:51 2008 +0200 +++ b/src/lib-storage/index/dbox/dbox-index.c Fri Dec 19 16:24:19 2008 +0200 @@ -90,7 +90,7 @@ static int dbox_index_parse_maildir(struct dbox_index *index, const char *line, struct dbox_index_record *rec) { - char *p; + char *p, *p2; unsigned long uid; if (*line++ != ' ') @@ -100,7 +100,14 @@ if (*p++ != ' ' || *p == '\0' || uid == 0 || uid >= (uint32_t)-1) return -1; - rec->data = p_strdup(index->record_data_pool, line); + p2 = strstr(p, " :"); + if (p2 != NULL) + rec->data = p_strdup(index->record_data_pool, line); + else { + /* convert to new format */ + rec->data = p_strconcat(index->record_data_pool, + t_strdup_until(line, p), ":", p, NULL); + } return 0; } @@ -762,6 +769,28 @@ array_append(&ctx->files, &file, 1); } +static const char *dbox_file_maildir_get_index_data(struct dbox_file *file) +{ + const char *pop3_uidl = NULL, *const *changes; + unsigned int i, count; + + changes = array_get(&file->metadata_changes, &count); + for (i = 0; i < count; i++) { + if (*changes[i] == DBOX_METADATA_POP3_UIDL) { + pop3_uidl = changes[i] + 1; + break; + } + } + + if (pop3_uidl == NULL) { + return t_strdup_printf("%u :%s", file->last_append_uid, + file->fname); + } else { + return t_strdup_printf("%u P%s :%s", file->last_append_uid, + pop3_uidl, file->fname); + } +} + static int dbox_index_append_commit_new(struct dbox_index_append_context *ctx, struct dbox_file *file, string_t *str) { @@ -808,9 +837,8 @@ rec.file_offset = ctx->output_offset + str_len(str); if (file->maildir_file) { rec.status = DBOX_INDEX_FILE_STATUS_MAILDIR; - rec.data = p_strdup_printf(ctx->index->record_data_pool, - "%u %s", file->last_append_uid, - file->fname); + rec.data = p_strdup(ctx->index->record_data_pool, + dbox_file_maildir_get_index_data(file)); } else { rec.status = dbox_file_can_append(file, 0) ?
--- a/src/lib-storage/index/dbox/dbox-index.h Fri Dec 19 13:03:51 2008 +0200 +++ b/src/lib-storage/index/dbox/dbox-index.h Fri Dec 19 16:24:19 2008 +0200 @@ -43,7 +43,9 @@ DBOX_INDEX_FILE_STATUS_UNLINKED = 'U', /* File is a maildir file. Status-specific data contains - <uid> <filename>. */ + old: <uid> <filename> + new: <uid> [<maildir extra field>] :<filename> + */ DBOX_INDEX_FILE_STATUS_MAILDIR = 'M' };
--- a/src/lib-storage/index/dbox/dbox-sync-rebuild.c Fri Dec 19 13:03:51 2008 +0200 +++ b/src/lib-storage/index/dbox/dbox-sync-rebuild.c Fri Dec 19 16:24:19 2008 +0200 @@ -143,7 +143,7 @@ { uint32_t seq, uid; uoff_t physical_size; - const char *path; + const char *path, *value; bool expunged; int ret; @@ -190,6 +190,15 @@ i_warning("%s: Ignoring broken file (metadata)", path); return 0; } + if (file->maildir_file) { + /* preserve POP3 UIDL */ + value = maildir_uidlist_lookup_ext(ctx->maildir_uidlist, uid, + MAILDIR_UIDLIST_REC_EXT_POP3_UIDL); + if (value != NULL) { + dbox_file_metadata_set(file, DBOX_METADATA_POP3_UIDL, + value); + } + } if (!expunged) { mail_index_append(ctx->trans, uid, &seq); file->maildir_append_seq = seq;