1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
27 int write_one_line_file(const char *fn, const char *line) {
28 _cleanup_fclose_ FILE *f = NULL;
38 if (fputs(line, f) < 0)
39 return errno ? -errno : -EIO;
41 if (!endswith(line, "\n"))
47 return errno ? -errno : -EIO;
52 int write_one_line_file_atomic(const char *fn, const char *line) {
53 _cleanup_fclose_ FILE *f = NULL;
54 _cleanup_free_ char *p = NULL;
60 r = fopen_temporary(fn, &f, &p);
64 fchmod_umask(fileno(f), 0644);
67 if (fputs(line, f) < 0) {
72 if (!endswith(line, "\n"))
78 r = errno ? -errno : -EIO;
80 if (rename(p, fn) < 0)
93 int read_one_line_file(const char *fn, char **line) {
94 _cleanup_fclose_ FILE *f = NULL;
104 if (!fgets(t, sizeof(t), f)) {
107 return errno ? -errno : -EIO;
121 int read_full_file(const char *fn, char **contents, size_t *size) {
122 _cleanup_fclose_ FILE *f = NULL;
124 _cleanup_free_ char *buf = NULL;
134 if (fstat(fileno(f), &st) < 0)
138 if (st.st_size > 4*1024*1024)
141 n = st.st_size > 0 ? st.st_size : LINE_MAX;
148 t = realloc(buf, n+1);
153 k = fread(buf + l, 1, n - l, f);
182 const char *separator, ...) {
185 char *contents = NULL, *p;
190 if ((r = read_full_file(fname, &contents, NULL)) < 0)
195 const char *key = NULL;
197 p += strspn(p, separator);
198 p += strspn(p, WHITESPACE);
203 if (!strchr(COMMENTS, *p)) {
207 va_start(ap, separator);
208 while ((key = va_arg(ap, char *))) {
212 value = va_arg(ap, char **);
215 if (!strneq(p, key, n) ||
220 n = strcspn(p, separator);
223 strchr(QUOTES, p[0]) &&
225 v = strndup(p+1, n-2);
236 /* return empty value strings as NULL */
253 p += strcspn(p, separator);
261 int load_env_file(const char *fname, char ***rl) {
263 _cleanup_fclose_ FILE *f;
264 _cleanup_strv_free_ char **m = NULL;
265 _cleanup_free_ char *c = NULL;
270 /* This reads an environment file, but will not complain about
271 * any invalid assignments, that needs to be done by the
274 f = fopen(fname, "re");
279 char l[LINE_MAX], *p, *cs, *b;
281 if (!fgets(l, sizeof(l), f)) {
285 /* The previous line was a continuation line?
286 * Let's process it now, before we leave the
294 /* Is this a continuation line? If so, just append
295 * this to c, and go to next line right-away */
296 cs = endswith(l, "\\\n");
308 /* If the previous line was a continuation line,
309 * append the current line to it */
320 p = strstrip(c ? c : l);
322 if (*p && !strchr(COMMENTS, *p)) {
323 _cleanup_free_ char *u;
326 u = normalize_env_assignment(p);
330 k = strv_extend(&m, u);
345 int write_env_file(const char *fname, char **l) {
350 r = fopen_temporary(fname, &f, &p);
354 fchmod_umask(fileno(f), 0644);
370 if (rename(p, fname) < 0)