Mercurial > dovecot > original-hg > dovecot-1.2
comparison src/lib-storage/index/maildir/maildir-sync.c @ 4397:5cbabd4ccd9c HEAD
Don't go fixing duplicate maildir filenames without properly checking that
they really are such.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 17 Jun 2006 16:55:30 +0300 |
parents | 3c8b191b0019 |
children | 14b10f7ea70e |
comparison
equal
deleted
inserted
replaced
4396:208194b3742a | 4397:5cbabd4ccd9c |
---|---|
609 (void)maildir_uidlist_sync_deinit(&ctx->uidlist_sync_ctx); | 609 (void)maildir_uidlist_sync_deinit(&ctx->uidlist_sync_ctx); |
610 if (ctx->index_sync_ctx != NULL) | 610 if (ctx->index_sync_ctx != NULL) |
611 (void)maildir_sync_index_finish(&ctx->index_sync_ctx, TRUE); | 611 (void)maildir_sync_index_finish(&ctx->index_sync_ctx, TRUE); |
612 } | 612 } |
613 | 613 |
614 static int maildir_fix_duplicate(struct maildir_mailbox *mbox, const char *dir, | 614 static int maildir_fix_duplicate(struct maildir_sync_context *ctx, |
615 const char *old_fname) | 615 const char *dir, const char *old_fname) |
616 { | 616 { |
617 struct maildir_mailbox *mbox = ctx->mbox; | |
618 const char *existing_fname, *existing_path; | |
617 const char *new_fname, *old_path, *new_path; | 619 const char *new_fname, *old_path, *new_path; |
620 struct stat st, st2; | |
618 int ret = 0; | 621 int ret = 0; |
619 | 622 |
623 existing_fname = | |
624 maildir_uidlist_sync_get_full_filename(ctx->uidlist_sync_ctx, | |
625 old_fname); | |
626 i_assert(existing_fname != NULL); | |
627 | |
620 t_push(); | 628 t_push(); |
621 | 629 |
630 existing_path = t_strconcat(dir, "/", existing_fname, NULL); | |
622 old_path = t_strconcat(dir, "/", old_fname, NULL); | 631 old_path = t_strconcat(dir, "/", old_fname, NULL); |
632 | |
633 if (stat(existing_path, &st) < 0 || | |
634 stat(old_path, &st2) < 0) { | |
635 /* most likely the files just don't exist anymore. | |
636 don't really care about other errors much. */ | |
637 t_pop(); | |
638 return 0; | |
639 } | |
640 if (st.st_ino == st2.st_ino && CMP_DEV_T(st.st_dev, st2.st_dev)) { | |
641 /* files are the same. this means either a race condition | |
642 between stat() calls, or someone has started link()ing the | |
643 files. either way there's no data loss if we just leave it | |
644 there. */ | |
645 t_pop(); | |
646 return 0; | |
647 } | |
648 | |
623 new_fname = maildir_generate_tmp_filename(&ioloop_timeval); | 649 new_fname = maildir_generate_tmp_filename(&ioloop_timeval); |
624 new_path = t_strconcat(mbox->path, "/new/", new_fname, NULL); | 650 new_path = t_strconcat(mbox->path, "/new/", new_fname, NULL); |
625 | 651 |
626 if (rename(old_path, new_path) == 0) { | 652 if (rename(old_path, new_path) == 0) { |
627 i_warning("Fixed duplicate in %s: %s -> %s", | 653 i_warning("Fixed duplicate in %s: %s -> %s", |
722 if (ret <= 0) { | 748 if (ret <= 0) { |
723 if (ret < 0) | 749 if (ret < 0) |
724 break; | 750 break; |
725 | 751 |
726 /* possibly duplicate - try fixing it */ | 752 /* possibly duplicate - try fixing it */ |
727 if (maildir_fix_duplicate(ctx->mbox, | 753 if (maildir_fix_duplicate(ctx, dir, dp->d_name) < 0) { |
728 dir, dp->d_name) < 0) { | |
729 ret = -1; | 754 ret = -1; |
730 break; | 755 break; |
731 } | 756 } |
732 } | 757 } |
733 } | 758 } |