X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fshared%2Ffileio.c;h=48dd44239fa6dc9930072b808eb2e140d3a7ffb9;hb=78edb35ab4f4227485cb9ec816b43c37e0d5e62a;hp=617afeace2bf0eb14930e4e60814b4326bc95ff3;hpb=ced2d10a28cff3bab6fb613652db5abde8ed940e;p=elogind.git diff --git a/src/shared/fileio.c b/src/shared/fileio.c index 617afeace..48dd44239 100644 --- a/src/shared/fileio.c +++ b/src/shared/fileio.c @@ -177,14 +177,13 @@ static int parse_env_file_internal( void *userdata) { _cleanup_free_ char *contents = NULL, *key = NULL; - size_t key_alloc = 0, n_key = 0, value_alloc = 0, n_value = 0, last_whitespace = (size_t) -1; + size_t key_alloc = 0, n_key = 0, value_alloc = 0, n_value = 0, last_value_whitespace = (size_t) -1, last_key_whitespace = (size_t) -1; char *p, *value = NULL; int r; enum { PRE_KEY, KEY, - PRE_EQUAL, PRE_VALUE, VALUE, VALUE_ESCAPE, @@ -213,6 +212,8 @@ static int parse_env_file_internal( state = COMMENT; else if (!strchr(WHITESPACE, c)) { state = KEY; + last_key_whitespace = (size_t) -1; + if (!greedy_realloc((void**) &key, &key_alloc, n_key+2)) { r = -ENOMEM; goto fail; @@ -226,11 +227,15 @@ static int parse_env_file_internal( if (strchr(newline, c)) { state = PRE_KEY; n_key = 0; - } else if (strchr(WHITESPACE, c)) - state = PRE_EQUAL; - else if (c == '=') + } else if (c == '=') { state = PRE_VALUE; - else { + last_value_whitespace = (size_t) -1; + } else { + if (!strchr(WHITESPACE, c)) + last_key_whitespace = (size_t) -1; + else if (last_key_whitespace == (size_t) -1) + last_key_whitespace = n_key; + if (!greedy_realloc((void**) &key, &key_alloc, n_key+2)) { r = -ENOMEM; goto fail; @@ -241,19 +246,6 @@ static int parse_env_file_internal( break; - case PRE_EQUAL: - if (strchr(newline, c)) { - state = PRE_KEY; - n_key = 0; - } else if (c == '=') - state = PRE_VALUE; - else if (!strchr(WHITESPACE, c)) { - n_key = 0; - state = COMMENT; - } - - break; - case PRE_VALUE: if (strchr(newline, c)) { state = PRE_KEY; @@ -262,6 +254,10 @@ static int parse_env_file_internal( if (value) value[n_value] = 0; + /* strip trailing whitespace from key */ + if (last_key_whitespace != (size_t) -1) + key[last_key_whitespace] = 0; + r = push(key, value, userdata); if (r < 0) goto fail; @@ -269,6 +265,7 @@ static int parse_env_file_internal( n_key = 0; value = NULL; value_alloc = n_value = 0; + } else if (c == '\'') state = SINGLE_QUOTE_VALUE; else if (c == '\"') @@ -291,14 +288,19 @@ static int parse_env_file_internal( case VALUE: if (strchr(newline, c)) { state = PRE_KEY; + key[n_key] = 0; if (value) value[n_value] = 0; - /* Chomp off trailing whitespace */ - if (last_whitespace != (size_t) -1) - value[last_whitespace] = 0; + /* Chomp off trailing whitespace from value */ + if (last_value_whitespace != (size_t) -1) + value[last_value_whitespace] = 0; + + /* strip trailing whitespace from key */ + if (last_key_whitespace != (size_t) -1) + key[last_key_whitespace] = 0; r = push(key, value, userdata); if (r < 0) @@ -307,14 +309,15 @@ static int parse_env_file_internal( n_key = 0; value = NULL; value_alloc = n_value = 0; + } else if (c == '\\') { state = VALUE_ESCAPE; - last_whitespace = (size_t) -1; + last_value_whitespace = (size_t) -1; } else { if (!strchr(WHITESPACE, c)) - last_whitespace = (size_t) -1; - else if (last_whitespace == (size_t) -1) - last_whitespace = n_value; + last_value_whitespace = (size_t) -1; + else if (last_value_whitespace == (size_t) -1) + last_value_whitespace = n_value; if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) { r = -ENOMEM; @@ -424,6 +427,14 @@ static int parse_env_file_internal( if (value) value[n_value] = 0; + if (state == VALUE) + if (last_value_whitespace != (size_t) -1) + value[last_value_whitespace] = 0; + + /* strip trailing whitespace from key */ + if (last_key_whitespace != (size_t) -1) + key[last_key_whitespace] = 0; + r = push(key, value, userdata); if (r < 0) goto fail; @@ -548,8 +559,8 @@ static void write_env_var(FILE *f, const char *v) { int write_env_file(const char *fname, char **l) { char **i; - char _cleanup_free_ *p = NULL; - FILE _cleanup_fclose_ *f = NULL; + _cleanup_free_ char *p = NULL; + _cleanup_fclose_ FILE *f = NULL; int r; r = fopen_temporary(fname, &f, &p);