# HG changeset patch # User Timo Sirainen # Date 1248665835 14400 # Node ID 5a4875e92829dd73645331a776a3e751bd540a45 # Parent 51aee73e49a5f90b9fa4ee6ddcdfc7318a7b814a maildir uidlist: Added better next_uid error tracking. diff -r 51aee73e49a5 -r 5a4875e92829 src/lib-storage/index/maildir/maildir-uidlist.c --- a/src/lib-storage/index/maildir/maildir-uidlist.c Sun Jul 26 23:36:12 2009 -0400 +++ b/src/lib-storage/index/maildir/maildir-uidlist.c Sun Jul 26 23:37:15 2009 -0400 @@ -83,6 +83,7 @@ unsigned int version; unsigned int uid_validity, next_uid, prev_read_uid, last_seen_uid; + unsigned int hdr_next_uid; unsigned int read_records_count, read_line_count; uoff_t last_read_offset; string_t *hdr_extensions; @@ -563,7 +564,7 @@ static int maildir_uidlist_read_header(struct maildir_uidlist *uidlist, struct istream *input) { - unsigned int uid_validity, next_uid; + unsigned int uid_validity = 0, next_uid = 0; string_t *ext_hdr; const char *line; char key; @@ -591,13 +592,6 @@ "Corrupted header (version 1)"); return 0; } - if (uid_validity == uidlist->uid_validity && - next_uid < uidlist->next_uid) { - maildir_uidlist_set_corrupted(uidlist, - "next_uid was lowered (v1, %u -> %u)", - uidlist->next_uid, next_uid); - return 0; - } break; case UIDLIST_VERSION: ext_hdr = uidlist->hdr_extensions; @@ -640,8 +634,17 @@ return 0; } + if (uid_validity == uidlist->uid_validity && + next_uid < uidlist->hdr_next_uid) { + maildir_uidlist_set_corrupted(uidlist, + "next_uid header was lowered (%u -> %u)", + uidlist->hdr_next_uid, next_uid); + return 0; + } + uidlist->uid_validity = uid_validity; uidlist->next_uid = next_uid; + uidlist->hdr_next_uid = next_uid; return 1; } @@ -662,7 +665,7 @@ { struct mail_storage *storage = uidlist->ibox->box.storage; const char *line; - unsigned int orig_next_uid; + uint32_t orig_next_uid, orig_uid_validity; struct istream *input; struct stat st; uoff_t last_read_offset; @@ -721,6 +724,7 @@ input = i_stream_create_fd(fd, 4096, FALSE); i_stream_seek(input, last_read_offset); + orig_uid_validity = uidlist->uid_validity; orig_next_uid = uidlist->next_uid; ret = input->v_offset != 0 ? 1 : maildir_uidlist_read_header(uidlist, input); @@ -754,11 +758,13 @@ } if (uidlist->next_uid <= uidlist->prev_read_uid) uidlist->next_uid = uidlist->prev_read_uid + 1; - if (ret > 0 && uidlist->next_uid < orig_next_uid) { + if (ret > 0 && uidlist->uid_validity != orig_uid_validity) { + uidlist->recreate = TRUE; + } else if (ret > 0 && uidlist->next_uid < orig_next_uid) { mail_storage_set_critical(storage, - "%s: next_uid was lowered (%u -> %u)", + "%s: next_uid was lowered (%u -> %u, hdr=%u)", uidlist->path, orig_next_uid, - uidlist->next_uid); + uidlist->next_uid, uidlist->hdr_next_uid); uidlist->recreate = TRUE; uidlist->next_uid = orig_next_uid; }