]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/fstab-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
9 #include "alloc-util.h"
10 #include "device-nodes.h"
11 #include "fstab-util.h"
13 #include "mount-util.h"
14 #include "nulstr-util.h"
15 #include "parse-util.h"
16 #include "path-util.h"
17 #include "string-util.h"
20 int fstab_has_fstype(const char *fstype
) {
21 _cleanup_endmntent_
FILE *f
= NULL
;
24 f
= setmntent("/etc/fstab", "re");
26 return errno
== ENOENT
? false : -errno
;
32 return errno
!= 0 ? -errno
: false;
34 if (streq(m
->mnt_type
, fstype
))
40 int fstab_is_mount_point(const char *mount
) {
41 _cleanup_endmntent_
FILE *f
= NULL
;
44 f
= setmntent("/etc/fstab", "re");
46 return errno
== ENOENT
? false : -errno
;
52 return errno
!= 0 ? -errno
: false;
54 if (path_equal(m
->mnt_dir
, mount
))
60 int fstab_filter_options(const char *opts
, const char *names
,
61 const char **namefound
, char **value
, char **filtered
) {
62 const char *name
, *n
= NULL
, *x
;
63 _cleanup_strv_free_
char **stor
= NULL
;
64 _cleanup_free_
char *v
= NULL
, **strv
= NULL
;
66 assert(names
&& *names
);
71 /* If !value and !filtered, this function is not allowed to fail. */
74 const char *word
, *state
;
77 FOREACH_WORD_SEPARATOR(word
, l
, opts
, ",", state
)
78 NULSTR_FOREACH(name
, names
) {
81 if (!strneq(word
, name
, strlen(name
)))
84 /* we know that the string is NUL
85 * terminated, so *x is valid */
86 x
= word
+ strlen(name
);
87 if (IN_SET(*x
, '\0', '=', ',')) {
91 if (IN_SET(*x
, '\0', ','))
96 v
= strndup(x
, l
- strlen(name
) - 1);
106 stor
= strv_split(opts
, ",");
109 strv
= memdup(stor
, sizeof(char*) * (strv_length(stor
) + 1));
113 for (s
= t
= strv
; *s
; s
++) {
114 NULSTR_FOREACH(name
, names
) {
115 x
= startswith(*s
, name
);
116 if (x
&& IN_SET(*x
, '\0', '='))
124 /* Keep the last occurence found */
148 f
= strv_join(strv
, ",");
155 *value
= TAKE_PTR(v
);
160 int fstab_extract_values(const char *opts
, const char *name
, char ***values
) {
161 _cleanup_strv_free_
char **optsv
= NULL
, **res
= NULL
;
168 optsv
= strv_split(opts
, ",");
172 STRV_FOREACH(s
, optsv
) {
176 arg
= startswith(*s
, name
);
177 if (!arg
|| *arg
!= '=')
179 r
= strv_extend(&res
, arg
+ 1);
184 *values
= TAKE_PTR(res
);
189 int fstab_find_pri(const char *options
, int *ret
) {
190 _cleanup_free_
char *opt
= NULL
;
196 r
= fstab_filter_options(options
, "pri\0", NULL
, &opt
, NULL
);
202 r
= safe_atou(opt
, &pri
);
213 static char *unquote(const char *s
, const char* quotes
) {
217 /* This is rather stupid, simply removes the heading and
218 * trailing quotes if there is one. Doesn't care about
219 * escaping or anything.
221 * DON'T USE THIS FOR NEW CODE ANYMORE! */
227 if (strchr(quotes
, s
[0]) && s
[l
-1] == s
[0])
228 return strndup(s
+1, l
-2);
233 static char *tag_to_udev_node(const char *tagvalue
, const char *by
) {
234 _cleanup_free_
char *t
= NULL
, *u
= NULL
;
237 u
= unquote(tagvalue
, QUOTES
);
241 enc_len
= strlen(u
) * 4 + 1;
242 t
= new(char, enc_len
);
246 if (encode_devnode_name(u
, t
, enc_len
) < 0)
249 return strjoin("/dev/disk/by-", by
, "/", t
);
252 char *fstab_node_to_udev_node(const char *p
) {
255 if (startswith(p
, "LABEL="))
256 return tag_to_udev_node(p
+6, "label");
258 if (startswith(p
, "UUID="))
259 return tag_to_udev_node(p
+5, "uuid");
261 if (startswith(p
, "PARTUUID="))
262 return tag_to_udev_node(p
+9, "partuuid");
264 if (startswith(p
, "PARTLABEL="))
265 return tag_to_udev_node(p
+10, "partlabel");