summaryrefslogtreecommitdiff
path: root/src/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/fstab-util.c145
-rw-r--r--src/shared/fstab-util.h34
-rw-r--r--src/shared/generator.c41
-rw-r--r--src/shared/util.c17
-rw-r--r--src/shared/util.h2
5 files changed, 187 insertions, 52 deletions
diff --git a/src/shared/fstab-util.c b/src/shared/fstab-util.c
new file mode 100644
index 0000000000..546c81b80f
--- /dev/null
+++ b/src/shared/fstab-util.c
@@ -0,0 +1,145 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+ This file is part of systemd.
+
+ Copyright 2015 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "fstab-util.h"
+#include "strv.h"
+#include "util.h"
+
+int fstab_filter_options(const char *opts, const char *names,
+ const char **namefound, char **value, char **filtered) {
+ const char *name, *n = NULL, *x;
+ _cleanup_strv_free_ char **stor = NULL;
+ _cleanup_free_ char *v = NULL, **strv = NULL;
+
+ assert(names && *names);
+
+ if (!opts)
+ goto answer;
+
+ /* If !value and !filtered, this function is not allowed to fail. */
+
+ if (!filtered) {
+ const char *word, *state;
+ size_t l;
+
+ FOREACH_WORD_SEPARATOR(word, l, opts, ",", state)
+ NULSTR_FOREACH(name, names) {
+ if (l < strlen(name))
+ continue;
+ if (!strneq(word, name, strlen(name)))
+ continue;
+
+ /* we know that the string is NUL
+ * terminated, so *x is valid */
+ x = word + strlen(name);
+ if (IN_SET(*x, '\0', '=', ',')) {
+ n = name;
+ if (value) {
+ free(v);
+ if (IN_SET(*x, '\0', ','))
+ v = NULL;
+ else {
+ assert(*x == '=');
+ x++;
+ v = strndup(x, l - strlen(name) - 1);
+ if (!v)
+ return -ENOMEM;
+ }
+ }
+ }
+ }
+ } else {
+ char **t, **s;
+
+ stor = strv_split(opts, ",");
+ if (!stor)
+ return -ENOMEM;
+ strv = memdup(stor, sizeof(char*) * (strv_length(stor) + 1));
+ if (!strv)
+ return -ENOMEM;
+
+ for (s = t = strv; *s; s++) {
+ NULSTR_FOREACH(name, names) {
+ x = startswith(*s, name);
+ if (x && IN_SET(*x, '\0', '='))
+ goto found;
+ }
+
+ *t = *s;
+ t++;
+ continue;
+ found:
+ /* Keep the last occurence found */
+ n = name;
+ if (value) {
+ free(v);
+ if (*x == '\0')
+ v = NULL;
+ else {
+ assert(*x == '=');
+ x++;
+ v = strdup(x);
+ if (!v)
+ return -ENOMEM;
+ }
+ }
+ }
+ *t = NULL;
+ }
+
+answer:
+ if (namefound)
+ *namefound = n;
+ if (filtered) {
+ char *f;
+
+ f = strv_join(strv, ",");
+ if (!f)
+ return -ENOMEM;
+
+ *filtered = f;
+ }
+ if (value) {
+ *value = v;
+ v = NULL;
+ }
+
+ return !!n;
+}
+
+int fstab_find_pri(const char *options, int *ret) {
+ _cleanup_free_ char *opt = NULL;
+ int r;
+ unsigned pri;
+
+ assert(ret);
+
+ r = fstab_filter_options(options, "pri\0", NULL, &opt, NULL);
+ if (r <= 0)
+ return r;
+
+ r = safe_atou(opt, &pri);
+ if (r < 0)
+ return r;
+
+ *ret = (int) r;
+ return 1;
+}
diff --git a/src/shared/fstab-util.h b/src/shared/fstab-util.h
new file mode 100644
index 0000000000..39ddb71ef4
--- /dev/null
+++ b/src/shared/fstab-util.h
@@ -0,0 +1,34 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+ This file is part of systemd.
+
+ Copyright 2015 Zbigniew Jędrzejewski-Szmek
+
+ systemd is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ systemd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdbool.h>
+#include <stddef.h>
+
+int fstab_filter_options(const char *opts, const char *names,
+ const char **namefound, char **value, char **filtered);
+
+static inline bool fstab_test_option(const char *opts, const char *names) {
+ return !!fstab_filter_options(opts, names, NULL, NULL, NULL);
+}
+
+int fstab_find_pri(const char *options, int *ret);
diff --git a/src/shared/generator.c b/src/shared/generator.c
index 465e5f6cc8..4140afba82 100644
--- a/src/shared/generator.c
+++ b/src/shared/generator.c
@@ -28,6 +28,7 @@
#include "unit-name.h"
#include "generator.h"
#include "path-util.h"
+#include "fstab-util.h"
#include "dropin.h"
int generator_write_fsck_deps(
@@ -92,42 +93,16 @@ int generator_write_timeouts(const char *dir, const char *what, const char *wher
* endless device timeouts for devices that show up only after
* user input, like crypto devices. */
- _cleanup_free_ char *node = NULL, *unit = NULL, *t = NULL;
- char *start, *timeout;
+ _cleanup_free_ char *node = NULL, *unit = NULL, *timeout = NULL;
usec_t u;
int r;
- size_t len;
-
- if ((start = mount_test_option(opts, "comment=systemd.device-timeout")))
- timeout = start + 31;
- else if ((start = mount_test_option(opts, "x-systemd.device-timeout")))
- timeout = start + 25;
- else {
- if (filtered) {
- *filtered = strdup(opts ?: "");
- if (!*filtered)
- return log_oom();
- }
- return 0;
- }
-
- len = strcspn(timeout, ",;" WHITESPACE);
- t = strndup(timeout, len);
- if (!t)
- return -ENOMEM;
-
- if (filtered) {
- char *prefix, *postfix;
+ r = fstab_filter_options(opts, "comment=systemd.device-timeout\0" "x-systemd.device-timeout\0",
+ NULL, &timeout, filtered);
+ if (r <= 0)
+ return r;
- prefix = strndupa(opts, start - opts - (start != opts));
- postfix = timeout + len + (start == opts && timeout[len] != '\0');
- *filtered = strjoin(prefix, *postfix ? postfix : NULL, NULL);
- if (!*filtered)
- return log_oom();
- }
-
- r = parse_sec(t, &u);
+ r = parse_sec(timeout, &u);
if (r < 0) {
log_warning("Failed to parse timeout for %s, ignoring: %s",
where, timeout);
@@ -140,7 +115,7 @@ int generator_write_timeouts(const char *dir, const char *what, const char *wher
unit = unit_name_from_path(node, ".device");
if (!unit)
- return -ENOMEM;
+ return log_oom();
return write_drop_in_format(dir, unit, 50, "device-timeout",
"# Automatically generated by %s\n\n"
diff --git a/src/shared/util.c b/src/shared/util.c
index 6520e511f0..280e42b305 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -6744,23 +6744,6 @@ uint64_t physical_memory(void) {
return (uint64_t) mem * (uint64_t) page_size();
}
-char* mount_test_option(const char *haystack, const char *needle) {
-
- struct mntent me = {
- .mnt_opts = (char*) haystack
- };
-
- assert(needle);
-
- /* Like glibc's hasmntopt(), but works on a string, not a
- * struct mntent */
-
- if (!haystack)
- return NULL;
-
- return hasmntopt(&me, needle);
-}
-
void hexdump(FILE *f, const void *p, size_t s) {
const uint8_t *b = p;
unsigned n = 0;
diff --git a/src/shared/util.h b/src/shared/util.h
index 141a3feab6..b337249faa 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -1010,8 +1010,6 @@ const char *personality_to_string(unsigned long);
uint64_t physical_memory(void);
-char* mount_test_option(const char *haystack, const char *needle);
-
void hexdump(FILE *f, const void *p, size_t s);
union file_handle_union {