Mercurial > dovecot > core-2.2
changeset 15652:6e5adbf30e35
lib-fs: Added flags to iteration, and FS_ITER_FLAG_DIRS as the first flag.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Mon, 21 Jan 2013 11:40:38 +0200 |
parents | 33830df49f59 |
children | df8fd01f355c |
files | src/lib-fs/fs-api-private.h src/lib-fs/fs-api.c src/lib-fs/fs-api.h src/lib-fs/fs-posix.c src/lib-fs/fs-sis-queue.c src/lib-fs/fs-sis.c src/lib-fs/fs-test.c |
diffstat | 7 files changed, 46 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- 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;
--- 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)
--- 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. */
--- 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;
--- 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 = {
--- 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 = {
--- 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]);