chiark / gitweb /
Use udev_encode_string in fstab_node_to_udev_node
[elogind.git] / src / shared / util.c
index 15abd5046d72e160e1cbf6a25254c8ec16a17679..2b76a5c885e93fba0faf881f2d9ea56b479fa2bc 100644 (file)
@@ -73,6 +73,7 @@
 #include "hashmap.h"
 #include "env-util.h"
 #include "fileio.h"
+#include "utf8.h"
 
 int saved_argc = 0;
 char **saved_argv = NULL;
@@ -128,40 +129,6 @@ char* endswith(const char *s, const char *postfix) {
         return (char*) s + sl - pl;
 }
 
-char* startswith(const char *s, const char *prefix) {
-        const char *a, *b;
-
-        assert(s);
-        assert(prefix);
-
-        a = s, b = prefix;
-        for (;;) {
-                if (*b == 0)
-                        return (char*) a;
-                if (*a != *b)
-                        return NULL;
-
-                a++, b++;
-        }
-}
-
-char* startswith_no_case(const char *s, const char *prefix) {
-        const char *a, *b;
-
-        assert(s);
-        assert(prefix);
-
-        a = s, b = prefix;
-        for (;;) {
-                if (*b == 0)
-                        return (char*) a;
-                if (tolower(*a) != tolower(*b))
-                        return NULL;
-
-                a++, b++;
-        }
-}
-
 bool first_word(const char *s, const char *word) {
         size_t sl, wl;
 
@@ -367,7 +334,7 @@ int safe_atolli(const char *s, long long int *ret_lli) {
 
 int safe_atod(const char *s, double *ret_d) {
         char *x = NULL;
-        double d;
+        double d = 0;
 
         assert(s);
         assert(ret_d);
@@ -728,9 +695,6 @@ int is_kernel_thread(pid_t pid) {
 
 int get_process_capeff(pid_t pid, char **capeff) {
         const char *p;
-        _cleanup_free_ char *status = NULL;
-        char *t = NULL;
-        int r;
 
         assert(capeff);
         assert(pid >= 0);
@@ -740,25 +704,7 @@ int get_process_capeff(pid_t pid, char **capeff) {
         else
                 p = procfs_file_alloca(pid, "status");
 
-        r = read_full_file(p, &status, NULL);
-        if (r < 0)
-                return r;
-
-        t = strstr(status, "\nCapEff:\t");
-        if (!t)
-                return -ENOENT;
-
-        for (t += strlen("\nCapEff:\t"); t[0] == '0'; t++)
-                continue;
-
-        if (t[0] == '\n')
-                t--;
-
-        *capeff = strndup(t, strchr(t, '\n') - t);
-        if (!*capeff)
-                return -ENOMEM;
-
-        return 0;
+        return get_status_field(p, "\nCapEff:", capeff);
 }
 
 int get_process_exe(pid_t pid, char **name) {
@@ -1875,8 +1821,10 @@ int open_terminal(const char *name, int mode) {
          * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
          */
 
+        assert(!(mode & O_CREAT));
+
         for (;;) {
-                fd = open(name, mode);
+                fd = open(name, mode, 0);
                 if (fd >= 0)
                         break;
 
@@ -2828,8 +2776,8 @@ int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct
 _pure_ static int is_temporary_fs(struct statfs *s) {
         assert(s);
         return
-                F_TYPE_CMP(s->f_type, TMPFS_MAGIC) ||
-                F_TYPE_CMP(s->f_type, RAMFS_MAGIC);
+                F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) ||
+                F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC);
 }
 
 int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
@@ -3330,7 +3278,7 @@ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne
 
         r = new0(char, new_length+1);
         if (!r)
-                return r;
+                return NULL;
 
         x = (new_length * percent) / 100;
 
@@ -3520,7 +3468,9 @@ DIR *xopendirat(int fd, const char *name, int flags) {
         int nfd;
         DIR *d;
 
-        nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags);
+        assert(!(flags & O_CREAT));
+
+        nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
         if (nfd < 0)
                 return NULL;
 
@@ -3546,26 +3496,23 @@ int signal_from_string_try_harder(const char *s) {
 }
 
 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
-        char *dn, *t, *u;
-        int r;
-
-        /* FIXME: to follow udev's logic 100% we need to leave valid
-         * UTF8 chars unescaped */
+        _cleanup_free_ char *t = NULL, *u = NULL;
+        char *dn;
+        size_t enc_len;
 
         u = unquote(tagvalue, "\"\'");
         if (u == NULL)
                 return NULL;
 
-        t = xescape(u, "/ ");
-        free(u);
-
+        enc_len = strlen(u) * 4;
+        t = new(char, enc_len);
         if (t == NULL)
                 return NULL;
 
-        r = asprintf(&dn, "/dev/disk/by-%s/%s", by, t);
-        free(t);
+        if (udev_encode_string(u, t, enc_len) < 0)
+                return NULL;
 
-        if (r < 0)
+        if (asprintf(&dn, "/dev/disk/by-%s/%s", by, t) < 0)
                 return NULL;
 
         return dn;
@@ -5341,13 +5288,17 @@ bool string_is_safe(const char *p) {
         return true;
 }
 
+/**
+ * Check if a string contains control characters.
+ * Spaces and tabs are not considered control characters.
+ */
 bool string_has_cc(const char *p) {
         const char *t;
 
         assert(p);
 
         for (t = p; *t; t++)
-                if (*t > 0 && *t < ' ')
+                if (*t > 0 && *t < ' ' && *t != '\t')
                         return true;
 
         return false;
@@ -5752,7 +5703,7 @@ int search_and_fopen_nulstr(const char *path, const char *mode, const char *sear
 
 int create_tmp_dir(char template[], char** dir_name) {
         int r = 0;
-        char *d, *dt;
+        char *d = NULL, *dt;
 
         assert(dir_name);
 
@@ -5942,3 +5893,34 @@ void parse_user_at_host(char *arg, char **user, char **host) {
                 *user = arg;
         }
 }
+
+int split_pair(const char *s, const char *sep, char **l, char **r) {
+        char *x, *a, *b;
+
+        assert(s);
+        assert(sep);
+        assert(l);
+        assert(r);
+
+        if (isempty(sep))
+                return -EINVAL;
+
+        x = strstr(s, sep);
+        if (!x)
+                return -EINVAL;
+
+        a = strndup(s, x - s);
+        if (!a)
+                return -ENOMEM;
+
+        b = strdup(x + strlen(sep));
+        if (!b) {
+                free(a);
+                return -ENOMEM;
+        }
+
+        *l = a;
+        *r = b;
+
+        return 0;
+}