fileio.c revision 7ff7394d9e4e9189c30fd018235e6b1728c6f2d0
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering This file is part of systemd.
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering Copyright 2010 Lennart Poettering
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering systemd is free software; you can redistribute it and/or modify it
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering under the terms of the GNU Lesser General Public License as published by
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering (at your option) any later version.
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering systemd is distributed in the hope that it will be useful, but
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering Lesser General Public License for more details.
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering You should have received a copy of the GNU Lesser General Public License
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekint write_string_to_file(FILE *f, const char *line) {
b92bea5d2a9481de69bb627a7b442a9f58fca43dZbigniew Jędrzejewski-Szmekint write_string_file(const char *fn, const char *line) {
b92bea5d2a9481de69bb627a7b442a9f58fca43dZbigniew Jędrzejewski-Szmek _cleanup_fclose_ FILE *f = NULL;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringint write_string_file_atomic(const char *fn, const char *line) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringint read_one_line_file(const char *fn, char **line) {
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering if (!fgets(t, sizeof(t), f)) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringint read_full_file(const char *fn, char **contents, size_t *size) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering /* Safety check */
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering n = st.st_size > 0 ? st.st_size : LINE_MAX;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering /* Safety check */
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering int (*push) (const char *filename, unsigned line,
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering const char *key, char *value, void *userdata),
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering _cleanup_free_ char *contents = NULL, *key = NULL;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering 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;
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering r = read_full_file(fname, &contents, NULL);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering for (p = contents; *p; p++) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (!greedy_realloc((void**) &key, &key_alloc, n_key+2)) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering } else if (c == '=') {
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek last_value_whitespace = (size_t) -1;
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering else if (last_key_whitespace == (size_t) -1)
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering if (!greedy_realloc((void**) &key, &key_alloc, n_key+2)) {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering /* strip trailing whitespace from key */
ac50788b0f5aeee09e7d45db28ae8ab7f39cd52eZbigniew Jędrzejewski-Szmek r = push(fname, line, key, value, userdata);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering } else if (c == '\'')
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering else if (c == '\"')
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering else if (c == '\\')
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering /* Chomp off trailing whitespace from value */
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering if (last_value_whitespace != (size_t) -1)
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering /* strip trailing whitespace from key */
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering r = push(fname, line, key, value, userdata);
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering } else if (c == '\\') {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering else if (last_value_whitespace == (size_t) -1)
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering /* Escaped newlines we eat up entirely */
5809560d858f45351856d6fe786a8117306dd0f2Lennart Poettering if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (c == '\'')
8457f8d6ac7adc6c6ef31378e6e7761cce522141Lennart Poettering else if (c == '\\')
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering else if (c == '\\')
8457f8d6ac7adc6c6ef31378e6e7761cce522141Lennart Poettering if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
8457f8d6ac7adc6c6ef31378e6e7761cce522141Lennart Poettering if (!greedy_realloc((void**) &value, &value_alloc, n_value+2)) {
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (c == '\\')
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering if (last_value_whitespace != (size_t) -1)
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering /* strip trailing whitespace from key */
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering r = push(fname, line, key, value, userdata);
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poetteringstatic int parse_env_file_push(const char *filename, unsigned line,
35e2e347d38cc2f8bd7c38a0d8a5129f5fbb0ab9Lennart Poettering const char *key, char *value, void *userdata) {
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering /* FIXME: filter UTF-8 */
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering log_error("%s:%u: invalid UTF-8 for key %s: '%s', ignoring.",
178cc7700c23ac088cd7190d7854282075028d91Lennart Poettering const char *k;
free(*v);
*v = value;
int parse_env_file(
const char *fname,
const char *newline, ...) {
if (!newline)
char ***m = userdata;
return -ENOMEM;
r = strv_push(m, p);
free(p);
char **m = NULL;
if (!newline)
strv_free(m);
*rl = m;
fputs(v, f);
fputc(*p, f);
fputs(p, f);
errno = 0;
STRV_FOREACH(i, l)
write_env_var(f, *i);
fflush(f);
if (ferror(f))
r = -errno;
unlink(p);
int len;
char *ans;
if (len == 0)
if (!ans)
return -ENOMEM;
return -ENOENT;
if (!*t || isspace(*t))
if (!*field)
return -ENOMEM;