]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/fstab-util.c
util-lib: split our string related calls from util.[ch] into its own file string...
[thirdparty/systemd.git] / src / shared / fstab-util.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2015 Zbigniew Jędrzejewski-Szmek
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include "path-util.h"
23 #include "string-util.h"
24 #include "strv.h"
25 #include "util.h"
26 #include "fstab-util.h"
27
28 bool fstab_is_mount_point(const char *mount) {
29 _cleanup_endmntent_ FILE *f = NULL;
30 struct mntent *m;
31
32 f = setmntent("/etc/fstab", "r");
33 if (!f)
34 return false;
35
36 while ((m = getmntent(f)))
37 if (path_equal(m->mnt_dir, mount))
38 return true;
39
40 return false;
41 }
42
43 int fstab_filter_options(const char *opts, const char *names,
44 const char **namefound, char **value, char **filtered) {
45 const char *name, *n = NULL, *x;
46 _cleanup_strv_free_ char **stor = NULL;
47 _cleanup_free_ char *v = NULL, **strv = NULL;
48
49 assert(names && *names);
50
51 if (!opts)
52 goto answer;
53
54 /* If !value and !filtered, this function is not allowed to fail. */
55
56 if (!filtered) {
57 const char *word, *state;
58 size_t l;
59
60 FOREACH_WORD_SEPARATOR(word, l, opts, ",", state)
61 NULSTR_FOREACH(name, names) {
62 if (l < strlen(name))
63 continue;
64 if (!strneq(word, name, strlen(name)))
65 continue;
66
67 /* we know that the string is NUL
68 * terminated, so *x is valid */
69 x = word + strlen(name);
70 if (IN_SET(*x, '\0', '=', ',')) {
71 n = name;
72 if (value) {
73 free(v);
74 if (IN_SET(*x, '\0', ','))
75 v = NULL;
76 else {
77 assert(*x == '=');
78 x++;
79 v = strndup(x, l - strlen(name) - 1);
80 if (!v)
81 return -ENOMEM;
82 }
83 }
84 }
85 }
86 } else {
87 char **t, **s;
88
89 stor = strv_split(opts, ",");
90 if (!stor)
91 return -ENOMEM;
92 strv = memdup(stor, sizeof(char*) * (strv_length(stor) + 1));
93 if (!strv)
94 return -ENOMEM;
95
96 for (s = t = strv; *s; s++) {
97 NULSTR_FOREACH(name, names) {
98 x = startswith(*s, name);
99 if (x && IN_SET(*x, '\0', '='))
100 goto found;
101 }
102
103 *t = *s;
104 t++;
105 continue;
106 found:
107 /* Keep the last occurence found */
108 n = name;
109 if (value) {
110 free(v);
111 if (*x == '\0')
112 v = NULL;
113 else {
114 assert(*x == '=');
115 x++;
116 v = strdup(x);
117 if (!v)
118 return -ENOMEM;
119 }
120 }
121 }
122 *t = NULL;
123 }
124
125 answer:
126 if (namefound)
127 *namefound = n;
128 if (filtered) {
129 char *f;
130
131 f = strv_join(strv, ",");
132 if (!f)
133 return -ENOMEM;
134
135 *filtered = f;
136 }
137 if (value) {
138 *value = v;
139 v = NULL;
140 }
141
142 return !!n;
143 }
144
145 int fstab_extract_values(const char *opts, const char *name, char ***values) {
146 _cleanup_strv_free_ char **optsv = NULL, **res = NULL;
147 char **s;
148
149 assert(opts);
150 assert(name);
151 assert(values);
152
153 optsv = strv_split(opts, ",");
154 if (!optsv)
155 return -ENOMEM;
156
157 STRV_FOREACH(s, optsv) {
158 char *arg;
159 int r;
160
161 arg = startswith(*s, name);
162 if (!arg || *arg != '=')
163 continue;
164 r = strv_extend(&res, arg + 1);
165 if (r < 0)
166 return r;
167 }
168
169 *values = res;
170 res = NULL;
171
172 return !!*values;
173 }
174
175 int fstab_find_pri(const char *options, int *ret) {
176 _cleanup_free_ char *opt = NULL;
177 int r;
178 unsigned pri;
179
180 assert(ret);
181
182 r = fstab_filter_options(options, "pri\0", NULL, &opt, NULL);
183 if (r < 0)
184 return r;
185 if (r == 0 || !opt)
186 return 0;
187
188 r = safe_atou(opt, &pri);
189 if (r < 0)
190 return r;
191
192 if ((int) pri < 0)
193 return -ERANGE;
194
195 *ret = (int) pri;
196 return 1;
197 }