Commit 768100ef authored by Lennart Poettering's avatar Lennart Poettering

fileio: write proper env var write-out code

This will properly escape all weird chars when writing env var files.
With this in place we can now read and write environment files where the
values contain arbitrary weird chars.

This enables hostnamed and suchlike to finally properly save pretty host
names with backlashes or quotes in them.
parent f73141d7
......@@ -522,6 +522,37 @@ int load_env_file(const char *fname, const char *newline, char ***rl) {
return 0;
}
static void write_env_var(FILE *f, const char *v) {
const char *p;
p = strchr(v, '=');
if (!p) {
/* Fallback */
fputs(v, f);
fputc('\n', f);
return;
}
p++;
fwrite(v, 1, p-v, f);
if (string_has_cc(p) || chars_intersect(p, WHITESPACE "\'\"\\")) {
fputc('\"', f);
for (; *p; p++) {
if (strchr("\'\"\\", *p))
fputc('\\', f);
fputc(*p, f);
}
fputc('\"', f);
} else
fputs(p, f);
fputc('\n', f);
}
int write_env_file(const char *fname, char **l) {
char **i;
char _cleanup_free_ *p = NULL;
......@@ -535,10 +566,8 @@ int write_env_file(const char *fname, char **l) {
fchmod_umask(fileno(f), 0644);
errno = 0;
STRV_FOREACH(i, l) {
fputs(*i, f);
fputc('\n', f);
}
STRV_FOREACH(i, l)
write_env_var(f, *i);
fflush(f);
......
......@@ -32,8 +32,9 @@ static void test_parse_env_file(void) {
int fd, r;
FILE *f;
_cleanup_free_ char *one = NULL, *two = NULL, *three = NULL, *four = NULL, *five = NULL, *six = NULL, *seven = NULL;
_cleanup_strv_free_ char **a = NULL;
_cleanup_strv_free_ char **a = NULL, **b = NULL;
char **i;
unsigned k;
fd = mkostemp(t, O_CLOEXEC);
assert_se(fd >= 0);
......@@ -90,9 +91,31 @@ static void test_parse_env_file(void) {
assert_se(r >= 0);
STRV_FOREACH(i, a)
log_info("Got: %s", *i);
log_info("Got: <%s>", *i);
assert_se(streq(a[0], "one=BAR"));
assert_se(streq(a[1], "two=bar"));
assert_se(streq(a[2], "three=333\nxxxx"));
assert_se(streq(a[3], "four=44\"44"));
assert_se(streq(a[4], "five=55\'55FIVEcinco"));
assert_se(streq(a[5], "six=seis sechs sis"));
assert_se(streq(a[6], "seven="));
assert_se(a[7] == NULL);
r = write_env_file("/tmp/test-fileio", a);
assert_se(r >= 0);
r = load_env_file("/tmp/test-fileio", NULL, &b);
assert_se(r >= 0);
k = 0;
STRV_FOREACH(i, b) {
log_info("Got2: <%s>", *i);
assert_se(streq(*i, a[k++]));
}
unlink(t);
unlink("/tmp/test-fileio");
}
int main(int argc, char *argv[]) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment