[dovecot-cvs] dovecot/src/lib-storage/index/maildir maildir-sync.c,
1.77, 1.78 maildir-uidlist.c, 1.51, 1.52 maildir-uidlist.h,
1.17, 1.18
cras at dovecot.org
cras at dovecot.org
Sat Jun 17 16:55:33 EEST 2006
Update of /var/lib/cvs/dovecot/src/lib-storage/index/maildir
In directory talvi:/tmp/cvs-serv16727
Modified Files:
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.78
diff -u -d -r1.77 -r1.78
--- maildir-sync.c 2 May 2006 11:11:05 -0000 1.77
+++ maildir-sync.c 17 Jun 2006 13:55:30 -0000 1.78
@@ -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.52
diff -u -d -r1.51 -r1.52
--- maildir-uidlist.c 2 May 2006 11:11:05 -0000 1.51
+++ maildir-uidlist.c 17 Jun 2006 13:55:30 -0000 1.52
@@ -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.18
diff -u -d -r1.17 -r1.18
--- maildir-uidlist.h 2 May 2006 11:11:05 -0000 1.17
+++ maildir-uidlist.h 17 Jun 2006 13:55:30 -0000 1.18
@@ -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