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