chiark / gitweb /
hashmap: allow hashmap_move() to fail
[elogind.git] / src / shared / env-util.c
index 6a52fb960d0e8df25791b66e6375263b8bc7c353..d90b878d1920e56b7a455443be3cc3448d4d17c5 100644 (file)
 #include "utf8.h"
 #include "util.h"
 #include "env-util.h"
+#include "def.h"
+#include "unit.h"
 
 #define VALID_CHARS_ENV_NAME                    \
-        "0123456789"                            \
-        "abcdefghijklmnopqrstuvwxyz"            \
-        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"            \
+        DIGITS LETTERS                          \
         "_"
 
 #ifndef ARG_MAX
@@ -79,7 +79,9 @@ bool env_value_is_valid(const char *e) {
         if (!utf8_is_valid(e))
                 return false;
 
-        if (string_has_cc(e))
+        /* bash allows tabs in environment variables, and so should
+         * we */
+        if (string_has_cc(e, "\t"))
                 return false;
 
         /* POSIX says the overall size of the environment block cannot
@@ -311,7 +313,7 @@ char **strv_env_unset(char **l, const char *p) {
         assert(p);
 
         /* Drops every occurrence of the env var setting p in the
-         * string list. edits in-place. */
+         * string list. Edits in-place. */
 
         for (f = t = l; *f; f++) {
 
@@ -327,6 +329,43 @@ char **strv_env_unset(char **l, const char *p) {
         return l;
 }
 
+char **strv_env_unset_many(char **l, ...) {
+
+        char **f, **t;
+
+        if (!l)
+                return NULL;
+
+        /* Like strv_env_unset() but applies many at once. Edits in-place. */
+
+        for (f = t = l; *f; f++) {
+                bool found = false;
+                const char *p;
+                va_list ap;
+
+                va_start(ap, l);
+
+                while ((p = va_arg(ap, const char*))) {
+                        if (env_match(*f, p)) {
+                                found = true;
+                                break;
+                        }
+                }
+
+                va_end(ap);
+
+                if (found) {
+                        free(*f);
+                        continue;
+                }
+
+                *(t++) = *f;
+        }
+
+        *t = NULL;
+        return l;
+}
+
 char **strv_env_set(char **x, const char *p) {
 
         char **k, **r;
@@ -376,7 +415,7 @@ char *strv_env_get(char **l, const char *name) {
         return strv_env_get_n(l, name, strlen(name));
 }
 
-char **strv_env_clean_log(char **e, const char *message) {
+char **strv_env_clean_log(char **e, const char *unit_id, const char *message) {
         char **p, **q;
         int k = 0;
 
@@ -386,7 +425,7 @@ char **strv_env_clean_log(char **e, const char *message) {
 
                 if (!env_assignment_is_valid(*p)) {
                         if (message)
-                                log_error("Ignoring invalid environment '%s': %s", *p, message);
+                                log_error_unit(unit_id, "Ignoring invalid environment '%s': %s", *p, message);
                         free(*p);
                         continue;
                 }
@@ -406,10 +445,12 @@ char **strv_env_clean_log(char **e, const char *message) {
                 e[k++] = *p;
         }
 
-        e[k] = NULL;
+        if (e)
+                e[k] = NULL;
+
         return e;
 }
 
 char **strv_env_clean(char **e) {
-        return strv_env_clean_log(e, NULL);
+        return strv_env_clean_log(e, NULL, NULL);
 }