[dovecot-cvs] dovecot/src/lib-storage/index/maildir maildir-sync.c, 1.77, 1.77.2.1 maildir-uidlist.c, 1.51, 1.51.2.1 maildir-uidlist.h, 1.17, 1.17.2.1

cras at dovecot.org cras at dovecot.org
Sat Jun 17 16:55:31 EEST 2006


Update of /var/lib/cvs/dovecot/src/lib-storage/index/maildir
In directory talvi:/tmp/cvs-serv2463

Modified Files:
      Tag: branch_1_0
	maildir-sync.c maildir-uidlist.c maildir-uidlist.h 
Log Message:
Don't go fixing duplicate maildir filenames without properly checking that
they really are such.



Index: maildir-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/maildir/maildir-sync.c,v
retrieving revision 1.77
retrieving revision 1.77.2.1
diff -u -d -r1.77 -r1.77.2.1
--- maildir-sync.c	2 May 2006 11:11:05 -0000	1.77
+++ maildir-sync.c	17 Jun 2006 13:55:28 -0000	1.77.2.1
@@ -611,15 +611,41 @@
 		(void)maildir_sync_index_finish(&ctx->index_sync_ctx, TRUE);
 }
 
-static int maildir_fix_duplicate(struct maildir_mailbox *mbox, const char *dir,
-				 const char *old_fname)
+static int maildir_fix_duplicate(struct maildir_sync_context *ctx,
+				 const char *dir, const char *old_fname)
 {
+	struct maildir_mailbox *mbox = ctx->mbox;
+	const char *existing_fname, *existing_path;
 	const char *new_fname, *old_path, *new_path;
+	struct stat st, st2;
 	int ret = 0;
 
+	existing_fname =
+		maildir_uidlist_sync_get_full_filename(ctx->uidlist_sync_ctx,
+						       old_fname);
+	i_assert(existing_fname != NULL);
+
 	t_push();
 
+	existing_path = t_strconcat(dir, "/", existing_fname, NULL);
 	old_path = t_strconcat(dir, "/", old_fname, NULL);
+
+	if (stat(existing_path, &st) < 0 ||
+	    stat(old_path, &st2) < 0) {
+		/* most likely the files just don't exist anymore.
+		   don't really care about other errors much. */
+		t_pop();
+		return 0;
+	}
+	if (st.st_ino == st2.st_ino && CMP_DEV_T(st.st_dev, st2.st_dev)) {
+		/* files are the same. this means either a race condition
+		   between stat() calls, or someone has started link()ing the
+		   files. either way there's no data loss if we just leave it
+		   there. */
+		t_pop();
+		return 0;
+	}
+
 	new_fname = maildir_generate_tmp_filename(&ioloop_timeval);
 	new_path = t_strconcat(mbox->path, "/new/", new_fname, NULL);
 
@@ -724,8 +750,7 @@
 				break;
 
 			/* possibly duplicate - try fixing it */
-			if (maildir_fix_duplicate(ctx->mbox,
-						  dir, dp->d_name) < 0) {
+			if (maildir_fix_duplicate(ctx, dir, dp->d_name) < 0) {
 				ret = -1;
 				break;
 			}

Index: maildir-uidlist.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/maildir/maildir-uidlist.c,v
retrieving revision 1.51
retrieving revision 1.51.2.1
diff -u -d -r1.51 -r1.51.2.1
--- maildir-uidlist.c	2 May 2006 11:11:05 -0000	1.51
+++ maildir-uidlist.c	17 Jun 2006 13:55:28 -0000	1.51.2.1
@@ -804,6 +804,16 @@
 	return 1;
 }
 
+const char *
+maildir_uidlist_sync_get_full_filename(struct maildir_uidlist_sync_ctx *ctx,
+				       const char *filename)
+{
+	struct maildir_uidlist_rec *rec;
+
+	rec = hash_lookup(ctx->files, filename);
+	return rec == NULL ? NULL : rec->filename;
+}
+
 static int maildir_time_cmp(const void *p1, const void *p2)
 {
 	const struct maildir_uidlist_rec *const *rec1 = p1, *const *rec2 = p2;

Index: maildir-uidlist.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/maildir/maildir-uidlist.h,v
retrieving revision 1.17
retrieving revision 1.17.2.1
diff -u -d -r1.17 -r1.17.2.1
--- maildir-uidlist.h	2 May 2006 11:11:05 -0000	1.17
+++ maildir-uidlist.h	17 Jun 2006 13:55:28 -0000	1.17.2.1
@@ -49,6 +49,9 @@
 int maildir_uidlist_sync_next(struct maildir_uidlist_sync_ctx *ctx,
 			      const char *filename,
 			      enum maildir_uidlist_rec_flag flags);
+const char *
+maildir_uidlist_sync_get_full_filename(struct maildir_uidlist_sync_ctx *ctx,
+				       const char *filename);
 void maildir_uidlist_sync_finish(struct maildir_uidlist_sync_ctx *ctx);
 int maildir_uidlist_sync_deinit(struct maildir_uidlist_sync_ctx **ctx);
 



More information about the dovecot-cvs mailing list