From 9bcfef421b420061f7342e5517d226aa9f58dbdd Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Tue, 8 May 2001 22:05:00 +0000 Subject: Walk a hierarchy using the "/subfolders/" convention and call a callback * e-path.c (e_path_find_folders): Walk a hierarchy using the "/subfolders/" convention and call a callback for each folder found. svn path=/trunk/; revision=9721 --- e-util/ChangeLog | 6 ++++ e-util/e-path.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- e-util/e-path.h | 12 +++++++- 3 files changed, 106 insertions(+), 2 deletions(-) diff --git a/e-util/ChangeLog b/e-util/ChangeLog index ab679f24f4..abf4fcc7ee 100644 --- a/e-util/ChangeLog +++ b/e-util/ChangeLog @@ -1,3 +1,9 @@ +2001-05-08 Dan Winship + + * e-path.c (e_path_find_folders): Walk a hierarchy using the + "/subfolders/" convention and call a callback for each folder + found. + 2001-05-01 Dan Winship * e-msgport.c (e_mutex_assert_locked): Debugging routine. (Only diff --git a/e-util/e-path.c b/e-util/e-path.c index 0728c94013..22b370b436 100644 --- a/e-util/e-path.c +++ b/e-util/e-path.c @@ -21,7 +21,9 @@ #include +#include #include +#include #include #include "e-path.h" @@ -37,7 +39,8 @@ * This converts the "virtual" path @path into an expanded form that * allows a given name to refer to both a file and a directory. The * expanded path will have a "subfolders" directory inserted between - * each path component. + * each path component. If the path ends with "/", the returned + * physical path will end with "/subfolders" * * If @prefix is non-%NULL, it will be prepended to the returned path. * @@ -117,3 +120,88 @@ e_path_to_physical (const char *prefix, const char *vpath) return ppath; } + + +static gboolean +find_folders_recursive (const char *physical_path, const char *path, + EPathFindFoldersCallback callback, gpointer data) +{ + DIR *dir; + char *subfolder_directory_path; + gboolean ok; + + if (*path) { + if (!callback (physical_path, path, data)) + return FALSE; + + subfolder_directory_path = g_strdup_printf ("%s/%s", physical_path, SUBFOLDER_DIR_NAME); + } else { + /* On the top level, we have no folders and, + * consequently, no subfolder directory. + */ + + subfolder_directory_path = g_strdup (physical_path); + } + + /* Now scan the subfolders and load them. */ + dir = opendir (subfolder_directory_path); + if (dir == NULL) { + g_free (subfolder_directory_path); + return TRUE; + } + + ok = TRUE; + while (ok) { + struct stat file_stat; + struct dirent *dirent; + char *file_path; + char *new_path; + + dirent = readdir (dir); + if (dirent == NULL) + break; + + if (strcmp (dirent->d_name, ".") == 0 || strcmp (dirent->d_name, "..") == 0) + continue; + + file_path = g_strdup_printf ("%s/%s", subfolder_directory_path, + dirent->d_name); + + if (stat (file_path, &file_stat) < 0 || + ! S_ISDIR (file_stat.st_mode)) { + g_free (file_path); + continue; + } + + new_path = g_strdup_printf ("%s/%s", path, dirent->d_name); + + ok = find_folders_recursive (file_path, new_path, callback, data); + + g_free (file_path); + g_free (new_path); + } + + closedir (dir); + g_free (subfolder_directory_path); + + return ok; +} + +/** + * e_path_find_folders: + * @prefix: directory to start from + * @callback: Callback to invoke on each folder + * @data: Data for @callback + * + * Walks the folder tree starting at @prefix and calls @callback + * on each folder. + * + * Return value: %TRUE on success, %FALSE if an error occurs at any point + **/ +gboolean +e_path_find_folders (const char *prefix, + EPathFindFoldersCallback callback, + gpointer data) +{ + return find_folders_recursive (prefix, "", callback, data); +} diff --git a/e-util/e-path.h b/e-util/e-path.h index 808b666d9e..50a3507363 100644 --- a/e-util/e-path.h +++ b/e-util/e-path.h @@ -21,6 +21,16 @@ #ifndef __E_PATH__ #define __E_PATH__ -char *e_path_to_physical (const char *prefix, const char *vpath); +#include + +typedef gboolean (*EPathFindFoldersCallback) (const char *physical_path, + const char *path, + gpointer user_data); + +char * e_path_to_physical (const char *prefix, const char *vpath); + +gboolean e_path_find_folders (const char *prefix, + EPathFindFoldersCallback callback, + gpointer data); #endif /* __E_PATH__ */ -- cgit v1.2.3