1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
31 #include <linux/magic.h>
32 #include <linux/oom.h>
33 #include <linux/sched.h>
44 #include <sys/ioctl.h>
46 #include <sys/mount.h>
47 #include <sys/personality.h>
48 #include <sys/prctl.h>
49 #include <sys/resource.h>
51 #include <sys/statvfs.h>
53 #include <sys/types.h>
54 #include <sys/utsname.h>
57 #include <sys/xattr.h>
61 /* When we include libgen.h because we need dirname() we immediately
62 * undefine basename() since libgen.h defines it as a macro to the
63 * POSIX version which is really broken. We prefer GNU basename(). */
67 #ifdef HAVE_SYS_AUXV_H
71 /* We include linux/fs.h as last of the system headers, as it
72 * otherwise conflicts with sys/mount.h. Yay, Linux is great! */
77 #include "device-nodes.h"
80 #include "exit-status.h"
83 #include "formats-util.h"
86 #include "hostname-util.h"
92 #include "parse-util.h"
93 #include "path-util.h"
94 #include "process-util.h"
95 #include "random-util.h"
96 #include "signal-util.h"
97 #include "sparse-endian.h"
98 #include "string-util.h"
100 #include "terminal-util.h"
101 #include "user-util.h"
106 /* Put this test here for a lack of better place */
107 assert_cc(EAGAIN
== EWOULDBLOCK
);
110 char **saved_argv
= NULL
;
112 size_t page_size(void) {
113 static thread_local
size_t pgsz
= 0;
116 if (_likely_(pgsz
> 0))
119 r
= sysconf(_SC_PAGESIZE
);
126 int unlink_noerrno(const char *path
) {
137 int fchmod_umask(int fd
, mode_t m
) {
142 r
= fchmod(fd
, m
& (~u
)) < 0 ? -errno
: 0;
148 int readlinkat_malloc(int fd
, const char *p
, char **ret
) {
163 n
= readlinkat(fd
, p
, c
, l
-1);
170 if ((size_t) n
< l
-1) {
181 int readlink_malloc(const char *p
, char **ret
) {
182 return readlinkat_malloc(AT_FDCWD
, p
, ret
);
185 int readlink_value(const char *p
, char **ret
) {
186 _cleanup_free_
char *link
= NULL
;
190 r
= readlink_malloc(p
, &link
);
194 value
= basename(link
);
198 value
= strdup(value
);
207 int readlink_and_make_absolute(const char *p
, char **r
) {
208 _cleanup_free_
char *target
= NULL
;
215 j
= readlink_malloc(p
, &target
);
219 k
= file_in_same_dir(p
, target
);
227 int readlink_and_canonicalize(const char *p
, char **r
) {
234 j
= readlink_and_make_absolute(p
, &t
);
238 s
= canonicalize_file_name(t
);
245 path_kill_slashes(*r
);
250 char *file_in_same_dir(const char *path
, const char *filename
) {
257 /* This removes the last component of path and appends
258 * filename, unless the latter is absolute anyway or the
261 if (path_is_absolute(filename
))
262 return strdup(filename
);
264 e
= strrchr(path
, '/');
266 return strdup(filename
);
268 k
= strlen(filename
);
269 ret
= new(char, (e
+ 1 - path
) + k
+ 1);
273 memcpy(mempcpy(ret
, path
, e
+ 1 - path
), filename
, k
+ 1);
277 int rmdir_parents(const char *path
, const char *stop
) {
286 /* Skip trailing slashes */
287 while (l
> 0 && path
[l
-1] == '/')
293 /* Skip last component */
294 while (l
> 0 && path
[l
-1] != '/')
297 /* Skip trailing slashes */
298 while (l
> 0 && path
[l
-1] == '/')
304 if (!(t
= strndup(path
, l
)))
307 if (path_startswith(stop
, t
)) {
323 char hexchar(int x
) {
324 static const char table
[16] = "0123456789abcdef";
326 return table
[x
& 15];
329 int unhexchar(char c
) {
331 if (c
>= '0' && c
<= '9')
334 if (c
>= 'a' && c
<= 'f')
337 if (c
>= 'A' && c
<= 'F')
343 char *hexmem(const void *p
, size_t l
) {
347 z
= r
= malloc(l
* 2 + 1);
351 for (x
= p
; x
< (const uint8_t*) p
+ l
; x
++) {
352 *(z
++) = hexchar(*x
>> 4);
353 *(z
++) = hexchar(*x
& 15);
360 int unhexmem(const char *p
, size_t l
, void **mem
, size_t *len
) {
361 _cleanup_free_
uint8_t *r
= NULL
;
369 z
= r
= malloc((l
+ 1) / 2 + 1);
373 for (x
= p
; x
< p
+ l
; x
+= 2) {
379 else if (x
+1 < p
+ l
) {
386 *(z
++) = (uint8_t) a
<< 4 | (uint8_t) b
;
398 /* https://tools.ietf.org/html/rfc4648#section-6
399 * Notice that base32hex differs from base32 in the alphabet it uses.
400 * The distinction is that the base32hex representation preserves the
401 * order of the underlying data when compared as bytestrings, this is
402 * useful when representing NSEC3 hashes, as one can then verify the
403 * order of hashes directly from their representation. */
404 char base32hexchar(int x
) {
405 static const char table
[32] = "0123456789"
406 "ABCDEFGHIJKLMNOPQRSTUV";
408 return table
[x
& 31];
411 int unbase32hexchar(char c
) {
414 if (c
>= '0' && c
<= '9')
417 offset
= '9' - '0' + 1;
419 if (c
>= 'A' && c
<= 'V')
420 return c
- 'A' + offset
;
425 char *base32hexmem(const void *p
, size_t l
, bool padding
) {
431 /* five input bytes makes eight output bytes, padding is added so we must round up */
432 len
= 8 * (l
+ 4) / 5;
434 /* same, but round down as there is no padding */
453 z
= r
= malloc(len
+ 1);
457 for (x
= p
; x
< (const uint8_t*) p
+ (l
/ 5) * 5; x
+= 5) {
458 /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ
459 x[3] == QQQQQQQQ; x[4] == WWWWWWWW */
460 *(z
++) = base32hexchar(x
[0] >> 3); /* 000XXXXX */
461 *(z
++) = base32hexchar((x
[0] & 7) << 2 | x
[1] >> 6); /* 000XXXYY */
462 *(z
++) = base32hexchar((x
[1] & 63) >> 1); /* 000YYYYY */
463 *(z
++) = base32hexchar((x
[1] & 1) << 4 | x
[2] >> 4); /* 000YZZZZ */
464 *(z
++) = base32hexchar((x
[2] & 15) << 1 | x
[3] >> 7); /* 000ZZZZQ */
465 *(z
++) = base32hexchar((x
[3] & 127) >> 2); /* 000QQQQQ */
466 *(z
++) = base32hexchar((x
[3] & 3) << 3 | x
[4] >> 5); /* 000QQWWW */
467 *(z
++) = base32hexchar((x
[4] & 31)); /* 000WWWWW */
472 *(z
++) = base32hexchar(x
[0] >> 3); /* 000XXXXX */
473 *(z
++) = base32hexchar((x
[0] & 7) << 2 | x
[1] >> 6); /* 000XXXYY */
474 *(z
++) = base32hexchar((x
[1] & 63) >> 1); /* 000YYYYY */
475 *(z
++) = base32hexchar((x
[1] & 1) << 4 | x
[2] >> 4); /* 000YZZZZ */
476 *(z
++) = base32hexchar((x
[2] & 15) << 1 | x
[3] >> 7); /* 000ZZZZQ */
477 *(z
++) = base32hexchar((x
[3] & 127) >> 2); /* 000QQQQQ */
478 *(z
++) = base32hexchar((x
[3] & 3) << 3); /* 000QQ000 */
485 *(z
++) = base32hexchar(x
[0] >> 3); /* 000XXXXX */
486 *(z
++) = base32hexchar((x
[0] & 7) << 2 | x
[1] >> 6); /* 000XXXYY */
487 *(z
++) = base32hexchar((x
[1] & 63) >> 1); /* 000YYYYY */
488 *(z
++) = base32hexchar((x
[1] & 1) << 4 | x
[2] >> 4); /* 000YZZZZ */
489 *(z
++) = base32hexchar((x
[2] & 15) << 1); /* 000ZZZZ0 */
499 *(z
++) = base32hexchar(x
[0] >> 3); /* 000XXXXX */
500 *(z
++) = base32hexchar((x
[0] & 7) << 2 | x
[1] >> 6); /* 000XXXYY */
501 *(z
++) = base32hexchar((x
[1] & 63) >> 1); /* 000YYYYY */
502 *(z
++) = base32hexchar((x
[1] & 1) << 4); /* 000Y0000 */
513 *(z
++) = base32hexchar(x
[0] >> 3); /* 000XXXXX */
514 *(z
++) = base32hexchar((x
[0] & 7) << 2); /* 000XXX00 */
531 int unbase32hexmem(const char *p
, size_t l
, bool padding
, void **mem
, size_t *_len
) {
532 _cleanup_free_
uint8_t *r
= NULL
;
533 int a
, b
, c
, d
, e
, f
, g
, h
;
541 /* padding ensures any base32hex input has input divisible by 8 */
542 if (padding
&& l
% 8 != 0)
546 /* strip the padding */
547 while (l
> 0 && p
[l
- 1] == '=' && pad
< 7) {
553 /* a group of eight input bytes needs five output bytes, in case of
554 padding we need to add some extra bytes */
576 z
= r
= malloc(len
+ 1);
580 for (x
= p
; x
< p
+ (l
/ 8) * 8; x
+= 8) {
581 /* a == 000XXXXX; b == 000YYYYY; c == 000ZZZZZ; d == 000WWWWW
582 e == 000SSSSS; f == 000QQQQQ; g == 000VVVVV; h == 000RRRRR */
583 a
= unbase32hexchar(x
[0]);
587 b
= unbase32hexchar(x
[1]);
591 c
= unbase32hexchar(x
[2]);
595 d
= unbase32hexchar(x
[3]);
599 e
= unbase32hexchar(x
[4]);
603 f
= unbase32hexchar(x
[5]);
607 g
= unbase32hexchar(x
[6]);
611 h
= unbase32hexchar(x
[7]);
615 *(z
++) = (uint8_t) a
<< 3 | (uint8_t) b
>> 2; /* XXXXXYYY */
616 *(z
++) = (uint8_t) b
<< 6 | (uint8_t) c
<< 1 | (uint8_t) d
>> 4; /* YYZZZZZW */
617 *(z
++) = (uint8_t) d
<< 4 | (uint8_t) e
>> 1; /* WWWWSSSS */
618 *(z
++) = (uint8_t) e
<< 7 | (uint8_t) f
<< 2 | (uint8_t) g
>> 3; /* SQQQQQVV */
619 *(z
++) = (uint8_t) g
<< 5 | (uint8_t) h
; /* VVVRRRRR */
624 a
= unbase32hexchar(x
[0]);
628 b
= unbase32hexchar(x
[1]);
632 c
= unbase32hexchar(x
[2]);
636 d
= unbase32hexchar(x
[3]);
640 e
= unbase32hexchar(x
[4]);
644 f
= unbase32hexchar(x
[5]);
648 g
= unbase32hexchar(x
[6]);
656 *(z
++) = (uint8_t) a
<< 3 | (uint8_t) b
>> 2; /* XXXXXYYY */
657 *(z
++) = (uint8_t) b
<< 6 | (uint8_t) c
<< 1 | (uint8_t) d
>> 4; /* YYZZZZZW */
658 *(z
++) = (uint8_t) d
<< 4 | (uint8_t) e
>> 1; /* WWWWSSSS */
659 *(z
++) = (uint8_t) e
<< 7 | (uint8_t) f
<< 2 | (uint8_t) g
>> 3; /* SQQQQQVV */
663 a
= unbase32hexchar(x
[0]);
667 b
= unbase32hexchar(x
[1]);
671 c
= unbase32hexchar(x
[2]);
675 d
= unbase32hexchar(x
[3]);
679 e
= unbase32hexchar(x
[4]);
687 *(z
++) = (uint8_t) a
<< 3 | (uint8_t) b
>> 2; /* XXXXXYYY */
688 *(z
++) = (uint8_t) b
<< 6 | (uint8_t) c
<< 1 | (uint8_t) d
>> 4; /* YYZZZZZW */
689 *(z
++) = (uint8_t) d
<< 4 | (uint8_t) e
>> 1; /* WWWWSSSS */
693 a
= unbase32hexchar(x
[0]);
697 b
= unbase32hexchar(x
[1]);
701 c
= unbase32hexchar(x
[2]);
705 d
= unbase32hexchar(x
[3]);
713 *(z
++) = (uint8_t) a
<< 3 | (uint8_t) b
>> 2; /* XXXXXYYY */
714 *(z
++) = (uint8_t) b
<< 6 | (uint8_t) c
<< 1 | (uint8_t) d
>> 4; /* YYZZZZZW */
718 a
= unbase32hexchar(x
[0]);
722 b
= unbase32hexchar(x
[1]);
730 *(z
++) = (uint8_t) a
<< 3 | (uint8_t) b
>> 2; /* XXXXXYYY */
748 /* https://tools.ietf.org/html/rfc4648#section-4 */
749 char base64char(int x
) {
750 static const char table
[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
751 "abcdefghijklmnopqrstuvwxyz"
753 return table
[x
& 63];
756 int unbase64char(char c
) {
759 if (c
>= 'A' && c
<= 'Z')
762 offset
= 'Z' - 'A' + 1;
764 if (c
>= 'a' && c
<= 'z')
765 return c
- 'a' + offset
;
767 offset
+= 'z' - 'a' + 1;
769 if (c
>= '0' && c
<= '9')
770 return c
- '0' + offset
;
772 offset
+= '9' - '0' + 1;
785 char *base64mem(const void *p
, size_t l
) {
789 /* three input bytes makes four output bytes, padding is added so we must round up */
790 z
= r
= malloc(4 * (l
+ 2) / 3 + 1);
794 for (x
= p
; x
< (const uint8_t*) p
+ (l
/ 3) * 3; x
+= 3) {
795 /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ */
796 *(z
++) = base64char(x
[0] >> 2); /* 00XXXXXX */
797 *(z
++) = base64char((x
[0] & 3) << 4 | x
[1] >> 4); /* 00XXYYYY */
798 *(z
++) = base64char((x
[1] & 15) << 2 | x
[2] >> 6); /* 00YYYYZZ */
799 *(z
++) = base64char(x
[2] & 63); /* 00ZZZZZZ */
804 *(z
++) = base64char(x
[0] >> 2); /* 00XXXXXX */
805 *(z
++) = base64char((x
[0] & 3) << 4 | x
[1] >> 4); /* 00XXYYYY */
806 *(z
++) = base64char((x
[1] & 15) << 2); /* 00YYYY00 */
811 *(z
++) = base64char(x
[0] >> 2); /* 00XXXXXX */
812 *(z
++) = base64char((x
[0] & 3) << 4); /* 00XX0000 */
823 int unbase64mem(const char *p
, size_t l
, void **mem
, size_t *_len
) {
824 _cleanup_free_
uint8_t *r
= NULL
;
832 /* padding ensures any base63 input has input divisible by 4 */
836 /* strip the padding */
837 if (l
> 0 && p
[l
- 1] == '=')
839 if (l
> 0 && p
[l
- 1] == '=')
842 /* a group of four input bytes needs three output bytes, in case of
843 padding we need to add two or three extra bytes */
844 len
= (l
/ 4) * 3 + (l
% 4 ? (l
% 4) - 1 : 0);
846 z
= r
= malloc(len
+ 1);
850 for (x
= p
; x
< p
+ (l
/ 4) * 4; x
+= 4) {
851 /* a == 00XXXXXX; b == 00YYYYYY; c == 00ZZZZZZ; d == 00WWWWWW */
852 a
= unbase64char(x
[0]);
856 b
= unbase64char(x
[1]);
860 c
= unbase64char(x
[2]);
864 d
= unbase64char(x
[3]);
868 *(z
++) = (uint8_t) a
<< 2 | (uint8_t) b
>> 4; /* XXXXXXYY */
869 *(z
++) = (uint8_t) b
<< 4 | (uint8_t) c
>> 2; /* YYYYZZZZ */
870 *(z
++) = (uint8_t) c
<< 6 | (uint8_t) d
; /* ZZWWWWWW */
875 a
= unbase64char(x
[0]);
879 b
= unbase64char(x
[1]);
883 c
= unbase64char(x
[2]);
891 *(z
++) = (uint8_t) a
<< 2 | (uint8_t) b
>> 4; /* XXXXXXYY */
892 *(z
++) = (uint8_t) b
<< 4 | (uint8_t) c
>> 2; /* YYYYZZZZ */
896 a
= unbase64char(x
[0]);
900 b
= unbase64char(x
[1]);
908 *(z
++) = (uint8_t) a
<< 2 | (uint8_t) (b
>> 4); /* XXXXXXYY */
927 char octchar(int x
) {
928 return '0' + (x
& 7);
931 int unoctchar(char c
) {
933 if (c
>= '0' && c
<= '7')
939 char decchar(int x
) {
940 return '0' + (x
% 10);
943 int undecchar(char c
) {
945 if (c
>= '0' && c
<= '9')
951 _pure_
static bool hidden_file_allow_backup(const char *filename
) {
955 filename
[0] == '.' ||
956 streq(filename
, "lost+found") ||
957 streq(filename
, "aquota.user") ||
958 streq(filename
, "aquota.group") ||
959 endswith(filename
, ".rpmnew") ||
960 endswith(filename
, ".rpmsave") ||
961 endswith(filename
, ".rpmorig") ||
962 endswith(filename
, ".dpkg-old") ||
963 endswith(filename
, ".dpkg-new") ||
964 endswith(filename
, ".dpkg-tmp") ||
965 endswith(filename
, ".dpkg-dist") ||
966 endswith(filename
, ".dpkg-bak") ||
967 endswith(filename
, ".dpkg-backup") ||
968 endswith(filename
, ".dpkg-remove") ||
969 endswith(filename
, ".swp");
972 bool hidden_file(const char *filename
) {
975 if (endswith(filename
, "~"))
978 return hidden_file_allow_backup(filename
);
981 bool fstype_is_network(const char *fstype
) {
982 static const char table
[] =
997 x
= startswith(fstype
, "fuse.");
1001 return nulstr_contains(table
, fstype
);
1004 bool is_device_path(const char *path
) {
1006 /* Returns true on paths that refer to a device, either in
1007 * sysfs or in /dev */
1010 path_startswith(path
, "/dev/") ||
1011 path_startswith(path
, "/sys/");
1014 int dir_is_empty(const char *path
) {
1015 _cleanup_closedir_
DIR *d
;
1022 FOREACH_DIRENT(de
, d
, return -errno
)
1028 char* dirname_malloc(const char *path
) {
1029 char *d
, *dir
, *dir2
;
1046 void rename_process(const char name
[8]) {
1049 /* This is a like a poor man's setproctitle(). It changes the
1050 * comm field, argv[0], and also the glibc's internally used
1051 * name of the process. For the first one a limit of 16 chars
1052 * applies, to the second one usually one of 10 (i.e. length
1053 * of "/sbin/init"), to the third one one of 7 (i.e. length of
1054 * "systemd"). If you pass a longer string it will be
1057 prctl(PR_SET_NAME
, name
);
1059 if (program_invocation_name
)
1060 strncpy(program_invocation_name
, name
, strlen(program_invocation_name
));
1062 if (saved_argc
> 0) {
1066 strncpy(saved_argv
[0], name
, strlen(saved_argv
[0]));
1068 for (i
= 1; i
< saved_argc
; i
++) {
1072 memzero(saved_argv
[i
], strlen(saved_argv
[i
]));
1077 bool is_fs_type(const struct statfs
*s
, statfs_f_type_t magic_value
) {
1079 assert_cc(sizeof(statfs_f_type_t
) >= sizeof(s
->f_type
));
1081 return F_TYPE_EQUAL(s
->f_type
, magic_value
);
1084 int fd_check_fstype(int fd
, statfs_f_type_t magic_value
) {
1087 if (fstatfs(fd
, &s
) < 0)
1090 return is_fs_type(&s
, magic_value
);
1093 int path_check_fstype(const char *path
, statfs_f_type_t magic_value
) {
1094 _cleanup_close_
int fd
= -1;
1096 fd
= open(path
, O_RDONLY
);
1100 return fd_check_fstype(fd
, magic_value
);
1103 bool is_temporary_fs(const struct statfs
*s
) {
1104 return is_fs_type(s
, TMPFS_MAGIC
) ||
1105 is_fs_type(s
, RAMFS_MAGIC
);
1108 int fd_is_temporary_fs(int fd
) {
1111 if (fstatfs(fd
, &s
) < 0)
1114 return is_temporary_fs(&s
);
1117 int chmod_and_chown(const char *path
, mode_t mode
, uid_t uid
, gid_t gid
) {
1120 /* Under the assumption that we are running privileged we
1121 * first change the access mode and only then hand out
1122 * ownership to avoid a window where access is too open. */
1124 if (mode
!= MODE_INVALID
)
1125 if (chmod(path
, mode
) < 0)
1128 if (uid
!= UID_INVALID
|| gid
!= GID_INVALID
)
1129 if (chown(path
, uid
, gid
) < 0)
1135 int fchmod_and_fchown(int fd
, mode_t mode
, uid_t uid
, gid_t gid
) {
1138 /* Under the assumption that we are running privileged we
1139 * first change the access mode and only then hand out
1140 * ownership to avoid a window where access is too open. */
1142 if (mode
!= MODE_INVALID
)
1143 if (fchmod(fd
, mode
) < 0)
1146 if (uid
!= UID_INVALID
|| gid
!= GID_INVALID
)
1147 if (fchown(fd
, uid
, gid
) < 0)
1153 int files_same(const char *filea
, const char *fileb
) {
1156 if (stat(filea
, &a
) < 0)
1159 if (stat(fileb
, &b
) < 0)
1162 return a
.st_dev
== b
.st_dev
&&
1163 a
.st_ino
== b
.st_ino
;
1166 int running_in_chroot(void) {
1169 ret
= files_same("/proc/1/root", "/");
1176 int touch_file(const char *path
, bool parents
, usec_t stamp
, uid_t uid
, gid_t gid
, mode_t mode
) {
1177 _cleanup_close_
int fd
;
1183 mkdir_parents(path
, 0755);
1185 fd
= open(path
, O_WRONLY
|O_CREAT
|O_CLOEXEC
|O_NOCTTY
, mode
> 0 ? mode
: 0644);
1190 r
= fchmod(fd
, mode
);
1195 if (uid
!= UID_INVALID
|| gid
!= GID_INVALID
) {
1196 r
= fchown(fd
, uid
, gid
);
1201 if (stamp
!= USEC_INFINITY
) {
1202 struct timespec ts
[2];
1204 timespec_store(&ts
[0], stamp
);
1206 r
= futimens(fd
, ts
);
1208 r
= futimens(fd
, NULL
);
1215 int touch(const char *path
) {
1216 return touch_file(path
, false, USEC_INFINITY
, UID_INVALID
, GID_INVALID
, 0);
1219 static char *unquote(const char *s
, const char* quotes
) {
1223 /* This is rather stupid, simply removes the heading and
1224 * trailing quotes if there is one. Doesn't care about
1225 * escaping or anything.
1227 * DON'T USE THIS FOR NEW CODE ANYMORE!*/
1233 if (strchr(quotes
, s
[0]) && s
[l
-1] == s
[0])
1234 return strndup(s
+1, l
-2);
1239 noreturn
void freeze(void) {
1241 /* Make sure nobody waits for us on a socket anymore */
1242 close_all_fds(NULL
, 0);
1250 bool null_or_empty(struct stat
*st
) {
1253 if (S_ISREG(st
->st_mode
) && st
->st_size
<= 0)
1256 if (S_ISCHR(st
->st_mode
) || S_ISBLK(st
->st_mode
))
1262 int null_or_empty_path(const char *fn
) {
1267 if (stat(fn
, &st
) < 0)
1270 return null_or_empty(&st
);
1273 int null_or_empty_fd(int fd
) {
1278 if (fstat(fd
, &st
) < 0)
1281 return null_or_empty(&st
);
1284 DIR *xopendirat(int fd
, const char *name
, int flags
) {
1288 assert(!(flags
& O_CREAT
));
1290 nfd
= openat(fd
, name
, O_RDONLY
|O_NONBLOCK
|O_DIRECTORY
|O_CLOEXEC
|flags
, 0);
1303 static char *tag_to_udev_node(const char *tagvalue
, const char *by
) {
1304 _cleanup_free_
char *t
= NULL
, *u
= NULL
;
1307 u
= unquote(tagvalue
, QUOTES
);
1311 enc_len
= strlen(u
) * 4 + 1;
1312 t
= new(char, enc_len
);
1316 if (encode_devnode_name(u
, t
, enc_len
) < 0)
1319 return strjoin("/dev/disk/by-", by
, "/", t
, NULL
);
1322 char *fstab_node_to_udev_node(const char *p
) {
1325 if (startswith(p
, "LABEL="))
1326 return tag_to_udev_node(p
+6, "label");
1328 if (startswith(p
, "UUID="))
1329 return tag_to_udev_node(p
+5, "uuid");
1331 if (startswith(p
, "PARTUUID="))
1332 return tag_to_udev_node(p
+9, "partuuid");
1334 if (startswith(p
, "PARTLABEL="))
1335 return tag_to_udev_node(p
+10, "partlabel");
1340 bool dirent_is_file(const struct dirent
*de
) {
1343 if (hidden_file(de
->d_name
))
1346 if (de
->d_type
!= DT_REG
&&
1347 de
->d_type
!= DT_LNK
&&
1348 de
->d_type
!= DT_UNKNOWN
)
1354 bool dirent_is_file_with_suffix(const struct dirent
*de
, const char *suffix
) {
1357 if (de
->d_type
!= DT_REG
&&
1358 de
->d_type
!= DT_LNK
&&
1359 de
->d_type
!= DT_UNKNOWN
)
1362 if (hidden_file_allow_backup(de
->d_name
))
1365 return endswith(de
->d_name
, suffix
);
1368 static int do_execute(char **directories
, usec_t timeout
, char *argv
[]) {
1369 _cleanup_hashmap_free_free_ Hashmap
*pids
= NULL
;
1370 _cleanup_set_free_free_ Set
*seen
= NULL
;
1373 /* We fork this all off from a child process so that we can
1374 * somewhat cleanly make use of SIGALRM to set a time limit */
1376 (void) reset_all_signal_handlers();
1377 (void) reset_signal_mask();
1379 assert_se(prctl(PR_SET_PDEATHSIG
, SIGTERM
) == 0);
1381 pids
= hashmap_new(NULL
);
1385 seen
= set_new(&string_hash_ops
);
1389 STRV_FOREACH(directory
, directories
) {
1390 _cleanup_closedir_
DIR *d
;
1393 d
= opendir(*directory
);
1395 if (errno
== ENOENT
)
1398 return log_error_errno(errno
, "Failed to open directory %s: %m", *directory
);
1401 FOREACH_DIRENT(de
, d
, break) {
1402 _cleanup_free_
char *path
= NULL
;
1406 if (!dirent_is_file(de
))
1409 if (set_contains(seen
, de
->d_name
)) {
1410 log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory
, de
->d_name
);
1414 r
= set_put_strdup(seen
, de
->d_name
);
1418 path
= strjoin(*directory
, "/", de
->d_name
, NULL
);
1422 if (null_or_empty_path(path
)) {
1423 log_debug("%s is empty (a mask).", path
);
1429 log_error_errno(errno
, "Failed to fork: %m");
1431 } else if (pid
== 0) {
1434 assert_se(prctl(PR_SET_PDEATHSIG
, SIGTERM
) == 0);
1444 return log_error_errno(errno
, "Failed to execute %s: %m", path
);
1447 log_debug("Spawned %s as " PID_FMT
".", path
, pid
);
1449 r
= hashmap_put(pids
, UINT_TO_PTR(pid
), path
);
1456 /* Abort execution of this process after the timout. We simply
1457 * rely on SIGALRM as default action terminating the process,
1458 * and turn on alarm(). */
1460 if (timeout
!= USEC_INFINITY
)
1461 alarm((timeout
+ USEC_PER_SEC
- 1) / USEC_PER_SEC
);
1463 while (!hashmap_isempty(pids
)) {
1464 _cleanup_free_
char *path
= NULL
;
1467 pid
= PTR_TO_UINT(hashmap_first_key(pids
));
1470 path
= hashmap_remove(pids
, UINT_TO_PTR(pid
));
1473 wait_for_terminate_and_warn(path
, pid
, true);
1479 void execute_directories(const char* const* directories
, usec_t timeout
, char *argv
[]) {
1483 char **dirs
= (char**) directories
;
1485 assert(!strv_isempty(dirs
));
1487 name
= basename(dirs
[0]);
1488 assert(!isempty(name
));
1490 /* Executes all binaries in the directories in parallel and waits
1491 * for them to finish. Optionally a timeout is applied. If a file
1492 * with the same name exists in more than one directory, the
1493 * earliest one wins. */
1495 executor_pid
= fork();
1496 if (executor_pid
< 0) {
1497 log_error_errno(errno
, "Failed to fork: %m");
1500 } else if (executor_pid
== 0) {
1501 r
= do_execute(dirs
, timeout
, argv
);
1502 _exit(r
< 0 ? EXIT_FAILURE
: EXIT_SUCCESS
);
1505 wait_for_terminate_and_warn(name
, executor_pid
, true);
1508 bool plymouth_running(void) {
1509 return access("/run/plymouth/pid", F_OK
) >= 0;
1512 int fopen_temporary(const char *path
, FILE **_f
, char **_temp_path
) {
1521 r
= tempfn_xxxxxx(path
, NULL
, &t
);
1525 fd
= mkostemp_safe(t
, O_WRONLY
|O_CLOEXEC
);
1531 f
= fdopen(fd
, "we");
1545 int symlink_atomic(const char *from
, const char *to
) {
1546 _cleanup_free_
char *t
= NULL
;
1552 r
= tempfn_random(to
, NULL
, &t
);
1556 if (symlink(from
, t
) < 0)
1559 if (rename(t
, to
) < 0) {
1567 int symlink_idempotent(const char *from
, const char *to
) {
1568 _cleanup_free_
char *p
= NULL
;
1574 if (symlink(from
, to
) < 0) {
1575 if (errno
!= EEXIST
)
1578 r
= readlink_malloc(to
, &p
);
1582 if (!streq(p
, from
))
1589 int mknod_atomic(const char *path
, mode_t mode
, dev_t dev
) {
1590 _cleanup_free_
char *t
= NULL
;
1595 r
= tempfn_random(path
, NULL
, &t
);
1599 if (mknod(t
, mode
, dev
) < 0)
1602 if (rename(t
, path
) < 0) {
1610 int mkfifo_atomic(const char *path
, mode_t mode
) {
1611 _cleanup_free_
char *t
= NULL
;
1616 r
= tempfn_random(path
, NULL
, &t
);
1620 if (mkfifo(t
, mode
) < 0)
1623 if (rename(t
, path
) < 0) {
1631 bool display_is_local(const char *display
) {
1635 display
[0] == ':' &&
1636 display
[1] >= '0' &&
1640 int socket_from_display(const char *display
, char **path
) {
1647 if (!display_is_local(display
))
1650 k
= strspn(display
+1, "0123456789");
1652 f
= new(char, strlen("/tmp/.X11-unix/X") + k
+ 1);
1656 c
= stpcpy(f
, "/tmp/.X11-unix/X");
1657 memcpy(c
, display
+1, k
);
1665 int glob_exists(const char *path
) {
1666 _cleanup_globfree_ glob_t g
= {};
1672 k
= glob(path
, GLOB_NOSORT
|GLOB_BRACE
, NULL
, &g
);
1674 if (k
== GLOB_NOMATCH
)
1676 else if (k
== GLOB_NOSPACE
)
1679 return !strv_isempty(g
.gl_pathv
);
1681 return errno
? -errno
: -EIO
;
1684 int glob_extend(char ***strv
, const char *path
) {
1685 _cleanup_globfree_ glob_t g
= {};
1690 k
= glob(path
, GLOB_NOSORT
|GLOB_BRACE
, NULL
, &g
);
1692 if (k
== GLOB_NOMATCH
)
1694 else if (k
== GLOB_NOSPACE
)
1696 else if (k
!= 0 || strv_isempty(g
.gl_pathv
))
1697 return errno
? -errno
: -EIO
;
1699 STRV_FOREACH(p
, g
.gl_pathv
) {
1700 k
= strv_extend(strv
, *p
);
1708 int dirent_ensure_type(DIR *d
, struct dirent
*de
) {
1714 if (de
->d_type
!= DT_UNKNOWN
)
1717 if (fstatat(dirfd(d
), de
->d_name
, &st
, AT_SYMLINK_NOFOLLOW
) < 0)
1721 S_ISREG(st
.st_mode
) ? DT_REG
:
1722 S_ISDIR(st
.st_mode
) ? DT_DIR
:
1723 S_ISLNK(st
.st_mode
) ? DT_LNK
:
1724 S_ISFIFO(st
.st_mode
) ? DT_FIFO
:
1725 S_ISSOCK(st
.st_mode
) ? DT_SOCK
:
1726 S_ISCHR(st
.st_mode
) ? DT_CHR
:
1727 S_ISBLK(st
.st_mode
) ? DT_BLK
:
1733 int get_files_in_directory(const char *path
, char ***list
) {
1734 _cleanup_closedir_
DIR *d
= NULL
;
1735 size_t bufsize
= 0, n
= 0;
1736 _cleanup_strv_free_
char **l
= NULL
;
1740 /* Returns all files in a directory in *list, and the number
1741 * of files as return value. If list is NULL returns only the
1753 if (!de
&& errno
!= 0)
1758 dirent_ensure_type(d
, de
);
1760 if (!dirent_is_file(de
))
1764 /* one extra slot is needed for the terminating NULL */
1765 if (!GREEDY_REALLOC(l
, bufsize
, n
+ 2))
1768 l
[n
] = strdup(de
->d_name
);
1779 l
= NULL
; /* avoid freeing */
1785 bool is_main_thread(void) {
1786 static thread_local
int cached
= 0;
1788 if (_unlikely_(cached
== 0))
1789 cached
= getpid() == gettid() ? 1 : -1;
1794 int block_get_whole_disk(dev_t d
, dev_t
*ret
) {
1801 /* If it has a queue this is good enough for us */
1802 if (asprintf(&p
, "/sys/dev/block/%u:%u/queue", major(d
), minor(d
)) < 0)
1805 r
= access(p
, F_OK
);
1813 /* If it is a partition find the originating device */
1814 if (asprintf(&p
, "/sys/dev/block/%u:%u/partition", major(d
), minor(d
)) < 0)
1817 r
= access(p
, F_OK
);
1823 /* Get parent dev_t */
1824 if (asprintf(&p
, "/sys/dev/block/%u:%u/../dev", major(d
), minor(d
)) < 0)
1827 r
= read_one_line_file(p
, &s
);
1833 r
= sscanf(s
, "%u:%u", &m
, &n
);
1839 /* Only return this if it is really good enough for us. */
1840 if (asprintf(&p
, "/sys/dev/block/%u:%u/queue", m
, n
) < 0)
1843 r
= access(p
, F_OK
);
1847 *ret
= makedev(m
, n
);
1854 static const char *const ioprio_class_table
[] = {
1855 [IOPRIO_CLASS_NONE
] = "none",
1856 [IOPRIO_CLASS_RT
] = "realtime",
1857 [IOPRIO_CLASS_BE
] = "best-effort",
1858 [IOPRIO_CLASS_IDLE
] = "idle"
1861 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class
, int, INT_MAX
);
1863 static const char *const sigchld_code_table
[] = {
1864 [CLD_EXITED
] = "exited",
1865 [CLD_KILLED
] = "killed",
1866 [CLD_DUMPED
] = "dumped",
1867 [CLD_TRAPPED
] = "trapped",
1868 [CLD_STOPPED
] = "stopped",
1869 [CLD_CONTINUED
] = "continued",
1872 DEFINE_STRING_TABLE_LOOKUP(sigchld_code
, int);
1874 static const char *const log_facility_unshifted_table
[LOG_NFACILITIES
] = {
1875 [LOG_FAC(LOG_KERN
)] = "kern",
1876 [LOG_FAC(LOG_USER
)] = "user",
1877 [LOG_FAC(LOG_MAIL
)] = "mail",
1878 [LOG_FAC(LOG_DAEMON
)] = "daemon",
1879 [LOG_FAC(LOG_AUTH
)] = "auth",
1880 [LOG_FAC(LOG_SYSLOG
)] = "syslog",
1881 [LOG_FAC(LOG_LPR
)] = "lpr",
1882 [LOG_FAC(LOG_NEWS
)] = "news",
1883 [LOG_FAC(LOG_UUCP
)] = "uucp",
1884 [LOG_FAC(LOG_CRON
)] = "cron",
1885 [LOG_FAC(LOG_AUTHPRIV
)] = "authpriv",
1886 [LOG_FAC(LOG_FTP
)] = "ftp",
1887 [LOG_FAC(LOG_LOCAL0
)] = "local0",
1888 [LOG_FAC(LOG_LOCAL1
)] = "local1",
1889 [LOG_FAC(LOG_LOCAL2
)] = "local2",
1890 [LOG_FAC(LOG_LOCAL3
)] = "local3",
1891 [LOG_FAC(LOG_LOCAL4
)] = "local4",
1892 [LOG_FAC(LOG_LOCAL5
)] = "local5",
1893 [LOG_FAC(LOG_LOCAL6
)] = "local6",
1894 [LOG_FAC(LOG_LOCAL7
)] = "local7"
1897 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted
, int, LOG_FAC(~0));
1899 bool log_facility_unshifted_is_valid(int facility
) {
1900 return facility
>= 0 && facility
<= LOG_FAC(~0);
1903 static const char *const log_level_table
[] = {
1904 [LOG_EMERG
] = "emerg",
1905 [LOG_ALERT
] = "alert",
1906 [LOG_CRIT
] = "crit",
1908 [LOG_WARNING
] = "warning",
1909 [LOG_NOTICE
] = "notice",
1910 [LOG_INFO
] = "info",
1911 [LOG_DEBUG
] = "debug"
1914 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level
, int, LOG_DEBUG
);
1916 bool log_level_is_valid(int level
) {
1917 return level
>= 0 && level
<= LOG_DEBUG
;
1920 static const char* const sched_policy_table
[] = {
1921 [SCHED_OTHER
] = "other",
1922 [SCHED_BATCH
] = "batch",
1923 [SCHED_IDLE
] = "idle",
1924 [SCHED_FIFO
] = "fifo",
1928 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy
, int, INT_MAX
);
1930 static const char* const rlimit_table
[_RLIMIT_MAX
] = {
1931 [RLIMIT_CPU
] = "LimitCPU",
1932 [RLIMIT_FSIZE
] = "LimitFSIZE",
1933 [RLIMIT_DATA
] = "LimitDATA",
1934 [RLIMIT_STACK
] = "LimitSTACK",
1935 [RLIMIT_CORE
] = "LimitCORE",
1936 [RLIMIT_RSS
] = "LimitRSS",
1937 [RLIMIT_NOFILE
] = "LimitNOFILE",
1938 [RLIMIT_AS
] = "LimitAS",
1939 [RLIMIT_NPROC
] = "LimitNPROC",
1940 [RLIMIT_MEMLOCK
] = "LimitMEMLOCK",
1941 [RLIMIT_LOCKS
] = "LimitLOCKS",
1942 [RLIMIT_SIGPENDING
] = "LimitSIGPENDING",
1943 [RLIMIT_MSGQUEUE
] = "LimitMSGQUEUE",
1944 [RLIMIT_NICE
] = "LimitNICE",
1945 [RLIMIT_RTPRIO
] = "LimitRTPRIO",
1946 [RLIMIT_RTTIME
] = "LimitRTTIME"
1949 DEFINE_STRING_TABLE_LOOKUP(rlimit
, int);
1951 bool kexec_loaded(void) {
1952 bool loaded
= false;
1955 if (read_one_line_file("/sys/kernel/kexec_loaded", &s
) >= 0) {
1963 int prot_from_flags(int flags
) {
1965 switch (flags
& O_ACCMODE
) {
1974 return PROT_READ
|PROT_WRITE
;
1981 void* memdup(const void *p
, size_t l
) {
1994 int fork_agent(pid_t
*pid
, const int except
[], unsigned n_except
, const char *path
, ...) {
1995 bool stdout_is_tty
, stderr_is_tty
;
1996 pid_t parent_pid
, agent_pid
;
1997 sigset_t ss
, saved_ss
;
2005 /* Spawns a temporary TTY agent, making sure it goes away when
2008 parent_pid
= getpid();
2010 /* First we temporarily block all signals, so that the new
2011 * child has them blocked initially. This way, we can be sure
2012 * that SIGTERMs are not lost we might send to the agent. */
2013 assert_se(sigfillset(&ss
) >= 0);
2014 assert_se(sigprocmask(SIG_SETMASK
, &ss
, &saved_ss
) >= 0);
2017 if (agent_pid
< 0) {
2018 assert_se(sigprocmask(SIG_SETMASK
, &saved_ss
, NULL
) >= 0);
2022 if (agent_pid
!= 0) {
2023 assert_se(sigprocmask(SIG_SETMASK
, &saved_ss
, NULL
) >= 0);
2030 * Make sure the agent goes away when the parent dies */
2031 if (prctl(PR_SET_PDEATHSIG
, SIGTERM
) < 0)
2032 _exit(EXIT_FAILURE
);
2034 /* Make sure we actually can kill the agent, if we need to, in
2035 * case somebody invoked us from a shell script that trapped
2036 * SIGTERM or so... */
2037 (void) reset_all_signal_handlers();
2038 (void) reset_signal_mask();
2040 /* Check whether our parent died before we were able
2041 * to set the death signal and unblock the signals */
2042 if (getppid() != parent_pid
)
2043 _exit(EXIT_SUCCESS
);
2045 /* Don't leak fds to the agent */
2046 close_all_fds(except
, n_except
);
2048 stdout_is_tty
= isatty(STDOUT_FILENO
);
2049 stderr_is_tty
= isatty(STDERR_FILENO
);
2051 if (!stdout_is_tty
|| !stderr_is_tty
) {
2054 /* Detach from stdout/stderr. and reopen
2055 * /dev/tty for them. This is important to
2056 * ensure that when systemctl is started via
2057 * popen() or a similar call that expects to
2058 * read EOF we actually do generate EOF and
2059 * not delay this indefinitely by because we
2060 * keep an unused copy of stdin around. */
2061 fd
= open("/dev/tty", O_WRONLY
);
2063 log_error_errno(errno
, "Failed to open /dev/tty: %m");
2064 _exit(EXIT_FAILURE
);
2068 dup2(fd
, STDOUT_FILENO
);
2071 dup2(fd
, STDERR_FILENO
);
2077 /* Count arguments */
2079 for (n
= 0; va_arg(ap
, char*); n
++)
2084 l
= alloca(sizeof(char *) * (n
+ 1));
2086 /* Fill in arguments */
2088 for (i
= 0; i
<= n
; i
++)
2089 l
[i
] = va_arg(ap
, char*);
2093 _exit(EXIT_FAILURE
);
2096 int setrlimit_closest(int resource
, const struct rlimit
*rlim
) {
2097 struct rlimit highest
, fixed
;
2101 if (setrlimit(resource
, rlim
) >= 0)
2107 /* So we failed to set the desired setrlimit, then let's try
2108 * to get as close as we can */
2109 assert_se(getrlimit(resource
, &highest
) == 0);
2111 fixed
.rlim_cur
= MIN(rlim
->rlim_cur
, highest
.rlim_max
);
2112 fixed
.rlim_max
= MIN(rlim
->rlim_max
, highest
.rlim_max
);
2114 if (setrlimit(resource
, &fixed
) < 0)
2120 bool http_etag_is_valid(const char *etag
) {
2124 if (!endswith(etag
, "\""))
2127 if (!startswith(etag
, "\"") && !startswith(etag
, "W/\""))
2133 bool http_url_is_valid(const char *url
) {
2139 p
= startswith(url
, "http://");
2141 p
= startswith(url
, "https://");
2148 return ascii_is_valid(p
);
2151 bool documentation_url_is_valid(const char *url
) {
2157 if (http_url_is_valid(url
))
2160 p
= startswith(url
, "file:/");
2162 p
= startswith(url
, "info:");
2164 p
= startswith(url
, "man:");
2169 return ascii_is_valid(p
);
2172 bool in_initrd(void) {
2173 static int saved
= -1;
2179 /* We make two checks here:
2181 * 1. the flag file /etc/initrd-release must exist
2182 * 2. the root file system must be a memory file system
2184 * The second check is extra paranoia, since misdetecting an
2185 * initrd can have bad bad consequences due the initrd
2186 * emptying when transititioning to the main systemd.
2189 saved
= access("/etc/initrd-release", F_OK
) >= 0 &&
2190 statfs("/", &s
) >= 0 &&
2191 is_temporary_fs(&s
);
2196 bool filename_is_valid(const char *p
) {
2210 if (strlen(p
) > FILENAME_MAX
)
2216 bool string_is_safe(const char *p
) {
2222 for (t
= p
; *t
; t
++) {
2223 if (*t
> 0 && *t
< ' ')
2226 if (strchr("\\\"\'\x7f", *t
))
2233 bool path_is_safe(const char *p
) {
2238 if (streq(p
, "..") || startswith(p
, "../") || endswith(p
, "/..") || strstr(p
, "/../"))
2241 if (strlen(p
)+1 > PATH_MAX
)
2244 /* The following two checks are not really dangerous, but hey, they still are confusing */
2245 if (streq(p
, ".") || startswith(p
, "./") || endswith(p
, "/.") || strstr(p
, "/./"))
2248 if (strstr(p
, "//"))
2254 /* hey glibc, APIs with callbacks without a user pointer are so useless */
2255 void *xbsearch_r(const void *key
, const void *base
, size_t nmemb
, size_t size
,
2256 int (*compar
) (const void *, const void *, void *), void *arg
) {
2265 p
= (void *)(((const char *) base
) + (idx
* size
));
2266 comparison
= compar(key
, p
, arg
);
2269 else if (comparison
> 0)
2277 void init_gettext(void) {
2278 setlocale(LC_ALL
, "");
2279 textdomain(GETTEXT_PACKAGE
);
2282 bool is_locale_utf8(void) {
2284 static int cached_answer
= -1;
2286 if (cached_answer
>= 0)
2289 if (!setlocale(LC_ALL
, "")) {
2290 cached_answer
= true;
2294 set
= nl_langinfo(CODESET
);
2296 cached_answer
= true;
2300 if (streq(set
, "UTF-8")) {
2301 cached_answer
= true;
2305 /* For LC_CTYPE=="C" return true, because CTYPE is effectly
2306 * unset and everything can do to UTF-8 nowadays. */
2307 set
= setlocale(LC_CTYPE
, NULL
);
2309 cached_answer
= true;
2313 /* Check result, but ignore the result if C was set
2316 STR_IN_SET(set
, "C", "POSIX") &&
2317 !getenv("LC_ALL") &&
2318 !getenv("LC_CTYPE") &&
2322 return (bool) cached_answer
;
2325 const char *draw_special_char(DrawSpecialChar ch
) {
2326 static const char *draw_table
[2][_DRAW_SPECIAL_CHAR_MAX
] = {
2329 [DRAW_TREE_VERTICAL
] = "\342\224\202 ", /* │ */
2330 [DRAW_TREE_BRANCH
] = "\342\224\234\342\224\200", /* ├─ */
2331 [DRAW_TREE_RIGHT
] = "\342\224\224\342\224\200", /* └─ */
2332 [DRAW_TREE_SPACE
] = " ", /* */
2333 [DRAW_TRIANGULAR_BULLET
] = "\342\200\243", /* ‣ */
2334 [DRAW_BLACK_CIRCLE
] = "\342\227\217", /* ● */
2335 [DRAW_ARROW
] = "\342\206\222", /* → */
2336 [DRAW_DASH
] = "\342\200\223", /* – */
2339 /* ASCII fallback */ {
2340 [DRAW_TREE_VERTICAL
] = "| ",
2341 [DRAW_TREE_BRANCH
] = "|-",
2342 [DRAW_TREE_RIGHT
] = "`-",
2343 [DRAW_TREE_SPACE
] = " ",
2344 [DRAW_TRIANGULAR_BULLET
] = ">",
2345 [DRAW_BLACK_CIRCLE
] = "*",
2346 [DRAW_ARROW
] = "->",
2351 return draw_table
[!is_locale_utf8()][ch
];
2354 int on_ac_power(void) {
2355 bool found_offline
= false, found_online
= false;
2356 _cleanup_closedir_
DIR *d
= NULL
;
2358 d
= opendir("/sys/class/power_supply");
2360 return errno
== ENOENT
? true : -errno
;
2364 _cleanup_close_
int fd
= -1, device
= -1;
2370 if (!de
&& errno
!= 0)
2376 if (hidden_file(de
->d_name
))
2379 device
= openat(dirfd(d
), de
->d_name
, O_DIRECTORY
|O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
2381 if (errno
== ENOENT
|| errno
== ENOTDIR
)
2387 fd
= openat(device
, "type", O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
2389 if (errno
== ENOENT
)
2395 n
= read(fd
, contents
, sizeof(contents
));
2399 if (n
!= 6 || memcmp(contents
, "Mains\n", 6))
2403 fd
= openat(device
, "online", O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
2405 if (errno
== ENOENT
)
2411 n
= read(fd
, contents
, sizeof(contents
));
2415 if (n
!= 2 || contents
[1] != '\n')
2418 if (contents
[0] == '1') {
2419 found_online
= true;
2421 } else if (contents
[0] == '0')
2422 found_offline
= true;
2427 return found_online
|| !found_offline
;
2430 static int search_and_fopen_internal(const char *path
, const char *mode
, const char *root
, char **search
, FILE **_f
) {
2437 if (!path_strv_resolve_uniq(search
, root
))
2440 STRV_FOREACH(i
, search
) {
2441 _cleanup_free_
char *p
= NULL
;
2445 p
= strjoin(root
, *i
, "/", path
, NULL
);
2447 p
= strjoin(*i
, "/", path
, NULL
);
2457 if (errno
!= ENOENT
)
2464 int search_and_fopen(const char *path
, const char *mode
, const char *root
, const char **search
, FILE **_f
) {
2465 _cleanup_strv_free_
char **copy
= NULL
;
2471 if (path_is_absolute(path
)) {
2474 f
= fopen(path
, mode
);
2483 copy
= strv_copy((char**) search
);
2487 return search_and_fopen_internal(path
, mode
, root
, copy
, _f
);
2490 int search_and_fopen_nulstr(const char *path
, const char *mode
, const char *root
, const char *search
, FILE **_f
) {
2491 _cleanup_strv_free_
char **s
= NULL
;
2493 if (path_is_absolute(path
)) {
2496 f
= fopen(path
, mode
);
2505 s
= strv_split_nulstr(search
);
2509 return search_and_fopen_internal(path
, mode
, root
, s
, _f
);
2512 void* greedy_realloc(void **p
, size_t *allocated
, size_t need
, size_t size
) {
2519 if (*allocated
>= need
)
2522 newalloc
= MAX(need
* 2, 64u / size
);
2523 a
= newalloc
* size
;
2525 /* check for overflows */
2526 if (a
< size
* need
)
2534 *allocated
= newalloc
;
2538 void* greedy_realloc0(void **p
, size_t *allocated
, size_t need
, size_t size
) {
2547 q
= greedy_realloc(p
, allocated
, need
, size
);
2551 if (*allocated
> prev
)
2552 memzero(q
+ prev
* size
, (*allocated
- prev
) * size
);
2557 bool id128_is_valid(const char *s
) {
2563 /* Simple formatted 128bit hex string */
2565 for (i
= 0; i
< l
; i
++) {
2568 if (!(c
>= '0' && c
<= '9') &&
2569 !(c
>= 'a' && c
<= 'z') &&
2570 !(c
>= 'A' && c
<= 'Z'))
2574 } else if (l
== 36) {
2576 /* Formatted UUID */
2578 for (i
= 0; i
< l
; i
++) {
2581 if ((i
== 8 || i
== 13 || i
== 18 || i
== 23)) {
2585 if (!(c
>= '0' && c
<= '9') &&
2586 !(c
>= 'a' && c
<= 'z') &&
2587 !(c
>= 'A' && c
<= 'Z'))
2598 int shall_restore_state(void) {
2599 _cleanup_free_
char *value
= NULL
;
2602 r
= get_proc_cmdline_key("systemd.restore_state=", &value
);
2608 return parse_boolean(value
) != 0;
2611 int proc_cmdline(char **ret
) {
2614 if (detect_container() > 0)
2615 return get_process_cmdline(1, 0, false, ret
);
2617 return read_one_line_file("/proc/cmdline", ret
);
2620 int parse_proc_cmdline(int (*parse_item
)(const char *key
, const char *value
)) {
2621 _cleanup_free_
char *line
= NULL
;
2627 r
= proc_cmdline(&line
);
2633 _cleanup_free_
char *word
= NULL
;
2636 r
= extract_first_word(&p
, &word
, NULL
, EXTRACT_QUOTES
|EXTRACT_RELAX
);
2642 /* Filter out arguments that are intended only for the
2644 if (!in_initrd() && startswith(word
, "rd."))
2647 value
= strchr(word
, '=');
2651 r
= parse_item(word
, value
);
2659 int get_proc_cmdline_key(const char *key
, char **value
) {
2660 _cleanup_free_
char *line
= NULL
, *ret
= NULL
;
2667 r
= proc_cmdline(&line
);
2673 _cleanup_free_
char *word
= NULL
;
2676 r
= extract_first_word(&p
, &word
, NULL
, EXTRACT_QUOTES
|EXTRACT_RELAX
);
2682 /* Filter out arguments that are intended only for the
2684 if (!in_initrd() && startswith(word
, "rd."))
2688 e
= startswith(word
, key
);
2692 r
= free_and_strdup(&ret
, e
);
2698 if (streq(word
, key
))
2712 int container_get_leader(const char *machine
, pid_t
*pid
) {
2713 _cleanup_free_
char *s
= NULL
, *class = NULL
;
2721 if (!machine_name_is_valid(machine
))
2724 p
= strjoina("/run/systemd/machines/", machine
);
2725 r
= parse_env_file(p
, NEWLINE
, "LEADER", &s
, "CLASS", &class, NULL
);
2733 if (!streq_ptr(class, "container"))
2736 r
= parse_pid(s
, &leader
);
2746 int namespace_open(pid_t pid
, int *pidns_fd
, int *mntns_fd
, int *netns_fd
, int *userns_fd
, int *root_fd
) {
2747 _cleanup_close_
int pidnsfd
= -1, mntnsfd
= -1, netnsfd
= -1, usernsfd
= -1;
2755 mntns
= procfs_file_alloca(pid
, "ns/mnt");
2756 mntnsfd
= open(mntns
, O_RDONLY
|O_NOCTTY
|O_CLOEXEC
);
2764 pidns
= procfs_file_alloca(pid
, "ns/pid");
2765 pidnsfd
= open(pidns
, O_RDONLY
|O_NOCTTY
|O_CLOEXEC
);
2773 netns
= procfs_file_alloca(pid
, "ns/net");
2774 netnsfd
= open(netns
, O_RDONLY
|O_NOCTTY
|O_CLOEXEC
);
2782 userns
= procfs_file_alloca(pid
, "ns/user");
2783 usernsfd
= open(userns
, O_RDONLY
|O_NOCTTY
|O_CLOEXEC
);
2784 if (usernsfd
< 0 && errno
!= ENOENT
)
2791 root
= procfs_file_alloca(pid
, "root");
2792 rfd
= open(root
, O_RDONLY
|O_NOCTTY
|O_CLOEXEC
|O_DIRECTORY
);
2798 *pidns_fd
= pidnsfd
;
2801 *mntns_fd
= mntnsfd
;
2804 *netns_fd
= netnsfd
;
2807 *userns_fd
= usernsfd
;
2812 pidnsfd
= mntnsfd
= netnsfd
= usernsfd
= -1;
2817 int namespace_enter(int pidns_fd
, int mntns_fd
, int netns_fd
, int userns_fd
, int root_fd
) {
2818 if (userns_fd
>= 0) {
2819 /* Can't setns to your own userns, since then you could
2820 * escalate from non-root to root in your own namespace, so
2821 * check if namespaces equal before attempting to enter. */
2822 _cleanup_free_
char *userns_fd_path
= NULL
;
2824 if (asprintf(&userns_fd_path
, "/proc/self/fd/%d", userns_fd
) < 0)
2827 r
= files_same(userns_fd_path
, "/proc/self/ns/user");
2835 if (setns(pidns_fd
, CLONE_NEWPID
) < 0)
2839 if (setns(mntns_fd
, CLONE_NEWNS
) < 0)
2843 if (setns(netns_fd
, CLONE_NEWNET
) < 0)
2847 if (setns(userns_fd
, CLONE_NEWUSER
) < 0)
2851 if (fchdir(root_fd
) < 0)
2854 if (chroot(".") < 0)
2858 return reset_uid_gid();
2861 /* This is much like like mkostemp() but is subject to umask(). */
2862 int mkostemp_safe(char *pattern
, int flags
) {
2863 _cleanup_umask_ mode_t u
;
2870 fd
= mkostemp(pattern
, flags
);
2877 int open_tmpfile(const char *path
, int flags
) {
2884 /* Try O_TMPFILE first, if it is supported */
2885 fd
= open(path
, flags
|O_TMPFILE
|O_EXCL
, S_IRUSR
|S_IWUSR
);
2890 /* Fall back to unguessable name + unlinking */
2891 p
= strjoina(path
, "/systemd-tmp-XXXXXX");
2893 fd
= mkostemp_safe(p
, flags
);
2901 int fd_warn_permissions(const char *path
, int fd
) {
2904 if (fstat(fd
, &st
) < 0)
2907 if (st
.st_mode
& 0111)
2908 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path
);
2910 if (st
.st_mode
& 0002)
2911 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path
);
2913 if (getpid() == 1 && (st
.st_mode
& 0044) != 0044)
2914 log_warning("Configuration file %s is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.", path
);
2919 unsigned long personality_from_string(const char *p
) {
2921 /* Parse a personality specifier. We introduce our own
2922 * identifiers that indicate specific ABIs, rather than just
2923 * hints regarding the register size, since we want to keep
2924 * things open for multiple locally supported ABIs for the
2925 * same register size. We try to reuse the ABI identifiers
2926 * used by libseccomp. */
2928 #if defined(__x86_64__)
2930 if (streq(p
, "x86"))
2933 if (streq(p
, "x86-64"))
2936 #elif defined(__i386__)
2938 if (streq(p
, "x86"))
2941 #elif defined(__s390x__)
2943 if (streq(p
, "s390"))
2946 if (streq(p
, "s390x"))
2949 #elif defined(__s390__)
2951 if (streq(p
, "s390"))
2955 return PERSONALITY_INVALID
;
2958 const char* personality_to_string(unsigned long p
) {
2960 #if defined(__x86_64__)
2962 if (p
== PER_LINUX32
)
2968 #elif defined(__i386__)
2973 #elif defined(__s390x__)
2978 if (p
== PER_LINUX32
)
2981 #elif defined(__s390__)
2991 uint64_t physical_memory(void) {
2994 /* We return this as uint64_t in case we are running as 32bit
2995 * process on a 64bit kernel with huge amounts of memory */
2997 mem
= sysconf(_SC_PHYS_PAGES
);
3000 return (uint64_t) mem
* (uint64_t) page_size();
3003 void hexdump(FILE *f
, const void *p
, size_t s
) {
3004 const uint8_t *b
= p
;
3007 assert(s
== 0 || b
);
3012 fprintf(f
, "%04x ", n
);
3014 for (i
= 0; i
< 16; i
++) {
3019 fprintf(f
, "%02x ", b
[i
]);
3027 for (i
= 0; i
< 16; i
++) {
3032 fputc(isprint(b
[i
]) ? (char) b
[i
] : '.', f
);
3046 int update_reboot_param_file(const char *param
) {
3050 r
= write_string_file(REBOOT_PARAM_FILE
, param
, WRITE_STRING_FILE_CREATE
);
3052 return log_error_errno(r
, "Failed to write reboot param to "REBOOT_PARAM_FILE
": %m");
3054 (void) unlink(REBOOT_PARAM_FILE
);
3059 int umount_recursive(const char *prefix
, int flags
) {
3063 /* Try to umount everything recursively below a
3064 * directory. Also, take care of stacked mounts, and keep
3065 * unmounting them until they are gone. */
3068 _cleanup_fclose_
FILE *proc_self_mountinfo
= NULL
;
3073 proc_self_mountinfo
= fopen("/proc/self/mountinfo", "re");
3074 if (!proc_self_mountinfo
)
3078 _cleanup_free_
char *path
= NULL
, *p
= NULL
;
3081 k
= fscanf(proc_self_mountinfo
,
3082 "%*s " /* (1) mount id */
3083 "%*s " /* (2) parent id */
3084 "%*s " /* (3) major:minor */
3085 "%*s " /* (4) root */
3086 "%ms " /* (5) mount point */
3087 "%*s" /* (6) mount options */
3088 "%*[^-]" /* (7) optional fields */
3089 "- " /* (8) separator */
3090 "%*s " /* (9) file system type */
3091 "%*s" /* (10) mount source */
3092 "%*s" /* (11) mount options 2 */
3093 "%*[^\n]", /* some rubbish at the end */
3102 r
= cunescape(path
, UNESCAPE_RELAX
, &p
);
3106 if (!path_startswith(p
, prefix
))
3109 if (umount2(p
, flags
) < 0) {
3125 static int get_mount_flags(const char *path
, unsigned long *flags
) {
3128 if (statvfs(path
, &buf
) < 0)
3130 *flags
= buf
.f_flag
;
3134 int bind_remount_recursive(const char *prefix
, bool ro
) {
3135 _cleanup_set_free_free_ Set
*done
= NULL
;
3136 _cleanup_free_
char *cleaned
= NULL
;
3139 /* Recursively remount a directory (and all its submounts)
3140 * read-only or read-write. If the directory is already
3141 * mounted, we reuse the mount and simply mark it
3142 * MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write
3143 * operation). If it isn't we first make it one. Afterwards we
3144 * apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to all
3145 * submounts we can access, too. When mounts are stacked on
3146 * the same mount point we only care for each individual
3147 * "top-level" mount on each point, as we cannot
3148 * influence/access the underlying mounts anyway. We do not
3149 * have any effect on future submounts that might get
3150 * propagated, they migt be writable. This includes future
3151 * submounts that have been triggered via autofs. */
3153 cleaned
= strdup(prefix
);
3157 path_kill_slashes(cleaned
);
3159 done
= set_new(&string_hash_ops
);
3164 _cleanup_fclose_
FILE *proc_self_mountinfo
= NULL
;
3165 _cleanup_set_free_free_ Set
*todo
= NULL
;
3166 bool top_autofs
= false;
3168 unsigned long orig_flags
;
3170 todo
= set_new(&string_hash_ops
);
3174 proc_self_mountinfo
= fopen("/proc/self/mountinfo", "re");
3175 if (!proc_self_mountinfo
)
3179 _cleanup_free_
char *path
= NULL
, *p
= NULL
, *type
= NULL
;
3182 k
= fscanf(proc_self_mountinfo
,
3183 "%*s " /* (1) mount id */
3184 "%*s " /* (2) parent id */
3185 "%*s " /* (3) major:minor */
3186 "%*s " /* (4) root */
3187 "%ms " /* (5) mount point */
3188 "%*s" /* (6) mount options (superblock) */
3189 "%*[^-]" /* (7) optional fields */
3190 "- " /* (8) separator */
3191 "%ms " /* (9) file system type */
3192 "%*s" /* (10) mount source */
3193 "%*s" /* (11) mount options (bind mount) */
3194 "%*[^\n]", /* some rubbish at the end */
3204 r
= cunescape(path
, UNESCAPE_RELAX
, &p
);
3208 /* Let's ignore autofs mounts. If they aren't
3209 * triggered yet, we want to avoid triggering
3210 * them, as we don't make any guarantees for
3211 * future submounts anyway. If they are
3212 * already triggered, then we will find
3213 * another entry for this. */
3214 if (streq(type
, "autofs")) {
3215 top_autofs
= top_autofs
|| path_equal(cleaned
, p
);
3219 if (path_startswith(p
, cleaned
) &&
3220 !set_contains(done
, p
)) {
3222 r
= set_consume(todo
, p
);
3232 /* If we have no submounts to process anymore and if
3233 * the root is either already done, or an autofs, we
3235 if (set_isempty(todo
) &&
3236 (top_autofs
|| set_contains(done
, cleaned
)))
3239 if (!set_contains(done
, cleaned
) &&
3240 !set_contains(todo
, cleaned
)) {
3241 /* The prefix directory itself is not yet a
3242 * mount, make it one. */
3243 if (mount(cleaned
, cleaned
, NULL
, MS_BIND
|MS_REC
, NULL
) < 0)
3247 (void) get_mount_flags(cleaned
, &orig_flags
);
3248 orig_flags
&= ~MS_RDONLY
;
3250 if (mount(NULL
, prefix
, NULL
, orig_flags
|MS_BIND
|MS_REMOUNT
|(ro
? MS_RDONLY
: 0), NULL
) < 0)
3253 x
= strdup(cleaned
);
3257 r
= set_consume(done
, x
);
3262 while ((x
= set_steal_first(todo
))) {
3264 r
= set_consume(done
, x
);
3265 if (r
== -EEXIST
|| r
== 0)
3270 /* Try to reuse the original flag set, but
3271 * don't care for errors, in case of
3272 * obstructed mounts */
3274 (void) get_mount_flags(x
, &orig_flags
);
3275 orig_flags
&= ~MS_RDONLY
;
3277 if (mount(NULL
, x
, NULL
, orig_flags
|MS_BIND
|MS_REMOUNT
|(ro
? MS_RDONLY
: 0), NULL
) < 0) {
3279 /* Deal with mount points that are
3280 * obstructed by a later mount */
3282 if (errno
!= ENOENT
)
3290 int fflush_and_check(FILE *f
) {
3297 return errno
? -errno
: -EIO
;
3302 int tempfn_xxxxxx(const char *p
, const char *extra
, char **ret
) {
3314 * /foo/bar/.#<extra>waldoXXXXXX
3318 if (!filename_is_valid(fn
))
3324 t
= new(char, strlen(p
) + 2 + strlen(extra
) + 6 + 1);
3328 strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t
, p
, fn
- p
), ".#"), extra
), fn
), "XXXXXX");
3330 *ret
= path_kill_slashes(t
);
3334 int tempfn_random(const char *p
, const char *extra
, char **ret
) {
3348 * /foo/bar/.#<extra>waldobaa2a261115984a9
3352 if (!filename_is_valid(fn
))
3358 t
= new(char, strlen(p
) + 2 + strlen(extra
) + 16 + 1);
3362 x
= stpcpy(stpcpy(stpcpy(mempcpy(t
, p
, fn
- p
), ".#"), extra
), fn
);
3365 for (i
= 0; i
< 16; i
++) {
3366 *(x
++) = hexchar(u
& 0xF);
3372 *ret
= path_kill_slashes(t
);
3376 int tempfn_random_child(const char *p
, const char *extra
, char **ret
) {
3387 * /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
3393 t
= new(char, strlen(p
) + 3 + strlen(extra
) + 16 + 1);
3397 x
= stpcpy(stpcpy(stpcpy(t
, p
), "/.#"), extra
);
3400 for (i
= 0; i
< 16; i
++) {
3401 *(x
++) = hexchar(u
& 0xF);
3407 *ret
= path_kill_slashes(t
);
3411 int take_password_lock(const char *root
) {
3413 struct flock flock
= {
3415 .l_whence
= SEEK_SET
,
3423 /* This is roughly the same as lckpwdf(), but not as awful. We
3424 * don't want to use alarm() and signals, hence we implement
3425 * our own trivial version of this.
3427 * Note that shadow-utils also takes per-database locks in
3428 * addition to lckpwdf(). However, we don't given that they
3429 * are redundant as they they invoke lckpwdf() first and keep
3430 * it during everything they do. The per-database locks are
3431 * awfully racy, and thus we just won't do them. */
3434 path
= strjoina(root
, "/etc/.pwd.lock");
3436 path
= "/etc/.pwd.lock";
3438 fd
= open(path
, O_WRONLY
|O_CREAT
|O_CLOEXEC
|O_NOCTTY
|O_NOFOLLOW
, 0600);
3442 r
= fcntl(fd
, F_SETLKW
, &flock
);
3451 int is_symlink(const char *path
) {
3454 if (lstat(path
, &info
) < 0)
3457 return !!S_ISLNK(info
.st_mode
);
3460 int is_dir(const char* path
, bool follow
) {
3465 r
= stat(path
, &st
);
3467 r
= lstat(path
, &st
);
3471 return !!S_ISDIR(st
.st_mode
);
3474 int is_device_node(const char *path
) {
3477 if (lstat(path
, &info
) < 0)
3480 return !!(S_ISBLK(info
.st_mode
) || S_ISCHR(info
.st_mode
));
3483 ssize_t
fgetxattrat_fake(int dirfd
, const char *filename
, const char *attribute
, void *value
, size_t size
, int flags
) {
3484 char fn
[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
3485 _cleanup_close_
int fd
= -1;
3488 /* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */
3490 fd
= openat(dirfd
, filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
|O_PATH
|(flags
& AT_SYMLINK_NOFOLLOW
? O_NOFOLLOW
: 0));
3494 xsprintf(fn
, "/proc/self/fd/%i", fd
);
3496 l
= getxattr(fn
, attribute
, value
, size
);
3503 static int parse_crtime(le64_t le
, usec_t
*usec
) {
3509 if (u
== 0 || u
== (uint64_t) -1)
3516 int fd_getcrtime(int fd
, usec_t
*usec
) {
3523 /* Until Linux gets a real concept of birthtime/creation time,
3524 * let's fake one with xattrs */
3526 n
= fgetxattr(fd
, "user.crtime_usec", &le
, sizeof(le
));
3529 if (n
!= sizeof(le
))
3532 return parse_crtime(le
, usec
);
3535 int fd_getcrtime_at(int dirfd
, const char *name
, usec_t
*usec
, int flags
) {
3539 n
= fgetxattrat_fake(dirfd
, name
, "user.crtime_usec", &le
, sizeof(le
), flags
);
3542 if (n
!= sizeof(le
))
3545 return parse_crtime(le
, usec
);
3548 int path_getcrtime(const char *p
, usec_t
*usec
) {
3555 n
= getxattr(p
, "user.crtime_usec", &le
, sizeof(le
));
3558 if (n
!= sizeof(le
))
3561 return parse_crtime(le
, usec
);
3564 int fd_setcrtime(int fd
, usec_t usec
) {
3570 usec
= now(CLOCK_REALTIME
);
3572 le
= htole64((uint64_t) usec
);
3573 if (fsetxattr(fd
, "user.crtime_usec", &le
, sizeof(le
), 0) < 0)
3579 int chattr_fd(int fd
, unsigned value
, unsigned mask
) {
3580 unsigned old_attr
, new_attr
;
3585 if (fstat(fd
, &st
) < 0)
3588 /* Explicitly check whether this is a regular file or
3589 * directory. If it is anything else (such as a device node or
3590 * fifo), then the ioctl will not hit the file systems but
3591 * possibly drivers, where the ioctl might have different
3592 * effects. Notably, DRM is using the same ioctl() number. */
3594 if (!S_ISDIR(st
.st_mode
) && !S_ISREG(st
.st_mode
))
3600 if (ioctl(fd
, FS_IOC_GETFLAGS
, &old_attr
) < 0)
3603 new_attr
= (old_attr
& ~mask
) | (value
& mask
);
3604 if (new_attr
== old_attr
)
3607 if (ioctl(fd
, FS_IOC_SETFLAGS
, &new_attr
) < 0)
3613 int chattr_path(const char *p
, unsigned value
, unsigned mask
) {
3614 _cleanup_close_
int fd
= -1;
3621 fd
= open(p
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
|O_NOFOLLOW
);
3625 return chattr_fd(fd
, value
, mask
);
3628 int read_attr_fd(int fd
, unsigned *ret
) {
3633 if (fstat(fd
, &st
) < 0)
3636 if (!S_ISDIR(st
.st_mode
) && !S_ISREG(st
.st_mode
))
3639 if (ioctl(fd
, FS_IOC_GETFLAGS
, ret
) < 0)
3645 int read_attr_path(const char *p
, unsigned *ret
) {
3646 _cleanup_close_
int fd
= -1;
3651 fd
= open(p
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
|O_NOFOLLOW
);
3655 return read_attr_fd(fd
, ret
);
3658 int syslog_parse_priority(const char **p
, int *priority
, bool with_facility
) {
3659 int a
= 0, b
= 0, c
= 0;
3669 if (!strchr(*p
, '>'))
3672 if ((*p
)[2] == '>') {
3673 c
= undecchar((*p
)[1]);
3675 } else if ((*p
)[3] == '>') {
3676 b
= undecchar((*p
)[1]);
3677 c
= undecchar((*p
)[2]);
3679 } else if ((*p
)[4] == '>') {
3680 a
= undecchar((*p
)[1]);
3681 b
= undecchar((*p
)[2]);
3682 c
= undecchar((*p
)[3]);
3687 if (a
< 0 || b
< 0 || c
< 0 ||
3688 (!with_facility
&& (a
|| b
|| c
> 7)))
3692 *priority
= a
*100 + b
*10 + c
;
3694 *priority
= (*priority
& LOG_FACMASK
) | c
;
3700 ssize_t
string_table_lookup(const char * const *table
, size_t len
, const char *key
) {
3706 for (i
= 0; i
< len
; ++i
)
3707 if (streq_ptr(table
[i
], key
))
3713 int rename_noreplace(int olddirfd
, const char *oldpath
, int newdirfd
, const char *newpath
) {
3717 ret
= renameat2(olddirfd
, oldpath
, newdirfd
, newpath
, RENAME_NOREPLACE
);
3721 /* renameat2() exists since Linux 3.15, btrfs added support for it later.
3722 * If it is not implemented, fallback to another method. */
3723 if (!IN_SET(errno
, EINVAL
, ENOSYS
))
3726 /* The link()/unlink() fallback does not work on directories. But
3727 * renameat() without RENAME_NOREPLACE gives the same semantics on
3728 * directories, except when newpath is an *empty* directory. This is
3730 ret
= fstatat(olddirfd
, oldpath
, &buf
, AT_SYMLINK_NOFOLLOW
);
3731 if (ret
>= 0 && S_ISDIR(buf
.st_mode
)) {
3732 ret
= renameat(olddirfd
, oldpath
, newdirfd
, newpath
);
3733 return ret
>= 0 ? 0 : -errno
;
3736 /* If it is not a directory, use the link()/unlink() fallback. */
3737 ret
= linkat(olddirfd
, oldpath
, newdirfd
, newpath
, 0);
3741 ret
= unlinkat(olddirfd
, oldpath
, 0);
3743 /* backup errno before the following unlinkat() alters it */
3745 (void) unlinkat(newdirfd
, newpath
, 0);
3753 int mount_move_root(const char *path
) {
3756 if (chdir(path
) < 0)
3759 if (mount(path
, "/", NULL
, MS_MOVE
, NULL
) < 0)
3762 if (chroot(".") < 0)
3771 int getxattr_malloc(const char *path
, const char *name
, char **value
, bool allow_symlink
) {
3780 for (l
= 100; ; l
= (size_t) n
+ 1) {
3786 n
= lgetxattr(path
, name
, v
, l
);
3788 n
= getxattr(path
, name
, v
, l
);
3790 if (n
>= 0 && (size_t) n
< l
) {
3797 if (n
< 0 && errno
!= ERANGE
)
3801 n
= lgetxattr(path
, name
, NULL
, 0);
3803 n
= getxattr(path
, name
, NULL
, 0);
3809 int fgetxattr_malloc(int fd
, const char *name
, char **value
) {
3818 for (l
= 100; ; l
= (size_t) n
+ 1) {
3823 n
= fgetxattr(fd
, name
, v
, l
);
3825 if (n
>= 0 && (size_t) n
< l
) {
3832 if (n
< 0 && errno
!= ERANGE
)
3835 n
= fgetxattr(fd
, name
, NULL
, 0);
3842 puts(PACKAGE_STRING
"\n"
3847 bool fdname_is_valid(const char *s
) {
3850 /* Validates a name for $LISTEN_FDNAMES. We basically allow
3851 * everything ASCII that's not a control character. Also, as
3852 * special exception the ":" character is not allowed, as we
3853 * use that as field separator in $LISTEN_FDNAMES.
3855 * Note that the empty string is explicitly allowed
3856 * here. However, we limit the length of the names to 255
3862 for (p
= s
; *p
; p
++) {
3874 bool oom_score_adjust_is_valid(int oa
) {
3875 return oa
>= OOM_SCORE_ADJ_MIN
&& oa
<= OOM_SCORE_ADJ_MAX
;