]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/fstab-util.c
tree-wide: beautify remaining copyright statements
[thirdparty/systemd.git] / src / shared / fstab-util.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
d15d0333 2/***
96b2fb93 3 Copyright © 2015 Zbigniew Jędrzejewski-Szmek
d15d0333
ZJS
4***/
5
a8fbdf54
TA
6#include <errno.h>
7#include <mntent.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
b5efdb8a 12#include "alloc-util.h"
6550203e 13#include "device-nodes.h"
6bedfcbb 14#include "fstab-util.h"
a8fbdf54 15#include "macro.h"
4349cd7c 16#include "mount-util.h"
6bedfcbb 17#include "parse-util.h"
0b6b6787 18#include "path-util.h"
07630cea 19#include "string-util.h"
d15d0333
ZJS
20#include "strv.h"
21#include "util.h"
22
6c1921e9
FB
23int fstab_has_fstype(const char *fstype) {
24 _cleanup_endmntent_ FILE *f = NULL;
25 struct mntent *m;
26
27 f = setmntent("/etc/fstab", "re");
28 if (!f)
29 return errno == ENOENT ? false : -errno;
30
31 for (;;) {
32 errno = 0;
33 m = getmntent(f);
34 if (!m)
35 return errno != 0 ? -errno : false;
36
37 if (streq(m->mnt_type, fstype))
38 return true;
39 }
40 return false;
41}
42
b9088048 43int fstab_is_mount_point(const char *mount) {
0b6b6787
KS
44 _cleanup_endmntent_ FILE *f = NULL;
45 struct mntent *m;
46
9ffcff0e 47 f = setmntent("/etc/fstab", "re");
0b6b6787 48 if (!f)
b9088048
FB
49 return errno == ENOENT ? false : -errno;
50
51 for (;;) {
52 errno = 0;
53 m = getmntent(f);
54 if (!m)
55 return errno != 0 ? -errno : false;
0b6b6787 56
0b6b6787
KS
57 if (path_equal(m->mnt_dir, mount))
58 return true;
b9088048 59 }
0b6b6787
KS
60 return false;
61}
62
d15d0333
ZJS
63int fstab_filter_options(const char *opts, const char *names,
64 const char **namefound, char **value, char **filtered) {
65 const char *name, *n = NULL, *x;
66 _cleanup_strv_free_ char **stor = NULL;
67 _cleanup_free_ char *v = NULL, **strv = NULL;
68
69 assert(names && *names);
70
71 if (!opts)
72 goto answer;
73
74 /* If !value and !filtered, this function is not allowed to fail. */
75
76 if (!filtered) {
77 const char *word, *state;
78 size_t l;
79
80 FOREACH_WORD_SEPARATOR(word, l, opts, ",", state)
81 NULSTR_FOREACH(name, names) {
82 if (l < strlen(name))
83 continue;
84 if (!strneq(word, name, strlen(name)))
85 continue;
86
87 /* we know that the string is NUL
88 * terminated, so *x is valid */
89 x = word + strlen(name);
90 if (IN_SET(*x, '\0', '=', ',')) {
91 n = name;
92 if (value) {
93 free(v);
94 if (IN_SET(*x, '\0', ','))
95 v = NULL;
96 else {
97 assert(*x == '=');
98 x++;
99 v = strndup(x, l - strlen(name) - 1);
100 if (!v)
101 return -ENOMEM;
102 }
103 }
104 }
105 }
106 } else {
107 char **t, **s;
108
109 stor = strv_split(opts, ",");
110 if (!stor)
111 return -ENOMEM;
112 strv = memdup(stor, sizeof(char*) * (strv_length(stor) + 1));
113 if (!strv)
114 return -ENOMEM;
115
116 for (s = t = strv; *s; s++) {
117 NULSTR_FOREACH(name, names) {
118 x = startswith(*s, name);
119 if (x && IN_SET(*x, '\0', '='))
120 goto found;
121 }
122
123 *t = *s;
124 t++;
125 continue;
126 found:
127 /* Keep the last occurence found */
128 n = name;
129 if (value) {
130 free(v);
131 if (*x == '\0')
132 v = NULL;
133 else {
134 assert(*x == '=');
135 x++;
136 v = strdup(x);
137 if (!v)
138 return -ENOMEM;
139 }
140 }
141 }
142 *t = NULL;
143 }
144
145answer:
146 if (namefound)
147 *namefound = n;
148 if (filtered) {
149 char *f;
150
151 f = strv_join(strv, ",");
152 if (!f)
153 return -ENOMEM;
154
155 *filtered = f;
156 }
ae2a15bc
LP
157 if (value)
158 *value = TAKE_PTR(v);
d15d0333
ZJS
159
160 return !!n;
161}
162
3519d230
KZ
163int fstab_extract_values(const char *opts, const char *name, char ***values) {
164 _cleanup_strv_free_ char **optsv = NULL, **res = NULL;
165 char **s;
166
167 assert(opts);
168 assert(name);
169 assert(values);
170
171 optsv = strv_split(opts, ",");
172 if (!optsv)
173 return -ENOMEM;
174
175 STRV_FOREACH(s, optsv) {
176 char *arg;
177 int r;
178
179 arg = startswith(*s, name);
180 if (!arg || *arg != '=')
181 continue;
182 r = strv_extend(&res, arg + 1);
183 if (r < 0)
184 return r;
185 }
186
ae2a15bc 187 *values = TAKE_PTR(res);
3519d230
KZ
188
189 return !!*values;
190}
191
d15d0333
ZJS
192int fstab_find_pri(const char *options, int *ret) {
193 _cleanup_free_ char *opt = NULL;
194 int r;
195 unsigned pri;
196
197 assert(ret);
198
199 r = fstab_filter_options(options, "pri\0", NULL, &opt, NULL);
a75f4e2a 200 if (r < 0)
d15d0333 201 return r;
a75f4e2a
ZJS
202 if (r == 0 || !opt)
203 return 0;
d15d0333
ZJS
204
205 r = safe_atou(opt, &pri);
206 if (r < 0)
207 return r;
208
c5e04d51
ZJS
209 if ((int) pri < 0)
210 return -ERANGE;
211
a75f4e2a 212 *ret = (int) pri;
d15d0333
ZJS
213 return 1;
214}
6550203e
LP
215
216static char *unquote(const char *s, const char* quotes) {
217 size_t l;
218 assert(s);
219
220 /* This is rather stupid, simply removes the heading and
221 * trailing quotes if there is one. Doesn't care about
222 * escaping or anything.
223 *
13e785f7 224 * DON'T USE THIS FOR NEW CODE ANYMORE! */
6550203e
LP
225
226 l = strlen(s);
227 if (l < 2)
228 return strdup(s);
229
230 if (strchr(quotes, s[0]) && s[l-1] == s[0])
231 return strndup(s+1, l-2);
232
233 return strdup(s);
234}
235
236static char *tag_to_udev_node(const char *tagvalue, const char *by) {
237 _cleanup_free_ char *t = NULL, *u = NULL;
238 size_t enc_len;
239
240 u = unquote(tagvalue, QUOTES);
241 if (!u)
242 return NULL;
243
244 enc_len = strlen(u) * 4 + 1;
245 t = new(char, enc_len);
246 if (!t)
247 return NULL;
248
249 if (encode_devnode_name(u, t, enc_len) < 0)
250 return NULL;
251
605405c6 252 return strjoin("/dev/disk/by-", by, "/", t);
6550203e
LP
253}
254
255char *fstab_node_to_udev_node(const char *p) {
256 assert(p);
257
258 if (startswith(p, "LABEL="))
259 return tag_to_udev_node(p+6, "label");
260
261 if (startswith(p, "UUID="))
262 return tag_to_udev_node(p+5, "uuid");
263
264 if (startswith(p, "PARTUUID="))
265 return tag_to_udev_node(p+9, "partuuid");
266
267 if (startswith(p, "PARTLABEL="))
268 return tag_to_udev_node(p+10, "partlabel");
269
270 return strdup(p);
271}