chiark / gitweb /
util: Rewrite in_charset to use strspn
[elogind.git] / src / shared / util.c
index 588b1f5..e1a1168 100644 (file)
@@ -921,16 +921,9 @@ char *delete_chars(char *s, const char *bad) {
 }
 
 bool in_charset(const char *s, const char* charset) {
-        const char *i;
-
         assert(s);
         assert(charset);
-
-        for (i = s; *i; i++)
-                if (!strchr(charset, *i))
-                        return false;
-
-        return true;
+        return s[strspn(s, charset)] == '\0';
 }
 
 char *file_in_same_dir(const char *path, const char *filename) {
@@ -3198,19 +3191,27 @@ bool on_tty(void) {
         return cached_on_tty;
 }
 
-int running_in_chroot(void) {
-        struct stat a = {}, b = {};
+int files_same(const char *filea, const char *fileb) {
+        struct stat a, b;
 
-        /* Only works as root */
-        if (stat("/proc/1/root", &a) < 0)
+        if (stat(filea, &a) < 0)
                 return -errno;
 
-        if (stat("/", &b) < 0)
+        if (stat(fileb, &b) < 0)
                 return -errno;
 
-        return
-                a.st_dev != b.st_dev ||
-                a.st_ino != b.st_ino;
+        return a.st_dev == b.st_dev &&
+               a.st_ino == b.st_ino;
+}
+
+int running_in_chroot(void) {
+        int ret;
+
+        ret = files_same("/proc/1/root", "/");
+        if (ret < 0)
+                return ret;
+
+        return ret == 0;
 }
 
 static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
@@ -3519,25 +3520,21 @@ int signal_from_string_try_harder(const char *s) {
 
 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
         _cleanup_free_ char *t = NULL, *u = NULL;
-        char *dn;
         size_t enc_len;
 
         u = unquote(tagvalue, "\"\'");
-        if (u == NULL)
+        if (!u)
                 return NULL;
 
         enc_len = strlen(u) * 4 + 1;
         t = new(char, enc_len);
-        if (t == NULL)
+        if (!t)
                 return NULL;
 
         if (encode_devnode_name(u, t, enc_len) < 0)
                 return NULL;
 
-        if (asprintf(&dn, "/dev/disk/by-%s/%s", by, t) < 0)
-                return NULL;
-
-        return dn;
+        return strjoin("/dev/disk/by-", by, "/", t, NULL);
 }
 
 char *fstab_node_to_udev_node(const char *p) {
@@ -5944,7 +5941,7 @@ int split_pair(const char *s, const char *sep, char **l, char **r) {
 }
 
 int shall_restore_state(void) {
-        _cleanup_free_ char *line;
+        _cleanup_free_ char *line = NULL;
         char *w, *state;
         size_t l;
         int r;
@@ -5955,11 +5952,26 @@ int shall_restore_state(void) {
         if (r == 0) /* Container ... */
                 return 1;
 
-        FOREACH_WORD_QUOTED(w, l, line, state)
-                if (l == 23 && strneq(w, "systemd.restore_state=0", 23))
-                        return 0;
+        r = 1;
 
-        return 1;
+        FOREACH_WORD_QUOTED(w, l, line, state) {
+                const char *e;
+                char n[l+1];
+                int k;
+
+                memcpy(n, w, l);
+                n[l] = 0;
+
+                e = startswith(n, "systemd.restore_state=");
+                if (!e)
+                        continue;
+
+                k = parse_boolean(e);
+                if (k >= 0)
+                        r = k;
+        }
+
+        return r;
 }
 
 int proc_cmdline(char **ret) {
@@ -5977,7 +5989,7 @@ int proc_cmdline(char **ret) {
                         if (*p == 0)
                                 *p = ' ';
 
-                *p  = 0;
+                *p = 0;
                 *ret = buf;
                 return 1;
         }
@@ -5989,12 +6001,14 @@ int proc_cmdline(char **ret) {
         return 1;
 }
 
-int parse_proc_cmdline(int (*parse_word)(const char *word)) {
+int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
         _cleanup_free_ char *line = NULL;
         char *w, *state;
         size_t l;
         int r;
 
+        assert(parse_item);
+
         r = proc_cmdline(&line);
         if (r < 0)
                 log_warning("Failed to read /proc/cmdline, ignoring: %s", strerror(-r));
@@ -6002,17 +6016,23 @@ int parse_proc_cmdline(int (*parse_word)(const char *word)) {
                 return 0;
 
         FOREACH_WORD_QUOTED(w, l, line, state) {
-                _cleanup_free_ char *word;
+                char word[l+1], *value;
 
-                word = strndup(w, l);
-                if (!word)
-                        return log_oom();
+                memcpy(word, w, l);
+                word[l] = 0;
 
-                r = parse_word(word);
-                if (r < 0) {
-                        log_error("Failed on cmdline argument %s: %s", word, strerror(-r));
+                /* Filter out arguments that are intended only for the
+                 * initrd */
+                if (!in_initrd() && startswith(word, "rd."))
+                        continue;
+
+                value = strchr(word, '=');
+                if (value)
+                        *(value++) = 0;
+
+                r = parse_item(word, value);
+                if (r < 0)
                         return r;
-                }
         }
 
         return 0;
@@ -6316,3 +6336,20 @@ 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);
+}