+int fs_foreach_dir (const char *base_dir, /* {{{ */
+ int (*callback) (const char *base_dir, const char *entry, void *),
+ void *user_data)
+{
+ DIR *dh;
+ struct dirent *entry;
+ int status = 0;
+
+ if (callback == NULL)
+ return (EINVAL);
+
+ dh = opendir (base_dir);
+ if (dh == NULL)
+ return (errno);
+
+ while ((entry = readdir (dh)) != NULL)
+ {
+ struct stat statbuf;
+ char abspath[PATH_MAX + 1];
+
+ if (entry->d_name[0] == '.')
+ continue;
+
+ snprintf (abspath, sizeof (abspath), "%s/%s", base_dir, entry->d_name);
+ abspath[sizeof (abspath) - 1] = 0;
+
+ memset (&statbuf, 0, sizeof (statbuf));
+
+ status = stat (abspath, &statbuf);
+ if (status != 0)
+ continue;
+
+ if (!S_ISDIR (statbuf.st_mode))
+ continue;
+
+ status = (*callback) (base_dir, entry->d_name, user_data);
+ if (status != 0)
+ break;
+ } /* while (readdir) */
+
+ closedir (dh);
+ return (status);
+} /* }}} int fs_foreach_dir */
+
+int fs_foreach_file (const char *base_dir, /* {{{ */
+ int (*callback) (const char *base_dir, const char *entry, void *),
+ void *user_data)
+{
+ DIR *dh;
+ struct dirent *entry;
+ int status = 0;
+
+ if (callback == NULL)
+ return (EINVAL);
+
+ dh = opendir (base_dir);
+ if (dh == NULL)
+ return (errno);
+
+ while ((entry = readdir (dh)) != NULL)
+ {
+ struct stat statbuf;
+ char abspath[PATH_MAX + 1];
+
+ if (entry->d_name[0] == '.')
+ continue;
+
+ snprintf (abspath, sizeof (abspath), "%s/%s", base_dir, entry->d_name);
+ abspath[sizeof (abspath) - 1] = 0;
+
+ memset (&statbuf, 0, sizeof (statbuf));
+
+ status = stat (abspath, &statbuf);
+ if (status != 0)
+ continue;
+
+ if (!S_ISREG (statbuf.st_mode))
+ continue;
+
+ status = (*callback) (base_dir, entry->d_name, user_data);
+ if (status != 0)
+ break;
+ } /* while (readdir) */
+
+ closedir (dh);
+ return (status);
+} /* }}} int fs_foreach_file */
+