]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/conf-files.c
nss-systemd: remove useless define
[thirdparty/systemd.git] / src / basic / conf-files.c
CommitLineData
2c21044f
KS
1/***
2 This file is part of systemd.
3
4 Copyright 2010 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18***/
19
07630cea 20#include <dirent.h>
2c21044f 21#include <errno.h>
11c3a366 22#include <stdarg.h>
2c21044f 23#include <stdio.h>
07630cea
LP
24#include <stdlib.h>
25#include <string.h>
2c21044f 26
3ffd4af2 27#include "conf-files.h"
a0956174 28#include "dirent-util.h"
3ffd4af2 29#include "fd-util.h"
07630cea
LP
30#include "hashmap.h"
31#include "log.h"
2c21044f 32#include "macro.h"
2c21044f 33#include "missing.h"
9eb977db 34#include "path-util.h"
07630cea
LP
35#include "string-util.h"
36#include "strv.h"
37#include "util.h"
2c21044f 38
cba2ef02 39static int files_add(Hashmap *h, const char *root, const char *path, const char *suffix) {
fabe5c0e 40 _cleanup_closedir_ DIR *dir = NULL;
1d13f648 41 const char *dirpath;
31d5192d 42 struct dirent *de;
1d13f648 43 int r;
e02caf30 44
cba2ef02 45 assert(path);
cebed500
LP
46 assert(suffix);
47
1d13f648 48 dirpath = prefix_roota(root, path);
cebed500 49
cba2ef02 50 dir = opendir(dirpath);
2c21044f
KS
51 if (!dir) {
52 if (errno == ENOENT)
53 return 0;
54 return -errno;
55 }
56
31d5192d 57 FOREACH_DIRENT(de, dir, return -errno) {
2c21044f
KS
58 char *p;
59
2c21044f
KS
60 if (!dirent_is_file_with_suffix(de, suffix))
61 continue;
62
fabe5c0e
LP
63 p = strjoin(dirpath, "/", de->d_name, NULL);
64 if (!p)
e02caf30 65 return -ENOMEM;
2c21044f 66
2b6bf07d 67 r = hashmap_put(h, basename(p), p);
fabe5c0e
LP
68 if (r == -EEXIST) {
69 log_debug("Skipping overridden file: %s.", p);
70 free(p);
71 } else if (r < 0) {
72 free(p);
73 return r;
74 } else if (r == 0) {
75 log_debug("Duplicate file %s", p);
2c21044f
KS
76 free(p);
77 }
78 }
79
e02caf30 80 return 0;
2c21044f
KS
81}
82
83static int base_cmp(const void *a, const void *b) {
84 const char *s1, *s2;
85
86 s1 = *(char * const *)a;
87 s2 = *(char * const *)b;
2b6bf07d 88 return strcmp(basename(s1), basename(s2));
2c21044f
KS
89}
90
fabe5c0e 91static int conf_files_list_strv_internal(char ***strv, const char *suffix, const char *root, char **dirs) {
e1d75803 92 _cleanup_hashmap_free_ Hashmap *fh = NULL;
fabe5c0e 93 char **files, **p;
578ac060 94 int r;
2c21044f 95
fabe5c0e
LP
96 assert(strv);
97 assert(suffix);
98
99 /* This alters the dirs string array */
7d8da2c9 100 if (!path_strv_resolve_uniq(dirs, root))
fabe5c0e 101 return -ENOMEM;
2c21044f 102
d5099efc 103 fh = hashmap_new(&string_hash_ops);
fabe5c0e
LP
104 if (!fh)
105 return -ENOMEM;
2c21044f
KS
106
107 STRV_FOREACH(p, dirs) {
cba2ef02 108 r = files_add(fh, root, *p, suffix);
31d5192d 109 if (r == -ENOMEM)
fabe5c0e 110 return r;
31d5192d
LP
111 if (r < 0)
112 log_debug_errno(r, "Failed to search for files in %s, ignoring: %m", *p);
2c21044f
KS
113 }
114
115 files = hashmap_get_strv(fh);
31d5192d 116 if (!files)
fabe5c0e 117 return -ENOMEM;
fabe5c0e 118
7ff7394d 119 qsort_safe(files, hashmap_size(fh), sizeof(char *), base_cmp);
fabe5c0e 120 *strv = files;
2c21044f 121
fabe5c0e
LP
122 return 0;
123}
124
844ec79b 125int conf_files_list_strv(char ***strv, const char *suffix, const char *root, const char* const* dirs) {
fabe5c0e
LP
126 _cleanup_strv_free_ char **copy = NULL;
127
128 assert(strv);
129 assert(suffix);
130
131 copy = strv_copy((char**) dirs);
132 if (!copy)
133 return -ENOMEM;
134
135 return conf_files_list_strv_internal(strv, suffix, root, copy);
2c21044f
KS
136}
137
7850b3b8 138int conf_files_list(char ***strv, const char *suffix, const char *root, const char *dir, ...) {
8201ad81
LP
139 _cleanup_strv_free_ char **dirs = NULL;
140 va_list ap;
fabe5c0e
LP
141
142 assert(strv);
143 assert(suffix);
2c21044f 144
8201ad81
LP
145 va_start(ap, dir);
146 dirs = strv_new_ap(dir, ap);
147 va_end(ap);
148
149 if (!dirs)
150 return -ENOMEM;
fabe5c0e
LP
151
152 return conf_files_list_strv_internal(strv, suffix, root, dirs);
153}
2c21044f 154
fabe5c0e
LP
155int conf_files_list_nulstr(char ***strv, const char *suffix, const char *root, const char *d) {
156 _cleanup_strv_free_ char **dirs = NULL;
157
158 assert(strv);
159 assert(suffix);
160
161 dirs = strv_split_nulstr(d);
162 if (!dirs)
163 return -ENOMEM;
2c21044f 164
fabe5c0e 165 return conf_files_list_strv_internal(strv, suffix, root, dirs);
2c21044f 166}