]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
7d50b32a | 2 | |
11c3a366 | 3 | #include <errno.h> |
48d7c648 | 4 | #include <sys/types.h> |
ca78ad1d ZJS |
5 | #include <sys/stat.h> |
6 | #include <unistd.h> | |
7d50b32a | 7 | |
48d7c648 | 8 | #include "dirent-util.h" |
66855de7 | 9 | #include "errno-util.h" |
7d50b32a | 10 | #include "glob-util.h" |
11c3a366 | 11 | #include "macro.h" |
48d7c648 | 12 | #include "path-util.h" |
7d50b32a | 13 | #include "strv.h" |
7d50b32a | 14 | |
46dcfbbd | 15 | static void closedir_wrapper(void* v) { |
1fe10174 ZJS |
16 | (void) closedir(v); |
17 | } | |
18 | ||
48d7c648 | 19 | int safe_glob(const char *path, int flags, glob_t *pglob) { |
7d50b32a LP |
20 | int k; |
21 | ||
48d7c648 ZJS |
22 | /* We want to set GLOB_ALTDIRFUNC ourselves, don't allow it to be set. */ |
23 | assert(!(flags & GLOB_ALTDIRFUNC)); | |
24 | ||
25 | if (!pglob->gl_closedir) | |
46dcfbbd | 26 | pglob->gl_closedir = closedir_wrapper; |
48d7c648 ZJS |
27 | if (!pglob->gl_readdir) |
28 | pglob->gl_readdir = (struct dirent *(*)(void *)) readdir_no_dot; | |
29 | if (!pglob->gl_opendir) | |
30 | pglob->gl_opendir = (void *(*)(const char *)) opendir; | |
31 | if (!pglob->gl_lstat) | |
32 | pglob->gl_lstat = lstat; | |
33 | if (!pglob->gl_stat) | |
34 | pglob->gl_stat = stat; | |
7d50b32a LP |
35 | |
36 | errno = 0; | |
48d7c648 | 37 | k = glob(path, flags | GLOB_ALTDIRFUNC, NULL, pglob); |
7d50b32a | 38 | if (k == GLOB_NOMATCH) |
48d7c648 | 39 | return -ENOENT; |
7d50b32a LP |
40 | if (k == GLOB_NOSPACE) |
41 | return -ENOMEM; | |
42 | if (k != 0) | |
66855de7 | 43 | return errno_or_else(EIO); |
48d7c648 ZJS |
44 | if (strv_isempty(pglob->gl_pathv)) |
45 | return -ENOENT; | |
7d50b32a | 46 | |
48d7c648 | 47 | return 0; |
7d50b32a LP |
48 | } |
49 | ||
48d7c648 | 50 | int glob_exists(const char *path) { |
7d50b32a LP |
51 | _cleanup_globfree_ glob_t g = {}; |
52 | int k; | |
7d50b32a | 53 | |
48d7c648 | 54 | assert(path); |
7d50b32a | 55 | |
48d7c648 ZJS |
56 | k = safe_glob(path, GLOB_NOSORT|GLOB_BRACE, &g); |
57 | if (k == -ENOENT) | |
58 | return false; | |
59 | if (k < 0) | |
60 | return k; | |
61 | return true; | |
62 | } | |
63 | ||
544e146b | 64 | int glob_extend(char ***strv, const char *path, int flags) { |
48d7c648 ZJS |
65 | _cleanup_globfree_ glob_t g = {}; |
66 | int k; | |
7d50b32a | 67 | |
544e146b | 68 | k = safe_glob(path, GLOB_NOSORT|GLOB_BRACE|flags, &g); |
48d7c648 ZJS |
69 | if (k < 0) |
70 | return k; | |
7d50b32a | 71 | |
48d7c648 | 72 | return strv_extend_strv(strv, g.gl_pathv, false); |
7d50b32a | 73 | } |