dovecot-2.2: lib-storage: MAILBOX_LIST_ITER_SKIP_ALIASES now ski...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Sep 26 18:01:29 EEST 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/eff1d11ce14b
changeset: 15134:eff1d11ce14b
user: Timo Sirainen <tss at iki.fi>
date: Tue Sep 18 18:40:17 2012 +0300
description:
lib-storage: MAILBOX_LIST_ITER_SKIP_ALIASES now skips also "alias symlinks"
An "alias symlink" is a symlink that points to the same directory. These can
safely be skipped when iterating through all mails in all mailboxes (unlike
other symlinks that may point to external storages).
diffstat:
src/lib-storage/list/mailbox-list-fs-iter.c | 6 ++++
src/lib-storage/list/mailbox-list-maildir-iter.c | 5 +++
src/lib-storage/mailbox-guid-cache.c | 1 +
src/lib-storage/mailbox-list-private.h | 3 ++
src/lib-storage/mailbox-list.c | 33 ++++++++++++++++++++++++
src/lib-storage/mailbox-list.h | 4 ++-
6 files changed, 51 insertions(+), 1 deletions(-)
diffs (112 lines):
diff -r 8cec3b4c43ca -r eff1d11ce14b src/lib-storage/list/mailbox-list-fs-iter.c
--- a/src/lib-storage/list/mailbox-list-fs-iter.c Fri Sep 14 20:51:02 2012 +0300
+++ b/src/lib-storage/list/mailbox-list-fs-iter.c Tue Sep 18 18:40:17 2012 +0300
@@ -183,6 +183,12 @@
/* mailbox doesn't match any patterns, we don't care about it */
return 0;
}
+ if ((ctx->ctx.flags & MAILBOX_LIST_ITER_SKIP_ALIASES) != 0) {
+ ret = mailbox_list_dirent_is_alias_symlink(ctx->ctx.list,
+ dir_path, d);
+ if (ret != 0)
+ return ret < 0 ? -1 : 0;
+ }
ret = ctx->ctx.list->v.
get_mailbox_flags(ctx->ctx.list, dir_path, d->d_name,
mailbox_list_get_file_type(d), &info_flags);
diff -r 8cec3b4c43ca -r eff1d11ce14b src/lib-storage/list/mailbox-list-maildir-iter.c
--- a/src/lib-storage/list/mailbox-list-maildir-iter.c Fri Sep 14 20:51:02 2012 +0300
+++ b/src/lib-storage/list/mailbox-list-maildir-iter.c Tue Sep 18 18:40:17 2012 +0300
@@ -323,6 +323,11 @@
if (maildir_delete_trash_dir(ctx, fname))
return 0;
+ if ((ctx->ctx.flags & MAILBOX_LIST_ITER_SKIP_ALIASES) != 0) {
+ ret = mailbox_list_dirent_is_alias_symlink(list, ctx->dir, d);
+ if (ret != 0)
+ return ret < 0 ? -1 : 0;
+ }
T_BEGIN {
ret = list->v.get_mailbox_flags(list, ctx->dir, fname,
mailbox_list_get_file_type(d), &flags);
diff -r 8cec3b4c43ca -r eff1d11ce14b src/lib-storage/mailbox-guid-cache.c
--- a/src/lib-storage/mailbox-guid-cache.c Fri Sep 14 20:51:02 2012 +0300
+++ b/src/lib-storage/mailbox-guid-cache.c Tue Sep 18 18:40:17 2012 +0300
@@ -56,6 +56,7 @@
list->guid_cache_errors = FALSE;
ctx = mailbox_list_iter_init(list, "*",
+ MAILBOX_LIST_ITER_SKIP_ALIASES |
MAILBOX_LIST_ITER_NO_AUTO_BOXES);
while ((info = mailbox_list_iter_next(ctx)) != NULL) {
if ((info->flags &
diff -r 8cec3b4c43ca -r eff1d11ce14b src/lib-storage/mailbox-list-private.h
--- a/src/lib-storage/mailbox-list-private.h Fri Sep 14 20:51:02 2012 +0300
+++ b/src/lib-storage/mailbox-list-private.h Tue Sep 18 18:40:17 2012 +0300
@@ -192,6 +192,9 @@
bool mailbox_list_name_is_too_large(const char *name, char sep);
enum mailbox_list_file_type mailbox_list_get_file_type(const struct dirent *d);
+int mailbox_list_dirent_is_alias_symlink(struct mailbox_list *list,
+ const char *dir_path,
+ const struct dirent *d);
bool mailbox_list_try_get_absolute_path(struct mailbox_list *list,
const char **name);
int mailbox_list_create_missing_index_dir(struct mailbox_list *list,
diff -r 8cec3b4c43ca -r eff1d11ce14b src/lib-storage/mailbox-list.c
--- a/src/lib-storage/mailbox-list.c Fri Sep 14 20:51:02 2012 +0300
+++ b/src/lib-storage/mailbox-list.c Tue Sep 18 18:40:17 2012 +0300
@@ -1282,6 +1282,39 @@
return type;
}
+int mailbox_list_dirent_is_alias_symlink(struct mailbox_list *list,
+ const char *dir_path,
+ const struct dirent *d)
+{
+ struct stat st;
+ int ret;
+
+ if (mailbox_list_get_file_type(d) == MAILBOX_LIST_FILE_TYPE_SYMLINK)
+ return 1;
+
+ T_BEGIN {
+ const char *path, *readlink;
+
+ path = t_strconcat(dir_path, "/", d->d_name, NULL);
+ if (lstat(path, &st) < 0) {
+ mailbox_list_set_critical(list,
+ "lstat(%s) failed: %m", path);
+ ret = -1;
+ } else if (!S_ISLNK(st.st_mode)) {
+ ret = 0;
+ } else if (t_readlink(path, &linkpath) < 0) {
+ i_error("readlink(%s) failed: %m", path);
+ ret = -1;
+ } else {
+ /* it's an alias only if it points to the same
+ directory */
+ ret = strchr(linkpath, '/') == NULL ? 1 : 0;
+ }
+ } T_END;
+ return ret;
+}
+
+
static bool
mailbox_list_try_get_home_path(struct mailbox_list *list, const char **name)
{
diff -r 8cec3b4c43ca -r eff1d11ce14b src/lib-storage/mailbox-list.h
--- a/src/lib-storage/mailbox-list.h Fri Sep 14 20:51:02 2012 +0300
+++ b/src/lib-storage/mailbox-list.h Tue Sep 18 18:40:17 2012 +0300
@@ -64,7 +64,9 @@
physically exist */
MAILBOX_LIST_ITER_NO_AUTO_BOXES = 0x000004,
- /* For mailbox_list_iter_init_namespaces(): Skip namespaces that
+ /* Skip all kinds of mailbox aliases. This typically includes symlinks
+ that point to the same directory. Also when iterating with
+ mailbox_list_iter_init_namespaces() skip namespaces that
have alias_for set. */
MAILBOX_LIST_ITER_SKIP_ALIASES = 0x000008,
/* For mailbox_list_iter_init_namespaces(): '*' in a pattern doesn't
More information about the dovecot-cvs
mailing list