dovecot-2.2: lib-fs: Added flags to iteration, and FS_ITER_FLAG_...

dovecot at dovecot.org dovecot at dovecot.org
Mon Jan 21 11:40:49 EET 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/6e5adbf30e35
changeset: 15652:6e5adbf30e35
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Jan 21 11:40:38 2013 +0200
description:
lib-fs: Added flags to iteration, and FS_ITER_FLAG_DIRS as the first flag.

diffstat:

 src/lib-fs/fs-api-private.h |   4 +++-
 src/lib-fs/fs-api.c         |   5 +++--
 src/lib-fs/fs-api.h         |  10 ++++++++--
 src/lib-fs/fs-posix.c       |  30 +++++++++++++++++++++---------
 src/lib-fs/fs-sis-queue.c   |   5 +++--
 src/lib-fs/fs-sis.c         |   4 ++--
 src/lib-fs/fs-test.c        |   9 ++++++---
 7 files changed, 46 insertions(+), 21 deletions(-)

diffs (212 lines):

diff -r 33830df49f59 -r 6e5adbf30e35 src/lib-fs/fs-api-private.h
--- a/src/lib-fs/fs-api-private.h	Thu Jan 17 09:00:54 2013 +0200
+++ b/src/lib-fs/fs-api-private.h	Mon Jan 21 11:40:38 2013 +0200
@@ -45,7 +45,8 @@
 	int (*rename)(struct fs_file *src, struct fs_file *dest);
 	int (*delete_file)(struct fs_file *file);
 
-	struct fs_iter *(*iter_init)(struct fs *fs, const char *path);
+	struct fs_iter *(*iter_init)(struct fs *fs, const char *path,
+				     enum fs_iter_flags flags);
 	const char *(*iter_next)(struct fs_iter *iter);
 	int (*iter_deinit)(struct fs_iter *iter);
 };
@@ -75,6 +76,7 @@
 
 struct fs_iter {
 	struct fs *fs;
+	enum fs_iter_flags flags;
 };
 
 extern const struct fs fs_class_posix;
diff -r 33830df49f59 -r 6e5adbf30e35 src/lib-fs/fs-api.c
--- a/src/lib-fs/fs-api.c	Thu Jan 17 09:00:54 2013 +0200
+++ b/src/lib-fs/fs-api.c	Mon Jan 21 11:40:38 2013 +0200
@@ -359,9 +359,10 @@
 	return file->fs->v.delete_file(file);
 }
 
-struct fs_iter *fs_iter_init(struct fs *fs, const char *path)
+struct fs_iter *
+fs_iter_init(struct fs *fs, const char *path, enum fs_iter_flags flags)
 {
-	return fs->v.iter_init(fs, path);
+	return fs->v.iter_init(fs, path, flags);
 }
 
 int fs_iter_deinit(struct fs_iter **_iter)
diff -r 33830df49f59 -r 6e5adbf30e35 src/lib-fs/fs-api.h
--- a/src/lib-fs/fs-api.h	Thu Jan 17 09:00:54 2013 +0200
+++ b/src/lib-fs/fs-api.h	Mon Jan 21 11:40:38 2013 +0200
@@ -52,6 +52,11 @@
 	FS_OPEN_FLAG_ASYNC		= 0x20
 };
 
+enum fs_iter_flags {
+	/* Iterate only directories, not files */
+	FS_ITER_FLAG_DIRS	= 0x01
+};
+
 struct fs_settings {
 	/* Dovecot instance's base_dir */
 	const char *base_dir;
@@ -168,10 +173,11 @@
 int fs_lock(struct fs_file *file, unsigned int secs, struct fs_lock **lock_r);
 void fs_unlock(struct fs_lock **lock);
 
-/* Iterate through all files (but not directories) in the given directory.
+/* Iterate through all files or directories in the given directory.
    Doesn't recurse to child directories. It's not an error to iterate a
    nonexistent directory. */
-struct fs_iter *fs_iter_init(struct fs *fs, const char *path);
+struct fs_iter *
+fs_iter_init(struct fs *fs, const char *path, enum fs_iter_flags flags);
 /* Returns 0 if ok, -1 if iteration failed. */
 int fs_iter_deinit(struct fs_iter **iter);
 /* Returns the next filename. */
diff -r 33830df49f59 -r 6e5adbf30e35 src/lib-fs/fs-posix.c
--- a/src/lib-fs/fs-posix.c	Thu Jan 17 09:00:54 2013 +0200
+++ b/src/lib-fs/fs-posix.c	Mon Jan 21 11:40:38 2013 +0200
@@ -644,12 +644,14 @@
 	return 0;
 }
 
-static struct fs_iter *fs_posix_iter_init(struct fs *fs, const char *path)
+static struct fs_iter *
+fs_posix_iter_init(struct fs *fs, const char *path, enum fs_iter_flags flags)
 {
 	struct posix_fs_iter *iter;
 
 	iter = i_new(struct posix_fs_iter, 1);
 	iter->iter.fs = fs;
+	iter->iter.flags = flags;
 	iter->path = i_strdup(path);
 	iter->dir = opendir(path);
 	if (iter->dir == NULL && errno != ENOENT) {
@@ -659,18 +661,20 @@
 	return &iter->iter;
 }
 
-static bool fs_posix_iter_want(const char *dir, const char *fname)
+static bool fs_posix_iter_want(struct posix_fs_iter *iter, const char *fname)
 {
 	bool ret;
 
 	T_BEGIN {
-		const char *path = t_strdup_printf("%s/%s", dir, fname);
+		const char *path = t_strdup_printf("%s/%s", iter->path, fname);
 		struct stat st;
 
 		if (stat(path, &st) < 0)
 			ret = FALSE;
+		else if (!S_ISDIR(st.st_mode))
+			ret = (iter->iter.flags & FS_ITER_FLAG_DIRS) == 0;
 		else
-			ret = !S_ISDIR(st.st_mode);
+			ret = (iter->iter.flags & FS_ITER_FLAG_DIRS) != 0;
 	} T_END;
 	return ret;
 }
@@ -684,24 +688,32 @@
 		return NULL;
 
 	errno = 0;
-	while ((d = readdir(iter->dir)) != NULL) {
+	for (; (d = readdir(iter->dir)) != NULL; errno = 0) {
+		if (strcmp(d->d_name, ".") == 0 ||
+		    strcmp(d->d_name, "..") == 0)
+			continue;
 #ifdef HAVE_DIRENT_D_TYPE
 		switch (d->d_type) {
 		case DT_UNKNOWN:
-			if (!fs_posix_iter_want(iter->path, d->d_name))
+			if (!fs_posix_iter_want(iter, d->d_name))
 				break;
 			/* fall through */
 		case DT_REG:
 		case DT_LNK:
-			return d->d_name;
+			if ((iter->iter.flags & FS_ITER_FLAG_DIRS) == 0)
+				return d->d_name;
+			break;
+		case DT_DIR:
+			if ((iter->iter.flags & FS_ITER_FLAG_DIRS) != 0)
+				return d->d_name;
+			break;
 		default:
 			break;
 		}
 #else
-		if (fs_posix_iter_want(iter->path, d->d_name))
+		if (fs_posix_iter_want(iter, d->d_name))
 			return d->d_name;
 #endif
-		errno = 0;
 	}
 	if (errno != 0) {
 		iter->err = errno;
diff -r 33830df49f59 -r 6e5adbf30e35 src/lib-fs/fs-sis-queue.c
--- a/src/lib-fs/fs-sis-queue.c	Thu Jan 17 09:00:54 2013 +0200
+++ b/src/lib-fs/fs-sis-queue.c	Mon Jan 21 11:40:38 2013 +0200
@@ -328,11 +328,12 @@
 }
 
 static struct fs_iter *
-fs_sis_queue_iter_init(struct fs *_fs, const char *path)
+fs_sis_queue_iter_init(struct fs *_fs, const char *path,
+		       enum fs_iter_flags flags)
 {
 	struct sis_queue_fs *fs = (struct sis_queue_fs *)_fs;
 
-	return fs_iter_init(fs->super, path);
+	return fs_iter_init(fs->super, path, flags);
 }
 
 const struct fs fs_class_sis_queue = {
diff -r 33830df49f59 -r 6e5adbf30e35 src/lib-fs/fs-sis.c
--- a/src/lib-fs/fs-sis.c	Thu Jan 17 09:00:54 2013 +0200
+++ b/src/lib-fs/fs-sis.c	Mon Jan 21 11:40:38 2013 +0200
@@ -463,11 +463,11 @@
 }
 
 static struct fs_iter *
-fs_sis_iter_init(struct fs *_fs, const char *path)
+fs_sis_iter_init(struct fs *_fs, const char *path, enum fs_iter_flags flags)
 {
 	struct sis_fs *fs = (struct sis_fs *)_fs;
 
-	return fs_iter_init(fs->super, path);
+	return fs_iter_init(fs->super, path, flags);
 }
 
 const struct fs fs_class_sis = {
diff -r 33830df49f59 -r 6e5adbf30e35 src/lib-fs/fs-test.c
--- a/src/lib-fs/fs-test.c	Thu Jan 17 09:00:54 2013 +0200
+++ b/src/lib-fs/fs-test.c	Mon Jan 21 11:40:38 2013 +0200
@@ -105,12 +105,13 @@
 	fs_file_deinit(&file);
 }
 
-static void fs_test_file_iter(struct fs *fs, const char *path)
+static void
+fs_test_file_iter(struct fs *fs, const char *path, enum fs_iter_flags flags)
 {
 	struct fs_iter *iter;
 	const char *fname;
 
-	iter = fs_iter_init(fs, path);
+	iter = fs_iter_init(fs, path, flags);
 	while ((fname = fs_iter_next(iter)) != NULL)
 		printf("%s\n", fname);
 	if (fs_iter_deinit(&iter) < 0) {
@@ -144,7 +145,9 @@
 	else if (strcmp(argv[3], "delete") == 0)
 		fs_test_file_delete(fs, argv[4]);
 	else if (strcmp(argv[3], "iter") == 0)
-		fs_test_file_iter(fs, argv[4]);
+		fs_test_file_iter(fs, argv[4], 0);
+	else if (strcmp(argv[3], "iter-dir") == 0)
+		fs_test_file_iter(fs, argv[4], FS_ITER_FLAG_DIRS);
 	else
 		i_fatal("Unknown command: %s", argv[3]);
 


More information about the dovecot-cvs mailing list