Mercurial > dovecot > core-2.2
changeset 4208:67f6d3afa5a5 HEAD
Fixes
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 20 Apr 2006 19:12:29 +0300 |
parents | 96f3908b7c34 |
children | ca14a26d28b4 |
files | src/lib-storage/index/dbox/dbox-sync-expunge.c src/lib-storage/index/dbox/dbox-sync.c src/lib-storage/index/dbox/dbox-uidlist.c |
diffstat | 3 files changed, 72 insertions(+), 31 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-storage/index/dbox/dbox-sync-expunge.c Thu Apr 20 19:04:04 2006 +0300 +++ b/src/lib-storage/index/dbox/dbox-sync-expunge.c Thu Apr 20 19:12:29 2006 +0300 @@ -109,8 +109,9 @@ if (ret <= 0) { if (ret == 0) { mail_storage_set_critical(STORAGE(mbox->storage), - "%s: Expunging lost UID %u from file", - mbox->path, first_nonexpunged_uid); + "%s: Expunging lost UID %u from file %u", + mbox->path, first_nonexpunged_uid, + orig_entry->file_seq); } return ret; } @@ -428,13 +429,45 @@ return 0; } +static int +uidlist_entry_remove_uids(struct dbox_sync_context *ctx, + const struct dbox_sync_file_entry *sync_entry) +{ + struct dbox_uidlist_entry *entry; + const struct dbox_sync_rec *recs; + uint32_t uid; + unsigned int i, count, seq; + + entry = dbox_uidlist_entry_lookup(ctx->mbox->uidlist, + sync_entry->file_seq); + if (entry == NULL) + return 0; + + recs = array_get(&sync_entry->sync_recs, &count); + for (i = 0; i < count; i++) { + for (seq = recs[i].seq1; seq <= recs[i].seq2; seq++) { + if (mail_index_lookup_uid(ctx->sync_view, + seq, &uid) < 0) { + mail_storage_set_index_error(&ctx->mbox->ibox); + return -1; + } + seq_range_array_remove(&entry->uid_list, uid); + } + } + if (array_count(&entry->uid_list) == 0) { + dbox_uidlist_sync_unlink(ctx->uidlist_sync_ctx, + entry->file_seq); + } + dbox_uidlist_sync_set_modified(ctx->uidlist_sync_ctx); + return 0; +} + int dbox_sync_expunge(struct dbox_sync_context *ctx, const struct dbox_sync_file_entry *sync_entry, unsigned int sync_idx) { struct dbox_mailbox *mbox = ctx->mbox; const struct dbox_sync_rec *sync_rec; - struct dbox_uidlist_entry *entry; struct dotlock *dotlock; const char *path; int ret; @@ -485,22 +518,5 @@ } /* remove UIDs from the uidlist entry */ - entry = dbox_uidlist_entry_lookup(mbox->uidlist, sync_entry->file_seq); - if (entry != NULL) { - const struct dbox_sync_rec *recs; - unsigned int i, count, seq; - - recs = array_get(&sync_entry->sync_recs, &count); - for (i = 0; i < count; i++) { - for (seq = recs[i].seq1; seq <= recs[i].seq2; seq++) - seq_range_array_remove(&entry->uid_list, seq); - } - if (array_count(&entry->uid_list) == 0) { - dbox_uidlist_sync_unlink(ctx->uidlist_sync_ctx, - entry->file_seq); - } - dbox_uidlist_sync_set_modified(ctx->uidlist_sync_ctx); - } - - return 0; + return uidlist_entry_remove_uids(ctx, sync_entry); }
--- a/src/lib-storage/index/dbox/dbox-sync.c Thu Apr 20 19:04:04 2006 +0300 +++ b/src/lib-storage/index/dbox/dbox-sync.c Thu Apr 20 19:12:29 2006 +0300 @@ -328,7 +328,9 @@ for (i = 0; i < count; i++) { switch (sync_recs[i].type) { case MAIL_INDEX_SYNC_TYPE_EXPUNGE: + t_push(); ret = dbox_sync_expunge(ctx, entry, i); + t_pop(); if (ret > 0) { /* handled expunging by copying the file. while at it, also wrote all the other sync
--- a/src/lib-storage/index/dbox/dbox-uidlist.c Thu Apr 20 19:04:04 2006 +0300 +++ b/src/lib-storage/index/dbox/dbox-uidlist.c Thu Apr 20 19:12:29 2006 +0300 @@ -221,6 +221,7 @@ { struct dbox_uidlist_entry *entry; struct seq_range range; + const char *error = NULL; uint32_t digit; int ret; @@ -239,7 +240,9 @@ if (range.seq1 == 0) { if (digit <= range.seq2) { /* broken */ - array_clear(&entry->uid_list); + error = t_strdup_printf("UID %u <= %u", + digit, + range.seq2); break; } range.seq1 = digit; @@ -247,7 +250,9 @@ if (*line == ',' || *line == ' ') { if (range.seq1 > digit) { /* broken */ - array_clear(&entry->uid_list); + error = t_strdup_printf("UID %u > %u", + range.seq1, + digit); break; } range.seq2 = digit; @@ -266,9 +271,17 @@ } } - if (*line != ' ' || array_count(&entry->uid_list) == 0) { + if (error == NULL) { + if (*line != ' ') { + error = *line == '\0' ? "File sequence missing" : + "Expecting space after UID list"; + } else if (array_count(&entry->uid_list) == 0) + error = "UID list missing"; + } + + if (error != NULL) { mail_storage_set_critical(STORAGE(uidlist->mbox->storage), - "%s: Corrupted entry", uidlist->path); + "%s: Corrupted entry: %s", uidlist->path, error); t_pop(); return FALSE; } @@ -285,7 +298,8 @@ if (*line != ' ') { mail_storage_set_critical(STORAGE(uidlist->mbox->storage), - "%s: Corrupted entry", uidlist->path); + "%s: Corrupted entry: Expecting space after timestamp", + uidlist->path); t_pop(); return FALSE; @@ -860,7 +874,7 @@ static int dbox_file_append(struct dbox_uidlist_append_ctx *ctx, const char *path, struct dbox_uidlist_entry *entry, - struct stat *st, struct dbox_file **file_r) + struct stat *st, struct dbox_file **file_r, bool existing) { struct dbox_mailbox *mbox = ctx->uidlist->mbox; struct dbox_file *file; @@ -868,8 +882,14 @@ *file_r = NULL; - fd = open(path, O_CREAT | O_RDWR, 0600); + fd = open(path, O_RDWR | (existing ? 0 : O_CREAT), 0600); if (fd == -1) { + if (errno == ENOENT && existing) { + /* the file was unlinked just now, update its size + so that we don't get back here. */ + entry->file_size = (uoff_t)-1; + return 0; + } mail_storage_set_critical(STORAGE(mbox->storage), "open(%s) failed: %m", path); return -1; @@ -919,7 +939,7 @@ static int dbox_file_append_lock(struct dbox_uidlist_append_ctx *ctx, string_t *path, uint32_t *file_seq_r, struct dbox_uidlist_entry **entry_r, - struct dotlock **dotlock_r) + struct dotlock **dotlock_r, bool *existing_r) { struct dbox_mailbox *mbox = ctx->uidlist->mbox; struct dbox_uidlist_entry *const *entries; @@ -930,11 +950,13 @@ entries = array_get(&ctx->uidlist->entries, &count); for (i = 0;; i++) { file_seq = 0; + *existing_r = FALSE; for (; i < count; i++) { if (DBOX_CAN_APPEND(ctx, entries[i]->create_time, entries[i]->file_size) && !dbox_uidlist_files_lookup(ctx, entries[i]->file_seq)) { + *existing_r = TRUE; file_seq = entries[i]->file_seq; break; } @@ -983,6 +1005,7 @@ unsigned int i, count; struct stat st; uint32_t file_seq; + bool existing; int ret; /* check first from already opened files */ @@ -1006,10 +1029,10 @@ if (dotlock != NULL) file_dotlock_delete(&dotlock); if (dbox_file_append_lock(ctx, path, &file_seq, - &entry, &dotlock) < 0) + &entry, &dotlock, &existing) < 0) return -1; } while ((ret = dbox_file_append(ctx, str_c(path), entry, - &st, &file)) == 0); + &st, &file, existing)) == 0); if (ret < 0) { file_dotlock_delete(&dotlock);