chiark / gitweb /
implement new utility functions strstrip() and file_in_same_dir()
[elogind.git] / util.c
diff --git a/util.c b/util.c
index 2e310f9f6848f325f2a3c49c0801bfa19bc7ba23..56f53eafd66caf1872c5e4d9954bb1a84c0177a3 100644 (file)
--- a/util.c
+++ b/util.c
@@ -100,9 +100,9 @@ int close_nointr(int fd) {
 int parse_boolean(const char *v) {
         assert(v);
 
-        if (!strcmp(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
+        if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
                 return 1;
-        else if (!strcmp(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
+        else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
                 return 0;
 
         return -EINVAL;
@@ -216,9 +216,6 @@ int safe_atolli(const char *s, long long int *ret_lli) {
         return 0;
 }
 
-/* What is interpreted as whitespace? */
-#define WHITESPACE " \t\n"
-
 /* Split a string into words. */
 char *split_spaces(const char *c, size_t *l, char **state) {
         char *current;
@@ -256,7 +253,7 @@ char *split_quoted(const char *c, size_t *l, char **state) {
                         (*state)++;
         } else if (*current == '\"') {
                 current ++;
-                *l = strcspn(current+1, "\"");
+                *l = strcspn(current, "\"");
                 *state = current+*l;
 
                 if (**state == '\"')
@@ -266,6 +263,9 @@ char *split_quoted(const char *c, size_t *l, char **state) {
                 *state = current+*l;
         }
 
+        /* FIXME: Cannot deal with strings that have spaces AND ticks
+         * in them */
+
         return (char*) current;
 }
 
@@ -382,3 +382,159 @@ finish:
         fclose(f);
         return r;
 }
+
+char *strappend(const char *s, const char *suffix) {
+        size_t a, b;
+        char *r;
+
+        assert(s);
+        assert(suffix);
+
+        a = strlen(s);
+        b = strlen(suffix);
+
+        if (!(r = new(char, a+b+1)))
+                return NULL;
+
+        memcpy(r, s, a);
+        memcpy(r+a, suffix, b);
+        r[a+b] = 0;
+
+        return r;
+}
+
+int readlink_malloc(const char *p, char **r) {
+        size_t l = 100;
+
+        assert(p);
+        assert(r);
+
+        for (;;) {
+                char *c;
+                ssize_t n;
+
+                if (!(c = new(char, l)))
+                        return -ENOMEM;
+
+                if ((n = readlink(p, c, l-1)) < 0) {
+                        int ret = -errno;
+                        free(c);
+                        return ret;
+                }
+
+                if ((size_t) n < l-1) {
+                        c[n] = 0;
+                        *r = c;
+                        return 0;
+                }
+
+                free(c);
+                l *= 2;
+        }
+}
+
+char *file_name_from_path(const char *p) {
+        char *r;
+
+        assert(p);
+
+        if ((r = strrchr(p, '/')))
+                return r + 1;
+
+        return (char*) p;
+}
+
+bool path_is_absolute(const char *p) {
+        assert(p);
+
+        return p[0] == '/';
+}
+
+bool is_path(const char *p) {
+
+        return !!strchr(p, '/');
+}
+
+char *path_make_absolute(const char *p, const char *prefix) {
+        char *r;
+
+        assert(p);
+
+        if (path_is_absolute(p) || !prefix)
+                return strdup(p);
+
+        if (asprintf(&r, "%s/%s", prefix, p) < 0)
+                return NULL;
+
+        return r;
+}
+
+int reset_all_signal_handlers(void) {
+        int sig;
+
+        for (sig = 1; sig < _NSIG; sig++) {
+                struct sigaction sa;
+
+                if (sig == SIGKILL || sig == SIGSTOP)
+                        continue;
+
+                zero(sa);
+                sa.sa_handler = SIG_DFL;
+
+                /* On Linux the first two RT signals are reserved by
+                 * glibc, and sigaction() will return EINVAL for them. */
+                if ((sigaction(sig, &sa, NULL) < 0))
+                        if (errno != EINVAL)
+                                return -errno;
+        }
+
+    return 0;
+}
+
+char *strstrip(char *s) {
+        char *e, *l = NULL;
+
+        /* Drops trailing whitespace. Modifies the string in
+         * place. Returns pointer to first non-space character */
+
+        s += strspn(s, WHITESPACE);
+
+        for (e = s; *e; e++)
+                if (!strchr(WHITESPACE, *e))
+                        l = e;
+
+        if (l)
+                *(l+1) = 0;
+        else
+                *s = 0;
+
+        return s;
+
+}
+
+char *file_in_same_dir(const char *path, const char *filename) {
+        char *e, *r;
+        size_t k;
+
+        assert(path);
+        assert(filename);
+
+        /* This removes the last component of path and appends
+         * filename, unless the latter is absolute anyway or the
+         * former isn't */
+
+        if (path_is_absolute(filename))
+                return strdup(filename);
+
+        if (!(e = strrchr(path, '/')))
+                return strdup(filename);
+
+        k = strlen(filename);
+        if (!(r = new(char, e-path+1+k+1)))
+                return NULL;
+
+        memcpy(r, path, e-path+1);
+        memcpy(r+(e-path)+1, filename, k+1);
+
+        return r;
+}