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