]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/conf-files.c
nss-myhostname: don't fill scopeid for non-link-local addresses
[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 46
1d13f648 47 dirpath = prefix_roota(root, path);
cebed500 48
cba2ef02 49 dir = opendir(dirpath);
2c21044f
KS
50 if (!dir) {
51 if (errno == ENOENT)
52 return 0;
53 return -errno;
54 }
55
31d5192d 56 FOREACH_DIRENT(de, dir, return -errno) {
2c21044f
KS
57 char *p;
58
2c21044f
KS
59 if (!dirent_is_file_with_suffix(de, suffix))
60 continue;
61
605405c6 62 p = strjoin(dirpath, "/", de->d_name);
fabe5c0e 63 if (!p)
e02caf30 64 return -ENOMEM;
2c21044f 65
2b6bf07d 66 r = hashmap_put(h, basename(p), p);
fabe5c0e
LP
67 if (r == -EEXIST) {
68 log_debug("Skipping overridden file: %s.", p);
69 free(p);
70 } else if (r < 0) {
71 free(p);
72 return r;
73 } else if (r == 0) {
74 log_debug("Duplicate file %s", p);
2c21044f
KS
75 free(p);
76 }
77 }
78
e02caf30 79 return 0;
2c21044f
KS
80}
81
82static int base_cmp(const void *a, const void *b) {
83 const char *s1, *s2;
84
85 s1 = *(char * const *)a;
86 s2 = *(char * const *)b;
2b6bf07d 87 return strcmp(basename(s1), basename(s2));
2c21044f
KS
88}
89
fabe5c0e 90static int conf_files_list_strv_internal(char ***strv, const char *suffix, const char *root, char **dirs) {
e1d75803 91 _cleanup_hashmap_free_ Hashmap *fh = NULL;
fabe5c0e 92 char **files, **p;
578ac060 93 int r;
2c21044f 94
fabe5c0e 95 assert(strv);
fabe5c0e
LP
96
97 /* This alters the dirs string array */
7d8da2c9 98 if (!path_strv_resolve_uniq(dirs, root))
fabe5c0e 99 return -ENOMEM;
2c21044f 100
d5099efc 101 fh = hashmap_new(&string_hash_ops);
fabe5c0e
LP
102 if (!fh)
103 return -ENOMEM;
2c21044f
KS
104
105 STRV_FOREACH(p, dirs) {
cba2ef02 106 r = files_add(fh, root, *p, suffix);
31d5192d 107 if (r == -ENOMEM)
fabe5c0e 108 return r;
31d5192d
LP
109 if (r < 0)
110 log_debug_errno(r, "Failed to search for files in %s, ignoring: %m", *p);
2c21044f
KS
111 }
112
113 files = hashmap_get_strv(fh);
31d5192d 114 if (!files)
fabe5c0e 115 return -ENOMEM;
fabe5c0e 116
7ff7394d 117 qsort_safe(files, hashmap_size(fh), sizeof(char *), base_cmp);
fabe5c0e 118 *strv = files;
2c21044f 119
fabe5c0e
LP
120 return 0;
121}
122
844ec79b 123int conf_files_list_strv(char ***strv, const char *suffix, const char *root, const char* const* dirs) {
fabe5c0e
LP
124 _cleanup_strv_free_ char **copy = NULL;
125
126 assert(strv);
fabe5c0e
LP
127
128 copy = strv_copy((char**) dirs);
129 if (!copy)
130 return -ENOMEM;
131
132 return conf_files_list_strv_internal(strv, suffix, root, copy);
2c21044f
KS
133}
134
7850b3b8 135int conf_files_list(char ***strv, const char *suffix, const char *root, const char *dir, ...) {
8201ad81
LP
136 _cleanup_strv_free_ char **dirs = NULL;
137 va_list ap;
fabe5c0e
LP
138
139 assert(strv);
140 assert(suffix);
2c21044f 141
8201ad81
LP
142 va_start(ap, dir);
143 dirs = strv_new_ap(dir, ap);
144 va_end(ap);
145
146 if (!dirs)
147 return -ENOMEM;
fabe5c0e
LP
148
149 return conf_files_list_strv_internal(strv, suffix, root, dirs);
150}
2c21044f 151
fabe5c0e
LP
152int conf_files_list_nulstr(char ***strv, const char *suffix, const char *root, const char *d) {
153 _cleanup_strv_free_ char **dirs = NULL;
154
155 assert(strv);
156 assert(suffix);
157
158 dirs = strv_split_nulstr(d);
159 if (!dirs)
160 return -ENOMEM;
2c21044f 161
fabe5c0e 162 return conf_files_list_strv_internal(strv, suffix, root, dirs);
2c21044f 163}