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 r = read_full_file(fname, &contents, NULL);
196 const char *key = NULL;
198 p += strspn(p, separator);
199 p += strspn(p, WHITESPACE);
204 if (!strchr(COMMENTS, *p)) {
208 va_start(ap, separator);
209 while ((key = va_arg(ap, char *))) {
213 value = va_arg(ap, char **);
216 if (!strneq(p, key, n) ||
221 n = strcspn(p, separator);
224 strchr(QUOTES, p[0]) &&
226 v = strndup(p+1, n-2);
237 /* return empty value strings as NULL */
254 p += strcspn(p, separator);
262 int load_env_file(const char *fname, char ***rl) {
264 _cleanup_fclose_ FILE *f;
265 _cleanup_strv_free_ char **m = NULL;
266 _cleanup_free_ char *c = NULL;
271 /* This reads an environment file, but will not complain about
272 * any invalid assignments, that needs to be done by the
275 f = fopen(fname, "re");
280 char l[LINE_MAX], *p, *cs, *b;
282 if (!fgets(l, sizeof(l), f)) {
286 /* The previous line was a continuation line?
287 * Let's process it now, before we leave the
295 /* Is this a continuation line? If so, just append
296 * this to c, and go to next line right-away */
297 cs = endswith(l, "\\\n");
309 /* If the previous line was a continuation line,
310 * append the current line to it */
321 p = strstrip(c ? c : l);
323 if (*p && !strchr(COMMENTS, *p)) {
324 _cleanup_free_ char *u;
327 u = normalize_env_assignment(p);
331 k = strv_extend(&m, u);
346 int write_env_file(const char *fname, char **l) {
348 char _cleanup_free_ *p = NULL;
349 FILE _cleanup_fclose_ *f = NULL;
352 r = fopen_temporary(fname, &f, &p);
356 fchmod_umask(fileno(f), 0644);
372 if (rename(p, fname) < 0)