]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/fileio.c
tree-wide: make use of fsync_directory_of_file() all over the place
[thirdparty/systemd.git] / src / basic / fileio.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright 2010 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <limits.h>
24 #include <stdarg.h>
25 #include <stdint.h>
26 #include <stdio_ext.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/mman.h>
30 #include <sys/stat.h>
31 #include <sys/types.h>
32 #include <unistd.h>
33
34 #include "alloc-util.h"
35 #include "ctype.h"
36 #include "def.h"
37 #include "env-util.h"
38 #include "escape.h"
39 #include "fd-util.h"
40 #include "fileio.h"
41 #include "fs-util.h"
42 #include "hexdecoct.h"
43 #include "log.h"
44 #include "macro.h"
45 #include "missing.h"
46 #include "parse-util.h"
47 #include "path-util.h"
48 #include "process-util.h"
49 #include "random-util.h"
50 #include "stdio-util.h"
51 #include "string-util.h"
52 #include "strv.h"
53 #include "time-util.h"
54 #include "umask-util.h"
55 #include "utf8.h"
56
57 #define READ_FULL_BYTES_MAX (4U*1024U*1024U)
58
59 int write_string_stream_ts(
60 FILE *f,
61 const char *line,
62 WriteStringFileFlags flags,
63 struct timespec *ts) {
64
65 bool needs_nl;
66
67 assert(f);
68 assert(line);
69
70 if (ferror(f))
71 return -EIO;
72
73 needs_nl = !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) && !endswith(line, "\n");
74
75 if (needs_nl && (flags & WRITE_STRING_FILE_DISABLE_BUFFER)) {
76 /* If STDIO buffering was disabled, then let's append the newline character to the string itself, so
77 * that the write goes out in one go, instead of two */
78
79 line = strjoina(line, "\n");
80 needs_nl = false;
81 }
82
83 if (fputs(line, f) == EOF)
84 return -errno;
85
86 if (needs_nl)
87 if (fputc('\n', f) == EOF)
88 return -errno;
89
90 if (ts) {
91 struct timespec twice[2] = {*ts, *ts};
92
93 if (futimens(fileno(f), twice) < 0)
94 return -errno;
95 }
96
97 if (flags & WRITE_STRING_FILE_SYNC)
98 return fflush_sync_and_check(f);
99 else
100 return fflush_and_check(f);
101 }
102
103 static int write_string_file_atomic(
104 const char *fn,
105 const char *line,
106 WriteStringFileFlags flags,
107 struct timespec *ts) {
108
109 _cleanup_fclose_ FILE *f = NULL;
110 _cleanup_free_ char *p = NULL;
111 int r;
112
113 assert(fn);
114 assert(line);
115
116 r = fopen_temporary(fn, &f, &p);
117 if (r < 0)
118 return r;
119
120 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
121 (void) fchmod_umask(fileno(f), 0644);
122
123 r = write_string_stream_ts(f, line, flags, ts);
124 if (r < 0)
125 goto fail;
126
127 if (rename(p, fn) < 0) {
128 r = -errno;
129 goto fail;
130 }
131
132 return 0;
133
134 fail:
135 (void) unlink(p);
136 return r;
137 }
138
139 int write_string_file_ts(
140 const char *fn,
141 const char *line,
142 WriteStringFileFlags flags,
143 struct timespec *ts) {
144
145 _cleanup_fclose_ FILE *f = NULL;
146 int q, r;
147
148 assert(fn);
149 assert(line);
150
151 /* We don't know how to verify whether the file contents was already on-disk. */
152 assert(!((flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE) && (flags & WRITE_STRING_FILE_SYNC)));
153
154 if (flags & WRITE_STRING_FILE_ATOMIC) {
155 assert(flags & WRITE_STRING_FILE_CREATE);
156
157 r = write_string_file_atomic(fn, line, flags, ts);
158 if (r < 0)
159 goto fail;
160
161 return r;
162 } else
163 assert(!ts);
164
165 if (flags & WRITE_STRING_FILE_CREATE) {
166 f = fopen(fn, "we");
167 if (!f) {
168 r = -errno;
169 goto fail;
170 }
171 } else {
172 int fd;
173
174 /* We manually build our own version of fopen(..., "we") that
175 * works without O_CREAT */
176 fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY);
177 if (fd < 0) {
178 r = -errno;
179 goto fail;
180 }
181
182 f = fdopen(fd, "we");
183 if (!f) {
184 r = -errno;
185 safe_close(fd);
186 goto fail;
187 }
188 }
189
190 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
191
192 if (flags & WRITE_STRING_FILE_DISABLE_BUFFER)
193 setvbuf(f, NULL, _IONBF, 0);
194
195 r = write_string_stream_ts(f, line, flags, ts);
196 if (r < 0)
197 goto fail;
198
199 return 0;
200
201 fail:
202 if (!(flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE))
203 return r;
204
205 f = safe_fclose(f);
206
207 /* OK, the operation failed, but let's see if the right
208 * contents in place already. If so, eat up the error. */
209
210 q = verify_file(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE));
211 if (q <= 0)
212 return r;
213
214 return 0;
215 }
216
217 int read_one_line_file(const char *fn, char **line) {
218 _cleanup_fclose_ FILE *f = NULL;
219 int r;
220
221 assert(fn);
222 assert(line);
223
224 f = fopen(fn, "re");
225 if (!f)
226 return -errno;
227
228 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
229
230 r = read_line(f, LONG_LINE_MAX, line);
231 return r < 0 ? r : 0;
232 }
233
234 int verify_file(const char *fn, const char *blob, bool accept_extra_nl) {
235 _cleanup_fclose_ FILE *f = NULL;
236 _cleanup_free_ char *buf = NULL;
237 size_t l, k;
238
239 assert(fn);
240 assert(blob);
241
242 l = strlen(blob);
243
244 if (accept_extra_nl && endswith(blob, "\n"))
245 accept_extra_nl = false;
246
247 buf = malloc(l + accept_extra_nl + 1);
248 if (!buf)
249 return -ENOMEM;
250
251 f = fopen(fn, "re");
252 if (!f)
253 return -errno;
254
255 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
256
257 /* We try to read one byte more than we need, so that we know whether we hit eof */
258 errno = 0;
259 k = fread(buf, 1, l + accept_extra_nl + 1, f);
260 if (ferror(f))
261 return errno > 0 ? -errno : -EIO;
262
263 if (k != l && k != l + accept_extra_nl)
264 return 0;
265 if (memcmp(buf, blob, l) != 0)
266 return 0;
267 if (k > l && buf[l] != '\n')
268 return 0;
269
270 return 1;
271 }
272
273 int read_full_stream(FILE *f, char **contents, size_t *size) {
274 size_t n, l;
275 _cleanup_free_ char *buf = NULL;
276 struct stat st;
277
278 assert(f);
279 assert(contents);
280
281 if (fstat(fileno(f), &st) < 0)
282 return -errno;
283
284 n = LINE_MAX;
285
286 if (S_ISREG(st.st_mode)) {
287
288 /* Safety check */
289 if (st.st_size > READ_FULL_BYTES_MAX)
290 return -E2BIG;
291
292 /* Start with the right file size, but be prepared for files from /proc which generally report a file
293 * size of 0. Note that we increase the size to read here by one, so that the first read attempt
294 * already makes us notice the EOF. */
295 if (st.st_size > 0)
296 n = st.st_size + 1;
297 }
298
299 l = 0;
300 for (;;) {
301 char *t;
302 size_t k;
303
304 t = realloc(buf, n + 1);
305 if (!t)
306 return -ENOMEM;
307
308 buf = t;
309 errno = 0;
310 k = fread(buf + l, 1, n - l, f);
311 if (k > 0)
312 l += k;
313
314 if (ferror(f))
315 return errno > 0 ? -errno : -EIO;
316
317 if (feof(f))
318 break;
319
320 /* We aren't expecting fread() to return a short read outside
321 * of (error && eof), assert buffer is full and enlarge buffer.
322 */
323 assert(l == n);
324
325 /* Safety check */
326 if (n >= READ_FULL_BYTES_MAX)
327 return -E2BIG;
328
329 n = MIN(n * 2, READ_FULL_BYTES_MAX);
330 }
331
332 buf[l] = 0;
333 *contents = buf;
334 buf = NULL; /* do not free */
335
336 if (size)
337 *size = l;
338
339 return 0;
340 }
341
342 int read_full_file(const char *fn, char **contents, size_t *size) {
343 _cleanup_fclose_ FILE *f = NULL;
344
345 assert(fn);
346 assert(contents);
347
348 f = fopen(fn, "re");
349 if (!f)
350 return -errno;
351
352 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
353
354 return read_full_stream(f, contents, size);
355 }
356
357 static int parse_env_file_internal(
358 FILE *f,
359 const char *fname,
360 const char *newline,
361 int (*push) (const char *filename, unsigned line,
362 const char *key, char *value, void *userdata, int *n_pushed),
363 void *userdata,
364 int *n_pushed) {
365
366 _cleanup_free_ char *contents = NULL, *key = NULL;
367 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;
368 char *p, *value = NULL;
369 int r;
370 unsigned line = 1;
371
372 enum {
373 PRE_KEY,
374 KEY,
375 PRE_VALUE,
376 VALUE,
377 VALUE_ESCAPE,
378 SINGLE_QUOTE_VALUE,
379 SINGLE_QUOTE_VALUE_ESCAPE,
380 DOUBLE_QUOTE_VALUE,
381 DOUBLE_QUOTE_VALUE_ESCAPE,
382 COMMENT,
383 COMMENT_ESCAPE
384 } state = PRE_KEY;
385
386 assert(newline);
387
388 if (f)
389 r = read_full_stream(f, &contents, NULL);
390 else
391 r = read_full_file(fname, &contents, NULL);
392 if (r < 0)
393 return r;
394
395 for (p = contents; *p; p++) {
396 char c = *p;
397
398 switch (state) {
399
400 case PRE_KEY:
401 if (strchr(COMMENTS, c))
402 state = COMMENT;
403 else if (!strchr(WHITESPACE, c)) {
404 state = KEY;
405 last_key_whitespace = (size_t) -1;
406
407 if (!GREEDY_REALLOC(key, key_alloc, n_key+2)) {
408 r = -ENOMEM;
409 goto fail;
410 }
411
412 key[n_key++] = c;
413 }
414 break;
415
416 case KEY:
417 if (strchr(newline, c)) {
418 state = PRE_KEY;
419 line++;
420 n_key = 0;
421 } else if (c == '=') {
422 state = PRE_VALUE;
423 last_value_whitespace = (size_t) -1;
424 } else {
425 if (!strchr(WHITESPACE, c))
426 last_key_whitespace = (size_t) -1;
427 else if (last_key_whitespace == (size_t) -1)
428 last_key_whitespace = n_key;
429
430 if (!GREEDY_REALLOC(key, key_alloc, n_key+2)) {
431 r = -ENOMEM;
432 goto fail;
433 }
434
435 key[n_key++] = c;
436 }
437
438 break;
439
440 case PRE_VALUE:
441 if (strchr(newline, c)) {
442 state = PRE_KEY;
443 line++;
444 key[n_key] = 0;
445
446 if (value)
447 value[n_value] = 0;
448
449 /* strip trailing whitespace from key */
450 if (last_key_whitespace != (size_t) -1)
451 key[last_key_whitespace] = 0;
452
453 r = push(fname, line, key, value, userdata, n_pushed);
454 if (r < 0)
455 goto fail;
456
457 n_key = 0;
458 value = NULL;
459 value_alloc = n_value = 0;
460
461 } else if (c == '\'')
462 state = SINGLE_QUOTE_VALUE;
463 else if (c == '\"')
464 state = DOUBLE_QUOTE_VALUE;
465 else if (c == '\\')
466 state = VALUE_ESCAPE;
467 else if (!strchr(WHITESPACE, c)) {
468 state = VALUE;
469
470 if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
471 r = -ENOMEM;
472 goto fail;
473 }
474
475 value[n_value++] = c;
476 }
477
478 break;
479
480 case VALUE:
481 if (strchr(newline, c)) {
482 state = PRE_KEY;
483 line++;
484
485 key[n_key] = 0;
486
487 if (value)
488 value[n_value] = 0;
489
490 /* Chomp off trailing whitespace from value */
491 if (last_value_whitespace != (size_t) -1)
492 value[last_value_whitespace] = 0;
493
494 /* strip trailing whitespace from key */
495 if (last_key_whitespace != (size_t) -1)
496 key[last_key_whitespace] = 0;
497
498 r = push(fname, line, key, value, userdata, n_pushed);
499 if (r < 0)
500 goto fail;
501
502 n_key = 0;
503 value = NULL;
504 value_alloc = n_value = 0;
505
506 } else if (c == '\\') {
507 state = VALUE_ESCAPE;
508 last_value_whitespace = (size_t) -1;
509 } else {
510 if (!strchr(WHITESPACE, c))
511 last_value_whitespace = (size_t) -1;
512 else if (last_value_whitespace == (size_t) -1)
513 last_value_whitespace = n_value;
514
515 if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
516 r = -ENOMEM;
517 goto fail;
518 }
519
520 value[n_value++] = c;
521 }
522
523 break;
524
525 case VALUE_ESCAPE:
526 state = VALUE;
527
528 if (!strchr(newline, c)) {
529 /* Escaped newlines we eat up entirely */
530 if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
531 r = -ENOMEM;
532 goto fail;
533 }
534
535 value[n_value++] = c;
536 }
537 break;
538
539 case SINGLE_QUOTE_VALUE:
540 if (c == '\'')
541 state = PRE_VALUE;
542 else if (c == '\\')
543 state = SINGLE_QUOTE_VALUE_ESCAPE;
544 else {
545 if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
546 r = -ENOMEM;
547 goto fail;
548 }
549
550 value[n_value++] = c;
551 }
552
553 break;
554
555 case SINGLE_QUOTE_VALUE_ESCAPE:
556 state = SINGLE_QUOTE_VALUE;
557
558 if (!strchr(newline, c)) {
559 if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
560 r = -ENOMEM;
561 goto fail;
562 }
563
564 value[n_value++] = c;
565 }
566 break;
567
568 case DOUBLE_QUOTE_VALUE:
569 if (c == '\"')
570 state = PRE_VALUE;
571 else if (c == '\\')
572 state = DOUBLE_QUOTE_VALUE_ESCAPE;
573 else {
574 if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
575 r = -ENOMEM;
576 goto fail;
577 }
578
579 value[n_value++] = c;
580 }
581
582 break;
583
584 case DOUBLE_QUOTE_VALUE_ESCAPE:
585 state = DOUBLE_QUOTE_VALUE;
586
587 if (!strchr(newline, c)) {
588 if (!GREEDY_REALLOC(value, value_alloc, n_value+2)) {
589 r = -ENOMEM;
590 goto fail;
591 }
592
593 value[n_value++] = c;
594 }
595 break;
596
597 case COMMENT:
598 if (c == '\\')
599 state = COMMENT_ESCAPE;
600 else if (strchr(newline, c)) {
601 state = PRE_KEY;
602 line++;
603 }
604 break;
605
606 case COMMENT_ESCAPE:
607 state = COMMENT;
608 break;
609 }
610 }
611
612 if (IN_SET(state,
613 PRE_VALUE,
614 VALUE,
615 VALUE_ESCAPE,
616 SINGLE_QUOTE_VALUE,
617 SINGLE_QUOTE_VALUE_ESCAPE,
618 DOUBLE_QUOTE_VALUE,
619 DOUBLE_QUOTE_VALUE_ESCAPE)) {
620
621 key[n_key] = 0;
622
623 if (value)
624 value[n_value] = 0;
625
626 if (state == VALUE)
627 if (last_value_whitespace != (size_t) -1)
628 value[last_value_whitespace] = 0;
629
630 /* strip trailing whitespace from key */
631 if (last_key_whitespace != (size_t) -1)
632 key[last_key_whitespace] = 0;
633
634 r = push(fname, line, key, value, userdata, n_pushed);
635 if (r < 0)
636 goto fail;
637 }
638
639 return 0;
640
641 fail:
642 free(value);
643 return r;
644 }
645
646 static int check_utf8ness_and_warn(
647 const char *filename, unsigned line,
648 const char *key, char *value) {
649
650 if (!utf8_is_valid(key)) {
651 _cleanup_free_ char *p = NULL;
652
653 p = utf8_escape_invalid(key);
654 log_error("%s:%u: invalid UTF-8 in key '%s', ignoring.", strna(filename), line, p);
655 return -EINVAL;
656 }
657
658 if (value && !utf8_is_valid(value)) {
659 _cleanup_free_ char *p = NULL;
660
661 p = utf8_escape_invalid(value);
662 log_error("%s:%u: invalid UTF-8 value for key %s: '%s', ignoring.", strna(filename), line, key, p);
663 return -EINVAL;
664 }
665
666 return 0;
667 }
668
669 static int parse_env_file_push(
670 const char *filename, unsigned line,
671 const char *key, char *value,
672 void *userdata,
673 int *n_pushed) {
674
675 const char *k;
676 va_list aq, *ap = userdata;
677 int r;
678
679 r = check_utf8ness_and_warn(filename, line, key, value);
680 if (r < 0)
681 return r;
682
683 va_copy(aq, *ap);
684
685 while ((k = va_arg(aq, const char *))) {
686 char **v;
687
688 v = va_arg(aq, char **);
689
690 if (streq(key, k)) {
691 va_end(aq);
692 free(*v);
693 *v = value;
694
695 if (n_pushed)
696 (*n_pushed)++;
697
698 return 1;
699 }
700 }
701
702 va_end(aq);
703 free(value);
704
705 return 0;
706 }
707
708 int parse_env_file(
709 const char *fname,
710 const char *newline, ...) {
711
712 va_list ap;
713 int r, n_pushed = 0;
714
715 if (!newline)
716 newline = NEWLINE;
717
718 va_start(ap, newline);
719 r = parse_env_file_internal(NULL, fname, newline, parse_env_file_push, &ap, &n_pushed);
720 va_end(ap);
721
722 return r < 0 ? r : n_pushed;
723 }
724
725 static int load_env_file_push(
726 const char *filename, unsigned line,
727 const char *key, char *value,
728 void *userdata,
729 int *n_pushed) {
730 char ***m = userdata;
731 char *p;
732 int r;
733
734 r = check_utf8ness_and_warn(filename, line, key, value);
735 if (r < 0)
736 return r;
737
738 p = strjoin(key, "=", value);
739 if (!p)
740 return -ENOMEM;
741
742 r = strv_env_replace(m, p);
743 if (r < 0) {
744 free(p);
745 return r;
746 }
747
748 if (n_pushed)
749 (*n_pushed)++;
750
751 free(value);
752 return 0;
753 }
754
755 int load_env_file(FILE *f, const char *fname, const char *newline, char ***rl) {
756 char **m = NULL;
757 int r;
758
759 if (!newline)
760 newline = NEWLINE;
761
762 r = parse_env_file_internal(f, fname, newline, load_env_file_push, &m, NULL);
763 if (r < 0) {
764 strv_free(m);
765 return r;
766 }
767
768 *rl = m;
769 return 0;
770 }
771
772 static int load_env_file_push_pairs(
773 const char *filename, unsigned line,
774 const char *key, char *value,
775 void *userdata,
776 int *n_pushed) {
777 char ***m = userdata;
778 int r;
779
780 r = check_utf8ness_and_warn(filename, line, key, value);
781 if (r < 0)
782 return r;
783
784 r = strv_extend(m, key);
785 if (r < 0)
786 return -ENOMEM;
787
788 if (!value) {
789 r = strv_extend(m, "");
790 if (r < 0)
791 return -ENOMEM;
792 } else {
793 r = strv_push(m, value);
794 if (r < 0)
795 return r;
796 }
797
798 if (n_pushed)
799 (*n_pushed)++;
800
801 return 0;
802 }
803
804 int load_env_file_pairs(FILE *f, const char *fname, const char *newline, char ***rl) {
805 char **m = NULL;
806 int r;
807
808 if (!newline)
809 newline = NEWLINE;
810
811 r = parse_env_file_internal(f, fname, newline, load_env_file_push_pairs, &m, NULL);
812 if (r < 0) {
813 strv_free(m);
814 return r;
815 }
816
817 *rl = m;
818 return 0;
819 }
820
821 static int merge_env_file_push(
822 const char *filename, unsigned line,
823 const char *key, char *value,
824 void *userdata,
825 int *n_pushed) {
826
827 char ***env = userdata;
828 char *expanded_value;
829
830 assert(env);
831
832 if (!value) {
833 log_error("%s:%u: invalid syntax (around \"%s\"), ignoring.", strna(filename), line, key);
834 return 0;
835 }
836
837 if (!env_name_is_valid(key)) {
838 log_error("%s:%u: invalid variable name \"%s\", ignoring.", strna(filename), line, key);
839 free(value);
840 return 0;
841 }
842
843 expanded_value = replace_env(value, *env,
844 REPLACE_ENV_USE_ENVIRONMENT|
845 REPLACE_ENV_ALLOW_BRACELESS|
846 REPLACE_ENV_ALLOW_EXTENDED);
847 if (!expanded_value)
848 return -ENOMEM;
849
850 free_and_replace(value, expanded_value);
851
852 return load_env_file_push(filename, line, key, value, env, n_pushed);
853 }
854
855 int merge_env_file(
856 char ***env,
857 FILE *f,
858 const char *fname) {
859
860 /* NOTE: this function supports braceful and braceless variable expansions,
861 * plus "extended" substitutions, unlike other exported parsing functions.
862 */
863
864 return parse_env_file_internal(f, fname, NEWLINE, merge_env_file_push, env, NULL);
865 }
866
867 static void write_env_var(FILE *f, const char *v) {
868 const char *p;
869
870 p = strchr(v, '=');
871 if (!p) {
872 /* Fallback */
873 fputs_unlocked(v, f);
874 fputc_unlocked('\n', f);
875 return;
876 }
877
878 p++;
879 fwrite_unlocked(v, 1, p-v, f);
880
881 if (string_has_cc(p, NULL) || chars_intersect(p, WHITESPACE SHELL_NEED_QUOTES)) {
882 fputc_unlocked('\"', f);
883
884 for (; *p; p++) {
885 if (strchr(SHELL_NEED_ESCAPE, *p))
886 fputc_unlocked('\\', f);
887
888 fputc_unlocked(*p, f);
889 }
890
891 fputc_unlocked('\"', f);
892 } else
893 fputs_unlocked(p, f);
894
895 fputc_unlocked('\n', f);
896 }
897
898 int write_env_file(const char *fname, char **l) {
899 _cleanup_fclose_ FILE *f = NULL;
900 _cleanup_free_ char *p = NULL;
901 char **i;
902 int r;
903
904 assert(fname);
905
906 r = fopen_temporary(fname, &f, &p);
907 if (r < 0)
908 return r;
909
910 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
911 (void) fchmod_umask(fileno(f), 0644);
912
913 STRV_FOREACH(i, l)
914 write_env_var(f, *i);
915
916 r = fflush_and_check(f);
917 if (r >= 0) {
918 if (rename(p, fname) >= 0)
919 return 0;
920
921 r = -errno;
922 }
923
924 unlink(p);
925 return r;
926 }
927
928 int executable_is_script(const char *path, char **interpreter) {
929 _cleanup_free_ char *line = NULL;
930 size_t len;
931 char *ans;
932 int r;
933
934 assert(path);
935
936 r = read_one_line_file(path, &line);
937 if (r == -ENOBUFS) /* First line overly long? if so, then it's not a script */
938 return 0;
939 if (r < 0)
940 return r;
941
942 if (!startswith(line, "#!"))
943 return 0;
944
945 ans = strstrip(line + 2);
946 len = strcspn(ans, " \t");
947
948 if (len == 0)
949 return 0;
950
951 ans = strndup(ans, len);
952 if (!ans)
953 return -ENOMEM;
954
955 *interpreter = ans;
956 return 1;
957 }
958
959 /**
960 * Retrieve one field from a file like /proc/self/status. pattern
961 * should not include whitespace or the delimiter (':'). pattern matches only
962 * the beginning of a line. Whitespace before ':' is skipped. Whitespace and
963 * zeros after the ':' will be skipped. field must be freed afterwards.
964 * terminator specifies the terminating characters of the field value (not
965 * included in the value).
966 */
967 int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field) {
968 _cleanup_free_ char *status = NULL;
969 char *t, *f;
970 size_t len;
971 int r;
972
973 assert(terminator);
974 assert(filename);
975 assert(pattern);
976 assert(field);
977
978 r = read_full_file(filename, &status, NULL);
979 if (r < 0)
980 return r;
981
982 t = status;
983
984 do {
985 bool pattern_ok;
986
987 do {
988 t = strstr(t, pattern);
989 if (!t)
990 return -ENOENT;
991
992 /* Check that pattern occurs in beginning of line. */
993 pattern_ok = (t == status || t[-1] == '\n');
994
995 t += strlen(pattern);
996
997 } while (!pattern_ok);
998
999 t += strspn(t, " \t");
1000 if (!*t)
1001 return -ENOENT;
1002
1003 } while (*t != ':');
1004
1005 t++;
1006
1007 if (*t) {
1008 t += strspn(t, " \t");
1009
1010 /* Also skip zeros, because when this is used for
1011 * capabilities, we don't want the zeros. This way the
1012 * same capability set always maps to the same string,
1013 * irrespective of the total capability set size. For
1014 * other numbers it shouldn't matter. */
1015 t += strspn(t, "0");
1016 /* Back off one char if there's nothing but whitespace
1017 and zeros */
1018 if (!*t || isspace(*t))
1019 t--;
1020 }
1021
1022 len = strcspn(t, terminator);
1023
1024 f = strndup(t, len);
1025 if (!f)
1026 return -ENOMEM;
1027
1028 *field = f;
1029 return 0;
1030 }
1031
1032 DIR *xopendirat(int fd, const char *name, int flags) {
1033 int nfd;
1034 DIR *d;
1035
1036 assert(!(flags & O_CREAT));
1037
1038 nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
1039 if (nfd < 0)
1040 return NULL;
1041
1042 d = fdopendir(nfd);
1043 if (!d) {
1044 safe_close(nfd);
1045 return NULL;
1046 }
1047
1048 return d;
1049 }
1050
1051 static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
1052 char **i;
1053
1054 assert(path);
1055 assert(mode);
1056 assert(_f);
1057
1058 if (!path_strv_resolve_uniq(search, root))
1059 return -ENOMEM;
1060
1061 STRV_FOREACH(i, search) {
1062 _cleanup_free_ char *p = NULL;
1063 FILE *f;
1064
1065 if (root)
1066 p = strjoin(root, *i, "/", path);
1067 else
1068 p = strjoin(*i, "/", path);
1069 if (!p)
1070 return -ENOMEM;
1071
1072 f = fopen(p, mode);
1073 if (f) {
1074 *_f = f;
1075 return 0;
1076 }
1077
1078 if (errno != ENOENT)
1079 return -errno;
1080 }
1081
1082 return -ENOENT;
1083 }
1084
1085 int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
1086 _cleanup_strv_free_ char **copy = NULL;
1087
1088 assert(path);
1089 assert(mode);
1090 assert(_f);
1091
1092 if (path_is_absolute(path)) {
1093 FILE *f;
1094
1095 f = fopen(path, mode);
1096 if (f) {
1097 *_f = f;
1098 return 0;
1099 }
1100
1101 return -errno;
1102 }
1103
1104 copy = strv_copy((char**) search);
1105 if (!copy)
1106 return -ENOMEM;
1107
1108 return search_and_fopen_internal(path, mode, root, copy, _f);
1109 }
1110
1111 int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
1112 _cleanup_strv_free_ char **s = NULL;
1113
1114 if (path_is_absolute(path)) {
1115 FILE *f;
1116
1117 f = fopen(path, mode);
1118 if (f) {
1119 *_f = f;
1120 return 0;
1121 }
1122
1123 return -errno;
1124 }
1125
1126 s = strv_split_nulstr(search);
1127 if (!s)
1128 return -ENOMEM;
1129
1130 return search_and_fopen_internal(path, mode, root, s, _f);
1131 }
1132
1133 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
1134 FILE *f;
1135 char *t;
1136 int r, fd;
1137
1138 assert(path);
1139 assert(_f);
1140 assert(_temp_path);
1141
1142 r = tempfn_xxxxxx(path, NULL, &t);
1143 if (r < 0)
1144 return r;
1145
1146 fd = mkostemp_safe(t);
1147 if (fd < 0) {
1148 free(t);
1149 return -errno;
1150 }
1151
1152 f = fdopen(fd, "we");
1153 if (!f) {
1154 unlink_noerrno(t);
1155 free(t);
1156 safe_close(fd);
1157 return -errno;
1158 }
1159
1160 *_f = f;
1161 *_temp_path = t;
1162
1163 return 0;
1164 }
1165
1166 int fflush_and_check(FILE *f) {
1167 assert(f);
1168
1169 errno = 0;
1170 fflush(f);
1171
1172 if (ferror(f))
1173 return errno > 0 ? -errno : -EIO;
1174
1175 return 0;
1176 }
1177
1178 int fflush_sync_and_check(FILE *f) {
1179 int r;
1180
1181 assert(f);
1182
1183 r = fflush_and_check(f);
1184 if (r < 0)
1185 return r;
1186
1187 if (fsync(fileno(f)) < 0)
1188 return -errno;
1189
1190 r = fsync_directory_of_file(fileno(f));
1191 if (r < 0)
1192 return r;
1193
1194 return 0;
1195 }
1196
1197 /* This is much like mkostemp() but is subject to umask(). */
1198 int mkostemp_safe(char *pattern) {
1199 _cleanup_umask_ mode_t u = 0;
1200 int fd;
1201
1202 assert(pattern);
1203
1204 u = umask(077);
1205
1206 fd = mkostemp(pattern, O_CLOEXEC);
1207 if (fd < 0)
1208 return -errno;
1209
1210 return fd;
1211 }
1212
1213 int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
1214 const char *fn;
1215 char *t;
1216
1217 assert(p);
1218 assert(ret);
1219
1220 /*
1221 * Turns this:
1222 * /foo/bar/waldo
1223 *
1224 * Into this:
1225 * /foo/bar/.#<extra>waldoXXXXXX
1226 */
1227
1228 fn = basename(p);
1229 if (!filename_is_valid(fn))
1230 return -EINVAL;
1231
1232 extra = strempty(extra);
1233
1234 t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
1235 if (!t)
1236 return -ENOMEM;
1237
1238 strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn), "XXXXXX");
1239
1240 *ret = path_kill_slashes(t);
1241 return 0;
1242 }
1243
1244 int tempfn_random(const char *p, const char *extra, char **ret) {
1245 const char *fn;
1246 char *t, *x;
1247 uint64_t u;
1248 unsigned i;
1249
1250 assert(p);
1251 assert(ret);
1252
1253 /*
1254 * Turns this:
1255 * /foo/bar/waldo
1256 *
1257 * Into this:
1258 * /foo/bar/.#<extra>waldobaa2a261115984a9
1259 */
1260
1261 fn = basename(p);
1262 if (!filename_is_valid(fn))
1263 return -EINVAL;
1264
1265 extra = strempty(extra);
1266
1267 t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1);
1268 if (!t)
1269 return -ENOMEM;
1270
1271 x = stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn);
1272
1273 u = random_u64();
1274 for (i = 0; i < 16; i++) {
1275 *(x++) = hexchar(u & 0xF);
1276 u >>= 4;
1277 }
1278
1279 *x = 0;
1280
1281 *ret = path_kill_slashes(t);
1282 return 0;
1283 }
1284
1285 int tempfn_random_child(const char *p, const char *extra, char **ret) {
1286 char *t, *x;
1287 uint64_t u;
1288 unsigned i;
1289 int r;
1290
1291 assert(ret);
1292
1293 /* Turns this:
1294 * /foo/bar/waldo
1295 * Into this:
1296 * /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
1297 */
1298
1299 if (!p) {
1300 r = tmp_dir(&p);
1301 if (r < 0)
1302 return r;
1303 }
1304
1305 extra = strempty(extra);
1306
1307 t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1);
1308 if (!t)
1309 return -ENOMEM;
1310
1311 x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra);
1312
1313 u = random_u64();
1314 for (i = 0; i < 16; i++) {
1315 *(x++) = hexchar(u & 0xF);
1316 u >>= 4;
1317 }
1318
1319 *x = 0;
1320
1321 *ret = path_kill_slashes(t);
1322 return 0;
1323 }
1324
1325 int write_timestamp_file_atomic(const char *fn, usec_t n) {
1326 char ln[DECIMAL_STR_MAX(n)+2];
1327
1328 /* Creates a "timestamp" file, that contains nothing but a
1329 * usec_t timestamp, formatted in ASCII. */
1330
1331 if (n <= 0 || n >= USEC_INFINITY)
1332 return -ERANGE;
1333
1334 xsprintf(ln, USEC_FMT "\n", n);
1335
1336 return write_string_file(fn, ln, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC);
1337 }
1338
1339 int read_timestamp_file(const char *fn, usec_t *ret) {
1340 _cleanup_free_ char *ln = NULL;
1341 uint64_t t;
1342 int r;
1343
1344 r = read_one_line_file(fn, &ln);
1345 if (r < 0)
1346 return r;
1347
1348 r = safe_atou64(ln, &t);
1349 if (r < 0)
1350 return r;
1351
1352 if (t <= 0 || t >= (uint64_t) USEC_INFINITY)
1353 return -ERANGE;
1354
1355 *ret = (usec_t) t;
1356 return 0;
1357 }
1358
1359 int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space) {
1360 int r;
1361
1362 assert(s);
1363
1364 /* Outputs the specified string with fputs(), but optionally prefixes it with a separator. The *space parameter
1365 * when specified shall initially point to a boolean variable initialized to false. It is set to true after the
1366 * first invocation. This call is supposed to be use in loops, where a separator shall be inserted between each
1367 * element, but not before the first one. */
1368
1369 if (!f)
1370 f = stdout;
1371
1372 if (space) {
1373 if (!separator)
1374 separator = " ";
1375
1376 if (*space) {
1377 r = fputs(separator, f);
1378 if (r < 0)
1379 return r;
1380 }
1381
1382 *space = true;
1383 }
1384
1385 return fputs(s, f);
1386 }
1387
1388 int open_tmpfile_unlinkable(const char *directory, int flags) {
1389 char *p;
1390 int fd, r;
1391
1392 if (!directory) {
1393 r = tmp_dir(&directory);
1394 if (r < 0)
1395 return r;
1396 }
1397
1398 /* Returns an unlinked temporary file that cannot be linked into the file system anymore */
1399
1400 /* Try O_TMPFILE first, if it is supported */
1401 fd = open(directory, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
1402 if (fd >= 0)
1403 return fd;
1404
1405 /* Fall back to unguessable name + unlinking */
1406 p = strjoina(directory, "/systemd-tmp-XXXXXX");
1407
1408 fd = mkostemp_safe(p);
1409 if (fd < 0)
1410 return fd;
1411
1412 (void) unlink(p);
1413
1414 return fd;
1415 }
1416
1417 int open_tmpfile_linkable(const char *target, int flags, char **ret_path) {
1418 _cleanup_free_ char *tmp = NULL;
1419 int r, fd;
1420
1421 assert(target);
1422 assert(ret_path);
1423
1424 /* Don't allow O_EXCL, as that has a special meaning for O_TMPFILE */
1425 assert((flags & O_EXCL) == 0);
1426
1427 /* Creates a temporary file, that shall be renamed to "target" later. If possible, this uses O_TMPFILE – in
1428 * which case "ret_path" will be returned as NULL. If not possible a the tempoary path name used is returned in
1429 * "ret_path". Use link_tmpfile() below to rename the result after writing the file in full. */
1430
1431 {
1432 _cleanup_free_ char *dn = NULL;
1433
1434 dn = dirname_malloc(target);
1435 if (!dn)
1436 return -ENOMEM;
1437
1438 fd = open(dn, O_TMPFILE|flags, 0640);
1439 if (fd >= 0) {
1440 *ret_path = NULL;
1441 return fd;
1442 }
1443
1444 log_debug_errno(errno, "Failed to use O_TMPFILE on %s: %m", dn);
1445 }
1446
1447 r = tempfn_random(target, NULL, &tmp);
1448 if (r < 0)
1449 return r;
1450
1451 fd = open(tmp, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|flags, 0640);
1452 if (fd < 0)
1453 return -errno;
1454
1455 *ret_path = tmp;
1456 tmp = NULL;
1457
1458 return fd;
1459 }
1460
1461 int open_serialization_fd(const char *ident) {
1462 int fd = -1;
1463
1464 fd = memfd_create(ident, MFD_CLOEXEC);
1465 if (fd < 0) {
1466 const char *path;
1467
1468 path = getpid_cached() == 1 ? "/run/systemd" : "/tmp";
1469 fd = open_tmpfile_unlinkable(path, O_RDWR|O_CLOEXEC);
1470 if (fd < 0)
1471 return fd;
1472
1473 log_debug("Serializing %s to %s.", ident, path);
1474 } else
1475 log_debug("Serializing %s to memfd.", ident);
1476
1477 return fd;
1478 }
1479
1480 int link_tmpfile(int fd, const char *path, const char *target) {
1481
1482 assert(fd >= 0);
1483 assert(target);
1484
1485 /* Moves a temporary file created with open_tmpfile() above into its final place. if "path" is NULL an fd
1486 * created with O_TMPFILE is assumed, and linkat() is used. Otherwise it is assumed O_TMPFILE is not supported
1487 * on the directory, and renameat2() is used instead.
1488 *
1489 * Note that in both cases we will not replace existing files. This is because linkat() does not support this
1490 * operation currently (renameat2() does), and there is no nice way to emulate this. */
1491
1492 if (path) {
1493 if (rename_noreplace(AT_FDCWD, path, AT_FDCWD, target) < 0)
1494 return -errno;
1495 } else {
1496 char proc_fd_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(fd) + 1];
1497
1498 xsprintf(proc_fd_path, "/proc/self/fd/%i", fd);
1499
1500 if (linkat(AT_FDCWD, proc_fd_path, AT_FDCWD, target, AT_SYMLINK_FOLLOW) < 0)
1501 return -errno;
1502 }
1503
1504 return 0;
1505 }
1506
1507 int read_nul_string(FILE *f, char **ret) {
1508 _cleanup_free_ char *x = NULL;
1509 size_t allocated = 0, n = 0;
1510
1511 assert(f);
1512 assert(ret);
1513
1514 /* Reads a NUL-terminated string from the specified file. */
1515
1516 for (;;) {
1517 int c;
1518
1519 if (!GREEDY_REALLOC(x, allocated, n+2))
1520 return -ENOMEM;
1521
1522 c = fgetc(f);
1523 if (c == 0) /* Terminate at NUL byte */
1524 break;
1525 if (c == EOF) {
1526 if (ferror(f))
1527 return -errno;
1528 break; /* Terminate at EOF */
1529 }
1530
1531 x[n++] = (char) c;
1532 }
1533
1534 if (x)
1535 x[n] = 0;
1536 else {
1537 x = new0(char, 1);
1538 if (!x)
1539 return -ENOMEM;
1540 }
1541
1542 *ret = x;
1543 x = NULL;
1544
1545 return 0;
1546 }
1547
1548 int mkdtemp_malloc(const char *template, char **ret) {
1549 char *p;
1550
1551 assert(template);
1552 assert(ret);
1553
1554 p = strdup(template);
1555 if (!p)
1556 return -ENOMEM;
1557
1558 if (!mkdtemp(p)) {
1559 free(p);
1560 return -errno;
1561 }
1562
1563 *ret = p;
1564 return 0;
1565 }
1566
1567 DEFINE_TRIVIAL_CLEANUP_FUNC(FILE*, funlockfile);
1568
1569 int read_line(FILE *f, size_t limit, char **ret) {
1570 _cleanup_free_ char *buffer = NULL;
1571 size_t n = 0, allocated = 0, count = 0;
1572
1573 assert(f);
1574
1575 /* Something like a bounded version of getline().
1576 *
1577 * Considers EOF, \n and \0 end of line delimiters, and does not include these delimiters in the string
1578 * returned.
1579 *
1580 * Returns the number of bytes read from the files (i.e. including delimiters — this hence usually differs from
1581 * the number of characters in the returned string). When EOF is hit, 0 is returned.
1582 *
1583 * The input parameter limit is the maximum numbers of characters in the returned string, i.e. excluding
1584 * delimiters. If the limit is hit we fail and return -ENOBUFS.
1585 *
1586 * If a line shall be skipped ret may be initialized as NULL. */
1587
1588 if (ret) {
1589 if (!GREEDY_REALLOC(buffer, allocated, 1))
1590 return -ENOMEM;
1591 }
1592
1593 {
1594 _unused_ _cleanup_(funlockfilep) FILE *flocked = f;
1595 flockfile(f);
1596
1597 for (;;) {
1598 int c;
1599
1600 if (n >= limit)
1601 return -ENOBUFS;
1602
1603 errno = 0;
1604 c = fgetc_unlocked(f);
1605 if (c == EOF) {
1606 /* if we read an error, and have no data to return, then propagate the error */
1607 if (ferror_unlocked(f) && n == 0)
1608 return errno > 0 ? -errno : -EIO;
1609
1610 break;
1611 }
1612
1613 count++;
1614
1615 if (IN_SET(c, '\n', 0)) /* Reached a delimiter */
1616 break;
1617
1618 if (ret) {
1619 if (!GREEDY_REALLOC(buffer, allocated, n + 2))
1620 return -ENOMEM;
1621
1622 buffer[n] = (char) c;
1623 }
1624
1625 n++;
1626 }
1627 }
1628
1629 if (ret) {
1630 buffer[n] = 0;
1631
1632 *ret = buffer;
1633 buffer = NULL;
1634 }
1635
1636 return (int) count;
1637 }