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 int running_in_chroot(void) {
2574 ret = files_same("/proc/1/root", "/");
2581 static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
2586 assert(percent <= 100);
2587 assert(new_length >= 3);
2589 if (old_length <= 3 || old_length <= new_length)
2590 return strndup(s, old_length);
2592 r = new0(char, new_length+1);
2596 x = (new_length * percent) / 100;
2598 if (x > new_length - 3)
2606 s + old_length - (new_length - x - 3),
2607 new_length - x - 3);
2612 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
2616 unsigned k, len, len2;
2619 assert(percent <= 100);
2620 assert(new_length >= 3);
2622 /* if no multibyte characters use ascii_ellipsize_mem for speed */
2623 if (ascii_is_valid(s))
2624 return ascii_ellipsize_mem(s, old_length, new_length, percent);
2626 if (old_length <= 3 || old_length <= new_length)
2627 return strndup(s, old_length);
2629 x = (new_length * percent) / 100;
2631 if (x > new_length - 3)
2635 for (i = s; k < x && i < s + old_length; i = utf8_next_char(i)) {
2638 c = utf8_encoded_to_unichar(i);
2641 k += unichar_iswide(c) ? 2 : 1;
2644 if (k > x) /* last character was wide and went over quota */
2647 for (j = s + old_length; k < new_length && j > i; ) {
2650 j = utf8_prev_char(j);
2651 c = utf8_encoded_to_unichar(j);
2654 k += unichar_iswide(c) ? 2 : 1;
2658 /* we don't actually need to ellipsize */
2660 return memdup(s, old_length + 1);
2662 /* make space for ellipsis */
2663 j = utf8_next_char(j);
2666 len2 = s + old_length - j;
2667 e = new(char, len + 3 + len2 + 1);
2672 printf("old_length=%zu new_length=%zu x=%zu len=%u len2=%u k=%u\n",
2673 old_length, new_length, x, len, len2, k);
2677 e[len] = 0xe2; /* tri-dot ellipsis: … */
2681 memcpy(e + len + 3, j, len2 + 1);
2686 char *ellipsize(const char *s, size_t length, unsigned percent) {
2687 return ellipsize_mem(s, strlen(s), length, percent);
2690 int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
2691 _cleanup_close_ int fd;
2697 mkdir_parents(path, 0755);
2699 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode > 0 ? mode : 0644);
2704 r = fchmod(fd, mode);
2709 if (uid != UID_INVALID || gid != GID_INVALID) {
2710 r = fchown(fd, uid, gid);
2715 if (stamp != USEC_INFINITY) {
2716 struct timespec ts[2];
2718 timespec_store(&ts[0], stamp);
2720 r = futimens(fd, ts);
2722 r = futimens(fd, NULL);
2729 int touch(const char *path) {
2730 return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, 0);
2733 /// UNNEEDED by elogind
2735 static char *unquote(const char *s, const char* quotes) {
2739 /* This is rather stupid, simply removes the heading and
2740 * trailing quotes if there is one. Doesn't care about
2741 * escaping or anything.
2743 * DON'T USE THIS FOR NEW CODE ANYMORE!*/
2749 if (strchr(quotes, s[0]) && s[l-1] == s[0])
2750 return strndup(s+1, l-2);
2756 noreturn void freeze(void) {
2758 /* Make sure nobody waits for us on a socket anymore */
2759 close_all_fds(NULL, 0);
2767 bool null_or_empty(struct stat *st) {
2770 if (S_ISREG(st->st_mode) && st->st_size <= 0)
2773 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
2779 int null_or_empty_path(const char *fn) {
2784 if (stat(fn, &st) < 0)
2787 return null_or_empty(&st);
2790 /// UNNEEDED by elogind
2792 int null_or_empty_fd(int fd) {
2797 if (fstat(fd, &st) < 0)
2800 return null_or_empty(&st);
2804 DIR *xopendirat(int fd, const char *name, int flags) {
2808 assert(!(flags & O_CREAT));
2810 nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
2823 /// UNNEEDED by elogind
2825 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
2826 _cleanup_free_ char *t = NULL, *u = NULL;
2829 u = unquote(tagvalue, QUOTES);
2833 enc_len = strlen(u) * 4 + 1;
2834 t = new(char, enc_len);
2838 if (encode_devnode_name(u, t, enc_len) < 0)
2841 return strjoin("/dev/disk/by-", by, "/", t, NULL);
2844 char *fstab_node_to_udev_node(const char *p) {
2847 if (startswith(p, "LABEL="))
2848 return tag_to_udev_node(p+6, "label");
2850 if (startswith(p, "UUID="))
2851 return tag_to_udev_node(p+5, "uuid");
2853 if (startswith(p, "PARTUUID="))
2854 return tag_to_udev_node(p+9, "partuuid");
2856 if (startswith(p, "PARTLABEL="))
2857 return tag_to_udev_node(p+10, "partlabel");
2863 bool dirent_is_file(const struct dirent *de) {
2866 if (hidden_file(de->d_name))
2869 if (de->d_type != DT_REG &&
2870 de->d_type != DT_LNK &&
2871 de->d_type != DT_UNKNOWN)
2877 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
2880 if (de->d_type != DT_REG &&
2881 de->d_type != DT_LNK &&
2882 de->d_type != DT_UNKNOWN)
2885 if (hidden_file_allow_backup(de->d_name))
2888 return endswith(de->d_name, suffix);
2891 static int do_execute(char **directories, usec_t timeout, char *argv[]) {
2892 _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
2893 _cleanup_set_free_free_ Set *seen = NULL;
2896 /* We fork this all off from a child process so that we can
2897 * somewhat cleanly make use of SIGALRM to set a time limit */
2899 (void) reset_all_signal_handlers();
2900 (void) reset_signal_mask();
2902 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
2904 pids = hashmap_new(NULL);
2908 seen = set_new(&string_hash_ops);
2912 STRV_FOREACH(directory, directories) {
2913 _cleanup_closedir_ DIR *d;
2916 d = opendir(*directory);
2918 if (errno == ENOENT)
2921 return log_error_errno(errno, "Failed to open directory %s: %m", *directory);
2924 FOREACH_DIRENT(de, d, break) {
2925 _cleanup_free_ char *path = NULL;
2929 if (!dirent_is_file(de))
2932 if (set_contains(seen, de->d_name)) {
2933 log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name);
2937 r = set_put_strdup(seen, de->d_name);
2941 path = strjoin(*directory, "/", de->d_name, NULL);
2945 if (null_or_empty_path(path)) {
2946 log_debug("%s is empty (a mask).", path);
2952 log_error_errno(errno, "Failed to fork: %m");
2954 } else if (pid == 0) {
2957 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
2967 return log_error_errno(errno, "Failed to execute %s: %m", path);
2970 log_debug("Spawned %s as " PID_FMT ".", path, pid);
2972 r = hashmap_put(pids, UINT_TO_PTR(pid), path);
2979 /* Abort execution of this process after the timout. We simply
2980 * rely on SIGALRM as default action terminating the process,
2981 * and turn on alarm(). */
2983 if (timeout != USEC_INFINITY)
2984 alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
2986 while (!hashmap_isempty(pids)) {
2987 _cleanup_free_ char *path = NULL;
2990 pid = PTR_TO_UINT(hashmap_first_key(pids));
2993 path = hashmap_remove(pids, UINT_TO_PTR(pid));
2996 wait_for_terminate_and_warn(path, pid, true);
3002 void execute_directories(const char* const* directories, usec_t timeout, char *argv[]) {
3006 char **dirs = (char**) directories;
3008 assert(!strv_isempty(dirs));
3010 name = basename(dirs[0]);
3011 assert(!isempty(name));
3013 /* Executes all binaries in the directories in parallel and waits
3014 * for them to finish. Optionally a timeout is applied. If a file
3015 * with the same name exists in more than one directory, the
3016 * earliest one wins. */
3018 executor_pid = fork();
3019 if (executor_pid < 0) {
3020 log_error_errno(errno, "Failed to fork: %m");
3023 } else if (executor_pid == 0) {
3024 r = do_execute(dirs, timeout, argv);
3025 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
3028 wait_for_terminate_and_warn(name, executor_pid, true);
3031 bool nulstr_contains(const char*nulstr, const char *needle) {
3037 NULSTR_FOREACH(i, nulstr)
3038 if (streq(i, needle))
3044 /// UNNEEDED by elogind
3046 bool plymouth_running(void) {
3047 return access("/run/plymouth/pid", F_OK) >= 0;
3051 char* strshorten(char *s, size_t l) {
3060 int pipe_eof(int fd) {
3061 struct pollfd pollfd = {
3063 .events = POLLIN|POLLHUP,
3068 r = poll(&pollfd, 1, 0);
3075 return pollfd.revents & POLLHUP;
3078 int fd_wait_for_event(int fd, int event, usec_t t) {
3080 struct pollfd pollfd = {
3088 r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
3095 return pollfd.revents;
3098 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
3107 r = tempfn_xxxxxx(path, NULL, &t);
3111 fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC);
3117 f = fdopen(fd, "we");
3131 /// UNNEEDED by elogind
3133 int symlink_atomic(const char *from, const char *to) {
3134 _cleanup_free_ char *t = NULL;
3140 r = tempfn_random(to, NULL, &t);
3144 if (symlink(from, t) < 0)
3147 if (rename(t, to) < 0) {
3155 int symlink_idempotent(const char *from, const char *to) {
3156 _cleanup_free_ char *p = NULL;
3162 if (symlink(from, to) < 0) {
3163 if (errno != EEXIST)
3166 r = readlink_malloc(to, &p);
3170 if (!streq(p, from))
3177 int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
3178 _cleanup_free_ char *t = NULL;
3183 r = tempfn_random(path, NULL, &t);
3187 if (mknod(t, mode, dev) < 0)
3190 if (rename(t, path) < 0) {
3198 int mkfifo_atomic(const char *path, mode_t mode) {
3199 _cleanup_free_ char *t = NULL;
3204 r = tempfn_random(path, NULL, &t);
3208 if (mkfifo(t, mode) < 0)
3211 if (rename(t, path) < 0) {
3220 bool display_is_local(const char *display) {
3224 display[0] == ':' &&
3225 display[1] >= '0' &&
3229 int socket_from_display(const char *display, char **path) {
3236 if (!display_is_local(display))
3239 k = strspn(display+1, "0123456789");
3241 f = new(char, strlen("/tmp/.X11-unix/X") + k + 1);
3245 c = stpcpy(f, "/tmp/.X11-unix/X");
3246 memcpy(c, display+1, k);
3255 const char **username,
3256 uid_t *uid, gid_t *gid,
3258 const char **shell) {
3266 /* We enforce some special rules for uid=0: in order to avoid
3267 * NSS lookups for root we hardcode its data. */
3269 if (streq(*username, "root") || streq(*username, "0")) {
3287 if (parse_uid(*username, &u) >= 0) {
3291 /* If there are multiple users with the same id, make
3292 * sure to leave $USER to the configured value instead
3293 * of the first occurrence in the database. However if
3294 * the uid was configured by a numeric uid, then let's
3295 * pick the real username from /etc/passwd. */
3297 *username = p->pw_name;
3300 p = getpwnam(*username);
3304 return errno > 0 ? -errno : -ESRCH;
3316 *shell = p->pw_shell;
3321 char* uid_to_name(uid_t uid) {
3326 return strdup("root");
3330 return strdup(p->pw_name);
3332 if (asprintf(&r, UID_FMT, uid) < 0)
3338 char* gid_to_name(gid_t gid) {
3343 return strdup("root");
3347 return strdup(p->gr_name);
3349 if (asprintf(&r, GID_FMT, gid) < 0)
3355 int get_group_creds(const char **groupname, gid_t *gid) {
3361 /* We enforce some special rules for gid=0: in order to avoid
3362 * NSS lookups for root we hardcode its data. */
3364 if (streq(*groupname, "root") || streq(*groupname, "0")) {
3365 *groupname = "root";
3373 if (parse_gid(*groupname, &id) >= 0) {
3378 *groupname = g->gr_name;
3381 g = getgrnam(*groupname);
3385 return errno > 0 ? -errno : -ESRCH;
3393 int in_gid(gid_t gid) {
3395 int ngroups_max, r, i;
3397 if (getgid() == gid)
3400 if (getegid() == gid)
3403 ngroups_max = sysconf(_SC_NGROUPS_MAX);
3404 assert(ngroups_max > 0);
3406 gids = alloca(sizeof(gid_t) * ngroups_max);
3408 r = getgroups(ngroups_max, gids);
3412 for (i = 0; i < r; i++)
3419 /// UNNEEDED by elogind
3421 int in_group(const char *name) {
3425 r = get_group_creds(&name, &gid);
3432 int glob_exists(const char *path) {
3433 _cleanup_globfree_ glob_t g = {};
3439 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
3441 if (k == GLOB_NOMATCH)
3443 else if (k == GLOB_NOSPACE)
3446 return !strv_isempty(g.gl_pathv);
3448 return errno ? -errno : -EIO;
3451 int glob_extend(char ***strv, const char *path) {
3452 _cleanup_globfree_ glob_t g = {};
3457 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
3459 if (k == GLOB_NOMATCH)
3461 else if (k == GLOB_NOSPACE)
3463 else if (k != 0 || strv_isempty(g.gl_pathv))
3464 return errno ? -errno : -EIO;
3466 STRV_FOREACH(p, g.gl_pathv) {
3467 k = strv_extend(strv, *p);
3476 int dirent_ensure_type(DIR *d, struct dirent *de) {
3482 if (de->d_type != DT_UNKNOWN)
3485 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
3489 S_ISREG(st.st_mode) ? DT_REG :
3490 S_ISDIR(st.st_mode) ? DT_DIR :
3491 S_ISLNK(st.st_mode) ? DT_LNK :
3492 S_ISFIFO(st.st_mode) ? DT_FIFO :
3493 S_ISSOCK(st.st_mode) ? DT_SOCK :
3494 S_ISCHR(st.st_mode) ? DT_CHR :
3495 S_ISBLK(st.st_mode) ? DT_BLK :
3501 int get_files_in_directory(const char *path, char ***list) {
3502 _cleanup_closedir_ DIR *d = NULL;
3503 size_t bufsize = 0, n = 0;
3504 _cleanup_strv_free_ char **l = NULL;
3508 /* Returns all files in a directory in *list, and the number
3509 * of files as return value. If list is NULL returns only the
3521 if (!de && errno != 0)
3526 dirent_ensure_type(d, de);
3528 if (!dirent_is_file(de))
3532 /* one extra slot is needed for the terminating NULL */
3533 if (!GREEDY_REALLOC(l, bufsize, n + 2))
3536 l[n] = strdup(de->d_name);
3547 l = NULL; /* avoid freeing */
3553 char *strjoin(const char *x, ...) {
3567 t = va_arg(ap, const char *);
3572 if (n > ((size_t) -1) - l) {
3596 t = va_arg(ap, const char *);
3610 bool is_main_thread(void) {
3611 static thread_local int cached = 0;
3613 if (_unlikely_(cached == 0))
3614 cached = getpid() == gettid() ? 1 : -1;
3619 /// UNNEEDED by elogind
3621 int block_get_whole_disk(dev_t d, dev_t *ret) {
3628 /* If it has a queue this is good enough for us */
3629 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
3632 r = access(p, F_OK);
3640 /* If it is a partition find the originating device */
3641 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
3644 r = access(p, F_OK);
3650 /* Get parent dev_t */
3651 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
3654 r = read_one_line_file(p, &s);
3660 r = sscanf(s, "%u:%u", &m, &n);
3666 /* Only return this if it is really good enough for us. */
3667 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
3670 r = access(p, F_OK);
3674 *ret = makedev(m, n);
3682 static const char *const ioprio_class_table[] = {
3683 [IOPRIO_CLASS_NONE] = "none",
3684 [IOPRIO_CLASS_RT] = "realtime",
3685 [IOPRIO_CLASS_BE] = "best-effort",
3686 [IOPRIO_CLASS_IDLE] = "idle"
3689 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
3691 static const char *const sigchld_code_table[] = {
3692 [CLD_EXITED] = "exited",
3693 [CLD_KILLED] = "killed",
3694 [CLD_DUMPED] = "dumped",
3695 [CLD_TRAPPED] = "trapped",
3696 [CLD_STOPPED] = "stopped",
3697 [CLD_CONTINUED] = "continued",
3700 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
3702 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
3703 [LOG_FAC(LOG_KERN)] = "kern",
3704 [LOG_FAC(LOG_USER)] = "user",
3705 [LOG_FAC(LOG_MAIL)] = "mail",
3706 [LOG_FAC(LOG_DAEMON)] = "daemon",
3707 [LOG_FAC(LOG_AUTH)] = "auth",
3708 [LOG_FAC(LOG_SYSLOG)] = "syslog",
3709 [LOG_FAC(LOG_LPR)] = "lpr",
3710 [LOG_FAC(LOG_NEWS)] = "news",
3711 [LOG_FAC(LOG_UUCP)] = "uucp",
3712 [LOG_FAC(LOG_CRON)] = "cron",
3713 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
3714 [LOG_FAC(LOG_FTP)] = "ftp",
3715 [LOG_FAC(LOG_LOCAL0)] = "local0",
3716 [LOG_FAC(LOG_LOCAL1)] = "local1",
3717 [LOG_FAC(LOG_LOCAL2)] = "local2",
3718 [LOG_FAC(LOG_LOCAL3)] = "local3",
3719 [LOG_FAC(LOG_LOCAL4)] = "local4",
3720 [LOG_FAC(LOG_LOCAL5)] = "local5",
3721 [LOG_FAC(LOG_LOCAL6)] = "local6",
3722 [LOG_FAC(LOG_LOCAL7)] = "local7"
3725 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
3727 static const char *const log_level_table[] = {
3728 [LOG_EMERG] = "emerg",
3729 [LOG_ALERT] = "alert",
3730 [LOG_CRIT] = "crit",
3732 [LOG_WARNING] = "warning",
3733 [LOG_NOTICE] = "notice",
3734 [LOG_INFO] = "info",
3735 [LOG_DEBUG] = "debug"
3738 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
3740 static const char* const sched_policy_table[] = {
3741 [SCHED_OTHER] = "other",
3742 [SCHED_BATCH] = "batch",
3743 [SCHED_IDLE] = "idle",
3744 [SCHED_FIFO] = "fifo",
3748 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
3750 static const char* const rlimit_table[_RLIMIT_MAX] = {
3751 [RLIMIT_CPU] = "LimitCPU",
3752 [RLIMIT_FSIZE] = "LimitFSIZE",
3753 [RLIMIT_DATA] = "LimitDATA",
3754 [RLIMIT_STACK] = "LimitSTACK",
3755 [RLIMIT_CORE] = "LimitCORE",
3756 [RLIMIT_RSS] = "LimitRSS",
3757 [RLIMIT_NOFILE] = "LimitNOFILE",
3758 [RLIMIT_AS] = "LimitAS",
3759 [RLIMIT_NPROC] = "LimitNPROC",
3760 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
3761 [RLIMIT_LOCKS] = "LimitLOCKS",
3762 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
3763 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
3764 [RLIMIT_NICE] = "LimitNICE",
3765 [RLIMIT_RTPRIO] = "LimitRTPRIO",
3766 [RLIMIT_RTTIME] = "LimitRTTIME"
3769 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
3771 static const char* const ip_tos_table[] = {
3772 [IPTOS_LOWDELAY] = "low-delay",
3773 [IPTOS_THROUGHPUT] = "throughput",
3774 [IPTOS_RELIABILITY] = "reliability",
3775 [IPTOS_LOWCOST] = "low-cost",
3778 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
3780 bool kexec_loaded(void) {
3781 bool loaded = false;
3784 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
3792 /// UNNEEDED by elogind
3794 int prot_from_flags(int flags) {
3796 switch (flags & O_ACCMODE) {
3805 return PROT_READ|PROT_WRITE;
3812 char *format_bytes(char *buf, size_t l, off_t t) {
3815 static const struct {
3819 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
3820 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
3821 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
3822 { "G", 1024ULL*1024ULL*1024ULL },
3823 { "M", 1024ULL*1024ULL },
3827 if (t == (off_t) -1)
3830 for (i = 0; i < ELEMENTSOF(table); i++) {
3832 if (t >= table[i].factor) {
3835 (unsigned long long) (t / table[i].factor),
3836 (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
3843 snprintf(buf, l, "%lluB", (unsigned long long) t);
3852 void* memdup(const void *p, size_t l) {
3865 int fd_inc_sndbuf(int fd, size_t n) {
3867 socklen_t l = sizeof(value);
3869 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
3870 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
3873 /* If we have the privileges we will ignore the kernel limit. */
3876 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
3877 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
3883 int fd_inc_rcvbuf(int fd, size_t n) {
3885 socklen_t l = sizeof(value);
3887 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
3888 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
3891 /* If we have the privileges we will ignore the kernel limit. */
3894 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
3895 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
3900 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
3901 bool stdout_is_tty, stderr_is_tty;
3902 pid_t parent_pid, agent_pid;
3903 sigset_t ss, saved_ss;
3911 /* Spawns a temporary TTY agent, making sure it goes away when
3914 parent_pid = getpid();
3916 /* First we temporarily block all signals, so that the new
3917 * child has them blocked initially. This way, we can be sure
3918 * that SIGTERMs are not lost we might send to the agent. */
3919 assert_se(sigfillset(&ss) >= 0);
3920 assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0);
3923 if (agent_pid < 0) {
3924 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
3928 if (agent_pid != 0) {
3929 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
3936 * Make sure the agent goes away when the parent dies */
3937 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
3938 _exit(EXIT_FAILURE);
3940 /* Make sure we actually can kill the agent, if we need to, in
3941 * case somebody invoked us from a shell script that trapped
3942 * SIGTERM or so... */
3943 (void) reset_all_signal_handlers();
3944 (void) reset_signal_mask();
3946 /* Check whether our parent died before we were able
3947 * to set the death signal and unblock the signals */
3948 if (getppid() != parent_pid)
3949 _exit(EXIT_SUCCESS);
3951 /* Don't leak fds to the agent */
3952 close_all_fds(except, n_except);
3954 stdout_is_tty = isatty(STDOUT_FILENO);
3955 stderr_is_tty = isatty(STDERR_FILENO);
3957 if (!stdout_is_tty || !stderr_is_tty) {
3960 /* Detach from stdout/stderr. and reopen
3961 * /dev/tty for them. This is important to
3962 * ensure that when systemctl is started via
3963 * popen() or a similar call that expects to
3964 * read EOF we actually do generate EOF and
3965 * not delay this indefinitely by because we
3966 * keep an unused copy of stdin around. */
3967 fd = open("/dev/tty", O_WRONLY);
3969 log_error_errno(errno, "Failed to open /dev/tty: %m");
3970 _exit(EXIT_FAILURE);
3974 dup2(fd, STDOUT_FILENO);
3977 dup2(fd, STDERR_FILENO);
3983 /* Count arguments */
3985 for (n = 0; va_arg(ap, char*); n++)
3990 l = alloca(sizeof(char *) * (n + 1));
3992 /* Fill in arguments */
3994 for (i = 0; i <= n; i++)
3995 l[i] = va_arg(ap, char*);
3999 _exit(EXIT_FAILURE);
4002 /// UNNEEDED by elogind
4004 int setrlimit_closest(int resource, const struct rlimit *rlim) {
4005 struct rlimit highest, fixed;
4009 if (setrlimit(resource, rlim) >= 0)
4015 /* So we failed to set the desired setrlimit, then let's try
4016 * to get as close as we can */
4017 assert_se(getrlimit(resource, &highest) == 0);
4019 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
4020 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
4022 if (setrlimit(resource, &fixed) < 0)
4028 bool http_etag_is_valid(const char *etag) {
4032 if (!endswith(etag, "\""))
4035 if (!startswith(etag, "\"") && !startswith(etag, "W/\""))
4042 bool http_url_is_valid(const char *url) {
4048 p = startswith(url, "http://");
4050 p = startswith(url, "https://");
4057 return ascii_is_valid(p);
4060 bool documentation_url_is_valid(const char *url) {
4066 if (http_url_is_valid(url))
4069 p = startswith(url, "file:/");
4071 p = startswith(url, "info:");
4073 p = startswith(url, "man:");
4078 return ascii_is_valid(p);
4081 bool in_initrd(void) {
4082 static int saved = -1;
4088 /* We make two checks here:
4090 * 1. the flag file /etc/initrd-release must exist
4091 * 2. the root file system must be a memory file system
4093 * The second check is extra paranoia, since misdetecting an
4094 * initrd can have bad bad consequences due the initrd
4095 * emptying when transititioning to the main systemd.
4098 saved = access("/etc/initrd-release", F_OK) >= 0 &&
4099 statfs("/", &s) >= 0 &&
4100 is_temporary_fs(&s);
4105 int get_home_dir(char **_h) {
4113 /* Take the user specified one */
4114 e = secure_getenv("HOME");
4115 if (e && path_is_absolute(e)) {
4124 /* Hardcode home directory for root to avoid NSS */
4127 h = strdup("/root");
4135 /* Check the database... */
4139 return errno > 0 ? -errno : -ESRCH;
4141 if (!path_is_absolute(p->pw_dir))
4144 h = strdup(p->pw_dir);
4152 /// UNNEEDED by elogind
4154 int get_shell(char **_s) {
4162 /* Take the user specified one */
4163 e = getenv("SHELL");
4173 /* Hardcode home directory for root to avoid NSS */
4176 s = strdup("/bin/sh");
4184 /* Check the database... */
4188 return errno > 0 ? -errno : -ESRCH;
4190 if (!path_is_absolute(p->pw_shell))
4193 s = strdup(p->pw_shell);
4202 bool filename_is_valid(const char *p) {
4216 if (strlen(p) > FILENAME_MAX)
4222 bool string_is_safe(const char *p) {
4228 for (t = p; *t; t++) {
4229 if (*t > 0 && *t < ' ')
4232 if (strchr("\\\"\'\x7f", *t))
4240 * Check if a string contains control characters. If 'ok' is non-NULL
4241 * it may be a string containing additional CCs to be considered OK.
4243 bool string_has_cc(const char *p, const char *ok) {
4248 for (t = p; *t; t++) {
4249 if (ok && strchr(ok, *t))
4252 if (*t > 0 && *t < ' ')
4262 bool path_is_safe(const char *p) {
4267 if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
4270 if (strlen(p)+1 > PATH_MAX)
4273 /* The following two checks are not really dangerous, but hey, they still are confusing */
4274 if (streq(p, ".") || startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
4277 if (strstr(p, "//"))
4283 /// UNNEEDED by elogind
4285 /* hey glibc, APIs with callbacks without a user pointer are so useless */
4286 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
4287 int (*compar) (const void *, const void *, void *), void *arg) {
4296 p = (void *)(((const char *) base) + (idx * size));
4297 comparison = compar(key, p, arg);
4300 else if (comparison > 0)
4308 void init_gettext(void) {
4309 setlocale(LC_ALL, "");
4310 textdomain(GETTEXT_PACKAGE);
4314 bool is_locale_utf8(void) {
4316 static int cached_answer = -1;
4318 if (cached_answer >= 0)
4321 if (!setlocale(LC_ALL, "")) {
4322 cached_answer = true;
4326 set = nl_langinfo(CODESET);
4328 cached_answer = true;
4332 if (streq(set, "UTF-8")) {
4333 cached_answer = true;
4337 /* For LC_CTYPE=="C" return true, because CTYPE is effectly
4338 * unset and everything can do to UTF-8 nowadays. */
4339 set = setlocale(LC_CTYPE, NULL);
4341 cached_answer = true;
4345 /* Check result, but ignore the result if C was set
4348 STR_IN_SET(set, "C", "POSIX") &&
4349 !getenv("LC_ALL") &&
4350 !getenv("LC_CTYPE") &&
4354 return (bool) cached_answer;
4357 const char *draw_special_char(DrawSpecialChar ch) {
4358 static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
4361 [DRAW_TREE_VERTICAL] = "\342\224\202 ", /* │ */
4362 [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */
4363 [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */
4364 [DRAW_TREE_SPACE] = " ", /* */
4365 [DRAW_TRIANGULAR_BULLET] = "\342\200\243", /* ‣ */
4366 [DRAW_BLACK_CIRCLE] = "\342\227\217", /* ● */
4367 [DRAW_ARROW] = "\342\206\222", /* → */
4368 [DRAW_DASH] = "\342\200\223", /* – */
4371 /* ASCII fallback */ {
4372 [DRAW_TREE_VERTICAL] = "| ",
4373 [DRAW_TREE_BRANCH] = "|-",
4374 [DRAW_TREE_RIGHT] = "`-",
4375 [DRAW_TREE_SPACE] = " ",
4376 [DRAW_TRIANGULAR_BULLET] = ">",
4377 [DRAW_BLACK_CIRCLE] = "*",
4378 [DRAW_ARROW] = "->",
4383 return draw_table[!is_locale_utf8()][ch];
4386 /// UNNEEDED by elogind
4388 char *strreplace(const char *text, const char *old_string, const char *new_string) {
4391 size_t l, old_len, new_len;
4397 old_len = strlen(old_string);
4398 new_len = strlen(new_string);
4411 if (!startswith(f, old_string)) {
4417 nl = l - old_len + new_len;
4418 a = realloc(r, nl + 1);
4426 t = stpcpy(t, new_string);
4438 char *strip_tab_ansi(char **ibuf, size_t *_isz) {
4439 const char *i, *begin = NULL;
4444 } state = STATE_OTHER;
4446 size_t osz = 0, isz;
4452 /* Strips ANSI color and replaces TABs by 8 spaces */
4454 isz = _isz ? *_isz : strlen(*ibuf);
4456 f = open_memstream(&obuf, &osz);
4460 for (i = *ibuf; i < *ibuf + isz + 1; i++) {
4465 if (i >= *ibuf + isz) /* EOT */
4467 else if (*i == '\x1B')
4468 state = STATE_ESCAPE;
4469 else if (*i == '\t')
4476 if (i >= *ibuf + isz) { /* EOT */
4479 } else if (*i == '[') {
4480 state = STATE_BRACKET;
4485 state = STATE_OTHER;
4492 if (i >= *ibuf + isz || /* EOT */
4493 (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
4496 state = STATE_OTHER;
4498 } else if (*i == 'm')
4499 state = STATE_OTHER;
4521 int on_ac_power(void) {
4522 bool found_offline = false, found_online = false;
4523 _cleanup_closedir_ DIR *d = NULL;
4525 d = opendir("/sys/class/power_supply");
4527 return errno == ENOENT ? true : -errno;
4531 _cleanup_close_ int fd = -1, device = -1;
4537 if (!de && errno != 0)
4543 if (hidden_file(de->d_name))
4546 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
4548 if (errno == ENOENT || errno == ENOTDIR)
4554 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
4556 if (errno == ENOENT)
4562 n = read(fd, contents, sizeof(contents));
4566 if (n != 6 || memcmp(contents, "Mains\n", 6))
4570 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
4572 if (errno == ENOENT)
4578 n = read(fd, contents, sizeof(contents));
4582 if (n != 2 || contents[1] != '\n')
4585 if (contents[0] == '1') {
4586 found_online = true;
4588 } else if (contents[0] == '0')
4589 found_offline = true;
4594 return found_online || !found_offline;
4598 static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
4605 if (!path_strv_resolve_uniq(search, root))
4608 STRV_FOREACH(i, search) {
4609 _cleanup_free_ char *p = NULL;
4613 p = strjoin(root, *i, "/", path, NULL);
4615 p = strjoin(*i, "/", path, NULL);
4625 if (errno != ENOENT)
4632 int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
4633 _cleanup_strv_free_ char **copy = NULL;
4639 if (path_is_absolute(path)) {
4642 f = fopen(path, mode);
4651 copy = strv_copy((char**) search);
4655 return search_and_fopen_internal(path, mode, root, copy, _f);
4658 /// UNNEEDED by elogind
4660 int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
4661 _cleanup_strv_free_ char **s = NULL;
4663 if (path_is_absolute(path)) {
4666 f = fopen(path, mode);
4675 s = strv_split_nulstr(search);
4679 return search_and_fopen_internal(path, mode, root, s, _f);
4683 char *strextend(char **x, ...) {
4690 l = f = *x ? strlen(*x) : 0;
4697 t = va_arg(ap, const char *);
4702 if (n > ((size_t) -1) - l) {
4711 r = realloc(*x, l+1);
4721 t = va_arg(ap, const char *);
4735 char *strrep(const char *s, unsigned n) {
4743 p = r = malloc(l * n + 1);
4747 for (i = 0; i < n; i++)
4754 void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
4761 if (*allocated >= need)
4764 newalloc = MAX(need * 2, 64u / size);
4765 a = newalloc * size;
4767 /* check for overflows */
4768 if (a < size * need)
4776 *allocated = newalloc;
4780 void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
4789 q = greedy_realloc(p, allocated, need, size);
4793 if (*allocated > prev)
4794 memzero(q + prev * size, (*allocated - prev) * size);
4799 bool id128_is_valid(const char *s) {
4805 /* Simple formatted 128bit hex string */
4807 for (i = 0; i < l; i++) {
4810 if (!(c >= '0' && c <= '9') &&
4811 !(c >= 'a' && c <= 'z') &&
4812 !(c >= 'A' && c <= 'Z'))
4816 } else if (l == 36) {
4818 /* Formatted UUID */
4820 for (i = 0; i < l; i++) {
4823 if ((i == 8 || i == 13 || i == 18 || i == 23)) {
4827 if (!(c >= '0' && c <= '9') &&
4828 !(c >= 'a' && c <= 'z') &&
4829 !(c >= 'A' && c <= 'Z'))
4840 /// UNNEEDED by elogind
4842 int split_pair(const char *s, const char *sep, char **l, char **r) {
4857 a = strndup(s, x - s);
4861 b = strdup(x + strlen(sep));
4873 int shall_restore_state(void) {
4874 _cleanup_free_ char *value = NULL;
4877 r = get_proc_cmdline_key("systemd.restore_state=", &value);
4883 return parse_boolean(value) != 0;
4887 int proc_cmdline(char **ret) {
4890 if (detect_container(NULL) > 0)
4891 return get_process_cmdline(1, 0, false, ret);
4893 return read_one_line_file("/proc/cmdline", ret);
4896 int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
4897 _cleanup_free_ char *line = NULL;
4903 r = proc_cmdline(&line);
4909 _cleanup_free_ char *word = NULL;
4912 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
4918 /* Filter out arguments that are intended only for the
4920 if (!in_initrd() && startswith(word, "rd."))
4923 value = strchr(word, '=');
4927 r = parse_item(word, value);
4935 int get_proc_cmdline_key(const char *key, char **value) {
4936 _cleanup_free_ char *line = NULL, *ret = NULL;
4943 r = proc_cmdline(&line);
4949 _cleanup_free_ char *word = NULL;
4952 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
4958 /* Filter out arguments that are intended only for the
4960 if (!in_initrd() && startswith(word, "rd."))
4964 e = startswith(word, key);
4968 r = free_and_strdup(&ret, e);
4974 if (streq(word, key))
4988 int container_get_leader(const char *machine, pid_t *pid) {
4989 _cleanup_free_ char *s = NULL, *class = NULL;
4997 if (!machine_name_is_valid(machine))
5000 p = strjoina("/run/systemd/machines/", machine);
5001 r = parse_env_file(p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
5009 if (!streq_ptr(class, "container"))
5012 r = parse_pid(s, &leader);
5022 int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd) {
5023 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, netnsfd = -1, usernsfd = -1;
5031 mntns = procfs_file_alloca(pid, "ns/mnt");
5032 mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5040 pidns = procfs_file_alloca(pid, "ns/pid");
5041 pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5049 netns = procfs_file_alloca(pid, "ns/net");
5050 netnsfd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5058 userns = procfs_file_alloca(pid, "ns/user");
5059 usernsfd = open(userns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5060 if (usernsfd < 0 && errno != ENOENT)
5067 root = procfs_file_alloca(pid, "root");
5068 rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
5074 *pidns_fd = pidnsfd;
5077 *mntns_fd = mntnsfd;
5080 *netns_fd = netnsfd;
5083 *userns_fd = usernsfd;
5088 pidnsfd = mntnsfd = netnsfd = usernsfd = -1;
5093 int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd) {
5094 if (userns_fd >= 0) {
5095 /* Can't setns to your own userns, since then you could
5096 * escalate from non-root to root in your own namespace, so
5097 * check if namespaces equal before attempting to enter. */
5098 _cleanup_free_ char *userns_fd_path = NULL;
5100 if (asprintf(&userns_fd_path, "/proc/self/fd/%d", userns_fd) < 0)
5103 r = files_same(userns_fd_path, "/proc/self/ns/user");
5111 if (setns(pidns_fd, CLONE_NEWPID) < 0)
5115 if (setns(mntns_fd, CLONE_NEWNS) < 0)
5119 if (setns(netns_fd, CLONE_NEWNET) < 0)
5123 if (setns(userns_fd, CLONE_NEWUSER) < 0)
5127 if (fchdir(root_fd) < 0)
5130 if (chroot(".") < 0)
5134 return reset_uid_gid();
5137 int getpeercred(int fd, struct ucred *ucred) {
5138 socklen_t n = sizeof(struct ucred);
5145 r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
5149 if (n != sizeof(struct ucred))
5152 /* Check if the data is actually useful and not suppressed due
5153 * to namespacing issues */
5156 if (u.uid == UID_INVALID)
5158 if (u.gid == GID_INVALID)
5165 int getpeersec(int fd, char **ret) {
5177 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
5181 if (errno != ERANGE)
5188 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
5204 /* This is much like like mkostemp() but is subject to umask(). */
5205 int mkostemp_safe(char *pattern, int flags) {
5206 _cleanup_umask_ mode_t u;
5213 fd = mkostemp(pattern, flags);
5220 /// UNNEEDED by elogind
5222 int open_tmpfile(const char *path, int flags) {
5229 /* Try O_TMPFILE first, if it is supported */
5230 fd = open(path, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
5235 /* Fall back to unguessable name + unlinking */
5236 p = strjoina(path, "/systemd-tmp-XXXXXX");
5238 fd = mkostemp_safe(p, flags);
5247 int fd_warn_permissions(const char *path, int fd) {
5250 if (fstat(fd, &st) < 0)
5253 if (st.st_mode & 0111)
5254 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
5256 if (st.st_mode & 0002)
5257 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
5259 if (getpid() == 1 && (st.st_mode & 0044) != 0044)
5260 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);
5265 /// UNNEEDED by elogind
5267 unsigned long personality_from_string(const char *p) {
5269 /* Parse a personality specifier. We introduce our own
5270 * identifiers that indicate specific ABIs, rather than just
5271 * hints regarding the register size, since we want to keep
5272 * things open for multiple locally supported ABIs for the
5273 * same register size. We try to reuse the ABI identifiers
5274 * used by libseccomp. */
5276 #if defined(__x86_64__)
5278 if (streq(p, "x86"))
5281 if (streq(p, "x86-64"))
5284 #elif defined(__i386__)
5286 if (streq(p, "x86"))
5290 return PERSONALITY_INVALID;
5293 const char* personality_to_string(unsigned long p) {
5295 #if defined(__x86_64__)
5297 if (p == PER_LINUX32)
5303 #elif defined(__i386__)
5313 uint64_t physical_memory(void) {
5316 /* We return this as uint64_t in case we are running as 32bit
5317 * process on a 64bit kernel with huge amounts of memory */
5319 mem = sysconf(_SC_PHYS_PAGES);
5322 return (uint64_t) mem * (uint64_t) page_size();
5325 /// UNNEEDED by elogind
5327 void hexdump(FILE *f, const void *p, size_t s) {
5328 const uint8_t *b = p;
5331 assert(s == 0 || b);
5336 fprintf(f, "%04x ", n);
5338 for (i = 0; i < 16; i++) {
5343 fprintf(f, "%02x ", b[i]);
5351 for (i = 0; i < 16; i++) {
5356 fputc(isprint(b[i]) ? (char) b[i] : '.', f);
5370 int update_reboot_param_file(const char *param) {
5375 r = write_string_file(REBOOT_PARAM_FILE, param, WRITE_STRING_FILE_CREATE);
5377 log_error("Failed to write reboot param to "
5378 REBOOT_PARAM_FILE": %s", strerror(-r));
5380 unlink(REBOOT_PARAM_FILE);
5385 int umount_recursive(const char *prefix, int flags) {
5389 /* Try to umount everything recursively below a
5390 * directory. Also, take care of stacked mounts, and keep
5391 * unmounting them until they are gone. */
5394 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
5399 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
5400 if (!proc_self_mountinfo)
5404 _cleanup_free_ char *path = NULL, *p = NULL;
5407 k = fscanf(proc_self_mountinfo,
5408 "%*s " /* (1) mount id */
5409 "%*s " /* (2) parent id */
5410 "%*s " /* (3) major:minor */
5411 "%*s " /* (4) root */
5412 "%ms " /* (5) mount point */
5413 "%*s" /* (6) mount options */
5414 "%*[^-]" /* (7) optional fields */
5415 "- " /* (8) separator */
5416 "%*s " /* (9) file system type */
5417 "%*s" /* (10) mount source */
5418 "%*s" /* (11) mount options 2 */
5419 "%*[^\n]", /* some rubbish at the end */
5428 r = cunescape(path, UNESCAPE_RELAX, &p);
5432 if (!path_startswith(p, prefix))
5435 if (umount2(p, flags) < 0) {
5451 static int get_mount_flags(const char *path, unsigned long *flags) {
5454 if (statvfs(path, &buf) < 0)
5456 *flags = buf.f_flag;
5460 int bind_remount_recursive(const char *prefix, bool ro) {
5461 _cleanup_set_free_free_ Set *done = NULL;
5462 _cleanup_free_ char *cleaned = NULL;
5465 /* Recursively remount a directory (and all its submounts)
5466 * read-only or read-write. If the directory is already
5467 * mounted, we reuse the mount and simply mark it
5468 * MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write
5469 * operation). If it isn't we first make it one. Afterwards we
5470 * apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to all
5471 * submounts we can access, too. When mounts are stacked on
5472 * the same mount point we only care for each individual
5473 * "top-level" mount on each point, as we cannot
5474 * influence/access the underlying mounts anyway. We do not
5475 * have any effect on future submounts that might get
5476 * propagated, they migt be writable. This includes future
5477 * submounts that have been triggered via autofs. */
5479 cleaned = strdup(prefix);
5483 path_kill_slashes(cleaned);
5485 done = set_new(&string_hash_ops);
5490 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
5491 _cleanup_set_free_free_ Set *todo = NULL;
5492 bool top_autofs = false;
5494 unsigned long orig_flags;
5496 todo = set_new(&string_hash_ops);
5500 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
5501 if (!proc_self_mountinfo)
5505 _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
5508 k = fscanf(proc_self_mountinfo,
5509 "%*s " /* (1) mount id */
5510 "%*s " /* (2) parent id */
5511 "%*s " /* (3) major:minor */
5512 "%*s " /* (4) root */
5513 "%ms " /* (5) mount point */
5514 "%*s" /* (6) mount options (superblock) */
5515 "%*[^-]" /* (7) optional fields */
5516 "- " /* (8) separator */
5517 "%ms " /* (9) file system type */
5518 "%*s" /* (10) mount source */
5519 "%*s" /* (11) mount options (bind mount) */
5520 "%*[^\n]", /* some rubbish at the end */
5530 r = cunescape(path, UNESCAPE_RELAX, &p);
5534 /* Let's ignore autofs mounts. If they aren't
5535 * triggered yet, we want to avoid triggering
5536 * them, as we don't make any guarantees for
5537 * future submounts anyway. If they are
5538 * already triggered, then we will find
5539 * another entry for this. */
5540 if (streq(type, "autofs")) {
5541 top_autofs = top_autofs || path_equal(cleaned, p);
5545 if (path_startswith(p, cleaned) &&
5546 !set_contains(done, p)) {
5548 r = set_consume(todo, p);
5558 /* If we have no submounts to process anymore and if
5559 * the root is either already done, or an autofs, we
5561 if (set_isempty(todo) &&
5562 (top_autofs || set_contains(done, cleaned)))
5565 if (!set_contains(done, cleaned) &&
5566 !set_contains(todo, cleaned)) {
5567 /* The prefix directory itself is not yet a
5568 * mount, make it one. */
5569 if (mount(cleaned, cleaned, NULL, MS_BIND|MS_REC, NULL) < 0)
5573 (void) get_mount_flags(cleaned, &orig_flags);
5574 orig_flags &= ~MS_RDONLY;
5576 if (mount(NULL, prefix, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0)
5579 x = strdup(cleaned);
5583 r = set_consume(done, x);
5588 while ((x = set_steal_first(todo))) {
5590 r = set_consume(done, x);
5591 if (r == -EEXIST || r == 0)
5596 /* Try to reuse the original flag set, but
5597 * don't care for errors, in case of
5598 * obstructed mounts */
5600 (void) get_mount_flags(x, &orig_flags);
5601 orig_flags &= ~MS_RDONLY;
5603 if (mount(NULL, x, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) {
5605 /* Deal with mount points that are
5606 * obstructed by a later mount */
5608 if (errno != ENOENT)
5617 int fflush_and_check(FILE *f) {
5624 return errno ? -errno : -EIO;
5629 int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
5641 * /foo/bar/.#<extra>waldoXXXXXX
5645 if (!filename_is_valid(fn))
5651 t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
5655 strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn), "XXXXXX");
5657 *ret = path_kill_slashes(t);
5661 int tempfn_random(const char *p, const char *extra, char **ret) {
5675 * /foo/bar/.#<extra>waldobaa2a261115984a9
5679 if (!filename_is_valid(fn))
5685 t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1);
5689 x = stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn);
5692 for (i = 0; i < 16; i++) {
5693 *(x++) = hexchar(u & 0xF);
5699 *ret = path_kill_slashes(t);
5703 /// UNNEEDED by elogind
5705 int tempfn_random_child(const char *p, const char *extra, char **ret) {
5716 * /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
5722 t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1);
5726 x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra);
5729 for (i = 0; i < 16; i++) {
5730 *(x++) = hexchar(u & 0xF);
5736 *ret = path_kill_slashes(t);
5740 int take_password_lock(const char *root) {
5742 struct flock flock = {
5744 .l_whence = SEEK_SET,
5752 /* This is roughly the same as lckpwdf(), but not as awful. We
5753 * don't want to use alarm() and signals, hence we implement
5754 * our own trivial version of this.
5756 * Note that shadow-utils also takes per-database locks in
5757 * addition to lckpwdf(). However, we don't given that they
5758 * are redundant as they they invoke lckpwdf() first and keep
5759 * it during everything they do. The per-database locks are
5760 * awfully racy, and thus we just won't do them. */
5763 path = strjoina(root, "/etc/.pwd.lock");
5765 path = "/etc/.pwd.lock";
5767 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
5771 r = fcntl(fd, F_SETLKW, &flock);
5780 int is_symlink(const char *path) {
5783 if (lstat(path, &info) < 0)
5786 return !!S_ISLNK(info.st_mode);
5790 int is_dir(const char* path, bool follow) {
5795 r = stat(path, &st);
5797 r = lstat(path, &st);
5801 return !!S_ISDIR(st.st_mode);
5804 /// UNNEEDED by elogind
5806 int is_device_node(const char *path) {
5809 if (lstat(path, &info) < 0)
5812 return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode));
5816 int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) {
5817 _cleanup_free_ char *s = NULL;
5818 size_t allocated = 0, sz = 0;
5826 SINGLE_QUOTE_ESCAPE,
5828 DOUBLE_QUOTE_ESCAPE,
5836 separators = WHITESPACE;
5838 /* Bail early if called after last value or with no input */
5840 goto finish_force_terminate;
5842 /* Parses the first word of a string, and returns it in
5843 * *ret. Removes all quotes in the process. When parsing fails
5844 * (because of an uneven number of quotes or similar), leaves
5845 * the pointer *p at the first invalid character. */
5853 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
5854 if (!GREEDY_REALLOC(s, allocated, sz+1))
5858 goto finish_force_terminate;
5859 else if (strchr(separators, c)) {
5860 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
5862 goto finish_force_next;
5867 /* We found a non-blank character, so we will always
5868 * want to return a string (even if it is empty),
5869 * allocate it here. */
5870 if (!GREEDY_REALLOC(s, allocated, sz+1))
5878 goto finish_force_terminate;
5879 else if (c == '\'' && (flags & EXTRACT_QUOTES))
5880 state = SINGLE_QUOTE;
5882 state = VALUE_ESCAPE;
5883 else if (c == '\"' && (flags & EXTRACT_QUOTES))
5884 state = DOUBLE_QUOTE;
5885 else if (strchr(separators, c)) {
5886 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
5888 goto finish_force_next;
5892 if (!GREEDY_REALLOC(s, allocated, sz+2))
5902 if (flags & EXTRACT_RELAX)
5903 goto finish_force_terminate;
5905 } else if (c == '\'')
5908 state = SINGLE_QUOTE_ESCAPE;
5910 if (!GREEDY_REALLOC(s, allocated, sz+2))
5924 state = DOUBLE_QUOTE_ESCAPE;
5926 if (!GREEDY_REALLOC(s, allocated, sz+2))
5934 case SINGLE_QUOTE_ESCAPE:
5935 case DOUBLE_QUOTE_ESCAPE:
5937 if (!GREEDY_REALLOC(s, allocated, sz+7))
5941 if ((flags & EXTRACT_CUNESCAPE_RELAX) &&
5942 (state == VALUE_ESCAPE || flags & EXTRACT_RELAX)) {
5943 /* If we find an unquoted trailing backslash and we're in
5944 * EXTRACT_CUNESCAPE_RELAX mode, keep it verbatim in the
5947 * Unbalanced quotes will only be allowed in EXTRACT_RELAX
5948 * mode, EXTRACT_CUNESCAPE_RELAX mode does not allow them.
5951 goto finish_force_terminate;
5953 if (flags & EXTRACT_RELAX)
5954 goto finish_force_terminate;
5958 if (flags & EXTRACT_CUNESCAPE) {
5961 r = cunescape_one(*p, (size_t) -1, &c, &u);
5963 if (flags & EXTRACT_CUNESCAPE_RELAX) {
5974 s[sz++] = c; /* normal explicit char */
5976 sz += utf8_encode_unichar(s + sz, u); /* unicode chars we'll encode as utf8 */
5981 state = (state == SINGLE_QUOTE_ESCAPE) ? SINGLE_QUOTE :
5982 (state == DOUBLE_QUOTE_ESCAPE) ? DOUBLE_QUOTE :
5988 goto finish_force_terminate;
5989 if (!strchr(separators, c))
5997 finish_force_terminate:
6014 /// UNNEEDED by elogind
6016 int extract_first_word_and_warn(
6019 const char *separators,
6022 const char *filename,
6024 const char *rvalue) {
6025 /* Try to unquote it, if it fails, warn about it and try again but this
6026 * time using EXTRACT_CUNESCAPE_RELAX to keep the backslashes verbatim
6027 * in invalid escape sequences. */
6032 r = extract_first_word(p, ret, separators, flags);
6033 if (r < 0 && !(flags&EXTRACT_CUNESCAPE_RELAX)) {
6034 /* Retry it with EXTRACT_CUNESCAPE_RELAX. */
6036 r = extract_first_word(p, ret, separators, flags|EXTRACT_CUNESCAPE_RELAX);
6038 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
6039 "Unbalanced quoting in command line, ignoring: \"%s\"", rvalue);
6041 log_syntax(unit, LOG_WARNING, filename, line, EINVAL,
6042 "Invalid escape sequences in command line: \"%s\"", rvalue);
6047 int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) {
6052 /* Parses a number of words from a string, stripping any
6053 * quotes if necessary. */
6057 /* Count how many words are expected */
6058 va_start(ap, flags);
6060 if (!va_arg(ap, char **))
6069 /* Read all words into a temporary array */
6070 l = newa0(char*, n);
6071 for (c = 0; c < n; c++) {
6073 r = extract_first_word(p, &l[c], separators, flags);
6077 for (j = 0; j < c; j++)
6087 /* If we managed to parse all words, return them in the passed
6089 va_start(ap, flags);
6090 for (i = 0; i < n; i++) {
6093 v = va_arg(ap, char **);
6104 int free_and_strdup(char **p, const char *s) {
6109 /* Replaces a string pointer with an strdup()ed new string,
6110 * possibly freeing the old one. */
6112 if (streq_ptr(*p, s))
6128 /// UNNEEDED by elogind
6130 int ptsname_malloc(int fd, char **ret) {
6143 if (ptsname_r(fd, c, l) == 0) {
6147 if (errno != ERANGE) {
6157 int openpt_in_namespace(pid_t pid, int flags) {
6158 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1;
6159 _cleanup_close_pair_ int pair[2] = { -1, -1 };
6161 struct cmsghdr cmsghdr;
6162 uint8_t buf[CMSG_SPACE(sizeof(int))];
6164 struct msghdr mh = {
6165 .msg_control = &control,
6166 .msg_controllen = sizeof(control),
6168 struct cmsghdr *cmsg;
6175 r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &usernsfd, &rootfd);
6179 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
6189 pair[0] = safe_close(pair[0]);
6191 r = namespace_enter(pidnsfd, mntnsfd, -1, usernsfd, rootfd);
6193 _exit(EXIT_FAILURE);
6195 master = posix_openpt(flags);
6197 _exit(EXIT_FAILURE);
6199 if (unlockpt(master) < 0)
6200 _exit(EXIT_FAILURE);
6202 cmsg = CMSG_FIRSTHDR(&mh);
6203 cmsg->cmsg_level = SOL_SOCKET;
6204 cmsg->cmsg_type = SCM_RIGHTS;
6205 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
6206 memcpy(CMSG_DATA(cmsg), &master, sizeof(int));
6208 mh.msg_controllen = cmsg->cmsg_len;
6210 if (sendmsg(pair[1], &mh, MSG_NOSIGNAL) < 0)
6211 _exit(EXIT_FAILURE);
6213 _exit(EXIT_SUCCESS);
6216 pair[1] = safe_close(pair[1]);
6218 r = wait_for_terminate(child, &si);
6221 if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
6224 if (recvmsg(pair[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
6227 CMSG_FOREACH(cmsg, &mh)
6228 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
6232 fds = (int*) CMSG_DATA(cmsg);
6233 n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
6236 close_many(fds, n_fds);
6247 ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) {
6248 _cleanup_close_ int fd = -1;
6251 /* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */
6253 fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOATIME|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
6257 l = fgetxattr(fd, attribute, value, size);
6264 static int parse_crtime(le64_t le, usec_t *usec) {
6270 if (u == 0 || u == (uint64_t) -1)
6277 int fd_getcrtime(int fd, usec_t *usec) {
6284 /* Until Linux gets a real concept of birthtime/creation time,
6285 * let's fake one with xattrs */
6287 n = fgetxattr(fd, "user.crtime_usec", &le, sizeof(le));
6290 if (n != sizeof(le))
6293 return parse_crtime(le, usec);
6296 /// UNNEEDED by elogind
6298 int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags) {
6302 n = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags);
6305 if (n != sizeof(le))
6308 return parse_crtime(le, usec);
6311 int path_getcrtime(const char *p, usec_t *usec) {
6318 n = getxattr(p, "user.crtime_usec", &le, sizeof(le));
6321 if (n != sizeof(le))
6324 return parse_crtime(le, usec);
6327 int fd_setcrtime(int fd, usec_t usec) {
6333 usec = now(CLOCK_REALTIME);
6335 le = htole64((uint64_t) usec);
6336 if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), 0) < 0)
6342 int same_fd(int a, int b) {
6343 struct stat sta, stb;
6350 /* Compares two file descriptors. Note that semantics are
6351 * quite different depending on whether we have kcmp() or we
6352 * don't. If we have kcmp() this will only return true for
6353 * dup()ed file descriptors, but not otherwise. If we don't
6354 * have kcmp() this will also return true for two fds of the same
6355 * file, created by separate open() calls. Since we use this
6356 * call mostly for filtering out duplicates in the fd store
6357 * this difference hopefully doesn't matter too much. */
6362 /* Try to use kcmp() if we have it. */
6364 r = kcmp(pid, pid, KCMP_FILE, a, b);
6369 if (errno != ENOSYS)
6372 /* We don't have kcmp(), use fstat() instead. */
6373 if (fstat(a, &sta) < 0)
6376 if (fstat(b, &stb) < 0)
6379 if ((sta.st_mode & S_IFMT) != (stb.st_mode & S_IFMT))
6382 /* We consider all device fds different, since two device fds
6383 * might refer to quite different device contexts even though
6384 * they share the same inode and backing dev_t. */
6386 if (S_ISCHR(sta.st_mode) || S_ISBLK(sta.st_mode))
6389 if (sta.st_dev != stb.st_dev || sta.st_ino != stb.st_ino)
6392 /* The fds refer to the same inode on disk, let's also check
6393 * if they have the same fd flags. This is useful to
6394 * distinguish the read and write side of a pipe created with
6396 fa = fcntl(a, F_GETFL);
6400 fb = fcntl(b, F_GETFL);
6408 int chattr_fd(int fd, unsigned value, unsigned mask) {
6409 unsigned old_attr, new_attr;
6414 if (fstat(fd, &st) < 0)
6417 /* Explicitly check whether this is a regular file or
6418 * directory. If it is anything else (such as a device node or
6419 * fifo), then the ioctl will not hit the file systems but
6420 * possibly drivers, where the ioctl might have different
6421 * effects. Notably, DRM is using the same ioctl() number. */
6423 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
6429 if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
6432 new_attr = (old_attr & ~mask) | (value & mask);
6433 if (new_attr == old_attr)
6436 if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
6442 /// UNNEEDED by elogind
6444 int chattr_path(const char *p, unsigned value, unsigned mask) {
6445 _cleanup_close_ int fd = -1;
6452 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
6456 return chattr_fd(fd, value, mask);
6460 int read_attr_fd(int fd, unsigned *ret) {
6465 if (fstat(fd, &st) < 0)
6468 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
6471 if (ioctl(fd, FS_IOC_GETFLAGS, ret) < 0)
6477 /// UNNEEDED by elogind
6479 int read_attr_path(const char *p, unsigned *ret) {
6480 _cleanup_close_ int fd = -1;
6485 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
6489 return read_attr_fd(fd, ret);
6492 static size_t nul_length(const uint8_t *p, size_t sz) {
6507 ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
6508 const uint8_t *q, *w, *e;
6516 n = nul_length(q, e - q);
6518 /* If there are more than the specified run length of
6519 * NUL bytes, or if this is the beginning or the end
6520 * of the buffer, then seek instead of write */
6521 if ((n > run_length) ||
6522 (n > 0 && q == p) ||
6523 (n > 0 && q + n >= e)) {
6525 l = write(fd, w, q - w);
6532 if (lseek(fd, n, SEEK_CUR) == (off_t) -1)
6544 l = write(fd, w, q - w);
6551 return q - (const uint8_t*) p;
6555 void sigkill_wait(pid_t *pid) {
6561 if (kill(*pid, SIGKILL) > 0)
6562 (void) wait_for_terminate(*pid, NULL);
6565 /// UNNEEDED by elogind
6567 int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
6568 int a = 0, b = 0, c = 0;
6578 if (!strchr(*p, '>'))
6581 if ((*p)[2] == '>') {
6582 c = undecchar((*p)[1]);
6584 } else if ((*p)[3] == '>') {
6585 b = undecchar((*p)[1]);
6586 c = undecchar((*p)[2]);
6588 } else if ((*p)[4] == '>') {
6589 a = undecchar((*p)[1]);
6590 b = undecchar((*p)[2]);
6591 c = undecchar((*p)[3]);
6596 if (a < 0 || b < 0 || c < 0 ||
6597 (!with_facility && (a || b || c > 7)))
6601 *priority = a*100 + b*10 + c;
6603 *priority = (*priority & LOG_FACMASK) | c;
6610 ssize_t string_table_lookup(const char * const *table, size_t len, const char *key) {
6616 for (i = 0; i < len; ++i)
6617 if (streq_ptr(table[i], key))
6623 /// UNNEEDED by elogind
6625 void cmsg_close_all(struct msghdr *mh) {
6626 struct cmsghdr *cmsg;
6630 CMSG_FOREACH(cmsg, mh)
6631 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
6632 close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int));
6635 int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
6639 ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
6643 /* renameat2() exists since Linux 3.15, btrfs added support for it later.
6644 * If it is not implemented, fallback to another method. */
6645 if (!IN_SET(errno, EINVAL, ENOSYS))
6648 /* The link()/unlink() fallback does not work on directories. But
6649 * renameat() without RENAME_NOREPLACE gives the same semantics on
6650 * directories, except when newpath is an *empty* directory. This is
6652 ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW);
6653 if (ret >= 0 && S_ISDIR(buf.st_mode)) {
6654 ret = renameat(olddirfd, oldpath, newdirfd, newpath);
6655 return ret >= 0 ? 0 : -errno;
6658 /* If it is not a directory, use the link()/unlink() fallback. */
6659 ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0);
6663 ret = unlinkat(olddirfd, oldpath, 0);
6665 /* backup errno before the following unlinkat() alters it */
6667 (void) unlinkat(newdirfd, newpath, 0);
6676 static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad) {
6680 if (*s == '\\' || strchr(bad, *s))
6689 char *shell_escape(const char *s, const char *bad) {
6692 r = new(char, strlen(s)*2+1);
6696 t = strcpy_backslash_escaped(r, s, bad);
6702 char *shell_maybe_quote(const char *s) {
6708 /* Encloses a string in double quotes if necessary to make it
6709 * OK as shell string. */
6711 for (p = s; *p; p++)
6714 strchr(SHELL_NEED_QUOTES, *p))
6720 r = new(char, 1+strlen(s)*2+1+1);
6726 t = mempcpy(t, s, p - s);
6728 t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE);
6736 int parse_mode(const char *s, mode_t *ret) {
6744 l = strtol(s, &x, 8);
6748 if (!x || x == s || *x)
6750 if (l < 0 || l > 07777)
6757 /// UNNEEDED by elogind
6759 int mount_move_root(const char *path) {
6762 if (chdir(path) < 0)
6765 if (mount(path, "/", NULL, MS_MOVE, NULL) < 0)
6768 if (chroot(".") < 0)
6778 int reset_uid_gid(void) {
6780 if (setgroups(0, NULL) < 0)
6783 if (setresgid(0, 0, 0) < 0)
6786 if (setresuid(0, 0, 0) < 0)
6792 int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink) {
6801 for (l = 100; ; l = (size_t) n + 1) {
6807 n = lgetxattr(path, name, v, l);
6809 n = getxattr(path, name, v, l);
6811 if (n >= 0 && (size_t) n < l) {
6818 if (n < 0 && errno != ERANGE)
6822 n = lgetxattr(path, name, NULL, 0);
6824 n = getxattr(path, name, NULL, 0);
6830 int fgetxattr_malloc(int fd, const char *name, char **value) {
6839 for (l = 100; ; l = (size_t) n + 1) {
6844 n = fgetxattr(fd, name, v, l);
6846 if (n >= 0 && (size_t) n < l) {
6853 if (n < 0 && errno != ERANGE)
6856 n = fgetxattr(fd, name, NULL, 0);