]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/glob-util.c
tree-wide: drop license boilerplate
[thirdparty/systemd.git] / src / basic / glob-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright 2010 Lennart Poettering
6 ***/
7
8 #include <dirent.h>
9 #include <errno.h>
10 #include <glob.h>
11 #include <sys/types.h>
12
13 #include "dirent-util.h"
14 #include "glob-util.h"
15 #include "macro.h"
16 #include "path-util.h"
17 #include "strv.h"
18
19 static void closedir_wrapper(void* v) {
20 (void) closedir(v);
21 }
22
23 int safe_glob(const char *path, int flags, glob_t *pglob) {
24 int k;
25
26 /* We want to set GLOB_ALTDIRFUNC ourselves, don't allow it to be set. */
27 assert(!(flags & GLOB_ALTDIRFUNC));
28
29 if (!pglob->gl_closedir)
30 pglob->gl_closedir = closedir_wrapper;
31 if (!pglob->gl_readdir)
32 pglob->gl_readdir = (struct dirent *(*)(void *)) readdir_no_dot;
33 if (!pglob->gl_opendir)
34 pglob->gl_opendir = (void *(*)(const char *)) opendir;
35 if (!pglob->gl_lstat)
36 pglob->gl_lstat = lstat;
37 if (!pglob->gl_stat)
38 pglob->gl_stat = stat;
39
40 errno = 0;
41 k = glob(path, flags | GLOB_ALTDIRFUNC, NULL, pglob);
42
43 if (k == GLOB_NOMATCH)
44 return -ENOENT;
45 if (k == GLOB_NOSPACE)
46 return -ENOMEM;
47 if (k != 0)
48 return errno > 0 ? -errno : -EIO;
49 if (strv_isempty(pglob->gl_pathv))
50 return -ENOENT;
51
52 return 0;
53 }
54
55 int glob_exists(const char *path) {
56 _cleanup_globfree_ glob_t g = {};
57 int k;
58
59 assert(path);
60
61 k = safe_glob(path, GLOB_NOSORT|GLOB_BRACE, &g);
62 if (k == -ENOENT)
63 return false;
64 if (k < 0)
65 return k;
66 return true;
67 }
68
69 int glob_extend(char ***strv, const char *path) {
70 _cleanup_globfree_ glob_t g = {};
71 int k;
72
73 k = safe_glob(path, GLOB_NOSORT|GLOB_BRACE, &g);
74 if (k < 0)
75 return k;
76
77 return strv_extend_strv(strv, g.gl_pathv, false);
78 }