diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2017-04-25 23:44:34 -0400 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2017-04-27 13:20:08 -0400 |
commit | 48d7c64805757d6c631a4ea2e973652f59058ac3 (patch) | |
tree | 684f8059f38e683782c850ff5b633011457226d4 /src/basic/glob-util.c | |
parent | 1f0f4f3bfd05fd416e3e2dea10ad225b276a6ef7 (diff) |
basic: add readdir_no_dot and safe_glob functions
safe_glob filters out "." and "..".
This converts all users of glob_extend() and glob_exists() to safe_glob.
Diffstat (limited to 'src/basic/glob-util.c')
-rw-r--r-- | src/basic/glob-util.c | 64 |
1 files changed, 40 insertions, 24 deletions
diff --git a/src/basic/glob-util.c b/src/basic/glob-util.c index 007198c269..f611c42e4c 100644 --- a/src/basic/glob-util.c +++ b/src/basic/glob-util.c @@ -17,54 +17,70 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ +#include <dirent.h> #include <errno.h> #include <glob.h> +#include <sys/types.h> +#include "dirent-util.h" #include "glob-util.h" #include "macro.h" +#include "path-util.h" #include "strv.h" -int glob_exists(const char *path) { - _cleanup_globfree_ glob_t g = {}; +int safe_glob(const char *path, int flags, glob_t *pglob) { int k; - assert(path); + /* We want to set GLOB_ALTDIRFUNC ourselves, don't allow it to be set. */ + assert(!(flags & GLOB_ALTDIRFUNC)); + + if (!pglob->gl_closedir) + pglob->gl_closedir = (void (*)(void *)) closedir; + if (!pglob->gl_readdir) + pglob->gl_readdir = (struct dirent *(*)(void *)) readdir_no_dot; + if (!pglob->gl_opendir) + pglob->gl_opendir = (void *(*)(const char *)) opendir; + if (!pglob->gl_lstat) + pglob->gl_lstat = lstat; + if (!pglob->gl_stat) + pglob->gl_stat = stat; errno = 0; - k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g); + k = glob(path, flags | GLOB_ALTDIRFUNC, NULL, pglob); if (k == GLOB_NOMATCH) - return 0; + return -ENOENT; if (k == GLOB_NOSPACE) return -ENOMEM; if (k != 0) return errno > 0 ? -errno : -EIO; + if (strv_isempty(pglob->gl_pathv)) + return -ENOENT; - return !strv_isempty(g.gl_pathv); + return 0; } -int glob_extend(char ***strv, const char *path) { +int glob_exists(const char *path) { _cleanup_globfree_ glob_t g = {}; int k; - char **p; - errno = 0; - k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g); + assert(path); - if (k == GLOB_NOMATCH) - return -ENOENT; - if (k == GLOB_NOSPACE) - return -ENOMEM; - if (k != 0) - return errno > 0 ? -errno : -EIO; - if (strv_isempty(g.gl_pathv)) - return -ENOENT; + k = safe_glob(path, GLOB_NOSORT|GLOB_BRACE, &g); + if (k == -ENOENT) + return false; + if (k < 0) + return k; + return true; +} + +int glob_extend(char ***strv, const char *path) { + _cleanup_globfree_ glob_t g = {}; + int k; - STRV_FOREACH(p, g.gl_pathv) { - k = strv_extend(strv, *p); - if (k < 0) - return k; - } + k = safe_glob(path, GLOB_NOSORT|GLOB_BRACE, &g); + if (k < 0) + return k; - return 0; + return strv_extend_strv(strv, g.gl_pathv, false); } |