]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/fileio.c
Merge pull request #18873 from yuwata/use-config-parse-many-and-null-or-empty-path
[thirdparty/systemd.git] / src / basic / fileio.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <ctype.h>
4 #include <errno.h>
5 #include <fcntl.h>
6 #include <limits.h>
7 #include <stdarg.h>
8 #include <stdint.h>
9 #include <stdio_ext.h>
10 #include <stdlib.h>
11 #include <sys/stat.h>
12 #include <sys/types.h>
13 #include <unistd.h>
14
15 #include "alloc-util.h"
16 #include "fd-util.h"
17 #include "fileio.h"
18 #include "fs-util.h"
19 #include "hexdecoct.h"
20 #include "log.h"
21 #include "macro.h"
22 #include "mkdir.h"
23 #include "parse-util.h"
24 #include "path-util.h"
25 #include "socket-util.h"
26 #include "stdio-util.h"
27 #include "string-util.h"
28 #include "tmpfile-util.h"
29
30 #define READ_FULL_BYTES_MAX (4U*1024U*1024U)
31
32 int fopen_unlocked(const char *path, const char *options, FILE **ret) {
33 assert(ret);
34
35 FILE *f = fopen(path, options);
36 if (!f)
37 return -errno;
38
39 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
40
41 *ret = f;
42 return 0;
43 }
44
45 int fdopen_unlocked(int fd, const char *options, FILE **ret) {
46 assert(ret);
47
48 FILE *f = fdopen(fd, options);
49 if (!f)
50 return -errno;
51
52 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
53
54 *ret = f;
55 return 0;
56 }
57
58 int take_fdopen_unlocked(int *fd, const char *options, FILE **ret) {
59 int r;
60
61 assert(fd);
62
63 r = fdopen_unlocked(*fd, options, ret);
64 if (r < 0)
65 return r;
66
67 *fd = -1;
68
69 return 0;
70 }
71
72 FILE* take_fdopen(int *fd, const char *options) {
73 assert(fd);
74
75 FILE *f = fdopen(*fd, options);
76 if (!f)
77 return NULL;
78
79 *fd = -1;
80
81 return f;
82 }
83
84 DIR* take_fdopendir(int *dfd) {
85 assert(dfd);
86
87 DIR *d = fdopendir(*dfd);
88 if (!d)
89 return NULL;
90
91 *dfd = -1;
92
93 return d;
94 }
95
96 FILE* open_memstream_unlocked(char **ptr, size_t *sizeloc) {
97 FILE *f = open_memstream(ptr, sizeloc);
98 if (!f)
99 return NULL;
100
101 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
102
103 return f;
104 }
105
106 FILE* fmemopen_unlocked(void *buf, size_t size, const char *mode) {
107 FILE *f = fmemopen(buf, size, mode);
108 if (!f)
109 return NULL;
110
111 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
112
113 return f;
114 }
115
116 int write_string_stream_ts(
117 FILE *f,
118 const char *line,
119 WriteStringFileFlags flags,
120 const struct timespec *ts) {
121
122 bool needs_nl;
123 int r, fd;
124
125 assert(f);
126 assert(line);
127
128 if (ferror(f))
129 return -EIO;
130
131 if (ts) {
132 /* If we shall set the timestamp we need the fd. But fmemopen() streams generally don't have
133 * an fd. Let's fail early in that case. */
134 fd = fileno(f);
135 if (fd < 0)
136 return -EBADF;
137 }
138
139 needs_nl = !(flags & WRITE_STRING_FILE_AVOID_NEWLINE) && !endswith(line, "\n");
140
141 if (needs_nl && (flags & WRITE_STRING_FILE_DISABLE_BUFFER)) {
142 /* If STDIO buffering was disabled, then let's append the newline character to the string itself, so
143 * that the write goes out in one go, instead of two */
144
145 line = strjoina(line, "\n");
146 needs_nl = false;
147 }
148
149 if (fputs(line, f) == EOF)
150 return -errno;
151
152 if (needs_nl)
153 if (fputc('\n', f) == EOF)
154 return -errno;
155
156 if (flags & WRITE_STRING_FILE_SYNC)
157 r = fflush_sync_and_check(f);
158 else
159 r = fflush_and_check(f);
160 if (r < 0)
161 return r;
162
163 if (ts) {
164 const struct timespec twice[2] = {*ts, *ts};
165
166 if (futimens(fd, twice) < 0)
167 return -errno;
168 }
169
170 return 0;
171 }
172
173 static int write_string_file_atomic(
174 const char *fn,
175 const char *line,
176 WriteStringFileFlags flags,
177 const struct timespec *ts) {
178
179 _cleanup_fclose_ FILE *f = NULL;
180 _cleanup_free_ char *p = NULL;
181 int r;
182
183 assert(fn);
184 assert(line);
185
186 /* Note that we'd really like to use O_TMPFILE here, but can't really, since we want replacement
187 * semantics here, and O_TMPFILE can't offer that. i.e. rename() replaces but linkat() doesn't. */
188
189 r = fopen_temporary(fn, &f, &p);
190 if (r < 0)
191 return r;
192
193 r = write_string_stream_ts(f, line, flags, ts);
194 if (r < 0)
195 goto fail;
196
197 r = fchmod_umask(fileno(f), FLAGS_SET(flags, WRITE_STRING_FILE_MODE_0600) ? 0600 : 0644);
198 if (r < 0)
199 goto fail;
200
201 if (rename(p, fn) < 0) {
202 r = -errno;
203 goto fail;
204 }
205
206 if (FLAGS_SET(flags, WRITE_STRING_FILE_SYNC)) {
207 /* Sync the rename, too */
208 r = fsync_directory_of_file(fileno(f));
209 if (r < 0)
210 return r;
211 }
212
213 return 0;
214
215 fail:
216 (void) unlink(p);
217 return r;
218 }
219
220 int write_string_file_ts(
221 const char *fn,
222 const char *line,
223 WriteStringFileFlags flags,
224 const struct timespec *ts) {
225
226 _cleanup_fclose_ FILE *f = NULL;
227 int q, r, fd;
228
229 assert(fn);
230 assert(line);
231
232 /* We don't know how to verify whether the file contents was already on-disk. */
233 assert(!((flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE) && (flags & WRITE_STRING_FILE_SYNC)));
234
235 if (flags & WRITE_STRING_FILE_MKDIR_0755) {
236 r = mkdir_parents(fn, 0755);
237 if (r < 0)
238 return r;
239 }
240
241 if (flags & WRITE_STRING_FILE_ATOMIC) {
242 assert(flags & WRITE_STRING_FILE_CREATE);
243
244 r = write_string_file_atomic(fn, line, flags, ts);
245 if (r < 0)
246 goto fail;
247
248 return r;
249 } else
250 assert(!ts);
251
252 /* We manually build our own version of fopen(..., "we") that works without O_CREAT and with O_NOFOLLOW if needed. */
253 fd = open(fn, O_WRONLY|O_CLOEXEC|O_NOCTTY |
254 (FLAGS_SET(flags, WRITE_STRING_FILE_NOFOLLOW) ? O_NOFOLLOW : 0) |
255 (FLAGS_SET(flags, WRITE_STRING_FILE_CREATE) ? O_CREAT : 0) |
256 (FLAGS_SET(flags, WRITE_STRING_FILE_TRUNCATE) ? O_TRUNC : 0),
257 (FLAGS_SET(flags, WRITE_STRING_FILE_MODE_0600) ? 0600 : 0666));
258 if (fd < 0) {
259 r = -errno;
260 goto fail;
261 }
262
263 r = fdopen_unlocked(fd, "w", &f);
264 if (r < 0) {
265 safe_close(fd);
266 goto fail;
267 }
268
269 if (flags & WRITE_STRING_FILE_DISABLE_BUFFER)
270 setvbuf(f, NULL, _IONBF, 0);
271
272 r = write_string_stream_ts(f, line, flags, ts);
273 if (r < 0)
274 goto fail;
275
276 return 0;
277
278 fail:
279 if (!(flags & WRITE_STRING_FILE_VERIFY_ON_FAILURE))
280 return r;
281
282 f = safe_fclose(f);
283
284 /* OK, the operation failed, but let's see if the right
285 * contents in place already. If so, eat up the error. */
286
287 q = verify_file(fn, line, !(flags & WRITE_STRING_FILE_AVOID_NEWLINE));
288 if (q <= 0)
289 return r;
290
291 return 0;
292 }
293
294 int write_string_filef(
295 const char *fn,
296 WriteStringFileFlags flags,
297 const char *format, ...) {
298
299 _cleanup_free_ char *p = NULL;
300 va_list ap;
301 int r;
302
303 va_start(ap, format);
304 r = vasprintf(&p, format, ap);
305 va_end(ap);
306
307 if (r < 0)
308 return -ENOMEM;
309
310 return write_string_file(fn, p, flags);
311 }
312
313 int read_one_line_file(const char *fn, char **line) {
314 _cleanup_fclose_ FILE *f = NULL;
315 int r;
316
317 assert(fn);
318 assert(line);
319
320 r = fopen_unlocked(fn, "re", &f);
321 if (r < 0)
322 return r;
323
324 return read_line(f, LONG_LINE_MAX, line);
325 }
326
327 int verify_file(const char *fn, const char *blob, bool accept_extra_nl) {
328 _cleanup_fclose_ FILE *f = NULL;
329 _cleanup_free_ char *buf = NULL;
330 size_t l, k;
331 int r;
332
333 assert(fn);
334 assert(blob);
335
336 l = strlen(blob);
337
338 if (accept_extra_nl && endswith(blob, "\n"))
339 accept_extra_nl = false;
340
341 buf = malloc(l + accept_extra_nl + 1);
342 if (!buf)
343 return -ENOMEM;
344
345 r = fopen_unlocked(fn, "re", &f);
346 if (r < 0)
347 return r;
348
349 /* We try to read one byte more than we need, so that we know whether we hit eof */
350 errno = 0;
351 k = fread(buf, 1, l + accept_extra_nl + 1, f);
352 if (ferror(f))
353 return errno_or_else(EIO);
354
355 if (k != l && k != l + accept_extra_nl)
356 return 0;
357 if (memcmp(buf, blob, l) != 0)
358 return 0;
359 if (k > l && buf[l] != '\n')
360 return 0;
361
362 return 1;
363 }
364
365 int read_full_virtual_file(const char *filename, char **ret_contents, size_t *ret_size) {
366 _cleanup_free_ char *buf = NULL;
367 _cleanup_close_ int fd = -1;
368 struct stat st;
369 size_t n, size;
370 int n_retries;
371 char *p;
372
373 assert(ret_contents);
374
375 /* Virtual filesystems such as sysfs or procfs use kernfs, and kernfs can work
376 * with two sorts of virtual files. One sort uses "seq_file", and the results of
377 * the first read are buffered for the second read. The other sort uses "raw"
378 * reads which always go direct to the device. In the latter case, the content of
379 * the virtual file must be retrieved with a single read otherwise a second read
380 * might get the new value instead of finding EOF immediately. That's the reason
381 * why the usage of fread(3) is prohibited in this case as it always performs a
382 * second call to read(2) looking for EOF. See issue 13585. */
383
384 fd = open(filename, O_RDONLY|O_CLOEXEC);
385 if (fd < 0)
386 return -errno;
387
388 /* Start size for files in /proc/ which usually report a file size of 0. (Files in /sys/ report a
389 * file size of 4K, which is probably OK for sizing our initial buffer, and sysfs attributes can't be
390 * larger anyway.) */
391 size = LINE_MAX / 2;
392
393 /* Limit the number of attempts to read the number of bytes returned by fstat(). */
394 n_retries = 3;
395
396 for (;;) {
397 if (n_retries <= 0)
398 return -EIO;
399
400 if (fstat(fd, &st) < 0)
401 return -errno;
402
403 if (!S_ISREG(st.st_mode))
404 return -EBADF;
405
406 /* Be prepared for files from /proc which generally report a file size of 0. */
407 if (st.st_size > 0) {
408 size = st.st_size;
409 n_retries--;
410 } else
411 size = size * 2;
412
413 if (size > READ_FULL_BYTES_MAX)
414 return -E2BIG;
415
416 p = realloc(buf, size + 1);
417 if (!p)
418 return -ENOMEM;
419 buf = TAKE_PTR(p);
420
421 for (;;) {
422 ssize_t k;
423
424 /* Read one more byte so we can detect whether the content of the
425 * file has already changed or the guessed size for files from /proc
426 * wasn't large enough . */
427 k = read(fd, buf, size + 1);
428 if (k >= 0) {
429 n = k;
430 break;
431 }
432
433 if (errno != EINTR)
434 return -errno;
435 }
436
437 /* Consider a short read as EOF */
438 if (n <= size)
439 break;
440
441 /* Hmm... either we read too few bytes from /proc or less likely the content
442 * of the file might have been changed (and is now bigger) while we were
443 * processing, let's try again either with a bigger guessed size or the new
444 * file size. */
445
446 if (lseek(fd, 0, SEEK_SET) < 0)
447 return -errno;
448 }
449
450 if (n < size) {
451 p = realloc(buf, n + 1);
452 if (!p)
453 return -ENOMEM;
454 buf = TAKE_PTR(p);
455 }
456
457 if (!ret_size) {
458 /* Safety check: if the caller doesn't want to know the size of what we
459 * just read it will rely on the trailing NUL byte. But if there's an
460 * embedded NUL byte, then we should refuse operation as otherwise
461 * there'd be ambiguity about what we just read. */
462
463 if (memchr(buf, 0, n))
464 return -EBADMSG;
465 } else
466 *ret_size = n;
467
468 buf[n] = 0;
469 *ret_contents = TAKE_PTR(buf);
470
471 return 0;
472 }
473
474 int read_full_stream_full(
475 FILE *f,
476 const char *filename,
477 uint64_t offset,
478 size_t size,
479 ReadFullFileFlags flags,
480 char **ret_contents,
481 size_t *ret_size) {
482
483 _cleanup_free_ char *buf = NULL;
484 size_t n, n_next, l;
485 int fd, r;
486
487 assert(f);
488 assert(ret_contents);
489 assert(!FLAGS_SET(flags, READ_FULL_FILE_UNBASE64 | READ_FULL_FILE_UNHEX));
490
491 if (offset != UINT64_MAX && offset > LONG_MAX)
492 return -ERANGE;
493
494 n_next = size != SIZE_MAX ? size : LINE_MAX; /* Start size */
495
496 fd = fileno(f);
497 if (fd >= 0) { /* If the FILE* object is backed by an fd (as opposed to memory or such, see
498 * fmemopen()), let's optimize our buffering */
499 struct stat st;
500
501 if (fstat(fd, &st) < 0)
502 return -errno;
503
504 if (S_ISREG(st.st_mode)) {
505 if (size == SIZE_MAX) {
506 uint64_t rsize =
507 LESS_BY((uint64_t) st.st_size, offset == UINT64_MAX ? 0 : offset);
508
509 /* Safety check */
510 if (rsize > READ_FULL_BYTES_MAX)
511 return -E2BIG;
512
513 /* Start with the right file size. Note that we increase the size to read
514 * here by one, so that the first read attempt already makes us notice the
515 * EOF. If the reported size of the file is zero, we avoid this logic
516 * however, since quite likely it might be a virtual file in procfs that all
517 * report a zero file size. */
518 if (st.st_size > 0)
519 n_next = rsize + 1;
520 }
521
522 if (flags & READ_FULL_FILE_WARN_WORLD_READABLE)
523 (void) warn_file_is_world_accessible(filename, &st, NULL, 0);
524 }
525 }
526
527 if (offset != UINT64_MAX && fseek(f, offset, SEEK_SET) < 0)
528 return -errno;
529
530 n = l = 0;
531 for (;;) {
532 char *t;
533 size_t k;
534
535 if (flags & READ_FULL_FILE_SECURE) {
536 t = malloc(n_next + 1);
537 if (!t) {
538 r = -ENOMEM;
539 goto finalize;
540 }
541 memcpy_safe(t, buf, n);
542 explicit_bzero_safe(buf, n);
543 buf = mfree(buf);
544 } else {
545 t = realloc(buf, n_next + 1);
546 if (!t)
547 return -ENOMEM;
548 }
549
550 buf = t;
551 /* Unless a size has been explicitly specified, try to read as much as fits into the memory
552 * we allocated (minus 1, to leave one byte for the safety NUL byte) */
553 n = size == SIZE_MAX ? malloc_usable_size(buf) - 1 : n_next;
554
555 errno = 0;
556 k = fread(buf + l, 1, n - l, f);
557
558 assert(k <= n - l);
559 l += k;
560
561 if (ferror(f)) {
562 r = errno_or_else(EIO);
563 goto finalize;
564 }
565 if (feof(f))
566 break;
567
568 if (size != SIZE_MAX) { /* If we got asked to read some specific size, we already sized the buffer right, hence leave */
569 assert(l == size);
570 break;
571 }
572
573 assert(k > 0); /* we can't have read zero bytes because that would have been EOF */
574
575 /* Safety check */
576 if (n >= READ_FULL_BYTES_MAX) {
577 r = -E2BIG;
578 goto finalize;
579 }
580
581 n_next = MIN(n * 2, READ_FULL_BYTES_MAX);
582 }
583
584 if (flags & (READ_FULL_FILE_UNBASE64 | READ_FULL_FILE_UNHEX)) {
585 _cleanup_free_ void *decoded = NULL;
586 size_t decoded_size;
587
588 buf[l++] = 0;
589 if (flags & READ_FULL_FILE_UNBASE64)
590 r = unbase64mem_full(buf, l, flags & READ_FULL_FILE_SECURE, &decoded, &decoded_size);
591 else
592 r = unhexmem_full(buf, l, flags & READ_FULL_FILE_SECURE, &decoded, &decoded_size);
593 if (r < 0)
594 goto finalize;
595
596 if (flags & READ_FULL_FILE_SECURE)
597 explicit_bzero_safe(buf, n);
598 free_and_replace(buf, decoded);
599 n = l = decoded_size;
600 }
601
602 if (!ret_size) {
603 /* Safety check: if the caller doesn't want to know the size of what we just read it will rely on the
604 * trailing NUL byte. But if there's an embedded NUL byte, then we should refuse operation as otherwise
605 * there'd be ambiguity about what we just read. */
606
607 if (memchr(buf, 0, l)) {
608 r = -EBADMSG;
609 goto finalize;
610 }
611 }
612
613 buf[l] = 0;
614 *ret_contents = TAKE_PTR(buf);
615
616 if (ret_size)
617 *ret_size = l;
618
619 return 0;
620
621 finalize:
622 if (flags & READ_FULL_FILE_SECURE)
623 explicit_bzero_safe(buf, n);
624
625 return r;
626 }
627
628 int read_full_file_full(
629 int dir_fd,
630 const char *filename,
631 uint64_t offset,
632 size_t size,
633 ReadFullFileFlags flags,
634 const char *bind_name,
635 char **ret_contents,
636 size_t *ret_size) {
637
638 _cleanup_fclose_ FILE *f = NULL;
639 int r;
640
641 assert(filename);
642 assert(ret_contents);
643
644 r = xfopenat(dir_fd, filename, "re", 0, &f);
645 if (r < 0) {
646 _cleanup_close_ int dfd = -1, sk = -1;
647 union sockaddr_union sa;
648
649 /* ENXIO is what Linux returns if we open a node that is an AF_UNIX socket */
650 if (r != -ENXIO)
651 return r;
652
653 /* If this is enabled, let's try to connect to it */
654 if (!FLAGS_SET(flags, READ_FULL_FILE_CONNECT_SOCKET))
655 return -ENXIO;
656
657 /* Seeking is not supported on AF_UNIX sockets */
658 if (offset != UINT64_MAX)
659 return -ESPIPE;
660
661 if (dir_fd == AT_FDCWD)
662 r = sockaddr_un_set_path(&sa.un, filename);
663 else {
664 char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
665
666 /* If we shall operate relative to some directory, then let's use O_PATH first to
667 * open the socket inode, and then connect to it via /proc/self/fd/. We have to do
668 * this since there's not connectat() that takes a directory fd as first arg. */
669
670 dfd = openat(dir_fd, filename, O_PATH|O_CLOEXEC);
671 if (dfd < 0)
672 return -errno;
673
674 xsprintf(procfs_path, "/proc/self/fd/%i", dfd);
675 r = sockaddr_un_set_path(&sa.un, procfs_path);
676 }
677 if (r < 0)
678 return r;
679
680 sk = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
681 if (sk < 0)
682 return -errno;
683
684 if (bind_name) {
685 /* If the caller specified a socket name to bind to, do so before connecting. This is
686 * useful to communicate some minor, short meta-information token from the client to
687 * the server. */
688 union sockaddr_union bsa;
689
690 r = sockaddr_un_set_path(&bsa.un, bind_name);
691 if (r < 0)
692 return r;
693
694 if (bind(sk, &bsa.sa, r) < 0)
695 return r;
696 }
697
698 if (connect(sk, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
699 return errno == ENOTSOCK ? -ENXIO : -errno; /* propagate original error if this is
700 * not a socket after all */
701
702 if (shutdown(sk, SHUT_WR) < 0)
703 return -errno;
704
705 f = fdopen(sk, "r");
706 if (!f)
707 return -errno;
708
709 TAKE_FD(sk);
710 }
711
712 (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
713
714 return read_full_stream_full(f, filename, offset, size, flags, ret_contents, ret_size);
715 }
716
717 int executable_is_script(const char *path, char **interpreter) {
718 _cleanup_free_ char *line = NULL;
719 size_t len;
720 char *ans;
721 int r;
722
723 assert(path);
724
725 r = read_one_line_file(path, &line);
726 if (r == -ENOBUFS) /* First line overly long? if so, then it's not a script */
727 return 0;
728 if (r < 0)
729 return r;
730
731 if (!startswith(line, "#!"))
732 return 0;
733
734 ans = strstrip(line + 2);
735 len = strcspn(ans, " \t");
736
737 if (len == 0)
738 return 0;
739
740 ans = strndup(ans, len);
741 if (!ans)
742 return -ENOMEM;
743
744 *interpreter = ans;
745 return 1;
746 }
747
748 /**
749 * Retrieve one field from a file like /proc/self/status. pattern
750 * should not include whitespace or the delimiter (':'). pattern matches only
751 * the beginning of a line. Whitespace before ':' is skipped. Whitespace and
752 * zeros after the ':' will be skipped. field must be freed afterwards.
753 * terminator specifies the terminating characters of the field value (not
754 * included in the value).
755 */
756 int get_proc_field(const char *filename, const char *pattern, const char *terminator, char **field) {
757 _cleanup_free_ char *status = NULL;
758 char *t, *f;
759 size_t len;
760 int r;
761
762 assert(terminator);
763 assert(filename);
764 assert(pattern);
765 assert(field);
766
767 r = read_full_virtual_file(filename, &status, NULL);
768 if (r < 0)
769 return r;
770
771 t = status;
772
773 do {
774 bool pattern_ok;
775
776 do {
777 t = strstr(t, pattern);
778 if (!t)
779 return -ENOENT;
780
781 /* Check that pattern occurs in beginning of line. */
782 pattern_ok = (t == status || t[-1] == '\n');
783
784 t += strlen(pattern);
785
786 } while (!pattern_ok);
787
788 t += strspn(t, " \t");
789 if (!*t)
790 return -ENOENT;
791
792 } while (*t != ':');
793
794 t++;
795
796 if (*t) {
797 t += strspn(t, " \t");
798
799 /* Also skip zeros, because when this is used for
800 * capabilities, we don't want the zeros. This way the
801 * same capability set always maps to the same string,
802 * irrespective of the total capability set size. For
803 * other numbers it shouldn't matter. */
804 t += strspn(t, "0");
805 /* Back off one char if there's nothing but whitespace
806 and zeros */
807 if (!*t || isspace(*t))
808 t--;
809 }
810
811 len = strcspn(t, terminator);
812
813 f = strndup(t, len);
814 if (!f)
815 return -ENOMEM;
816
817 *field = f;
818 return 0;
819 }
820
821 DIR *xopendirat(int fd, const char *name, int flags) {
822 int nfd;
823 DIR *d;
824
825 assert(!(flags & O_CREAT));
826
827 nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
828 if (nfd < 0)
829 return NULL;
830
831 d = fdopendir(nfd);
832 if (!d) {
833 safe_close(nfd);
834 return NULL;
835 }
836
837 return d;
838 }
839
840 static int mode_to_flags(const char *mode) {
841 const char *p;
842 int flags;
843
844 if ((p = startswith(mode, "r+")))
845 flags = O_RDWR;
846 else if ((p = startswith(mode, "r")))
847 flags = O_RDONLY;
848 else if ((p = startswith(mode, "w+")))
849 flags = O_RDWR|O_CREAT|O_TRUNC;
850 else if ((p = startswith(mode, "w")))
851 flags = O_WRONLY|O_CREAT|O_TRUNC;
852 else if ((p = startswith(mode, "a+")))
853 flags = O_RDWR|O_CREAT|O_APPEND;
854 else if ((p = startswith(mode, "a")))
855 flags = O_WRONLY|O_CREAT|O_APPEND;
856 else
857 return -EINVAL;
858
859 for (; *p != 0; p++) {
860
861 switch (*p) {
862
863 case 'e':
864 flags |= O_CLOEXEC;
865 break;
866
867 case 'x':
868 flags |= O_EXCL;
869 break;
870
871 case 'm':
872 /* ignore this here, fdopen() might care later though */
873 break;
874
875 case 'c': /* not sure what to do about this one */
876 default:
877 return -EINVAL;
878 }
879 }
880
881 return flags;
882 }
883
884 int xfopenat(int dir_fd, const char *path, const char *mode, int flags, FILE **ret) {
885 FILE *f;
886
887 /* A combination of fopen() with openat() */
888
889 if (dir_fd == AT_FDCWD && flags == 0) {
890 f = fopen(path, mode);
891 if (!f)
892 return -errno;
893 } else {
894 int fd, mode_flags;
895
896 mode_flags = mode_to_flags(mode);
897 if (mode_flags < 0)
898 return mode_flags;
899
900 fd = openat(dir_fd, path, mode_flags | flags);
901 if (fd < 0)
902 return -errno;
903
904 f = fdopen(fd, mode);
905 if (!f) {
906 safe_close(fd);
907 return -errno;
908 }
909 }
910
911 *ret = f;
912 return 0;
913 }
914
915 static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
916 char **i;
917
918 assert(path);
919 assert(mode);
920 assert(_f);
921
922 if (!path_strv_resolve_uniq(search, root))
923 return -ENOMEM;
924
925 STRV_FOREACH(i, search) {
926 _cleanup_free_ char *p = NULL;
927 FILE *f;
928
929 p = path_join(root, *i, path);
930 if (!p)
931 return -ENOMEM;
932
933 f = fopen(p, mode);
934 if (f) {
935 *_f = f;
936 return 0;
937 }
938
939 if (errno != ENOENT)
940 return -errno;
941 }
942
943 return -ENOENT;
944 }
945
946 int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
947 _cleanup_strv_free_ char **copy = NULL;
948
949 assert(path);
950 assert(mode);
951 assert(_f);
952
953 if (path_is_absolute(path)) {
954 FILE *f;
955
956 f = fopen(path, mode);
957 if (f) {
958 *_f = f;
959 return 0;
960 }
961
962 return -errno;
963 }
964
965 copy = strv_copy((char**) search);
966 if (!copy)
967 return -ENOMEM;
968
969 return search_and_fopen_internal(path, mode, root, copy, _f);
970 }
971
972 int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
973 _cleanup_strv_free_ char **s = NULL;
974
975 if (path_is_absolute(path)) {
976 FILE *f;
977
978 f = fopen(path, mode);
979 if (f) {
980 *_f = f;
981 return 0;
982 }
983
984 return -errno;
985 }
986
987 s = strv_split_nulstr(search);
988 if (!s)
989 return -ENOMEM;
990
991 return search_and_fopen_internal(path, mode, root, s, _f);
992 }
993
994 int chase_symlinks_and_fopen_unlocked(
995 const char *path,
996 const char *root,
997 unsigned chase_flags,
998 const char *open_flags,
999 FILE **ret_file,
1000 char **ret_path) {
1001
1002 _cleanup_close_ int fd = -1;
1003 _cleanup_free_ char *final_path = NULL;
1004 int mode_flags, r;
1005 FILE *f;
1006
1007 assert(path);
1008 assert(open_flags);
1009 assert(ret_file);
1010
1011 mode_flags = mode_to_flags(open_flags);
1012 if (mode_flags < 0)
1013 return mode_flags;
1014
1015 fd = chase_symlinks_and_open(path, root, chase_flags, mode_flags, ret_path ? &final_path : NULL);
1016 if (fd < 0)
1017 return fd;
1018
1019 r = fdopen_unlocked(fd, open_flags, &f);
1020 if (r < 0)
1021 return r;
1022 TAKE_FD(fd);
1023
1024 *ret_file = f;
1025 if (ret_path)
1026 *ret_path = TAKE_PTR(final_path);
1027 return 0;
1028 }
1029
1030 int fflush_and_check(FILE *f) {
1031 assert(f);
1032
1033 errno = 0;
1034 fflush(f);
1035
1036 if (ferror(f))
1037 return errno_or_else(EIO);
1038
1039 return 0;
1040 }
1041
1042 int fflush_sync_and_check(FILE *f) {
1043 int r, fd;
1044
1045 assert(f);
1046
1047 r = fflush_and_check(f);
1048 if (r < 0)
1049 return r;
1050
1051 /* Not all file streams have an fd associated (think: fmemopen()), let's handle this gracefully and
1052 * assume that in that case we need no explicit syncing */
1053 fd = fileno(f);
1054 if (fd < 0)
1055 return 0;
1056
1057 if (fsync(fd) < 0)
1058 return -errno;
1059
1060 r = fsync_directory_of_file(fd);
1061 if (r < 0)
1062 return r;
1063
1064 return 0;
1065 }
1066
1067 int write_timestamp_file_atomic(const char *fn, usec_t n) {
1068 char ln[DECIMAL_STR_MAX(n)+2];
1069
1070 /* Creates a "timestamp" file, that contains nothing but a
1071 * usec_t timestamp, formatted in ASCII. */
1072
1073 if (n <= 0 || n >= USEC_INFINITY)
1074 return -ERANGE;
1075
1076 xsprintf(ln, USEC_FMT "\n", n);
1077
1078 return write_string_file(fn, ln, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC);
1079 }
1080
1081 int read_timestamp_file(const char *fn, usec_t *ret) {
1082 _cleanup_free_ char *ln = NULL;
1083 uint64_t t;
1084 int r;
1085
1086 r = read_one_line_file(fn, &ln);
1087 if (r < 0)
1088 return r;
1089
1090 r = safe_atou64(ln, &t);
1091 if (r < 0)
1092 return r;
1093
1094 if (t <= 0 || t >= (uint64_t) USEC_INFINITY)
1095 return -ERANGE;
1096
1097 *ret = (usec_t) t;
1098 return 0;
1099 }
1100
1101 int fputs_with_space(FILE *f, const char *s, const char *separator, bool *space) {
1102 int r;
1103
1104 assert(s);
1105
1106 /* Outputs the specified string with fputs(), but optionally prefixes it with a separator. The *space parameter
1107 * when specified shall initially point to a boolean variable initialized to false. It is set to true after the
1108 * first invocation. This call is supposed to be use in loops, where a separator shall be inserted between each
1109 * element, but not before the first one. */
1110
1111 if (!f)
1112 f = stdout;
1113
1114 if (space) {
1115 if (!separator)
1116 separator = " ";
1117
1118 if (*space) {
1119 r = fputs(separator, f);
1120 if (r < 0)
1121 return r;
1122 }
1123
1124 *space = true;
1125 }
1126
1127 return fputs(s, f);
1128 }
1129
1130 /* A bitmask of the EOL markers we know */
1131 typedef enum EndOfLineMarker {
1132 EOL_NONE = 0,
1133 EOL_ZERO = 1 << 0, /* \0 (aka NUL) */
1134 EOL_TEN = 1 << 1, /* \n (aka NL, aka LF) */
1135 EOL_THIRTEEN = 1 << 2, /* \r (aka CR) */
1136 } EndOfLineMarker;
1137
1138 static EndOfLineMarker categorize_eol(char c, ReadLineFlags flags) {
1139
1140 if (!IN_SET(flags, READ_LINE_ONLY_NUL)) {
1141 if (c == '\n')
1142 return EOL_TEN;
1143 if (c == '\r')
1144 return EOL_THIRTEEN;
1145 }
1146
1147 if (c == '\0')
1148 return EOL_ZERO;
1149
1150 return EOL_NONE;
1151 }
1152
1153 DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(FILE*, funlockfile, NULL);
1154
1155 int read_line_full(FILE *f, size_t limit, ReadLineFlags flags, char **ret) {
1156 size_t n = 0, allocated = 0, count = 0;
1157 _cleanup_free_ char *buffer = NULL;
1158 int r;
1159
1160 assert(f);
1161
1162 /* Something like a bounded version of getline().
1163 *
1164 * Considers EOF, \n, \r and \0 end of line delimiters (or combinations of these), and does not include these
1165 * delimiters in the string returned. Specifically, recognizes the following combinations of markers as line
1166 * endings:
1167 *
1168 * • \n (UNIX)
1169 * • \r (old MacOS)
1170 * • \0 (C strings)
1171 * • \n\0
1172 * • \r\0
1173 * • \r\n (Windows)
1174 * • \n\r
1175 * • \r\n\0
1176 * • \n\r\0
1177 *
1178 * Returns the number of bytes read from the files (i.e. including delimiters — this hence usually differs from
1179 * the number of characters in the returned string). When EOF is hit, 0 is returned.
1180 *
1181 * The input parameter limit is the maximum numbers of characters in the returned string, i.e. excluding
1182 * delimiters. If the limit is hit we fail and return -ENOBUFS.
1183 *
1184 * If a line shall be skipped ret may be initialized as NULL. */
1185
1186 if (ret) {
1187 if (!GREEDY_REALLOC(buffer, allocated, 1))
1188 return -ENOMEM;
1189 }
1190
1191 {
1192 _unused_ _cleanup_(funlockfilep) FILE *flocked = f;
1193 EndOfLineMarker previous_eol = EOL_NONE;
1194 flockfile(f);
1195
1196 for (;;) {
1197 EndOfLineMarker eol;
1198 char c;
1199
1200 if (n >= limit)
1201 return -ENOBUFS;
1202
1203 if (count >= INT_MAX) /* We couldn't return the counter anymore as "int", hence refuse this */
1204 return -ENOBUFS;
1205
1206 r = safe_fgetc(f, &c);
1207 if (r < 0)
1208 return r;
1209 if (r == 0) /* EOF is definitely EOL */
1210 break;
1211
1212 eol = categorize_eol(c, flags);
1213
1214 if (FLAGS_SET(previous_eol, EOL_ZERO) ||
1215 (eol == EOL_NONE && previous_eol != EOL_NONE) ||
1216 (eol != EOL_NONE && (previous_eol & eol) != 0)) {
1217 /* Previous char was a NUL? This is not an EOL, but the previous char was? This type of
1218 * EOL marker has been seen right before? In either of these three cases we are
1219 * done. But first, let's put this character back in the queue. (Note that we have to
1220 * cast this to (unsigned char) here as ungetc() expects a positive 'int', and if we
1221 * are on an architecture where 'char' equals 'signed char' we need to ensure we don't
1222 * pass a negative value here. That said, to complicate things further ungetc() is
1223 * actually happy with most negative characters and implicitly casts them back to
1224 * positive ones as needed, except for \xff (aka -1, aka EOF), which it refuses. What a
1225 * godawful API!) */
1226 assert_se(ungetc((unsigned char) c, f) != EOF);
1227 break;
1228 }
1229
1230 count++;
1231
1232 if (eol != EOL_NONE) {
1233 /* If we are on a tty, we can't shouldn't wait for more input, because that
1234 * generally means waiting for the user, interactively. In the case of a TTY
1235 * we expect only \n as the single EOL marker, so we are in the lucky
1236 * position that there is no need to wait. We check this condition last, to
1237 * avoid isatty() check if not necessary. */
1238
1239 if ((flags & (READ_LINE_IS_A_TTY|READ_LINE_NOT_A_TTY)) == 0) {
1240 int fd;
1241
1242 fd = fileno(f);
1243 if (fd < 0) /* Maybe an fmemopen() stream? Handle this gracefully,
1244 * and don't call isatty() on an invalid fd */
1245 flags |= READ_LINE_NOT_A_TTY;
1246 else
1247 flags |= isatty(fd) ? READ_LINE_IS_A_TTY : READ_LINE_NOT_A_TTY;
1248 }
1249 if (FLAGS_SET(flags, READ_LINE_IS_A_TTY))
1250 break;
1251 }
1252
1253 if (eol != EOL_NONE) {
1254 previous_eol |= eol;
1255 continue;
1256 }
1257
1258 if (ret) {
1259 if (!GREEDY_REALLOC(buffer, allocated, n + 2))
1260 return -ENOMEM;
1261
1262 buffer[n] = c;
1263 }
1264
1265 n++;
1266 }
1267 }
1268
1269 if (ret) {
1270 buffer[n] = 0;
1271
1272 *ret = TAKE_PTR(buffer);
1273 }
1274
1275 return (int) count;
1276 }
1277
1278 int safe_fgetc(FILE *f, char *ret) {
1279 int k;
1280
1281 assert(f);
1282
1283 /* A safer version of plain fgetc(): let's propagate the error that happened while reading as such, and
1284 * separate the EOF condition from the byte read, to avoid those confusion signed/unsigned issues fgetc()
1285 * has. */
1286
1287 errno = 0;
1288 k = fgetc(f);
1289 if (k == EOF) {
1290 if (ferror(f))
1291 return errno_or_else(EIO);
1292
1293 if (ret)
1294 *ret = 0;
1295
1296 return 0;
1297 }
1298
1299 if (ret)
1300 *ret = k;
1301
1302 return 1;
1303 }
1304
1305 int warn_file_is_world_accessible(const char *filename, struct stat *st, const char *unit, unsigned line) {
1306 struct stat _st;
1307
1308 if (!filename)
1309 return 0;
1310
1311 if (!st) {
1312 if (stat(filename, &_st) < 0)
1313 return -errno;
1314 st = &_st;
1315 }
1316
1317 if ((st->st_mode & S_IRWXO) == 0)
1318 return 0;
1319
1320 if (unit)
1321 log_syntax(unit, LOG_WARNING, filename, line, 0,
1322 "%s has %04o mode that is too permissive, please adjust the ownership and access mode.",
1323 filename, st->st_mode & 07777);
1324 else
1325 log_warning("%s has %04o mode that is too permissive, please adjust the ownership and access mode.",
1326 filename, st->st_mode & 07777);
1327 return 0;
1328 }
1329
1330 int rename_and_apply_smack_floor_label(const char *from, const char *to) {
1331 int r = 0;
1332 if (rename(from, to) < 0)
1333 return -errno;
1334
1335 #ifdef SMACK_RUN_LABEL
1336 r = mac_smack_apply(to, SMACK_ATTR_ACCESS, SMACK_FLOOR_LABEL);
1337 if (r < 0)
1338 return r;
1339 #endif
1340 return r;
1341 }