Mercurial > dovecot > original-hg > dovecot-1.2
changeset 101:edc37d046b08 HEAD
Added overwrite_incompatible_index setting. Also we now try to use only
.imap.index-<hostname> and .imap.index index files instead of scanning the
dir for any compatible index. This also fixes (partly) LIST giving \Marked
flag when there's no new mails.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 31 Aug 2002 18:24:00 +0300 |
parents | 867ec80dbf42 |
children | fc3383ac21a9 |
files | dovecot-example.conf src/lib-index/mail-index.c src/lib-storage/index/maildir/maildir-list.c src/master/imap-process.c src/master/settings.c src/master/settings.h |
diffstat | 6 files changed, 116 insertions(+), 59 deletions(-) [+] |
line wrap: on
line diff
--- a/dovecot-example.conf Thu Aug 29 22:21:51 2002 +0300 +++ b/dovecot-example.conf Sat Aug 31 18:24:00 2002 +0300 @@ -98,6 +98,12 @@ # down things as extra stat() needs to be called for each file. #maildir_check_content_changes = no +# If main index file is incompatible with us, should we overwrite it or +# create a new index with another name. Unless you are running Dovecot in +# multiple computers with different architectures accessing the same +# mailboxes (eg. via NFS), it's safe to set this "yes". +#overwrite_incompatible_index = no + # umask to use for mail files and directories #umask = 0077
--- a/src/lib-index/mail-index.c Thu Aug 29 22:21:51 2002 +0300 +++ b/src/lib-index/mail-index.c Sat Aug 31 18:24:00 2002 +0300 @@ -16,9 +16,10 @@ #include <stdlib.h> #include <unistd.h> #include <fcntl.h> -#include <dirent.h> #include <utime.h> +static const char *index_file_prefixes[] = { "data", "hash", "log", NULL }; + static int mmap_update(MailIndex *index) { unsigned int extra; @@ -363,7 +364,28 @@ return TRUE; } -static int read_and_verify_header(int fd, MailIndexHeader *hdr) +static int delete_index(const char *path) +{ + char tmp[1024]; + int i; + + /* main index */ + if (unlink(path) < 0) + return FALSE; + + for (i = 0; index_file_prefixes[i] != NULL; i++) { + i_snprintf(tmp, sizeof(tmp), "%s.%s", + path, index_file_prefixes[i]); + if (unlink(tmp) < 0) + return FALSE; + i++; + } + + return TRUE; +} + +static int read_and_verify_header(int fd, MailIndexHeader *hdr, + int check_version) { /* read the header */ if (lseek(fd, 0, SEEK_SET) != 0) @@ -373,25 +395,37 @@ return FALSE; /* check the compatibility */ - return hdr->compat_data[0] == MAIL_INDEX_VERSION && - hdr->compat_data[1] == MAIL_INDEX_COMPAT_FLAGS && + return hdr->compat_data[1] == MAIL_INDEX_COMPAT_FLAGS && hdr->compat_data[2] == sizeof(unsigned int) && hdr->compat_data[3] == sizeof(time_t) && hdr->compat_data[4] == sizeof(uoff_t) && - hdr->compat_data[5] == MEM_ALIGN_SIZE; + hdr->compat_data[5] == MEM_ALIGN_SIZE && + (!check_version || hdr->compat_data[0] == MAIL_INDEX_VERSION); } -/* Returns TRUE if we're compatible with given index file */ -static int mail_is_compatible_index(const char *path) +/* Returns TRUE if we're compatible with given index file. May delete the + file if it's from older version. */ +static int mail_check_compatible_index(MailIndex *index, const char *path) { MailIndexHeader hdr; int fd, compatible; fd = open(path, O_RDONLY); - if (fd == -1) + if (fd == -1) { + if (errno != ENOENT) + index_set_error(index, "Can't open index %s: %m", path); return FALSE; + } - compatible = read_and_verify_header(fd, &hdr); + compatible = read_and_verify_header(fd, &hdr, FALSE); + if (hdr.compat_data[0] != MAIL_INDEX_VERSION) { + /* version mismatch */ + compatible = FALSE; + if (hdr.compat_data[0] < MAIL_INDEX_VERSION) { + /* of older version, we don't need it anymore */ + (void)delete_index(path); + } + } (void)close(fd); return compatible; @@ -400,41 +434,24 @@ /* Returns a file name of compatible index */ static const char *mail_find_index(MailIndex *index) { - DIR *dir; - struct dirent *d; const char *name; char path[1024]; - unsigned int len; - /* first try the primary name */ - i_snprintf(path, sizeof(path), "%s/" INDEX_FILE_PREFIX, index->dir); - if (mail_is_compatible_index(path)) - return INDEX_FILE_PREFIX; - - dir = opendir(index->dir); - if (dir == NULL) { - /* path doesn't exist */ - index_set_error(index, "Can't open dir %s: %m", - index->dir); - return NULL; - } + hostpid_init(); - len = strlen(INDEX_FILE_PREFIX); - name = NULL; - while ((d = readdir(dir)) != NULL) { - if (strncmp(d->d_name, INDEX_FILE_PREFIX, len) == 0) { - /* index found, check if we're compatible */ - i_snprintf(path, sizeof(path), "%s/%s", - index->dir, d->d_name); - if (mail_is_compatible_index(path)) { - name = t_strdup(d->d_name); - break; - } - } - } + /* first try .imap.index-<hostname> */ + name = t_strconcat(INDEX_FILE_PREFIX "-", my_hostname, NULL); + i_snprintf(path, sizeof(path), "%s/%s", index->dir, name); + if (mail_check_compatible_index(index, path)) + return name; - (void)closedir(dir); - return name; + /* then try the generic .imap.index */ + name = INDEX_FILE_PREFIX; + i_snprintf(path, sizeof(path), "%s/%s", index->dir, name); + if (mail_check_compatible_index(index, path)) + return name; + + return NULL; } static int mail_index_open_init(MailIndex *index, int update_recent, @@ -491,7 +508,7 @@ } /* check the compatibility anyway just to be sure */ - if (!read_and_verify_header(fd, &hdr)) { + if (!read_and_verify_header(fd, &hdr, TRUE)) { index_set_error(index, "Non-compatible index file %s", path); return FALSE; } @@ -647,12 +664,17 @@ return FALSE; } - /* fallback to index.hostname - we require each system to - have a different hostname so it's safe to override - previous index as well */ - hostpid_init(); - i_snprintf(index_path + len, sizeof(index_path)-len, - "-%s", my_hostname); + if (getenv("OVERWRITE_INCOMPATIBLE_INDEX") != NULL) { + /* don't try to support different architectures, + just overwrite the index if it's already there. */ + } else { + /* fallback to .imap.index-hostname - we require each + system to have a different hostname so it's safe to + override previous index as well */ + hostpid_init(); + i_snprintf(index_path + len, sizeof(index_path)-len, + "-%s", my_hostname); + } if (rename(path, index_path) == -1) { index_set_error(index, "rename(%s, %s) failed: %m",
--- a/src/lib-storage/index/maildir/maildir-list.c Thu Aug 29 22:21:51 2002 +0300 +++ b/src/lib-storage/index/maildir/maildir-list.c Sat Aug 31 18:24:00 2002 +0300 @@ -1,6 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" +#include "hostpid.h" #include "unlink-directory.h" #include "imap-match.h" #include "subscription-file/subscription-file.h" @@ -15,20 +16,12 @@ void *context; } FindSubscribedContext; -static MailboxFlags maildir_get_marked_flags(const char *dir) +static MailboxFlags +maildir_get_marked_flags_from(const char *dir, time_t index_stamp) { struct stat st; char path[1024]; - time_t index_stamp, cur_stamp; - - i_snprintf(path, sizeof(path), "%s/" INDEX_FILE_PREFIX, dir); - if (stat(path, &st) == -1) { - /* index file wasn't found. it might be with another name, - but finding it would be too slow. */ - return 0; - } - - index_stamp = st.st_mtime; + time_t cur_stamp; i_snprintf(path, sizeof(path), "%s/cur", dir); if (stat(path, &st) == -1) { @@ -51,6 +44,33 @@ return st.st_mtime <= cur_stamp ? MAILBOX_UNMARKED : MAILBOX_MARKED; } +static MailboxFlags +maildir_get_marked_flags(MailStorage *storage, const char *dir) +{ + const char *path; + struct stat st; + + hostpid_init(); + + /* first try to use .imap.index-hostname */ + path = t_strconcat(dir, "/" INDEX_FILE_PREFIX "-", my_hostname, NULL); + if (stat(path, &st) == -1 && errno == ENOENT) { + /* fallback to .imap.index */ + path = t_strconcat(dir, "/" INDEX_FILE_PREFIX, NULL); + } + + if (stat(path, &st) == -1) { + /* error, or index simply isn't created yet */ + if (errno != ENOENT) { + mail_storage_set_critical(storage, + "stat(%s) failed: %m", path); + } + return 0; + } + + return maildir_get_marked_flags_from(dir, st.st_mtime); +} + int maildir_find_mailboxes(MailStorage *storage, const char *mask, MailboxFunc func, void *context) { @@ -115,7 +135,10 @@ continue; } - flags = maildir_get_marked_flags(path); + if (strcasecmp(fname+1, "INBOX") == 0) + found_inbox = TRUE; + + flags = maildir_get_marked_flags(storage, path); func(storage, fname+1, flags, context); } @@ -140,7 +163,7 @@ i_snprintf(path, sizeof(path), "%s/.%s", storage->dir, name); if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) - flags = maildir_get_marked_flags(path); + flags = maildir_get_marked_flags(storage, path); else flags = MAILBOX_NOSELECT;
--- a/src/master/imap-process.c Thu Aug 29 22:21:51 2002 +0300 +++ b/src/master/imap-process.c Sat Aug 31 18:24:00 2002 +0300 @@ -119,6 +119,8 @@ putenv("COPY_WITH_HARDLINKS=1"); if (set_maildir_check_content_changes) putenv("CHECK_CONTENT_CHANGES=1"); + if (set_overwrite_incompatible_index) + putenv("OVERWRITE_INCOMPATIBLE_INDEX=1"); if (umask(set_umask) != set_umask) i_fatal("Invalid umask: %o", set_umask);
--- a/src/master/settings.c Thu Aug 29 22:21:51 2002 +0300 +++ b/src/master/settings.c Sat Aug 31 18:24:00 2002 +0300 @@ -52,6 +52,8 @@ SET_BOOL,&set_maildir_copy_with_hardlinks }, { "maildir_check_content_changes", SET_BOOL,&set_maildir_check_content_changes }, + { "overwrite_incompatible_index", + SET_BOOL,&set_overwrite_incompatible_index }, { "umask", SET_INT, &set_umask }, { NULL, 0, NULL } @@ -92,6 +94,7 @@ int set_maildir_copy_with_hardlinks = FALSE; int set_maildir_check_content_changes = FALSE; +int set_overwrite_incompatible_index = FALSE; unsigned int set_umask = 0077; /* auth */
--- a/src/master/settings.h Thu Aug 29 22:21:51 2002 +0300 +++ b/src/master/settings.h Sat Aug 31 18:24:00 2002 +0300 @@ -35,6 +35,7 @@ extern int set_maildir_copy_with_hardlinks; extern int set_maildir_check_content_changes; +extern int set_overwrite_incompatible_index; extern unsigned int set_umask; /* auth */