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 }