]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/fstab-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2015 Zbigniew Jędrzejewski-Szmek
14 #include "alloc-util.h"
15 #include "device-nodes.h"
16 #include "fstab-util.h"
18 #include "mount-util.h"
19 #include "parse-util.h"
20 #include "path-util.h"
21 #include "string-util.h"
25 int fstab_has_fstype(const char *fstype
) {
26 _cleanup_endmntent_
FILE *f
= NULL
;
29 f
= setmntent("/etc/fstab", "re");
31 return errno
== ENOENT
? false : -errno
;
37 return errno
!= 0 ? -errno
: false;
39 if (streq(m
->mnt_type
, fstype
))
45 int fstab_is_mount_point(const char *mount
) {
46 _cleanup_endmntent_
FILE *f
= NULL
;
49 f
= setmntent("/etc/fstab", "re");
51 return errno
== ENOENT
? false : -errno
;
57 return errno
!= 0 ? -errno
: false;
59 if (path_equal(m
->mnt_dir
, mount
))
65 int fstab_filter_options(const char *opts
, const char *names
,
66 const char **namefound
, char **value
, char **filtered
) {
67 const char *name
, *n
= NULL
, *x
;
68 _cleanup_strv_free_
char **stor
= NULL
;
69 _cleanup_free_
char *v
= NULL
, **strv
= NULL
;
71 assert(names
&& *names
);
76 /* If !value and !filtered, this function is not allowed to fail. */
79 const char *word
, *state
;
82 FOREACH_WORD_SEPARATOR(word
, l
, opts
, ",", state
)
83 NULSTR_FOREACH(name
, names
) {
86 if (!strneq(word
, name
, strlen(name
)))
89 /* we know that the string is NUL
90 * terminated, so *x is valid */
91 x
= word
+ strlen(name
);
92 if (IN_SET(*x
, '\0', '=', ',')) {
96 if (IN_SET(*x
, '\0', ','))
101 v
= strndup(x
, l
- strlen(name
) - 1);
111 stor
= strv_split(opts
, ",");
114 strv
= memdup(stor
, sizeof(char*) * (strv_length(stor
) + 1));
118 for (s
= t
= strv
; *s
; s
++) {
119 NULSTR_FOREACH(name
, names
) {
120 x
= startswith(*s
, name
);
121 if (x
&& IN_SET(*x
, '\0', '='))
129 /* Keep the last occurence found */
153 f
= strv_join(strv
, ",");
160 *value
= TAKE_PTR(v
);
165 int fstab_extract_values(const char *opts
, const char *name
, char ***values
) {
166 _cleanup_strv_free_
char **optsv
= NULL
, **res
= NULL
;
173 optsv
= strv_split(opts
, ",");
177 STRV_FOREACH(s
, optsv
) {
181 arg
= startswith(*s
, name
);
182 if (!arg
|| *arg
!= '=')
184 r
= strv_extend(&res
, arg
+ 1);
189 *values
= TAKE_PTR(res
);
194 int fstab_find_pri(const char *options
, int *ret
) {
195 _cleanup_free_
char *opt
= NULL
;
201 r
= fstab_filter_options(options
, "pri\0", NULL
, &opt
, NULL
);
207 r
= safe_atou(opt
, &pri
);
218 static char *unquote(const char *s
, const char* quotes
) {
222 /* This is rather stupid, simply removes the heading and
223 * trailing quotes if there is one. Doesn't care about
224 * escaping or anything.
226 * DON'T USE THIS FOR NEW CODE ANYMORE! */
232 if (strchr(quotes
, s
[0]) && s
[l
-1] == s
[0])
233 return strndup(s
+1, l
-2);
238 static char *tag_to_udev_node(const char *tagvalue
, const char *by
) {
239 _cleanup_free_
char *t
= NULL
, *u
= NULL
;
242 u
= unquote(tagvalue
, QUOTES
);
246 enc_len
= strlen(u
) * 4 + 1;
247 t
= new(char, enc_len
);
251 if (encode_devnode_name(u
, t
, enc_len
) < 0)
254 return strjoin("/dev/disk/by-", by
, "/", t
);
257 char *fstab_node_to_udev_node(const char *p
) {
260 if (startswith(p
, "LABEL="))
261 return tag_to_udev_node(p
+6, "label");
263 if (startswith(p
, "UUID="))
264 return tag_to_udev_node(p
+5, "uuid");
266 if (startswith(p
, "PARTUUID="))
267 return tag_to_udev_node(p
+9, "partuuid");
269 if (startswith(p
, "PARTLABEL="))
270 return tag_to_udev_node(p
+10, "partlabel");