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