]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Include microseconds in maildir filename base.
authorTimo Sirainen <tss@iki.fi>
Wed, 19 Feb 2003 21:32:21 +0000 (23:32 +0200)
committerTimo Sirainen <tss@iki.fi>
Wed, 19 Feb 2003 21:32:21 +0000 (23:32 +0200)
--HG--
branch : HEAD

src/lib-storage/index/maildir/maildir-copy.c
src/lib-storage/index/maildir/maildir-save.c
src/lib-storage/index/maildir/maildir-storage.h

index 2393db019104d3f4b9f8dae95cf7aac0c8edb030..0dfc2218853c13c68492baf49d684153f7abcf3a 100644 (file)
@@ -1,6 +1,7 @@
 /* Copyright (C) 2002 Timo Sirainen */
 
 #include "lib.h"
+#include "ioloop.h"
 #include "maildir-index.h"
 #include "maildir-storage.h"
 #include "mail-custom-flags.h"
@@ -57,8 +58,9 @@ static int hardlink_messageset(struct messageset_context *ctx,
                t_push();
                src_path = t_strconcat(index->mailbox_path, "/cur/",
                                       fname, NULL);
-               dest_fname = t_strconcat(maildir_filename_set_flags(
-                               maildir_generate_tmp_filename(), flags), NULL);
+
+               dest_fname = maildir_generate_tmp_filename(&ioloop_timeval);
+               dest_fname = maildir_filename_set_flags(dest_fname, flags);
                dest_path = t_strconcat(dest->index->mailbox_path, "/new/",
                                        dest_fname, NULL);
 
index 4c8130530444f649b4fe9f0f595c735817f5b086..1f1b4852c1f862737e027241e27448f253c35072 100644 (file)
@@ -11,6 +11,9 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <utime.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <time.h>
 
 struct mail_filename {
        struct mail_filename *next;
@@ -27,38 +30,58 @@ struct mail_save_context {
        struct mail_filename *files;
 };
 
-const char *maildir_generate_tmp_filename(void)
+const char *maildir_generate_tmp_filename(const struct timeval *tv)
 {
        static unsigned int create_count = 0;
 
        hostpid_init();
-
-       return t_strdup_printf("%s.P%sQ%u.%s", dec2str(ioloop_time),
-                              my_pid, create_count++, my_hostname);
+       return t_strdup_printf("%s.P%sQ%uM%s.%s",
+                              dec2str(tv->tv_sec), my_pid, create_count++,
+                              dec2str(tv->tv_usec), my_hostname);
 }
 
 static int maildir_create_tmp(struct mail_storage *storage, const char *dir,
                              const char **fname)
 {
-       const char *path;
+       const char *path, *tmp_fname;
+       struct stat st;
+       struct timeval *tv, tv_now;
+       pool_t pool;
        int fd;
 
-       *fname = maildir_generate_tmp_filename();
+       tv = &ioloop_timeval;
+       pool = pool_alloconly_create("maildir_tmp", 4096);
+       for (;;) {
+               p_clear(pool);
+               tmp_fname = maildir_generate_tmp_filename(tv);
+
+               path = p_strconcat(pool, dir, "/", tmp_fname, NULL);
+               if (stat(path, &st) < 0 && errno == ENOENT) {
+                       /* doesn't exist */
+                       fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0600);
+                       if (fd != -1 || errno != EEXIST)
+                               break;
+               }
+
+               /* wait and try again - very unlikely */
+               sleep(2);
+               tv = &tv_now;
+               if (gettimeofday(&tv_now, NULL) < 0)
+                       i_fatal("gettimeofday(): %m");
+       }
 
-       path = t_strconcat(dir, "/", *fname, NULL);
-       fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0660);
+       *fname = t_strdup(tmp_fname);
        if (fd == -1) {
                if (errno == ENOSPC) {
                        mail_storage_set_error(storage,
-                                              "Not enough disk space");
+                               "Not enough disk space");
                } else {
-                       /* don't bother checking if it was because file
-                          existed - if that happens it's itself an error. */
-                       mail_storage_set_critical(storage, "Can't create file "
-                                                 "%s: %m", path);
+                       mail_storage_set_critical(storage,
+                               "Can't create file %s: %m", path);
                }
        }
 
+       pool_unref(pool);
        return fd;
 }
 
@@ -166,7 +189,8 @@ int maildir_storage_save_next(struct mail_save_context *ctx,
        /* now, if we want to be able to rollback the whole append session,
           we'll just store the name of this temp file and move it later
           into new/ */
-       dest_fname = maildir_filename_set_flags(fname, mail_flags);
+       dest_fname = mail_flags == 0 ? fname :
+               maildir_filename_set_flags(fname, mail_flags);
        if (ctx->transaction) {
                struct mail_filename *mf;
 
index 4c57f5316d2800b2dbb93926e06739f02bf3589a..1913f32283a0f4ca5d42149aad53616d13fc79eb 100644 (file)
@@ -25,7 +25,7 @@ maildir_list_mailbox_next(struct mailbox_list_context *ctx);
 int maildir_expunge_locked(struct index_mailbox *ibox, int notify);
 
 /* Return new filename base to save into tmp/ */
-const char *maildir_generate_tmp_filename(void);
+const char *maildir_generate_tmp_filename(const struct timeval *tv);
 
 const char *maildir_get_path(struct mail_storage *storage, const char *name);