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/>.
22 // #include <string.h>
23 // #include <unistd.h>
25 // #include <stdlib.h>
26 // #include <signal.h>
27 // #include <libintl.h>
29 // #include <syslog.h>
31 // #include <sys/resource.h>
32 // #include <linux/sched.h>
33 // #include <sys/types.h>
34 // #include <sys/stat.h>
36 // #include <dirent.h>
37 // #include <sys/ioctl.h>
38 // #include <stdarg.h>
41 #include <sys/prctl.h>
42 // #include <sys/utsname.h>
44 #include <netinet/ip.h>
45 // #include <sys/wait.h>
46 // #include <sys/time.h>
49 // #include <sys/mman.h>
50 // #include <sys/vfs.h>
51 // #include <sys/mount.h>
52 #include <linux/magic.h>
53 // #include <limits.h>
55 // #include <locale.h>
56 // #include <sys/personality.h>
57 #include <sys/xattr.h>
58 // #include <sys/statvfs.h>
59 // #include <sys/file.h>
62 /* When we include libgen.h because we need dirname() we immediately
63 * undefine basename() since libgen.h defines it as a macro to the POSIX
64 * version which is really broken. We prefer GNU basename(). */
65 // #include <libgen.h>
68 #ifdef HAVE_SYS_AUXV_H
76 // #include "missing.h"
80 #include "path-util.h"
81 // #include "exit-status.h"
84 // #include "env-util.h"
86 // #include "device-nodes.h"
91 #include "sparse-endian.h"
92 // #include "formats-util.h"
93 #include "process-util.h"
94 #include "random-util.h"
95 // #include "terminal-util.h"
96 #include "hostname-util.h"
97 #include "signal-util.h"
99 /* Put this test here for a lack of better place */
100 assert_cc(EAGAIN == EWOULDBLOCK);
103 char **saved_argv = NULL;
105 size_t page_size(void) {
106 static thread_local size_t pgsz = 0;
109 if (_likely_(pgsz > 0))
112 r = sysconf(_SC_PAGESIZE);
119 int strcmp_ptr(const char *a, const char *b) {
121 /* Like strcmp(), but tries to make sense of NULL pointers */
134 bool streq_ptr(const char *a, const char *b) {
135 return strcmp_ptr(a, b) == 0;
138 char* endswith(const char *s, const char *postfix) {
145 pl = strlen(postfix);
148 return (char*) s + sl;
153 if (memcmp(s + sl - pl, postfix, pl) != 0)
156 return (char*) s + sl - pl;
159 char* endswith_no_case(const char *s, const char *postfix) {
166 pl = strlen(postfix);
169 return (char*) s + sl;
174 if (strcasecmp(s + sl - pl, postfix) != 0)
177 return (char*) s + sl - pl;
180 char* first_word(const char *s, const char *word) {
187 /* Checks if the string starts with the specified word, either
188 * followed by NUL or by whitespace. Returns a pointer to the
189 * NUL or the first character after the whitespace. */
200 if (memcmp(s, word, wl) != 0)
207 if (!strchr(WHITESPACE, *p))
210 p += strspn(p, WHITESPACE);
214 size_t cescape_char(char c, char *buf) {
215 char * buf_old = buf;
261 /* For special chars we prefer octal over
262 * hexadecimal encoding, simply because glib's
263 * g_strescape() does the same */
264 if ((c < ' ') || (c >= 127)) {
266 *(buf++) = octchar((unsigned char) c >> 6);
267 *(buf++) = octchar((unsigned char) c >> 3);
268 *(buf++) = octchar((unsigned char) c);
274 return buf - buf_old;
277 int close_nointr(int fd) {
284 * Just ignore EINTR; a retry loop is the wrong thing to do on
287 * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
288 * https://bugzilla.gnome.org/show_bug.cgi?id=682819
289 * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
290 * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
298 int safe_close(int fd) {
301 * Like close_nointr() but cannot fail. Guarantees errno is
302 * unchanged. Is a NOP with negative fds passed, and returns
303 * -1, so that it can be used in this syntax:
305 * fd = safe_close(fd);
311 /* The kernel might return pretty much any error code
312 * via close(), but the fd will be closed anyway. The
313 * only condition we want to check for here is whether
314 * the fd was invalid at all... */
316 assert_se(close_nointr(fd) != -EBADF);
322 void close_many(const int fds[], unsigned n_fd) {
325 assert(fds || n_fd <= 0);
327 for (i = 0; i < n_fd; i++)
331 int unlink_noerrno(const char *path) {
342 int parse_boolean(const char *v) {
345 if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on"))
347 else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off"))
353 int parse_pid(const char *s, pid_t* ret_pid) {
354 unsigned long ul = 0;
361 r = safe_atolu(s, &ul);
367 if ((unsigned long) pid != ul)
377 bool uid_is_valid(uid_t uid) {
379 /* Some libc APIs use UID_INVALID as special placeholder */
380 if (uid == (uid_t) 0xFFFFFFFF)
383 /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
384 if (uid == (uid_t) 0xFFFF)
390 int parse_uid(const char *s, uid_t* ret_uid) {
391 unsigned long ul = 0;
397 r = safe_atolu(s, &ul);
403 if ((unsigned long) uid != ul)
406 if (!uid_is_valid(uid))
407 return -ENXIO; /* we return ENXIO instead of EINVAL
408 * here, to make it easy to distuingish
409 * invalid numeric uids invalid
418 int safe_atou(const char *s, unsigned *ret_u) {
426 l = strtoul(s, &x, 0);
428 if (!x || x == s || *x || errno)
429 return errno > 0 ? -errno : -EINVAL;
431 if ((unsigned long) (unsigned) l != l)
434 *ret_u = (unsigned) l;
438 int safe_atoi(const char *s, int *ret_i) {
446 l = strtol(s, &x, 0);
448 if (!x || x == s || *x || errno)
449 return errno > 0 ? -errno : -EINVAL;
451 if ((long) (int) l != l)
458 int safe_atou8(const char *s, uint8_t *ret) {
466 l = strtoul(s, &x, 0);
468 if (!x || x == s || *x || errno)
469 return errno > 0 ? -errno : -EINVAL;
471 if ((unsigned long) (uint8_t) l != l)
478 int safe_atou16(const char *s, uint16_t *ret) {
486 l = strtoul(s, &x, 0);
488 if (!x || x == s || *x || errno)
489 return errno > 0 ? -errno : -EINVAL;
491 if ((unsigned long) (uint16_t) l != l)
498 int safe_atoi16(const char *s, int16_t *ret) {
506 l = strtol(s, &x, 0);
508 if (!x || x == s || *x || errno)
509 return errno > 0 ? -errno : -EINVAL;
511 if ((long) (int16_t) l != l)
518 int safe_atollu(const char *s, long long unsigned *ret_llu) {
520 unsigned long long l;
526 l = strtoull(s, &x, 0);
528 if (!x || x == s || *x || errno)
529 return errno ? -errno : -EINVAL;
535 int safe_atolli(const char *s, long long int *ret_lli) {
543 l = strtoll(s, &x, 0);
545 if (!x || x == s || *x || errno)
546 return errno ? -errno : -EINVAL;
552 int safe_atod(const char *s, double *ret_d) {
560 loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
561 if (loc == (locale_t) 0)
565 d = strtod_l(s, &x, loc);
567 if (!x || x == s || *x || errno) {
569 return errno ? -errno : -EINVAL;
577 static size_t strcspn_escaped(const char *s, const char *reject) {
578 bool escaped = false;
581 for (n=0; s[n]; n++) {
584 else if (s[n] == '\\')
586 else if (strchr(reject, s[n]))
590 /* if s ends in \, return index of previous char */
594 /* Split a string into words. */
595 const char* split(const char **state, size_t *l, const char *separator, bool quoted) {
601 assert(**state == '\0');
605 current += strspn(current, separator);
611 if (quoted && strchr("\'\"", *current)) {
612 char quotechars[2] = {*current, '\0'};
614 *l = strcspn_escaped(current + 1, quotechars);
615 if (current[*l + 1] == '\0' || current[*l + 1] != quotechars[0] ||
616 (current[*l + 2] && !strchr(separator, current[*l + 2]))) {
617 /* right quote missing or garbage at the end */
621 *state = current++ + *l + 2;
623 *l = strcspn_escaped(current, separator);
624 if (current[*l] && !strchr(separator, current[*l])) {
625 /* unfinished escape */
629 *state = current + *l;
631 *l = strcspn(current, separator);
632 *state = current + *l;
638 int fchmod_umask(int fd, mode_t m) {
643 r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
649 char *truncate_nl(char *s) {
652 s[strcspn(s, NEWLINE)] = 0;
656 char *strnappend(const char *s, const char *suffix, size_t b) {
664 return strndup(suffix, b);
673 if (b > ((size_t) -1) - a)
676 r = new(char, a+b+1);
681 memcpy(r+a, suffix, b);
687 char *strappend(const char *s, const char *suffix) {
688 return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
691 int readlinkat_malloc(int fd, const char *p, char **ret) {
706 n = readlinkat(fd, p, c, l-1);
713 if ((size_t) n < l-1) {
724 int readlink_malloc(const char *p, char **ret) {
725 return readlinkat_malloc(AT_FDCWD, p, ret);
728 /// UNNEEDED by elogind
730 int readlink_value(const char *p, char **ret) {
731 _cleanup_free_ char *link = NULL;
735 r = readlink_malloc(p, &link);
739 value = basename(link);
743 value = strdup(value);
753 int readlink_and_make_absolute(const char *p, char **r) {
754 _cleanup_free_ char *target = NULL;
761 j = readlink_malloc(p, &target);
765 k = file_in_same_dir(p, target);
773 /// UNNEEDED by elogind
775 int readlink_and_canonicalize(const char *p, char **r) {
782 j = readlink_and_make_absolute(p, &t);
786 s = canonicalize_file_name(t);
793 path_kill_slashes(*r);
799 char *strstrip(char *s) {
802 /* Drops trailing whitespace. Modifies the string in
803 * place. Returns pointer to first non-space character */
805 s += strspn(s, WHITESPACE);
807 for (e = strchr(s, 0); e > s; e --)
808 if (!strchr(WHITESPACE, e[-1]))
816 /// UNNEEDED by elogind
818 char *delete_chars(char *s, const char *bad) {
821 /* Drops all whitespace, regardless where in the string */
823 for (f = s, t = s; *f; f++) {
836 char *file_in_same_dir(const char *path, const char *filename) {
843 /* This removes the last component of path and appends
844 * filename, unless the latter is absolute anyway or the
847 if (path_is_absolute(filename))
848 return strdup(filename);
850 e = strrchr(path, '/');
852 return strdup(filename);
854 k = strlen(filename);
855 ret = new(char, (e + 1 - path) + k + 1);
859 memcpy(mempcpy(ret, path, e + 1 - path), filename, k + 1);
863 /// UNNEEDED by elogind
865 int rmdir_parents(const char *path, const char *stop) {
874 /* Skip trailing slashes */
875 while (l > 0 && path[l-1] == '/')
881 /* Skip last component */
882 while (l > 0 && path[l-1] != '/')
885 /* Skip trailing slashes */
886 while (l > 0 && path[l-1] == '/')
892 if (!(t = strndup(path, l)))
895 if (path_startswith(stop, t)) {
912 char hexchar(int x) {
913 static const char table[16] = "0123456789abcdef";
915 return table[x & 15];
918 int unhexchar(char c) {
920 if (c >= '0' && c <= '9')
923 if (c >= 'a' && c <= 'f')
926 if (c >= 'A' && c <= 'F')
932 char *hexmem(const void *p, size_t l) {
936 z = r = malloc(l * 2 + 1);
940 for (x = p; x < (const uint8_t*) p + l; x++) {
941 *(z++) = hexchar(*x >> 4);
942 *(z++) = hexchar(*x & 15);
949 int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
950 _cleanup_free_ uint8_t *r = NULL;
958 z = r = malloc((l + 1) / 2 + 1);
962 for (x = p; x < p + l; x += 2) {
968 else if (x+1 < p + l) {
975 *(z++) = (uint8_t) a << 4 | (uint8_t) b;
987 /* https://tools.ietf.org/html/rfc4648#section-6
988 * Notice that base32hex differs from base32 in the alphabet it uses.
989 * The distinction is that the base32hex representation preserves the
990 * order of the underlying data when compared as bytestrings, this is
991 * useful when representing NSEC3 hashes, as one can then verify the
992 * order of hashes directly from their representation. */
993 char base32hexchar(int x) {
994 static const char table[32] = "0123456789"
995 "ABCDEFGHIJKLMNOPQRSTUV";
997 return table[x & 31];
1000 int unbase32hexchar(char c) {
1003 if (c >= '0' && c <= '9')
1006 offset = '9' - '0' + 1;
1008 if (c >= 'A' && c <= 'V')
1009 return c - 'A' + offset;
1014 char *base32hexmem(const void *p, size_t l, bool padding) {
1020 /* five input bytes makes eight output bytes, padding is added so we must round up */
1021 len = 8 * (l + 4) / 5;
1023 /* same, but round down as there is no padding */
1042 z = r = malloc(len + 1);
1046 for (x = p; x < (const uint8_t*) p + (l / 5) * 5; x += 5) {
1047 /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ
1048 x[3] == QQQQQQQQ; x[4] == WWWWWWWW */
1049 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1050 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1051 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1052 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
1053 *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */
1054 *(z++) = base32hexchar((x[3] & 127) >> 2); /* 000QQQQQ */
1055 *(z++) = base32hexchar((x[3] & 3) << 3 | x[4] >> 5); /* 000QQWWW */
1056 *(z++) = base32hexchar((x[4] & 31)); /* 000WWWWW */
1061 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1062 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1063 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1064 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
1065 *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */
1066 *(z++) = base32hexchar((x[3] & 127) >> 2); /* 000QQQQQ */
1067 *(z++) = base32hexchar((x[3] & 3) << 3); /* 000QQ000 */
1074 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1075 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1076 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1077 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
1078 *(z++) = base32hexchar((x[2] & 15) << 1); /* 000ZZZZ0 */
1088 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1089 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1090 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1091 *(z++) = base32hexchar((x[1] & 1) << 4); /* 000Y0000 */
1102 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1103 *(z++) = base32hexchar((x[0] & 7) << 2); /* 000XXX00 */
1120 int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_len) {
1121 _cleanup_free_ uint8_t *r = NULL;
1122 int a, b, c, d, e, f, g, h;
1130 /* padding ensures any base32hex input has input divisible by 8 */
1131 if (padding && l % 8 != 0)
1135 /* strip the padding */
1136 while (l > 0 && p[l - 1] == '=' && pad < 7) {
1142 /* a group of eight input bytes needs five output bytes, in case of
1143 padding we need to add some extra bytes */
1165 z = r = malloc(len + 1);
1169 for (x = p; x < p + (l / 8) * 8; x += 8) {
1170 /* a == 000XXXXX; b == 000YYYYY; c == 000ZZZZZ; d == 000WWWWW
1171 e == 000SSSSS; f == 000QQQQQ; g == 000VVVVV; h == 000RRRRR */
1172 a = unbase32hexchar(x[0]);
1176 b = unbase32hexchar(x[1]);
1180 c = unbase32hexchar(x[2]);
1184 d = unbase32hexchar(x[3]);
1188 e = unbase32hexchar(x[4]);
1192 f = unbase32hexchar(x[5]);
1196 g = unbase32hexchar(x[6]);
1200 h = unbase32hexchar(x[7]);
1204 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1205 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1206 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
1207 *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */
1208 *(z++) = (uint8_t) g << 5 | (uint8_t) h; /* VVVRRRRR */
1213 a = unbase32hexchar(x[0]);
1217 b = unbase32hexchar(x[1]);
1221 c = unbase32hexchar(x[2]);
1225 d = unbase32hexchar(x[3]);
1229 e = unbase32hexchar(x[4]);
1233 f = unbase32hexchar(x[5]);
1237 g = unbase32hexchar(x[6]);
1245 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1246 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1247 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
1248 *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */
1252 a = unbase32hexchar(x[0]);
1256 b = unbase32hexchar(x[1]);
1260 c = unbase32hexchar(x[2]);
1264 d = unbase32hexchar(x[3]);
1268 e = unbase32hexchar(x[4]);
1276 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1277 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1278 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
1282 a = unbase32hexchar(x[0]);
1286 b = unbase32hexchar(x[1]);
1290 c = unbase32hexchar(x[2]);
1294 d = unbase32hexchar(x[3]);
1302 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1303 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1307 a = unbase32hexchar(x[0]);
1311 b = unbase32hexchar(x[1]);
1319 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1337 /* https://tools.ietf.org/html/rfc4648#section-4 */
1338 char base64char(int x) {
1339 static const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1340 "abcdefghijklmnopqrstuvwxyz"
1342 return table[x & 63];
1345 int unbase64char(char c) {
1348 if (c >= 'A' && c <= 'Z')
1351 offset = 'Z' - 'A' + 1;
1353 if (c >= 'a' && c <= 'z')
1354 return c - 'a' + offset;
1356 offset += 'z' - 'a' + 1;
1358 if (c >= '0' && c <= '9')
1359 return c - '0' + offset;
1361 offset += '9' - '0' + 1;
1374 char *base64mem(const void *p, size_t l) {
1378 /* three input bytes makes four output bytes, padding is added so we must round up */
1379 z = r = malloc(4 * (l + 2) / 3 + 1);
1383 for (x = p; x < (const uint8_t*) p + (l / 3) * 3; x += 3) {
1384 /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ */
1385 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1386 *(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4); /* 00XXYYYY */
1387 *(z++) = base64char((x[1] & 15) << 2 | x[2] >> 6); /* 00YYYYZZ */
1388 *(z++) = base64char(x[2] & 63); /* 00ZZZZZZ */
1393 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1394 *(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4); /* 00XXYYYY */
1395 *(z++) = base64char((x[1] & 15) << 2); /* 00YYYY00 */
1400 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1401 *(z++) = base64char((x[0] & 3) << 4); /* 00XX0000 */
1412 int unbase64mem(const char *p, size_t l, void **mem, size_t *_len) {
1413 _cleanup_free_ uint8_t *r = NULL;
1421 /* padding ensures any base63 input has input divisible by 4 */
1425 /* strip the padding */
1426 if (l > 0 && p[l - 1] == '=')
1428 if (l > 0 && p[l - 1] == '=')
1431 /* a group of four input bytes needs three output bytes, in case of
1432 padding we need to add two or three extra bytes */
1433 len = (l / 4) * 3 + (l % 4 ? (l % 4) - 1 : 0);
1435 z = r = malloc(len + 1);
1439 for (x = p; x < p + (l / 4) * 4; x += 4) {
1440 /* a == 00XXXXXX; b == 00YYYYYY; c == 00ZZZZZZ; d == 00WWWWWW */
1441 a = unbase64char(x[0]);
1445 b = unbase64char(x[1]);
1449 c = unbase64char(x[2]);
1453 d = unbase64char(x[3]);
1457 *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
1458 *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
1459 *(z++) = (uint8_t) c << 6 | (uint8_t) d; /* ZZWWWWWW */
1464 a = unbase64char(x[0]);
1468 b = unbase64char(x[1]);
1472 c = unbase64char(x[2]);
1480 *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
1481 *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
1485 a = unbase64char(x[0]);
1489 b = unbase64char(x[1]);
1497 *(z++) = (uint8_t) a << 2 | (uint8_t) (b >> 4); /* XXXXXXYY */
1516 char octchar(int x) {
1517 return '0' + (x & 7);
1520 int unoctchar(char c) {
1522 if (c >= '0' && c <= '7')
1528 char decchar(int x) {
1529 return '0' + (x % 10);
1532 int undecchar(char c) {
1534 if (c >= '0' && c <= '9')
1540 char *cescape(const char *s) {
1546 /* Does C style string escaping. May be reversed with
1549 r = new(char, strlen(s)*4 + 1);
1553 for (f = s, t = r; *f; f++)
1554 t += cescape_char(*f, t);
1561 static int cunescape_one(const char *p, size_t length, char *ret, uint32_t *ret_unicode) {
1568 /* Unescapes C style. Returns the unescaped character in ret,
1569 * unless we encountered a \u sequence in which case the full
1570 * unicode character is returned in ret_unicode, instead. */
1572 if (length != (size_t) -1 && length < 1)
1609 /* This is an extension of the XDG syntax files */
1614 /* hexadecimal encoding */
1617 if (length != (size_t) -1 && length < 3)
1620 a = unhexchar(p[1]);
1624 b = unhexchar(p[2]);
1628 /* Don't allow NUL bytes */
1629 if (a == 0 && b == 0)
1632 *ret = (char) ((a << 4U) | b);
1638 /* C++11 style 16bit unicode */
1644 if (length != (size_t) -1 && length < 5)
1647 for (i = 0; i < 4; i++) {
1648 a[i] = unhexchar(p[1 + i]);
1653 c = ((uint32_t) a[0] << 12U) | ((uint32_t) a[1] << 8U) | ((uint32_t) a[2] << 4U) | (uint32_t) a[3];
1655 /* Don't allow 0 chars */
1674 /* C++11 style 32bit unicode */
1680 if (length != (size_t) -1 && length < 9)
1683 for (i = 0; i < 8; i++) {
1684 a[i] = unhexchar(p[1 + i]);
1689 c = ((uint32_t) a[0] << 28U) | ((uint32_t) a[1] << 24U) | ((uint32_t) a[2] << 20U) | ((uint32_t) a[3] << 16U) |
1690 ((uint32_t) a[4] << 12U) | ((uint32_t) a[5] << 8U) | ((uint32_t) a[6] << 4U) | (uint32_t) a[7];
1692 /* Don't allow 0 chars */
1696 /* Don't allow invalid code points */
1697 if (!unichar_is_valid(c))
1722 /* octal encoding */
1726 if (length != (size_t) -1 && length < 3)
1729 a = unoctchar(p[0]);
1733 b = unoctchar(p[1]);
1737 c = unoctchar(p[2]);
1741 /* don't allow NUL bytes */
1742 if (a == 0 && b == 0 && c == 0)
1745 /* Don't allow bytes above 255 */
1746 m = ((uint32_t) a << 6U) | ((uint32_t) b << 3U) | (uint32_t) c;
1762 int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret) {
1770 /* Undoes C style string escaping, and optionally prefixes it. */
1772 pl = prefix ? strlen(prefix) : 0;
1774 r = new(char, pl+length+1);
1779 memcpy(r, prefix, pl);
1781 for (f = s, t = r + pl; f < s + length; f++) {
1787 remaining = s + length - f;
1788 assert(remaining > 0);
1791 /* A literal literal, copy verbatim */
1796 if (remaining == 1) {
1797 if (flags & UNESCAPE_RELAX) {
1798 /* A trailing backslash, copy verbatim */
1807 k = cunescape_one(f + 1, remaining - 1, &c, &u);
1809 if (flags & UNESCAPE_RELAX) {
1810 /* Invalid escape code, let's take it literal then */
1820 /* Non-Unicode? Let's encode this directly */
1823 /* Unicode? Then let's encode this in UTF-8 */
1824 t += utf8_encode_unichar(t, u);
1835 int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret) {
1836 return cunescape_length_with_prefix(s, length, NULL, flags, ret);
1839 int cunescape(const char *s, UnescapeFlags flags, char **ret) {
1840 return cunescape_length(s, strlen(s), flags, ret);
1843 char *xescape(const char *s, const char *bad) {
1847 /* Escapes all chars in bad, in addition to \ and all special
1848 * chars, in \xFF style escaping. May be reversed with
1851 r = new(char, strlen(s) * 4 + 1);
1855 for (f = s, t = r; *f; f++) {
1857 if ((*f < ' ') || (*f >= 127) ||
1858 (*f == '\\') || strchr(bad, *f)) {
1861 *(t++) = hexchar(*f >> 4);
1862 *(t++) = hexchar(*f);
1872 /// UNNEEDED by elogind
1874 char *ascii_strlower(char *t) {
1879 for (p = t; *p; p++)
1880 if (*p >= 'A' && *p <= 'Z')
1881 *p = *p - 'A' + 'a';
1887 _pure_ static bool hidden_file_allow_backup(const char *filename) {
1891 filename[0] == '.' ||
1892 streq(filename, "lost+found") ||
1893 streq(filename, "aquota.user") ||
1894 streq(filename, "aquota.group") ||
1895 endswith(filename, ".rpmnew") ||
1896 endswith(filename, ".rpmsave") ||
1897 endswith(filename, ".rpmorig") ||
1898 endswith(filename, ".dpkg-old") ||
1899 endswith(filename, ".dpkg-new") ||
1900 endswith(filename, ".dpkg-tmp") ||
1901 endswith(filename, ".dpkg-dist") ||
1902 endswith(filename, ".dpkg-bak") ||
1903 endswith(filename, ".dpkg-backup") ||
1904 endswith(filename, ".dpkg-remove") ||
1905 endswith(filename, ".swp");
1908 bool hidden_file(const char *filename) {
1911 if (endswith(filename, "~"))
1914 return hidden_file_allow_backup(filename);
1917 int fd_nonblock(int fd, bool nonblock) {
1922 flags = fcntl(fd, F_GETFL, 0);
1927 nflags = flags | O_NONBLOCK;
1929 nflags = flags & ~O_NONBLOCK;
1931 if (nflags == flags)
1934 if (fcntl(fd, F_SETFL, nflags) < 0)
1940 int fd_cloexec(int fd, bool cloexec) {
1945 flags = fcntl(fd, F_GETFD, 0);
1950 nflags = flags | FD_CLOEXEC;
1952 nflags = flags & ~FD_CLOEXEC;
1954 if (nflags == flags)
1957 if (fcntl(fd, F_SETFD, nflags) < 0)
1963 _pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
1966 assert(n_fdset == 0 || fdset);
1968 for (i = 0; i < n_fdset; i++)
1975 int close_all_fds(const int except[], unsigned n_except) {
1976 _cleanup_closedir_ DIR *d = NULL;
1980 assert(n_except == 0 || except);
1982 d = opendir("/proc/self/fd");
1987 /* When /proc isn't available (for example in chroots)
1988 * the fallback is brute forcing through the fd
1991 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
1992 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
1994 if (fd_in_set(fd, except, n_except))
1997 if (close_nointr(fd) < 0)
1998 if (errno != EBADF && r == 0)
2005 while ((de = readdir(d))) {
2008 if (hidden_file(de->d_name))
2011 if (safe_atoi(de->d_name, &fd) < 0)
2012 /* Let's better ignore this, just in case */
2021 if (fd_in_set(fd, except, n_except))
2024 if (close_nointr(fd) < 0) {
2025 /* Valgrind has its own FD and doesn't want to have it closed */
2026 if (errno != EBADF && r == 0)
2034 bool chars_intersect(const char *a, const char *b) {
2037 /* Returns true if any of the chars in a are in b. */
2038 for (p = a; *p; p++)
2045 /// UNNEEDED by elogind
2047 bool fstype_is_network(const char *fstype) {
2048 static const char table[] =
2063 x = startswith(fstype, "fuse.");
2067 return nulstr_contains(table, fstype);
2071 int flush_fd(int fd) {
2072 struct pollfd pollfd = {
2082 r = poll(&pollfd, 1, 0);
2092 l = read(fd, buf, sizeof(buf));
2098 if (errno == EAGAIN)
2107 void safe_close_pair(int p[]) {
2111 /* Special case pairs which use the same fd in both
2113 p[0] = p[1] = safe_close(p[0]);
2117 p[0] = safe_close(p[0]);
2118 p[1] = safe_close(p[1]);
2121 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
2128 while (nbytes > 0) {
2131 k = read(fd, p, nbytes);
2136 if (errno == EAGAIN && do_poll) {
2138 /* We knowingly ignore any return value here,
2139 * and expect that any error/EOF is reported
2142 fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
2146 return n > 0 ? n : -errno;
2160 int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
2163 n = loop_read(fd, buf, nbytes, do_poll);
2166 if ((size_t) n != nbytes)
2171 int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
2172 const uint8_t *p = buf;
2182 k = write(fd, p, nbytes);
2187 if (errno == EAGAIN && do_poll) {
2188 /* We knowingly ignore any return value here,
2189 * and expect that any error/EOF is reported
2192 fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
2199 if (nbytes > 0 && k == 0) /* Can't really happen */
2204 } while (nbytes > 0);
2209 int parse_size(const char *t, off_t base, off_t *size) {
2211 /* Soo, sometimes we want to parse IEC binary suffixes, and
2212 * sometimes SI decimal suffixes. This function can parse
2213 * both. Which one is the right way depends on the
2214 * context. Wikipedia suggests that SI is customary for
2215 * hardware metrics and network speeds, while IEC is
2216 * customary for most data sizes used by software and volatile
2217 * (RAM) memory. Hence be careful which one you pick!
2219 * In either case we use just K, M, G as suffix, and not Ki,
2220 * Mi, Gi or so (as IEC would suggest). That's because that's
2221 * frickin' ugly. But this means you really need to make sure
2222 * to document which base you are parsing when you use this
2227 unsigned long long factor;
2230 static const struct table iec[] = {
2231 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2232 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2233 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
2234 { "G", 1024ULL*1024ULL*1024ULL },
2235 { "M", 1024ULL*1024ULL },
2241 static const struct table si[] = {
2242 { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
2243 { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
2244 { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
2245 { "G", 1000ULL*1000ULL*1000ULL },
2246 { "M", 1000ULL*1000ULL },
2252 const struct table *table;
2254 unsigned long long r = 0;
2255 unsigned n_entries, start_pos = 0;
2258 assert(base == 1000 || base == 1024);
2263 n_entries = ELEMENTSOF(si);
2266 n_entries = ELEMENTSOF(iec);
2272 unsigned long long l2;
2278 l = strtoll(p, &e, 10);
2291 if (*e >= '0' && *e <= '9') {
2294 /* strotoull itself would accept space/+/- */
2295 l2 = strtoull(e, &e2, 10);
2297 if (errno == ERANGE)
2300 /* Ignore failure. E.g. 10.M is valid */
2307 e += strspn(e, WHITESPACE);
2309 for (i = start_pos; i < n_entries; i++)
2310 if (startswith(e, table[i].suffix)) {
2311 unsigned long long tmp;
2312 if ((unsigned long long) l + (frac > 0) > ULLONG_MAX / table[i].factor)
2314 tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
2315 if (tmp > ULLONG_MAX - r)
2319 if ((unsigned long long) (off_t) r != r)
2322 p = e + strlen(table[i].suffix);
2338 bool is_device_path(const char *path) {
2340 /* Returns true on paths that refer to a device, either in
2341 * sysfs or in /dev */
2344 path_startswith(path, "/dev/") ||
2345 path_startswith(path, "/sys/");
2348 /// UNNEEDED by elogind
2350 int dir_is_empty(const char *path) {
2351 _cleanup_closedir_ DIR *d;
2362 if (!de && errno != 0)
2368 if (!hidden_file(de->d_name))
2373 char* dirname_malloc(const char *path) {
2374 char *d, *dir, *dir2;
2391 void rename_process(const char name[8]) {
2394 /* This is a like a poor man's setproctitle(). It changes the
2395 * comm field, argv[0], and also the glibc's internally used
2396 * name of the process. For the first one a limit of 16 chars
2397 * applies, to the second one usually one of 10 (i.e. length
2398 * of "/sbin/init"), to the third one one of 7 (i.e. length of
2399 * "systemd"). If you pass a longer string it will be
2402 prctl(PR_SET_NAME, name);
2404 if (program_invocation_name)
2405 strncpy(program_invocation_name, name, strlen(program_invocation_name));
2407 if (saved_argc > 0) {
2411 strncpy(saved_argv[0], name, strlen(saved_argv[0]));
2413 for (i = 1; i < saved_argc; i++) {
2417 memzero(saved_argv[i], strlen(saved_argv[i]));
2423 char *lookup_uid(uid_t uid) {
2426 _cleanup_free_ char *buf = NULL;
2427 struct passwd pwbuf, *pw = NULL;
2429 /* Shortcut things to avoid NSS lookups */
2431 return strdup("root");
2433 bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
2437 buf = malloc(bufsize);
2441 if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
2442 return strdup(pw->pw_name);
2444 if (asprintf(&name, UID_FMT, uid) < 0)
2450 /// UNNEEDED by elogind
2452 char* getlogname_malloc(void) {
2456 if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
2461 return lookup_uid(uid);
2464 char *getusername_malloc(void) {
2471 return lookup_uid(getuid());
2475 bool is_temporary_fs(const struct statfs *s) {
2478 return F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) ||
2479 F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC);
2482 int fd_is_temporary_fs(int fd) {
2485 if (fstatfs(fd, &s) < 0)
2488 return is_temporary_fs(&s);
2491 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
2494 /* Under the assumption that we are running privileged we
2495 * first change the access mode and only then hand out
2496 * ownership to avoid a window where access is too open. */
2498 if (mode != MODE_INVALID)
2499 if (chmod(path, mode) < 0)
2502 if (uid != UID_INVALID || gid != GID_INVALID)
2503 if (chown(path, uid, gid) < 0)
2509 /// UNNEEDED by elogind
2511 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
2514 /* Under the assumption that we are running privileged we
2515 * first change the access mode and only then hand out
2516 * ownership to avoid a window where access is too open. */
2518 if (mode != MODE_INVALID)
2519 if (fchmod(fd, mode) < 0)
2522 if (uid != UID_INVALID || gid != GID_INVALID)
2523 if (fchown(fd, uid, gid) < 0)
2529 cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
2533 /* Allocates the cpuset in the right size */
2536 if (!(r = CPU_ALLOC(n)))
2539 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
2540 CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
2550 if (errno != EINVAL)
2558 int files_same(const char *filea, const char *fileb) {
2561 if (stat(filea, &a) < 0)
2564 if (stat(fileb, &b) < 0)
2567 return a.st_dev == b.st_dev &&
2568 a.st_ino == b.st_ino;
2571 /// UNNEEDED by elogind
2573 int running_in_chroot(void) {
2576 ret = files_same("/proc/1/root", "/");
2584 static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
2589 assert(percent <= 100);
2590 assert(new_length >= 3);
2592 if (old_length <= 3 || old_length <= new_length)
2593 return strndup(s, old_length);
2595 r = new0(char, new_length+1);
2599 x = (new_length * percent) / 100;
2601 if (x > new_length - 3)
2609 s + old_length - (new_length - x - 3),
2610 new_length - x - 3);
2615 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
2619 unsigned k, len, len2;
2622 assert(percent <= 100);
2623 assert(new_length >= 3);
2625 /* if no multibyte characters use ascii_ellipsize_mem for speed */
2626 if (ascii_is_valid(s))
2627 return ascii_ellipsize_mem(s, old_length, new_length, percent);
2629 if (old_length <= 3 || old_length <= new_length)
2630 return strndup(s, old_length);
2632 x = (new_length * percent) / 100;
2634 if (x > new_length - 3)
2638 for (i = s; k < x && i < s + old_length; i = utf8_next_char(i)) {
2641 c = utf8_encoded_to_unichar(i);
2644 k += unichar_iswide(c) ? 2 : 1;
2647 if (k > x) /* last character was wide and went over quota */
2650 for (j = s + old_length; k < new_length && j > i; ) {
2653 j = utf8_prev_char(j);
2654 c = utf8_encoded_to_unichar(j);
2657 k += unichar_iswide(c) ? 2 : 1;
2661 /* we don't actually need to ellipsize */
2663 return memdup(s, old_length + 1);
2665 /* make space for ellipsis */
2666 j = utf8_next_char(j);
2669 len2 = s + old_length - j;
2670 e = new(char, len + 3 + len2 + 1);
2675 printf("old_length=%zu new_length=%zu x=%zu len=%u len2=%u k=%u\n",
2676 old_length, new_length, x, len, len2, k);
2680 e[len] = 0xe2; /* tri-dot ellipsis: … */
2684 memcpy(e + len + 3, j, len2 + 1);
2689 char *ellipsize(const char *s, size_t length, unsigned percent) {
2690 return ellipsize_mem(s, strlen(s), length, percent);
2693 int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
2694 _cleanup_close_ int fd;
2700 mkdir_parents(path, 0755);
2702 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode > 0 ? mode : 0644);
2707 r = fchmod(fd, mode);
2712 if (uid != UID_INVALID || gid != GID_INVALID) {
2713 r = fchown(fd, uid, gid);
2718 if (stamp != USEC_INFINITY) {
2719 struct timespec ts[2];
2721 timespec_store(&ts[0], stamp);
2723 r = futimens(fd, ts);
2725 r = futimens(fd, NULL);
2732 int touch(const char *path) {
2733 return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, 0);
2736 /// UNNEEDED by elogind
2738 static char *unquote(const char *s, const char* quotes) {
2742 /* This is rather stupid, simply removes the heading and
2743 * trailing quotes if there is one. Doesn't care about
2744 * escaping or anything.
2746 * DON'T USE THIS FOR NEW CODE ANYMORE!*/
2752 if (strchr(quotes, s[0]) && s[l-1] == s[0])
2753 return strndup(s+1, l-2);
2759 noreturn void freeze(void) {
2761 /* Make sure nobody waits for us on a socket anymore */
2762 close_all_fds(NULL, 0);
2770 bool null_or_empty(struct stat *st) {
2773 if (S_ISREG(st->st_mode) && st->st_size <= 0)
2776 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
2782 int null_or_empty_path(const char *fn) {
2787 if (stat(fn, &st) < 0)
2790 return null_or_empty(&st);
2793 /// UNNEEDED by elogind
2795 int null_or_empty_fd(int fd) {
2800 if (fstat(fd, &st) < 0)
2803 return null_or_empty(&st);
2807 DIR *xopendirat(int fd, const char *name, int flags) {
2811 assert(!(flags & O_CREAT));
2813 nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
2826 /// UNNEEDED by elogind
2828 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
2829 _cleanup_free_ char *t = NULL, *u = NULL;
2832 u = unquote(tagvalue, QUOTES);
2836 enc_len = strlen(u) * 4 + 1;
2837 t = new(char, enc_len);
2841 if (encode_devnode_name(u, t, enc_len) < 0)
2844 return strjoin("/dev/disk/by-", by, "/", t, NULL);
2847 char *fstab_node_to_udev_node(const char *p) {
2850 if (startswith(p, "LABEL="))
2851 return tag_to_udev_node(p+6, "label");
2853 if (startswith(p, "UUID="))
2854 return tag_to_udev_node(p+5, "uuid");
2856 if (startswith(p, "PARTUUID="))
2857 return tag_to_udev_node(p+9, "partuuid");
2859 if (startswith(p, "PARTLABEL="))
2860 return tag_to_udev_node(p+10, "partlabel");
2866 bool dirent_is_file(const struct dirent *de) {
2869 if (hidden_file(de->d_name))
2872 if (de->d_type != DT_REG &&
2873 de->d_type != DT_LNK &&
2874 de->d_type != DT_UNKNOWN)
2880 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
2883 if (de->d_type != DT_REG &&
2884 de->d_type != DT_LNK &&
2885 de->d_type != DT_UNKNOWN)
2888 if (hidden_file_allow_backup(de->d_name))
2891 return endswith(de->d_name, suffix);
2894 static int do_execute(char **directories, usec_t timeout, char *argv[]) {
2895 _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
2896 _cleanup_set_free_free_ Set *seen = NULL;
2899 /* We fork this all off from a child process so that we can
2900 * somewhat cleanly make use of SIGALRM to set a time limit */
2902 (void) reset_all_signal_handlers();
2903 (void) reset_signal_mask();
2905 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
2907 pids = hashmap_new(NULL);
2911 seen = set_new(&string_hash_ops);
2915 STRV_FOREACH(directory, directories) {
2916 _cleanup_closedir_ DIR *d;
2919 d = opendir(*directory);
2921 if (errno == ENOENT)
2924 return log_error_errno(errno, "Failed to open directory %s: %m", *directory);
2927 FOREACH_DIRENT(de, d, break) {
2928 _cleanup_free_ char *path = NULL;
2932 if (!dirent_is_file(de))
2935 if (set_contains(seen, de->d_name)) {
2936 log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name);
2940 r = set_put_strdup(seen, de->d_name);
2944 path = strjoin(*directory, "/", de->d_name, NULL);
2948 if (null_or_empty_path(path)) {
2949 log_debug("%s is empty (a mask).", path);
2955 log_error_errno(errno, "Failed to fork: %m");
2957 } else if (pid == 0) {
2960 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
2970 return log_error_errno(errno, "Failed to execute %s: %m", path);
2973 log_debug("Spawned %s as " PID_FMT ".", path, pid);
2975 r = hashmap_put(pids, UINT_TO_PTR(pid), path);
2982 /* Abort execution of this process after the timout. We simply
2983 * rely on SIGALRM as default action terminating the process,
2984 * and turn on alarm(). */
2986 if (timeout != USEC_INFINITY)
2987 alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
2989 while (!hashmap_isempty(pids)) {
2990 _cleanup_free_ char *path = NULL;
2993 pid = PTR_TO_UINT(hashmap_first_key(pids));
2996 path = hashmap_remove(pids, UINT_TO_PTR(pid));
2999 wait_for_terminate_and_warn(path, pid, true);
3005 void execute_directories(const char* const* directories, usec_t timeout, char *argv[]) {
3009 char **dirs = (char**) directories;
3011 assert(!strv_isempty(dirs));
3013 name = basename(dirs[0]);
3014 assert(!isempty(name));
3016 /* Executes all binaries in the directories in parallel and waits
3017 * for them to finish. Optionally a timeout is applied. If a file
3018 * with the same name exists in more than one directory, the
3019 * earliest one wins. */
3021 executor_pid = fork();
3022 if (executor_pid < 0) {
3023 log_error_errno(errno, "Failed to fork: %m");
3026 } else if (executor_pid == 0) {
3027 r = do_execute(dirs, timeout, argv);
3028 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
3031 wait_for_terminate_and_warn(name, executor_pid, true);
3034 bool nulstr_contains(const char*nulstr, const char *needle) {
3040 NULSTR_FOREACH(i, nulstr)
3041 if (streq(i, needle))
3047 /// UNNEEDED by elogind
3049 bool plymouth_running(void) {
3050 return access("/run/plymouth/pid", F_OK) >= 0;
3054 char* strshorten(char *s, size_t l) {
3063 int pipe_eof(int fd) {
3064 struct pollfd pollfd = {
3066 .events = POLLIN|POLLHUP,
3071 r = poll(&pollfd, 1, 0);
3078 return pollfd.revents & POLLHUP;
3081 int fd_wait_for_event(int fd, int event, usec_t t) {
3083 struct pollfd pollfd = {
3091 r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
3098 return pollfd.revents;
3101 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
3110 r = tempfn_xxxxxx(path, NULL, &t);
3114 fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC);
3120 f = fdopen(fd, "we");
3134 /// UNNEEDED by elogind
3136 int symlink_atomic(const char *from, const char *to) {
3137 _cleanup_free_ char *t = NULL;
3143 r = tempfn_random(to, NULL, &t);
3147 if (symlink(from, t) < 0)
3150 if (rename(t, to) < 0) {
3158 int symlink_idempotent(const char *from, const char *to) {
3159 _cleanup_free_ char *p = NULL;
3165 if (symlink(from, to) < 0) {
3166 if (errno != EEXIST)
3169 r = readlink_malloc(to, &p);
3173 if (!streq(p, from))
3180 int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
3181 _cleanup_free_ char *t = NULL;
3186 r = tempfn_random(path, NULL, &t);
3190 if (mknod(t, mode, dev) < 0)
3193 if (rename(t, path) < 0) {
3201 int mkfifo_atomic(const char *path, mode_t mode) {
3202 _cleanup_free_ char *t = NULL;
3207 r = tempfn_random(path, NULL, &t);
3211 if (mkfifo(t, mode) < 0)
3214 if (rename(t, path) < 0) {
3223 bool display_is_local(const char *display) {
3227 display[0] == ':' &&
3228 display[1] >= '0' &&
3232 int socket_from_display(const char *display, char **path) {
3239 if (!display_is_local(display))
3242 k = strspn(display+1, "0123456789");
3244 f = new(char, strlen("/tmp/.X11-unix/X") + k + 1);
3248 c = stpcpy(f, "/tmp/.X11-unix/X");
3249 memcpy(c, display+1, k);
3258 const char **username,
3259 uid_t *uid, gid_t *gid,
3261 const char **shell) {
3269 /* We enforce some special rules for uid=0: in order to avoid
3270 * NSS lookups for root we hardcode its data. */
3272 if (streq(*username, "root") || streq(*username, "0")) {
3290 if (parse_uid(*username, &u) >= 0) {
3294 /* If there are multiple users with the same id, make
3295 * sure to leave $USER to the configured value instead
3296 * of the first occurrence in the database. However if
3297 * the uid was configured by a numeric uid, then let's
3298 * pick the real username from /etc/passwd. */
3300 *username = p->pw_name;
3303 p = getpwnam(*username);
3307 return errno > 0 ? -errno : -ESRCH;
3319 *shell = p->pw_shell;
3324 char* uid_to_name(uid_t uid) {
3329 return strdup("root");
3333 return strdup(p->pw_name);
3335 if (asprintf(&r, UID_FMT, uid) < 0)
3341 char* gid_to_name(gid_t gid) {
3346 return strdup("root");
3350 return strdup(p->gr_name);
3352 if (asprintf(&r, GID_FMT, gid) < 0)
3358 int get_group_creds(const char **groupname, gid_t *gid) {
3364 /* We enforce some special rules for gid=0: in order to avoid
3365 * NSS lookups for root we hardcode its data. */
3367 if (streq(*groupname, "root") || streq(*groupname, "0")) {
3368 *groupname = "root";
3376 if (parse_gid(*groupname, &id) >= 0) {
3381 *groupname = g->gr_name;
3384 g = getgrnam(*groupname);
3388 return errno > 0 ? -errno : -ESRCH;
3396 int in_gid(gid_t gid) {
3398 int ngroups_max, r, i;
3400 if (getgid() == gid)
3403 if (getegid() == gid)
3406 ngroups_max = sysconf(_SC_NGROUPS_MAX);
3407 assert(ngroups_max > 0);
3409 gids = alloca(sizeof(gid_t) * ngroups_max);
3411 r = getgroups(ngroups_max, gids);
3415 for (i = 0; i < r; i++)
3422 /// UNNEEDED by elogind
3424 int in_group(const char *name) {
3428 r = get_group_creds(&name, &gid);
3435 int glob_exists(const char *path) {
3436 _cleanup_globfree_ glob_t g = {};
3442 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
3444 if (k == GLOB_NOMATCH)
3446 else if (k == GLOB_NOSPACE)
3449 return !strv_isempty(g.gl_pathv);
3451 return errno ? -errno : -EIO;
3454 int glob_extend(char ***strv, const char *path) {
3455 _cleanup_globfree_ glob_t g = {};
3460 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
3462 if (k == GLOB_NOMATCH)
3464 else if (k == GLOB_NOSPACE)
3466 else if (k != 0 || strv_isempty(g.gl_pathv))
3467 return errno ? -errno : -EIO;
3469 STRV_FOREACH(p, g.gl_pathv) {
3470 k = strv_extend(strv, *p);
3479 int dirent_ensure_type(DIR *d, struct dirent *de) {
3485 if (de->d_type != DT_UNKNOWN)
3488 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
3492 S_ISREG(st.st_mode) ? DT_REG :
3493 S_ISDIR(st.st_mode) ? DT_DIR :
3494 S_ISLNK(st.st_mode) ? DT_LNK :
3495 S_ISFIFO(st.st_mode) ? DT_FIFO :
3496 S_ISSOCK(st.st_mode) ? DT_SOCK :
3497 S_ISCHR(st.st_mode) ? DT_CHR :
3498 S_ISBLK(st.st_mode) ? DT_BLK :
3504 int get_files_in_directory(const char *path, char ***list) {
3505 _cleanup_closedir_ DIR *d = NULL;
3506 size_t bufsize = 0, n = 0;
3507 _cleanup_strv_free_ char **l = NULL;
3511 /* Returns all files in a directory in *list, and the number
3512 * of files as return value. If list is NULL returns only the
3524 if (!de && errno != 0)
3529 dirent_ensure_type(d, de);
3531 if (!dirent_is_file(de))
3535 /* one extra slot is needed for the terminating NULL */
3536 if (!GREEDY_REALLOC(l, bufsize, n + 2))
3539 l[n] = strdup(de->d_name);
3550 l = NULL; /* avoid freeing */
3556 char *strjoin(const char *x, ...) {
3570 t = va_arg(ap, const char *);
3575 if (n > ((size_t) -1) - l) {
3599 t = va_arg(ap, const char *);
3613 bool is_main_thread(void) {
3614 static thread_local int cached = 0;
3616 if (_unlikely_(cached == 0))
3617 cached = getpid() == gettid() ? 1 : -1;
3622 /// UNNEEDED by elogind
3624 int block_get_whole_disk(dev_t d, dev_t *ret) {
3631 /* If it has a queue this is good enough for us */
3632 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
3635 r = access(p, F_OK);
3643 /* If it is a partition find the originating device */
3644 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
3647 r = access(p, F_OK);
3653 /* Get parent dev_t */
3654 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
3657 r = read_one_line_file(p, &s);
3663 r = sscanf(s, "%u:%u", &m, &n);
3669 /* Only return this if it is really good enough for us. */
3670 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
3673 r = access(p, F_OK);
3677 *ret = makedev(m, n);
3685 static const char *const ioprio_class_table[] = {
3686 [IOPRIO_CLASS_NONE] = "none",
3687 [IOPRIO_CLASS_RT] = "realtime",
3688 [IOPRIO_CLASS_BE] = "best-effort",
3689 [IOPRIO_CLASS_IDLE] = "idle"
3692 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
3694 static const char *const sigchld_code_table[] = {
3695 [CLD_EXITED] = "exited",
3696 [CLD_KILLED] = "killed",
3697 [CLD_DUMPED] = "dumped",
3698 [CLD_TRAPPED] = "trapped",
3699 [CLD_STOPPED] = "stopped",
3700 [CLD_CONTINUED] = "continued",
3703 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
3705 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
3706 [LOG_FAC(LOG_KERN)] = "kern",
3707 [LOG_FAC(LOG_USER)] = "user",
3708 [LOG_FAC(LOG_MAIL)] = "mail",
3709 [LOG_FAC(LOG_DAEMON)] = "daemon",
3710 [LOG_FAC(LOG_AUTH)] = "auth",
3711 [LOG_FAC(LOG_SYSLOG)] = "syslog",
3712 [LOG_FAC(LOG_LPR)] = "lpr",
3713 [LOG_FAC(LOG_NEWS)] = "news",
3714 [LOG_FAC(LOG_UUCP)] = "uucp",
3715 [LOG_FAC(LOG_CRON)] = "cron",
3716 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
3717 [LOG_FAC(LOG_FTP)] = "ftp",
3718 [LOG_FAC(LOG_LOCAL0)] = "local0",
3719 [LOG_FAC(LOG_LOCAL1)] = "local1",
3720 [LOG_FAC(LOG_LOCAL2)] = "local2",
3721 [LOG_FAC(LOG_LOCAL3)] = "local3",
3722 [LOG_FAC(LOG_LOCAL4)] = "local4",
3723 [LOG_FAC(LOG_LOCAL5)] = "local5",
3724 [LOG_FAC(LOG_LOCAL6)] = "local6",
3725 [LOG_FAC(LOG_LOCAL7)] = "local7"
3728 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
3730 static const char *const log_level_table[] = {
3731 [LOG_EMERG] = "emerg",
3732 [LOG_ALERT] = "alert",
3733 [LOG_CRIT] = "crit",
3735 [LOG_WARNING] = "warning",
3736 [LOG_NOTICE] = "notice",
3737 [LOG_INFO] = "info",
3738 [LOG_DEBUG] = "debug"
3741 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
3743 static const char* const sched_policy_table[] = {
3744 [SCHED_OTHER] = "other",
3745 [SCHED_BATCH] = "batch",
3746 [SCHED_IDLE] = "idle",
3747 [SCHED_FIFO] = "fifo",
3751 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
3753 static const char* const rlimit_table[_RLIMIT_MAX] = {
3754 [RLIMIT_CPU] = "LimitCPU",
3755 [RLIMIT_FSIZE] = "LimitFSIZE",
3756 [RLIMIT_DATA] = "LimitDATA",
3757 [RLIMIT_STACK] = "LimitSTACK",
3758 [RLIMIT_CORE] = "LimitCORE",
3759 [RLIMIT_RSS] = "LimitRSS",
3760 [RLIMIT_NOFILE] = "LimitNOFILE",
3761 [RLIMIT_AS] = "LimitAS",
3762 [RLIMIT_NPROC] = "LimitNPROC",
3763 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
3764 [RLIMIT_LOCKS] = "LimitLOCKS",
3765 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
3766 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
3767 [RLIMIT_NICE] = "LimitNICE",
3768 [RLIMIT_RTPRIO] = "LimitRTPRIO",
3769 [RLIMIT_RTTIME] = "LimitRTTIME"
3772 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
3774 static const char* const ip_tos_table[] = {
3775 [IPTOS_LOWDELAY] = "low-delay",
3776 [IPTOS_THROUGHPUT] = "throughput",
3777 [IPTOS_RELIABILITY] = "reliability",
3778 [IPTOS_LOWCOST] = "low-cost",
3781 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
3783 bool kexec_loaded(void) {
3784 bool loaded = false;
3787 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
3795 /// UNNEEDED by elogind
3797 int prot_from_flags(int flags) {
3799 switch (flags & O_ACCMODE) {
3808 return PROT_READ|PROT_WRITE;
3815 char *format_bytes(char *buf, size_t l, off_t t) {
3818 static const struct {
3822 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
3823 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
3824 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
3825 { "G", 1024ULL*1024ULL*1024ULL },
3826 { "M", 1024ULL*1024ULL },
3830 if (t == (off_t) -1)
3833 for (i = 0; i < ELEMENTSOF(table); i++) {
3835 if (t >= table[i].factor) {
3838 (unsigned long long) (t / table[i].factor),
3839 (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
3846 snprintf(buf, l, "%lluB", (unsigned long long) t);
3855 void* memdup(const void *p, size_t l) {
3868 int fd_inc_sndbuf(int fd, size_t n) {
3870 socklen_t l = sizeof(value);
3872 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
3873 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
3876 /* If we have the privileges we will ignore the kernel limit. */
3879 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
3880 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
3886 int fd_inc_rcvbuf(int fd, size_t n) {
3888 socklen_t l = sizeof(value);
3890 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
3891 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
3894 /* If we have the privileges we will ignore the kernel limit. */
3897 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
3898 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
3903 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
3904 bool stdout_is_tty, stderr_is_tty;
3905 pid_t parent_pid, agent_pid;
3906 sigset_t ss, saved_ss;
3914 /* Spawns a temporary TTY agent, making sure it goes away when
3917 parent_pid = getpid();
3919 /* First we temporarily block all signals, so that the new
3920 * child has them blocked initially. This way, we can be sure
3921 * that SIGTERMs are not lost we might send to the agent. */
3922 assert_se(sigfillset(&ss) >= 0);
3923 assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0);
3926 if (agent_pid < 0) {
3927 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
3931 if (agent_pid != 0) {
3932 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
3939 * Make sure the agent goes away when the parent dies */
3940 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
3941 _exit(EXIT_FAILURE);
3943 /* Make sure we actually can kill the agent, if we need to, in
3944 * case somebody invoked us from a shell script that trapped
3945 * SIGTERM or so... */
3946 (void) reset_all_signal_handlers();
3947 (void) reset_signal_mask();
3949 /* Check whether our parent died before we were able
3950 * to set the death signal and unblock the signals */
3951 if (getppid() != parent_pid)
3952 _exit(EXIT_SUCCESS);
3954 /* Don't leak fds to the agent */
3955 close_all_fds(except, n_except);
3957 stdout_is_tty = isatty(STDOUT_FILENO);
3958 stderr_is_tty = isatty(STDERR_FILENO);
3960 if (!stdout_is_tty || !stderr_is_tty) {
3963 /* Detach from stdout/stderr. and reopen
3964 * /dev/tty for them. This is important to
3965 * ensure that when systemctl is started via
3966 * popen() or a similar call that expects to
3967 * read EOF we actually do generate EOF and
3968 * not delay this indefinitely by because we
3969 * keep an unused copy of stdin around. */
3970 fd = open("/dev/tty", O_WRONLY);
3972 log_error_errno(errno, "Failed to open /dev/tty: %m");
3973 _exit(EXIT_FAILURE);
3977 dup2(fd, STDOUT_FILENO);
3980 dup2(fd, STDERR_FILENO);
3986 /* Count arguments */
3988 for (n = 0; va_arg(ap, char*); n++)
3993 l = alloca(sizeof(char *) * (n + 1));
3995 /* Fill in arguments */
3997 for (i = 0; i <= n; i++)
3998 l[i] = va_arg(ap, char*);
4002 _exit(EXIT_FAILURE);
4005 /// UNNEEDED by elogind
4007 int setrlimit_closest(int resource, const struct rlimit *rlim) {
4008 struct rlimit highest, fixed;
4012 if (setrlimit(resource, rlim) >= 0)
4018 /* So we failed to set the desired setrlimit, then let's try
4019 * to get as close as we can */
4020 assert_se(getrlimit(resource, &highest) == 0);
4022 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
4023 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
4025 if (setrlimit(resource, &fixed) < 0)
4031 bool http_etag_is_valid(const char *etag) {
4035 if (!endswith(etag, "\""))
4038 if (!startswith(etag, "\"") && !startswith(etag, "W/\""))
4045 bool http_url_is_valid(const char *url) {
4051 p = startswith(url, "http://");
4053 p = startswith(url, "https://");
4060 return ascii_is_valid(p);
4063 bool documentation_url_is_valid(const char *url) {
4069 if (http_url_is_valid(url))
4072 p = startswith(url, "file:/");
4074 p = startswith(url, "info:");
4076 p = startswith(url, "man:");
4081 return ascii_is_valid(p);
4084 bool in_initrd(void) {
4085 static int saved = -1;
4091 /* We make two checks here:
4093 * 1. the flag file /etc/initrd-release must exist
4094 * 2. the root file system must be a memory file system
4096 * The second check is extra paranoia, since misdetecting an
4097 * initrd can have bad bad consequences due the initrd
4098 * emptying when transititioning to the main systemd.
4101 saved = access("/etc/initrd-release", F_OK) >= 0 &&
4102 statfs("/", &s) >= 0 &&
4103 is_temporary_fs(&s);
4108 int get_home_dir(char **_h) {
4116 /* Take the user specified one */
4117 e = secure_getenv("HOME");
4118 if (e && path_is_absolute(e)) {
4127 /* Hardcode home directory for root to avoid NSS */
4130 h = strdup("/root");
4138 /* Check the database... */
4142 return errno > 0 ? -errno : -ESRCH;
4144 if (!path_is_absolute(p->pw_dir))
4147 h = strdup(p->pw_dir);
4155 /// UNNEEDED by elogind
4157 int get_shell(char **_s) {
4165 /* Take the user specified one */
4166 e = getenv("SHELL");
4176 /* Hardcode home directory for root to avoid NSS */
4179 s = strdup("/bin/sh");
4187 /* Check the database... */
4191 return errno > 0 ? -errno : -ESRCH;
4193 if (!path_is_absolute(p->pw_shell))
4196 s = strdup(p->pw_shell);
4205 bool filename_is_valid(const char *p) {
4219 if (strlen(p) > FILENAME_MAX)
4225 bool string_is_safe(const char *p) {
4231 for (t = p; *t; t++) {
4232 if (*t > 0 && *t < ' ')
4235 if (strchr("\\\"\'\x7f", *t))
4243 * Check if a string contains control characters. If 'ok' is non-NULL
4244 * it may be a string containing additional CCs to be considered OK.
4246 bool string_has_cc(const char *p, const char *ok) {
4251 for (t = p; *t; t++) {
4252 if (ok && strchr(ok, *t))
4255 if (*t > 0 && *t < ' ')
4265 bool path_is_safe(const char *p) {
4270 if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
4273 if (strlen(p)+1 > PATH_MAX)
4276 /* The following two checks are not really dangerous, but hey, they still are confusing */
4277 if (streq(p, ".") || startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
4280 if (strstr(p, "//"))
4286 /// UNNEEDED by elogind
4288 /* hey glibc, APIs with callbacks without a user pointer are so useless */
4289 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
4290 int (*compar) (const void *, const void *, void *), void *arg) {
4299 p = (void *)(((const char *) base) + (idx * size));
4300 comparison = compar(key, p, arg);
4303 else if (comparison > 0)
4311 void init_gettext(void) {
4312 setlocale(LC_ALL, "");
4313 textdomain(GETTEXT_PACKAGE);
4317 bool is_locale_utf8(void) {
4319 static int cached_answer = -1;
4321 if (cached_answer >= 0)
4324 if (!setlocale(LC_ALL, "")) {
4325 cached_answer = true;
4329 set = nl_langinfo(CODESET);
4331 cached_answer = true;
4335 if (streq(set, "UTF-8")) {
4336 cached_answer = true;
4340 /* For LC_CTYPE=="C" return true, because CTYPE is effectly
4341 * unset and everything can do to UTF-8 nowadays. */
4342 set = setlocale(LC_CTYPE, NULL);
4344 cached_answer = true;
4348 /* Check result, but ignore the result if C was set
4351 STR_IN_SET(set, "C", "POSIX") &&
4352 !getenv("LC_ALL") &&
4353 !getenv("LC_CTYPE") &&
4357 return (bool) cached_answer;
4360 const char *draw_special_char(DrawSpecialChar ch) {
4361 static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
4364 [DRAW_TREE_VERTICAL] = "\342\224\202 ", /* │ */
4365 [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */
4366 [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */
4367 [DRAW_TREE_SPACE] = " ", /* */
4368 [DRAW_TRIANGULAR_BULLET] = "\342\200\243", /* ‣ */
4369 [DRAW_BLACK_CIRCLE] = "\342\227\217", /* ● */
4370 [DRAW_ARROW] = "\342\206\222", /* → */
4371 [DRAW_DASH] = "\342\200\223", /* – */
4374 /* ASCII fallback */ {
4375 [DRAW_TREE_VERTICAL] = "| ",
4376 [DRAW_TREE_BRANCH] = "|-",
4377 [DRAW_TREE_RIGHT] = "`-",
4378 [DRAW_TREE_SPACE] = " ",
4379 [DRAW_TRIANGULAR_BULLET] = ">",
4380 [DRAW_BLACK_CIRCLE] = "*",
4381 [DRAW_ARROW] = "->",
4386 return draw_table[!is_locale_utf8()][ch];
4389 /// UNNEEDED by elogind
4391 char *strreplace(const char *text, const char *old_string, const char *new_string) {
4394 size_t l, old_len, new_len;
4400 old_len = strlen(old_string);
4401 new_len = strlen(new_string);
4414 if (!startswith(f, old_string)) {
4420 nl = l - old_len + new_len;
4421 a = realloc(r, nl + 1);
4429 t = stpcpy(t, new_string);
4441 char *strip_tab_ansi(char **ibuf, size_t *_isz) {
4442 const char *i, *begin = NULL;
4447 } state = STATE_OTHER;
4449 size_t osz = 0, isz;
4455 /* Strips ANSI color and replaces TABs by 8 spaces */
4457 isz = _isz ? *_isz : strlen(*ibuf);
4459 f = open_memstream(&obuf, &osz);
4463 for (i = *ibuf; i < *ibuf + isz + 1; i++) {
4468 if (i >= *ibuf + isz) /* EOT */
4470 else if (*i == '\x1B')
4471 state = STATE_ESCAPE;
4472 else if (*i == '\t')
4479 if (i >= *ibuf + isz) { /* EOT */
4482 } else if (*i == '[') {
4483 state = STATE_BRACKET;
4488 state = STATE_OTHER;
4495 if (i >= *ibuf + isz || /* EOT */
4496 (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
4499 state = STATE_OTHER;
4501 } else if (*i == 'm')
4502 state = STATE_OTHER;
4524 int on_ac_power(void) {
4525 bool found_offline = false, found_online = false;
4526 _cleanup_closedir_ DIR *d = NULL;
4528 d = opendir("/sys/class/power_supply");
4530 return errno == ENOENT ? true : -errno;
4534 _cleanup_close_ int fd = -1, device = -1;
4540 if (!de && errno != 0)
4546 if (hidden_file(de->d_name))
4549 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
4551 if (errno == ENOENT || errno == ENOTDIR)
4557 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
4559 if (errno == ENOENT)
4565 n = read(fd, contents, sizeof(contents));
4569 if (n != 6 || memcmp(contents, "Mains\n", 6))
4573 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
4575 if (errno == ENOENT)
4581 n = read(fd, contents, sizeof(contents));
4585 if (n != 2 || contents[1] != '\n')
4588 if (contents[0] == '1') {
4589 found_online = true;
4591 } else if (contents[0] == '0')
4592 found_offline = true;
4597 return found_online || !found_offline;
4601 static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
4608 if (!path_strv_resolve_uniq(search, root))
4611 STRV_FOREACH(i, search) {
4612 _cleanup_free_ char *p = NULL;
4616 p = strjoin(root, *i, "/", path, NULL);
4618 p = strjoin(*i, "/", path, NULL);
4628 if (errno != ENOENT)
4635 int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
4636 _cleanup_strv_free_ char **copy = NULL;
4642 if (path_is_absolute(path)) {
4645 f = fopen(path, mode);
4654 copy = strv_copy((char**) search);
4658 return search_and_fopen_internal(path, mode, root, copy, _f);
4661 /// UNNEEDED by elogind
4663 int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
4664 _cleanup_strv_free_ char **s = NULL;
4666 if (path_is_absolute(path)) {
4669 f = fopen(path, mode);
4678 s = strv_split_nulstr(search);
4682 return search_and_fopen_internal(path, mode, root, s, _f);
4686 char *strextend(char **x, ...) {
4693 l = f = *x ? strlen(*x) : 0;
4700 t = va_arg(ap, const char *);
4705 if (n > ((size_t) -1) - l) {
4714 r = realloc(*x, l+1);
4724 t = va_arg(ap, const char *);
4738 char *strrep(const char *s, unsigned n) {
4746 p = r = malloc(l * n + 1);
4750 for (i = 0; i < n; i++)
4757 void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
4764 if (*allocated >= need)
4767 newalloc = MAX(need * 2, 64u / size);
4768 a = newalloc * size;
4770 /* check for overflows */
4771 if (a < size * need)
4779 *allocated = newalloc;
4783 void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
4792 q = greedy_realloc(p, allocated, need, size);
4796 if (*allocated > prev)
4797 memzero(q + prev * size, (*allocated - prev) * size);
4802 bool id128_is_valid(const char *s) {
4808 /* Simple formatted 128bit hex string */
4810 for (i = 0; i < l; i++) {
4813 if (!(c >= '0' && c <= '9') &&
4814 !(c >= 'a' && c <= 'z') &&
4815 !(c >= 'A' && c <= 'Z'))
4819 } else if (l == 36) {
4821 /* Formatted UUID */
4823 for (i = 0; i < l; i++) {
4826 if ((i == 8 || i == 13 || i == 18 || i == 23)) {
4830 if (!(c >= '0' && c <= '9') &&
4831 !(c >= 'a' && c <= 'z') &&
4832 !(c >= 'A' && c <= 'Z'))
4843 /// UNNEEDED by elogind
4845 int split_pair(const char *s, const char *sep, char **l, char **r) {
4860 a = strndup(s, x - s);
4864 b = strdup(x + strlen(sep));
4876 int shall_restore_state(void) {
4877 _cleanup_free_ char *value = NULL;
4880 r = get_proc_cmdline_key("systemd.restore_state=", &value);
4886 return parse_boolean(value) != 0;
4890 int proc_cmdline(char **ret) {
4893 if (detect_container(NULL) > 0)
4894 return get_process_cmdline(1, 0, false, ret);
4896 return read_one_line_file("/proc/cmdline", ret);
4899 int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
4900 _cleanup_free_ char *line = NULL;
4906 r = proc_cmdline(&line);
4912 _cleanup_free_ char *word = NULL;
4915 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
4921 /* Filter out arguments that are intended only for the
4923 if (!in_initrd() && startswith(word, "rd."))
4926 value = strchr(word, '=');
4930 r = parse_item(word, value);
4938 int get_proc_cmdline_key(const char *key, char **value) {
4939 _cleanup_free_ char *line = NULL, *ret = NULL;
4946 r = proc_cmdline(&line);
4952 _cleanup_free_ char *word = NULL;
4955 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
4961 /* Filter out arguments that are intended only for the
4963 if (!in_initrd() && startswith(word, "rd."))
4967 e = startswith(word, key);
4971 r = free_and_strdup(&ret, e);
4977 if (streq(word, key))
4991 int container_get_leader(const char *machine, pid_t *pid) {
4992 _cleanup_free_ char *s = NULL, *class = NULL;
5000 if (!machine_name_is_valid(machine))
5003 p = strjoina("/run/systemd/machines/", machine);
5004 r = parse_env_file(p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
5012 if (!streq_ptr(class, "container"))
5015 r = parse_pid(s, &leader);
5025 int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd) {
5026 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, netnsfd = -1, usernsfd = -1;
5034 mntns = procfs_file_alloca(pid, "ns/mnt");
5035 mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5043 pidns = procfs_file_alloca(pid, "ns/pid");
5044 pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5052 netns = procfs_file_alloca(pid, "ns/net");
5053 netnsfd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5061 userns = procfs_file_alloca(pid, "ns/user");
5062 usernsfd = open(userns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5063 if (usernsfd < 0 && errno != ENOENT)
5070 root = procfs_file_alloca(pid, "root");
5071 rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
5077 *pidns_fd = pidnsfd;
5080 *mntns_fd = mntnsfd;
5083 *netns_fd = netnsfd;
5086 *userns_fd = usernsfd;
5091 pidnsfd = mntnsfd = netnsfd = usernsfd = -1;
5096 int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd) {
5097 if (userns_fd >= 0) {
5098 /* Can't setns to your own userns, since then you could
5099 * escalate from non-root to root in your own namespace, so
5100 * check if namespaces equal before attempting to enter. */
5101 _cleanup_free_ char *userns_fd_path = NULL;
5103 if (asprintf(&userns_fd_path, "/proc/self/fd/%d", userns_fd) < 0)
5106 r = files_same(userns_fd_path, "/proc/self/ns/user");
5114 if (setns(pidns_fd, CLONE_NEWPID) < 0)
5118 if (setns(mntns_fd, CLONE_NEWNS) < 0)
5122 if (setns(netns_fd, CLONE_NEWNET) < 0)
5126 if (setns(userns_fd, CLONE_NEWUSER) < 0)
5130 if (fchdir(root_fd) < 0)
5133 if (chroot(".") < 0)
5137 return reset_uid_gid();
5140 int getpeercred(int fd, struct ucred *ucred) {
5141 socklen_t n = sizeof(struct ucred);
5148 r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
5152 if (n != sizeof(struct ucred))
5155 /* Check if the data is actually useful and not suppressed due
5156 * to namespacing issues */
5159 if (u.uid == UID_INVALID)
5161 if (u.gid == GID_INVALID)
5168 int getpeersec(int fd, char **ret) {
5180 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
5184 if (errno != ERANGE)
5191 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
5207 /* This is much like like mkostemp() but is subject to umask(). */
5208 int mkostemp_safe(char *pattern, int flags) {
5209 _cleanup_umask_ mode_t u;
5216 fd = mkostemp(pattern, flags);
5223 /// UNNEEDED by elogind
5225 int open_tmpfile(const char *path, int flags) {
5232 /* Try O_TMPFILE first, if it is supported */
5233 fd = open(path, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
5238 /* Fall back to unguessable name + unlinking */
5239 p = strjoina(path, "/systemd-tmp-XXXXXX");
5241 fd = mkostemp_safe(p, flags);
5250 int fd_warn_permissions(const char *path, int fd) {
5253 if (fstat(fd, &st) < 0)
5256 if (st.st_mode & 0111)
5257 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
5259 if (st.st_mode & 0002)
5260 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
5262 if (getpid() == 1 && (st.st_mode & 0044) != 0044)
5263 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);
5268 /// UNNEEDED by elogind
5270 unsigned long personality_from_string(const char *p) {
5272 /* Parse a personality specifier. We introduce our own
5273 * identifiers that indicate specific ABIs, rather than just
5274 * hints regarding the register size, since we want to keep
5275 * things open for multiple locally supported ABIs for the
5276 * same register size. We try to reuse the ABI identifiers
5277 * used by libseccomp. */
5279 #if defined(__x86_64__)
5281 if (streq(p, "x86"))
5284 if (streq(p, "x86-64"))
5287 #elif defined(__i386__)
5289 if (streq(p, "x86"))
5293 return PERSONALITY_INVALID;
5296 const char* personality_to_string(unsigned long p) {
5298 #if defined(__x86_64__)
5300 if (p == PER_LINUX32)
5306 #elif defined(__i386__)
5316 uint64_t physical_memory(void) {
5319 /* We return this as uint64_t in case we are running as 32bit
5320 * process on a 64bit kernel with huge amounts of memory */
5322 mem = sysconf(_SC_PHYS_PAGES);
5325 return (uint64_t) mem * (uint64_t) page_size();
5328 /// UNNEEDED by elogind
5330 void hexdump(FILE *f, const void *p, size_t s) {
5331 const uint8_t *b = p;
5334 assert(s == 0 || b);
5339 fprintf(f, "%04x ", n);
5341 for (i = 0; i < 16; i++) {
5346 fprintf(f, "%02x ", b[i]);
5354 for (i = 0; i < 16; i++) {
5359 fputc(isprint(b[i]) ? (char) b[i] : '.', f);
5373 int update_reboot_param_file(const char *param) {
5378 r = write_string_file(REBOOT_PARAM_FILE, param, WRITE_STRING_FILE_CREATE);
5380 log_error("Failed to write reboot param to "
5381 REBOOT_PARAM_FILE": %s", strerror(-r));
5383 unlink(REBOOT_PARAM_FILE);
5388 int umount_recursive(const char *prefix, int flags) {
5392 /* Try to umount everything recursively below a
5393 * directory. Also, take care of stacked mounts, and keep
5394 * unmounting them until they are gone. */
5397 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
5402 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
5403 if (!proc_self_mountinfo)
5407 _cleanup_free_ char *path = NULL, *p = NULL;
5410 k = fscanf(proc_self_mountinfo,
5411 "%*s " /* (1) mount id */
5412 "%*s " /* (2) parent id */
5413 "%*s " /* (3) major:minor */
5414 "%*s " /* (4) root */
5415 "%ms " /* (5) mount point */
5416 "%*s" /* (6) mount options */
5417 "%*[^-]" /* (7) optional fields */
5418 "- " /* (8) separator */
5419 "%*s " /* (9) file system type */
5420 "%*s" /* (10) mount source */
5421 "%*s" /* (11) mount options 2 */
5422 "%*[^\n]", /* some rubbish at the end */
5431 r = cunescape(path, UNESCAPE_RELAX, &p);
5435 if (!path_startswith(p, prefix))
5438 if (umount2(p, flags) < 0) {
5454 static int get_mount_flags(const char *path, unsigned long *flags) {
5457 if (statvfs(path, &buf) < 0)
5459 *flags = buf.f_flag;
5463 int bind_remount_recursive(const char *prefix, bool ro) {
5464 _cleanup_set_free_free_ Set *done = NULL;
5465 _cleanup_free_ char *cleaned = NULL;
5468 /* Recursively remount a directory (and all its submounts)
5469 * read-only or read-write. If the directory is already
5470 * mounted, we reuse the mount and simply mark it
5471 * MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write
5472 * operation). If it isn't we first make it one. Afterwards we
5473 * apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to all
5474 * submounts we can access, too. When mounts are stacked on
5475 * the same mount point we only care for each individual
5476 * "top-level" mount on each point, as we cannot
5477 * influence/access the underlying mounts anyway. We do not
5478 * have any effect on future submounts that might get
5479 * propagated, they migt be writable. This includes future
5480 * submounts that have been triggered via autofs. */
5482 cleaned = strdup(prefix);
5486 path_kill_slashes(cleaned);
5488 done = set_new(&string_hash_ops);
5493 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
5494 _cleanup_set_free_free_ Set *todo = NULL;
5495 bool top_autofs = false;
5497 unsigned long orig_flags;
5499 todo = set_new(&string_hash_ops);
5503 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
5504 if (!proc_self_mountinfo)
5508 _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
5511 k = fscanf(proc_self_mountinfo,
5512 "%*s " /* (1) mount id */
5513 "%*s " /* (2) parent id */
5514 "%*s " /* (3) major:minor */
5515 "%*s " /* (4) root */
5516 "%ms " /* (5) mount point */
5517 "%*s" /* (6) mount options (superblock) */
5518 "%*[^-]" /* (7) optional fields */
5519 "- " /* (8) separator */
5520 "%ms " /* (9) file system type */
5521 "%*s" /* (10) mount source */
5522 "%*s" /* (11) mount options (bind mount) */
5523 "%*[^\n]", /* some rubbish at the end */
5533 r = cunescape(path, UNESCAPE_RELAX, &p);
5537 /* Let's ignore autofs mounts. If they aren't
5538 * triggered yet, we want to avoid triggering
5539 * them, as we don't make any guarantees for
5540 * future submounts anyway. If they are
5541 * already triggered, then we will find
5542 * another entry for this. */
5543 if (streq(type, "autofs")) {
5544 top_autofs = top_autofs || path_equal(cleaned, p);
5548 if (path_startswith(p, cleaned) &&
5549 !set_contains(done, p)) {
5551 r = set_consume(todo, p);
5561 /* If we have no submounts to process anymore and if
5562 * the root is either already done, or an autofs, we
5564 if (set_isempty(todo) &&
5565 (top_autofs || set_contains(done, cleaned)))
5568 if (!set_contains(done, cleaned) &&
5569 !set_contains(todo, cleaned)) {
5570 /* The prefix directory itself is not yet a
5571 * mount, make it one. */
5572 if (mount(cleaned, cleaned, NULL, MS_BIND|MS_REC, NULL) < 0)
5576 (void) get_mount_flags(cleaned, &orig_flags);
5577 orig_flags &= ~MS_RDONLY;
5579 if (mount(NULL, prefix, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0)
5582 x = strdup(cleaned);
5586 r = set_consume(done, x);
5591 while ((x = set_steal_first(todo))) {
5593 r = set_consume(done, x);
5594 if (r == -EEXIST || r == 0)
5599 /* Try to reuse the original flag set, but
5600 * don't care for errors, in case of
5601 * obstructed mounts */
5603 (void) get_mount_flags(x, &orig_flags);
5604 orig_flags &= ~MS_RDONLY;
5606 if (mount(NULL, x, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) {
5608 /* Deal with mount points that are
5609 * obstructed by a later mount */
5611 if (errno != ENOENT)
5620 int fflush_and_check(FILE *f) {
5627 return errno ? -errno : -EIO;
5632 int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
5644 * /foo/bar/.#<extra>waldoXXXXXX
5648 if (!filename_is_valid(fn))
5654 t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
5658 strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn), "XXXXXX");
5660 *ret = path_kill_slashes(t);
5664 int tempfn_random(const char *p, const char *extra, char **ret) {
5678 * /foo/bar/.#<extra>waldobaa2a261115984a9
5682 if (!filename_is_valid(fn))
5688 t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1);
5692 x = stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn);
5695 for (i = 0; i < 16; i++) {
5696 *(x++) = hexchar(u & 0xF);
5702 *ret = path_kill_slashes(t);
5706 /// UNNEEDED by elogind
5708 int tempfn_random_child(const char *p, const char *extra, char **ret) {
5719 * /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
5725 t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1);
5729 x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra);
5732 for (i = 0; i < 16; i++) {
5733 *(x++) = hexchar(u & 0xF);
5739 *ret = path_kill_slashes(t);
5743 int take_password_lock(const char *root) {
5745 struct flock flock = {
5747 .l_whence = SEEK_SET,
5755 /* This is roughly the same as lckpwdf(), but not as awful. We
5756 * don't want to use alarm() and signals, hence we implement
5757 * our own trivial version of this.
5759 * Note that shadow-utils also takes per-database locks in
5760 * addition to lckpwdf(). However, we don't given that they
5761 * are redundant as they they invoke lckpwdf() first and keep
5762 * it during everything they do. The per-database locks are
5763 * awfully racy, and thus we just won't do them. */
5766 path = strjoina(root, "/etc/.pwd.lock");
5768 path = "/etc/.pwd.lock";
5770 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
5774 r = fcntl(fd, F_SETLKW, &flock);
5783 int is_symlink(const char *path) {
5786 if (lstat(path, &info) < 0)
5789 return !!S_ISLNK(info.st_mode);
5793 int is_dir(const char* path, bool follow) {
5798 r = stat(path, &st);
5800 r = lstat(path, &st);
5804 return !!S_ISDIR(st.st_mode);
5807 /// UNNEEDED by elogind
5809 int is_device_node(const char *path) {
5812 if (lstat(path, &info) < 0)
5815 return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode));
5819 int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) {
5820 _cleanup_free_ char *s = NULL;
5821 size_t allocated = 0, sz = 0;
5829 SINGLE_QUOTE_ESCAPE,
5831 DOUBLE_QUOTE_ESCAPE,
5839 separators = WHITESPACE;
5841 /* Bail early if called after last value or with no input */
5843 goto finish_force_terminate;
5845 /* Parses the first word of a string, and returns it in
5846 * *ret. Removes all quotes in the process. When parsing fails
5847 * (because of an uneven number of quotes or similar), leaves
5848 * the pointer *p at the first invalid character. */
5856 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
5857 if (!GREEDY_REALLOC(s, allocated, sz+1))
5861 goto finish_force_terminate;
5862 else if (strchr(separators, c)) {
5863 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
5865 goto finish_force_next;
5870 /* We found a non-blank character, so we will always
5871 * want to return a string (even if it is empty),
5872 * allocate it here. */
5873 if (!GREEDY_REALLOC(s, allocated, sz+1))
5881 goto finish_force_terminate;
5882 else if (c == '\'' && (flags & EXTRACT_QUOTES))
5883 state = SINGLE_QUOTE;
5885 state = VALUE_ESCAPE;
5886 else if (c == '\"' && (flags & EXTRACT_QUOTES))
5887 state = DOUBLE_QUOTE;
5888 else if (strchr(separators, c)) {
5889 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
5891 goto finish_force_next;
5895 if (!GREEDY_REALLOC(s, allocated, sz+2))
5905 if (flags & EXTRACT_RELAX)
5906 goto finish_force_terminate;
5908 } else if (c == '\'')
5911 state = SINGLE_QUOTE_ESCAPE;
5913 if (!GREEDY_REALLOC(s, allocated, sz+2))
5927 state = DOUBLE_QUOTE_ESCAPE;
5929 if (!GREEDY_REALLOC(s, allocated, sz+2))
5937 case SINGLE_QUOTE_ESCAPE:
5938 case DOUBLE_QUOTE_ESCAPE:
5940 if (!GREEDY_REALLOC(s, allocated, sz+7))
5944 if ((flags & EXTRACT_CUNESCAPE_RELAX) &&
5945 (state == VALUE_ESCAPE || flags & EXTRACT_RELAX)) {
5946 /* If we find an unquoted trailing backslash and we're in
5947 * EXTRACT_CUNESCAPE_RELAX mode, keep it verbatim in the
5950 * Unbalanced quotes will only be allowed in EXTRACT_RELAX
5951 * mode, EXTRACT_CUNESCAPE_RELAX mode does not allow them.
5954 goto finish_force_terminate;
5956 if (flags & EXTRACT_RELAX)
5957 goto finish_force_terminate;
5961 if (flags & EXTRACT_CUNESCAPE) {
5964 r = cunescape_one(*p, (size_t) -1, &c, &u);
5966 if (flags & EXTRACT_CUNESCAPE_RELAX) {
5977 s[sz++] = c; /* normal explicit char */
5979 sz += utf8_encode_unichar(s + sz, u); /* unicode chars we'll encode as utf8 */
5984 state = (state == SINGLE_QUOTE_ESCAPE) ? SINGLE_QUOTE :
5985 (state == DOUBLE_QUOTE_ESCAPE) ? DOUBLE_QUOTE :
5991 goto finish_force_terminate;
5992 if (!strchr(separators, c))
6000 finish_force_terminate:
6017 /// UNNEEDED by elogind
6019 int extract_first_word_and_warn(
6022 const char *separators,
6025 const char *filename,
6027 const char *rvalue) {
6028 /* Try to unquote it, if it fails, warn about it and try again but this
6029 * time using EXTRACT_CUNESCAPE_RELAX to keep the backslashes verbatim
6030 * in invalid escape sequences. */
6035 r = extract_first_word(p, ret, separators, flags);
6036 if (r < 0 && !(flags&EXTRACT_CUNESCAPE_RELAX)) {
6037 /* Retry it with EXTRACT_CUNESCAPE_RELAX. */
6039 r = extract_first_word(p, ret, separators, flags|EXTRACT_CUNESCAPE_RELAX);
6041 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
6042 "Unbalanced quoting in command line, ignoring: \"%s\"", rvalue);
6044 log_syntax(unit, LOG_WARNING, filename, line, EINVAL,
6045 "Invalid escape sequences in command line: \"%s\"", rvalue);
6050 int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) {
6055 /* Parses a number of words from a string, stripping any
6056 * quotes if necessary. */
6060 /* Count how many words are expected */
6061 va_start(ap, flags);
6063 if (!va_arg(ap, char **))
6072 /* Read all words into a temporary array */
6073 l = newa0(char*, n);
6074 for (c = 0; c < n; c++) {
6076 r = extract_first_word(p, &l[c], separators, flags);
6080 for (j = 0; j < c; j++)
6090 /* If we managed to parse all words, return them in the passed
6092 va_start(ap, flags);
6093 for (i = 0; i < n; i++) {
6096 v = va_arg(ap, char **);
6107 int free_and_strdup(char **p, const char *s) {
6112 /* Replaces a string pointer with an strdup()ed new string,
6113 * possibly freeing the old one. */
6115 if (streq_ptr(*p, s))
6131 /// UNNEEDED by elogind
6133 int ptsname_malloc(int fd, char **ret) {
6146 if (ptsname_r(fd, c, l) == 0) {
6150 if (errno != ERANGE) {
6160 int openpt_in_namespace(pid_t pid, int flags) {
6161 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1;
6162 _cleanup_close_pair_ int pair[2] = { -1, -1 };
6164 struct cmsghdr cmsghdr;
6165 uint8_t buf[CMSG_SPACE(sizeof(int))];
6167 struct msghdr mh = {
6168 .msg_control = &control,
6169 .msg_controllen = sizeof(control),
6171 struct cmsghdr *cmsg;
6178 r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &usernsfd, &rootfd);
6182 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
6192 pair[0] = safe_close(pair[0]);
6194 r = namespace_enter(pidnsfd, mntnsfd, -1, usernsfd, rootfd);
6196 _exit(EXIT_FAILURE);
6198 master = posix_openpt(flags);
6200 _exit(EXIT_FAILURE);
6202 if (unlockpt(master) < 0)
6203 _exit(EXIT_FAILURE);
6205 cmsg = CMSG_FIRSTHDR(&mh);
6206 cmsg->cmsg_level = SOL_SOCKET;
6207 cmsg->cmsg_type = SCM_RIGHTS;
6208 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
6209 memcpy(CMSG_DATA(cmsg), &master, sizeof(int));
6211 mh.msg_controllen = cmsg->cmsg_len;
6213 if (sendmsg(pair[1], &mh, MSG_NOSIGNAL) < 0)
6214 _exit(EXIT_FAILURE);
6216 _exit(EXIT_SUCCESS);
6219 pair[1] = safe_close(pair[1]);
6221 r = wait_for_terminate(child, &si);
6224 if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
6227 if (recvmsg(pair[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
6230 CMSG_FOREACH(cmsg, &mh)
6231 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
6235 fds = (int*) CMSG_DATA(cmsg);
6236 n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
6239 close_many(fds, n_fds);
6250 ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) {
6251 _cleanup_close_ int fd = -1;
6254 /* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */
6256 fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOATIME|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
6260 l = fgetxattr(fd, attribute, value, size);
6267 static int parse_crtime(le64_t le, usec_t *usec) {
6273 if (u == 0 || u == (uint64_t) -1)
6280 int fd_getcrtime(int fd, usec_t *usec) {
6287 /* Until Linux gets a real concept of birthtime/creation time,
6288 * let's fake one with xattrs */
6290 n = fgetxattr(fd, "user.crtime_usec", &le, sizeof(le));
6293 if (n != sizeof(le))
6296 return parse_crtime(le, usec);
6299 /// UNNEEDED by elogind
6301 int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags) {
6305 n = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags);
6308 if (n != sizeof(le))
6311 return parse_crtime(le, usec);
6314 int path_getcrtime(const char *p, usec_t *usec) {
6321 n = getxattr(p, "user.crtime_usec", &le, sizeof(le));
6324 if (n != sizeof(le))
6327 return parse_crtime(le, usec);
6330 int fd_setcrtime(int fd, usec_t usec) {
6336 usec = now(CLOCK_REALTIME);
6338 le = htole64((uint64_t) usec);
6339 if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), 0) < 0)
6345 int same_fd(int a, int b) {
6346 struct stat sta, stb;
6353 /* Compares two file descriptors. Note that semantics are
6354 * quite different depending on whether we have kcmp() or we
6355 * don't. If we have kcmp() this will only return true for
6356 * dup()ed file descriptors, but not otherwise. If we don't
6357 * have kcmp() this will also return true for two fds of the same
6358 * file, created by separate open() calls. Since we use this
6359 * call mostly for filtering out duplicates in the fd store
6360 * this difference hopefully doesn't matter too much. */
6365 /* Try to use kcmp() if we have it. */
6367 r = kcmp(pid, pid, KCMP_FILE, a, b);
6372 if (errno != ENOSYS)
6375 /* We don't have kcmp(), use fstat() instead. */
6376 if (fstat(a, &sta) < 0)
6379 if (fstat(b, &stb) < 0)
6382 if ((sta.st_mode & S_IFMT) != (stb.st_mode & S_IFMT))
6385 /* We consider all device fds different, since two device fds
6386 * might refer to quite different device contexts even though
6387 * they share the same inode and backing dev_t. */
6389 if (S_ISCHR(sta.st_mode) || S_ISBLK(sta.st_mode))
6392 if (sta.st_dev != stb.st_dev || sta.st_ino != stb.st_ino)
6395 /* The fds refer to the same inode on disk, let's also check
6396 * if they have the same fd flags. This is useful to
6397 * distinguish the read and write side of a pipe created with
6399 fa = fcntl(a, F_GETFL);
6403 fb = fcntl(b, F_GETFL);
6411 int chattr_fd(int fd, unsigned value, unsigned mask) {
6412 unsigned old_attr, new_attr;
6417 if (fstat(fd, &st) < 0)
6420 /* Explicitly check whether this is a regular file or
6421 * directory. If it is anything else (such as a device node or
6422 * fifo), then the ioctl will not hit the file systems but
6423 * possibly drivers, where the ioctl might have different
6424 * effects. Notably, DRM is using the same ioctl() number. */
6426 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
6432 if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
6435 new_attr = (old_attr & ~mask) | (value & mask);
6436 if (new_attr == old_attr)
6439 if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
6445 /// UNNEEDED by elogind
6447 int chattr_path(const char *p, unsigned value, unsigned mask) {
6448 _cleanup_close_ int fd = -1;
6455 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
6459 return chattr_fd(fd, value, mask);
6463 int read_attr_fd(int fd, unsigned *ret) {
6468 if (fstat(fd, &st) < 0)
6471 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
6474 if (ioctl(fd, FS_IOC_GETFLAGS, ret) < 0)
6480 /// UNNEEDED by elogind
6482 int read_attr_path(const char *p, unsigned *ret) {
6483 _cleanup_close_ int fd = -1;
6488 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
6492 return read_attr_fd(fd, ret);
6495 static size_t nul_length(const uint8_t *p, size_t sz) {
6510 ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
6511 const uint8_t *q, *w, *e;
6519 n = nul_length(q, e - q);
6521 /* If there are more than the specified run length of
6522 * NUL bytes, or if this is the beginning or the end
6523 * of the buffer, then seek instead of write */
6524 if ((n > run_length) ||
6525 (n > 0 && q == p) ||
6526 (n > 0 && q + n >= e)) {
6528 l = write(fd, w, q - w);
6535 if (lseek(fd, n, SEEK_CUR) == (off_t) -1)
6547 l = write(fd, w, q - w);
6554 return q - (const uint8_t*) p;
6558 void sigkill_wait(pid_t *pid) {
6564 if (kill(*pid, SIGKILL) > 0)
6565 (void) wait_for_terminate(*pid, NULL);
6568 /// UNNEEDED by elogind
6570 int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
6571 int a = 0, b = 0, c = 0;
6581 if (!strchr(*p, '>'))
6584 if ((*p)[2] == '>') {
6585 c = undecchar((*p)[1]);
6587 } else if ((*p)[3] == '>') {
6588 b = undecchar((*p)[1]);
6589 c = undecchar((*p)[2]);
6591 } else if ((*p)[4] == '>') {
6592 a = undecchar((*p)[1]);
6593 b = undecchar((*p)[2]);
6594 c = undecchar((*p)[3]);
6599 if (a < 0 || b < 0 || c < 0 ||
6600 (!with_facility && (a || b || c > 7)))
6604 *priority = a*100 + b*10 + c;
6606 *priority = (*priority & LOG_FACMASK) | c;
6613 ssize_t string_table_lookup(const char * const *table, size_t len, const char *key) {
6619 for (i = 0; i < len; ++i)
6620 if (streq_ptr(table[i], key))
6626 /// UNNEEDED by elogind
6628 void cmsg_close_all(struct msghdr *mh) {
6629 struct cmsghdr *cmsg;
6633 CMSG_FOREACH(cmsg, mh)
6634 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
6635 close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int));
6638 int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
6642 ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
6646 /* renameat2() exists since Linux 3.15, btrfs added support for it later.
6647 * If it is not implemented, fallback to another method. */
6648 if (!IN_SET(errno, EINVAL, ENOSYS))
6651 /* The link()/unlink() fallback does not work on directories. But
6652 * renameat() without RENAME_NOREPLACE gives the same semantics on
6653 * directories, except when newpath is an *empty* directory. This is
6655 ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW);
6656 if (ret >= 0 && S_ISDIR(buf.st_mode)) {
6657 ret = renameat(olddirfd, oldpath, newdirfd, newpath);
6658 return ret >= 0 ? 0 : -errno;
6661 /* If it is not a directory, use the link()/unlink() fallback. */
6662 ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0);
6666 ret = unlinkat(olddirfd, oldpath, 0);
6668 /* backup errno before the following unlinkat() alters it */
6670 (void) unlinkat(newdirfd, newpath, 0);
6679 static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad) {
6683 if (*s == '\\' || strchr(bad, *s))
6692 char *shell_escape(const char *s, const char *bad) {
6695 r = new(char, strlen(s)*2+1);
6699 t = strcpy_backslash_escaped(r, s, bad);
6705 char *shell_maybe_quote(const char *s) {
6711 /* Encloses a string in double quotes if necessary to make it
6712 * OK as shell string. */
6714 for (p = s; *p; p++)
6717 strchr(SHELL_NEED_QUOTES, *p))
6723 r = new(char, 1+strlen(s)*2+1+1);
6729 t = mempcpy(t, s, p - s);
6731 t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE);
6739 int parse_mode(const char *s, mode_t *ret) {
6747 l = strtol(s, &x, 8);
6751 if (!x || x == s || *x)
6753 if (l < 0 || l > 07777)
6760 /// UNNEEDED by elogind
6762 int mount_move_root(const char *path) {
6765 if (chdir(path) < 0)
6768 if (mount(path, "/", NULL, MS_MOVE, NULL) < 0)
6771 if (chroot(".") < 0)
6781 int reset_uid_gid(void) {
6783 if (setgroups(0, NULL) < 0)
6786 if (setresgid(0, 0, 0) < 0)
6789 if (setresuid(0, 0, 0) < 0)
6795 int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink) {
6804 for (l = 100; ; l = (size_t) n + 1) {
6810 n = lgetxattr(path, name, v, l);
6812 n = getxattr(path, name, v, l);
6814 if (n >= 0 && (size_t) n < l) {
6821 if (n < 0 && errno != ERANGE)
6825 n = lgetxattr(path, name, NULL, 0);
6827 n = getxattr(path, name, NULL, 0);
6833 int fgetxattr_malloc(int fd, const char *name, char **value) {
6842 for (l = 100; ; l = (size_t) n + 1) {
6847 n = fgetxattr(fd, name, v, l);
6849 if (n >= 0 && (size_t) n < l) {
6856 if (n < 0 && errno != ERANGE)
6859 n = fgetxattr(fd, name, NULL, 0);