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"
82 // #include "hashmap.h"
83 // #include "env-util.h"
85 // #include "device-nodes.h"
90 #include "sparse-endian.h"
91 // #include "formats-util.h"
92 #include "process-util.h"
93 #include "random-util.h"
94 // #include "terminal-util.h"
95 #include "hostname-util.h"
96 #include "signal-util.h"
98 /* Put this test here for a lack of better place */
99 assert_cc(EAGAIN == EWOULDBLOCK);
102 char **saved_argv = NULL;
104 size_t page_size(void) {
105 static thread_local size_t pgsz = 0;
108 if (_likely_(pgsz > 0))
111 r = sysconf(_SC_PAGESIZE);
118 int strcmp_ptr(const char *a, const char *b) {
120 /* Like strcmp(), but tries to make sense of NULL pointers */
133 bool streq_ptr(const char *a, const char *b) {
134 return strcmp_ptr(a, b) == 0;
137 char* endswith(const char *s, const char *postfix) {
144 pl = strlen(postfix);
147 return (char*) s + sl;
152 if (memcmp(s + sl - pl, postfix, pl) != 0)
155 return (char*) s + sl - pl;
158 char* endswith_no_case(const char *s, const char *postfix) {
165 pl = strlen(postfix);
168 return (char*) s + sl;
173 if (strcasecmp(s + sl - pl, postfix) != 0)
176 return (char*) s + sl - pl;
179 char* first_word(const char *s, const char *word) {
186 /* Checks if the string starts with the specified word, either
187 * followed by NUL or by whitespace. Returns a pointer to the
188 * NUL or the first character after the whitespace. */
199 if (memcmp(s, word, wl) != 0)
206 if (!strchr(WHITESPACE, *p))
209 p += strspn(p, WHITESPACE);
213 size_t cescape_char(char c, char *buf) {
214 char * buf_old = buf;
260 /* For special chars we prefer octal over
261 * hexadecimal encoding, simply because glib's
262 * g_strescape() does the same */
263 if ((c < ' ') || (c >= 127)) {
265 *(buf++) = octchar((unsigned char) c >> 6);
266 *(buf++) = octchar((unsigned char) c >> 3);
267 *(buf++) = octchar((unsigned char) c);
273 return buf - buf_old;
276 int close_nointr(int fd) {
283 * Just ignore EINTR; a retry loop is the wrong thing to do on
286 * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
287 * https://bugzilla.gnome.org/show_bug.cgi?id=682819
288 * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
289 * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
297 int safe_close(int fd) {
300 * Like close_nointr() but cannot fail. Guarantees errno is
301 * unchanged. Is a NOP with negative fds passed, and returns
302 * -1, so that it can be used in this syntax:
304 * fd = safe_close(fd);
310 /* The kernel might return pretty much any error code
311 * via close(), but the fd will be closed anyway. The
312 * only condition we want to check for here is whether
313 * the fd was invalid at all... */
315 assert_se(close_nointr(fd) != -EBADF);
321 void close_many(const int fds[], unsigned n_fd) {
324 assert(fds || n_fd <= 0);
326 for (i = 0; i < n_fd; i++)
330 int unlink_noerrno(const char *path) {
341 int parse_boolean(const char *v) {
344 if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on"))
346 else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off"))
352 int parse_pid(const char *s, pid_t* ret_pid) {
353 unsigned long ul = 0;
360 r = safe_atolu(s, &ul);
366 if ((unsigned long) pid != ul)
376 bool uid_is_valid(uid_t uid) {
378 /* Some libc APIs use UID_INVALID as special placeholder */
379 if (uid == (uid_t) 0xFFFFFFFF)
382 /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
383 if (uid == (uid_t) 0xFFFF)
389 int parse_uid(const char *s, uid_t* ret_uid) {
390 unsigned long ul = 0;
396 r = safe_atolu(s, &ul);
402 if ((unsigned long) uid != ul)
405 if (!uid_is_valid(uid))
414 int safe_atou(const char *s, unsigned *ret_u) {
422 l = strtoul(s, &x, 0);
424 if (!x || x == s || *x || errno)
425 return errno > 0 ? -errno : -EINVAL;
427 if ((unsigned long) (unsigned) l != l)
430 *ret_u = (unsigned) l;
434 int safe_atoi(const char *s, int *ret_i) {
442 l = strtol(s, &x, 0);
444 if (!x || x == s || *x || errno)
445 return errno > 0 ? -errno : -EINVAL;
447 if ((long) (int) l != l)
454 int safe_atou8(const char *s, uint8_t *ret) {
462 l = strtoul(s, &x, 0);
464 if (!x || x == s || *x || errno)
465 return errno > 0 ? -errno : -EINVAL;
467 if ((unsigned long) (uint8_t) l != l)
474 int safe_atou16(const char *s, uint16_t *ret) {
482 l = strtoul(s, &x, 0);
484 if (!x || x == s || *x || errno)
485 return errno > 0 ? -errno : -EINVAL;
487 if ((unsigned long) (uint16_t) l != l)
494 int safe_atoi16(const char *s, int16_t *ret) {
502 l = strtol(s, &x, 0);
504 if (!x || x == s || *x || errno)
505 return errno > 0 ? -errno : -EINVAL;
507 if ((long) (int16_t) l != l)
514 int safe_atollu(const char *s, long long unsigned *ret_llu) {
516 unsigned long long l;
522 l = strtoull(s, &x, 0);
524 if (!x || x == s || *x || errno)
525 return errno ? -errno : -EINVAL;
531 int safe_atolli(const char *s, long long int *ret_lli) {
539 l = strtoll(s, &x, 0);
541 if (!x || x == s || *x || errno)
542 return errno ? -errno : -EINVAL;
548 int safe_atod(const char *s, double *ret_d) {
556 loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
557 if (loc == (locale_t) 0)
561 d = strtod_l(s, &x, loc);
563 if (!x || x == s || *x || errno) {
565 return errno ? -errno : -EINVAL;
573 static size_t strcspn_escaped(const char *s, const char *reject) {
574 bool escaped = false;
577 for (n=0; s[n]; n++) {
580 else if (s[n] == '\\')
582 else if (strchr(reject, s[n]))
586 /* if s ends in \, return index of previous char */
590 /* Split a string into words. */
591 const char* split(const char **state, size_t *l, const char *separator, bool quoted) {
597 assert(**state == '\0');
601 current += strspn(current, separator);
607 if (quoted && strchr("\'\"", *current)) {
608 char quotechars[2] = {*current, '\0'};
610 *l = strcspn_escaped(current + 1, quotechars);
611 if (current[*l + 1] == '\0' || current[*l + 1] != quotechars[0] ||
612 (current[*l + 2] && !strchr(separator, current[*l + 2]))) {
613 /* right quote missing or garbage at the end */
617 *state = current++ + *l + 2;
619 *l = strcspn_escaped(current, separator);
620 if (current[*l] && !strchr(separator, current[*l])) {
621 /* unfinished escape */
625 *state = current + *l;
627 *l = strcspn(current, separator);
628 *state = current + *l;
634 int fchmod_umask(int fd, mode_t m) {
639 r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
645 char *truncate_nl(char *s) {
648 s[strcspn(s, NEWLINE)] = 0;
652 char *strnappend(const char *s, const char *suffix, size_t b) {
660 return strndup(suffix, b);
669 if (b > ((size_t) -1) - a)
672 r = new(char, a+b+1);
677 memcpy(r+a, suffix, b);
683 char *strappend(const char *s, const char *suffix) {
684 return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
687 int readlinkat_malloc(int fd, const char *p, char **ret) {
702 n = readlinkat(fd, p, c, l-1);
709 if ((size_t) n < l-1) {
720 int readlink_malloc(const char *p, char **ret) {
721 return readlinkat_malloc(AT_FDCWD, p, ret);
724 /// UNNEEDED by elogind
726 int readlink_value(const char *p, char **ret) {
727 _cleanup_free_ char *link = NULL;
731 r = readlink_malloc(p, &link);
735 value = basename(link);
739 value = strdup(value);
749 int readlink_and_make_absolute(const char *p, char **r) {
750 _cleanup_free_ char *target = NULL;
757 j = readlink_malloc(p, &target);
761 k = file_in_same_dir(p, target);
769 /// UNNEEDED by elogind
771 int readlink_and_canonicalize(const char *p, char **r) {
778 j = readlink_and_make_absolute(p, &t);
782 s = canonicalize_file_name(t);
789 path_kill_slashes(*r);
795 char *strstrip(char *s) {
798 /* Drops trailing whitespace. Modifies the string in
799 * place. Returns pointer to first non-space character */
801 s += strspn(s, WHITESPACE);
803 for (e = strchr(s, 0); e > s; e --)
804 if (!strchr(WHITESPACE, e[-1]))
812 /// UNNEEDED by elogind
814 char *delete_chars(char *s, const char *bad) {
817 /* Drops all whitespace, regardless where in the string */
819 for (f = s, t = s; *f; f++) {
832 char *file_in_same_dir(const char *path, const char *filename) {
839 /* This removes the last component of path and appends
840 * filename, unless the latter is absolute anyway or the
843 if (path_is_absolute(filename))
844 return strdup(filename);
846 e = strrchr(path, '/');
848 return strdup(filename);
850 k = strlen(filename);
851 ret = new(char, (e + 1 - path) + k + 1);
855 memcpy(mempcpy(ret, path, e + 1 - path), filename, k + 1);
859 /// UNNEEDED by elogind
861 int rmdir_parents(const char *path, const char *stop) {
870 /* Skip trailing slashes */
871 while (l > 0 && path[l-1] == '/')
877 /* Skip last component */
878 while (l > 0 && path[l-1] != '/')
881 /* Skip trailing slashes */
882 while (l > 0 && path[l-1] == '/')
888 if (!(t = strndup(path, l)))
891 if (path_startswith(stop, t)) {
908 char hexchar(int x) {
909 static const char table[16] = "0123456789abcdef";
911 return table[x & 15];
914 int unhexchar(char c) {
916 if (c >= '0' && c <= '9')
919 if (c >= 'a' && c <= 'f')
922 if (c >= 'A' && c <= 'F')
928 char *hexmem(const void *p, size_t l) {
932 z = r = malloc(l * 2 + 1);
936 for (x = p; x < (const uint8_t*) p + l; x++) {
937 *(z++) = hexchar(*x >> 4);
938 *(z++) = hexchar(*x & 15);
945 int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
946 _cleanup_free_ uint8_t *r = NULL;
954 z = r = malloc((l + 1) / 2 + 1);
958 for (x = p; x < p + l; x += 2) {
964 else if (x+1 < p + l) {
971 *(z++) = (uint8_t) a << 4 | (uint8_t) b;
983 /* https://tools.ietf.org/html/rfc4648#section-6
984 * Notice that base32hex differs from base32 in the alphabet it uses.
985 * The distinction is that the base32hex representation preserves the
986 * order of the underlying data when compared as bytestrings, this is
987 * useful when representing NSEC3 hashes, as one can then verify the
988 * order of hashes directly from their representation. */
989 char base32hexchar(int x) {
990 static const char table[32] = "0123456789"
991 "ABCDEFGHIJKLMNOPQRSTUV";
993 return table[x & 31];
996 int unbase32hexchar(char c) {
999 if (c >= '0' && c <= '9')
1002 offset = '9' - '0' + 1;
1004 if (c >= 'A' && c <= 'V')
1005 return c - 'A' + offset;
1010 char *base32hexmem(const void *p, size_t l, bool padding) {
1016 /* five input bytes makes eight output bytes, padding is added so we must round up */
1017 len = 8 * (l + 4) / 5;
1019 /* same, but round down as there is no padding */
1038 z = r = malloc(len + 1);
1042 for (x = p; x < (const uint8_t*) p + (l / 5) * 5; x += 5) {
1043 /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ
1044 x[3] == QQQQQQQQ; x[4] == WWWWWWWW */
1045 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1046 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1047 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1048 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
1049 *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */
1050 *(z++) = base32hexchar((x[3] & 127) >> 2); /* 000QQQQQ */
1051 *(z++) = base32hexchar((x[3] & 3) << 3 | x[4] >> 5); /* 000QQWWW */
1052 *(z++) = base32hexchar((x[4] & 31)); /* 000WWWWW */
1057 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1058 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1059 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1060 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
1061 *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */
1062 *(z++) = base32hexchar((x[3] & 127) >> 2); /* 000QQQQQ */
1063 *(z++) = base32hexchar((x[3] & 3) << 3); /* 000QQ000 */
1070 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1071 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1072 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1073 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
1074 *(z++) = base32hexchar((x[2] & 15) << 1); /* 000ZZZZ0 */
1084 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1085 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1086 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1087 *(z++) = base32hexchar((x[1] & 1) << 4); /* 000Y0000 */
1098 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1099 *(z++) = base32hexchar((x[0] & 7) << 2); /* 000XXX00 */
1116 int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_len) {
1117 _cleanup_free_ uint8_t *r = NULL;
1118 int a, b, c, d, e, f, g, h;
1126 /* padding ensures any base32hex input has input divisible by 8 */
1127 if (padding && l % 8 != 0)
1131 /* strip the padding */
1132 while (l > 0 && p[l - 1] == '=' && pad < 7) {
1138 /* a group of eight input bytes needs five output bytes, in case of
1139 padding we need to add some extra bytes */
1161 z = r = malloc(len + 1);
1165 for (x = p; x < p + (l / 8) * 8; x += 8) {
1166 /* a == 000XXXXX; b == 000YYYYY; c == 000ZZZZZ; d == 000WWWWW
1167 e == 000SSSSS; f == 000QQQQQ; g == 000VVVVV; h == 000RRRRR */
1168 a = unbase32hexchar(x[0]);
1172 b = unbase32hexchar(x[1]);
1176 c = unbase32hexchar(x[2]);
1180 d = unbase32hexchar(x[3]);
1184 e = unbase32hexchar(x[4]);
1188 f = unbase32hexchar(x[5]);
1192 g = unbase32hexchar(x[6]);
1196 h = unbase32hexchar(x[7]);
1200 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1201 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1202 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
1203 *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */
1204 *(z++) = (uint8_t) g << 5 | (uint8_t) h; /* VVVRRRRR */
1209 a = unbase32hexchar(x[0]);
1213 b = unbase32hexchar(x[1]);
1217 c = unbase32hexchar(x[2]);
1221 d = unbase32hexchar(x[3]);
1225 e = unbase32hexchar(x[4]);
1229 f = unbase32hexchar(x[5]);
1233 g = unbase32hexchar(x[6]);
1241 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1242 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1243 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
1244 *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */
1248 a = unbase32hexchar(x[0]);
1252 b = unbase32hexchar(x[1]);
1256 c = unbase32hexchar(x[2]);
1260 d = unbase32hexchar(x[3]);
1264 e = unbase32hexchar(x[4]);
1272 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1273 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1274 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
1278 a = unbase32hexchar(x[0]);
1282 b = unbase32hexchar(x[1]);
1286 c = unbase32hexchar(x[2]);
1290 d = unbase32hexchar(x[3]);
1298 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1299 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1303 a = unbase32hexchar(x[0]);
1307 b = unbase32hexchar(x[1]);
1315 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1333 /* https://tools.ietf.org/html/rfc4648#section-4 */
1334 char base64char(int x) {
1335 static const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1336 "abcdefghijklmnopqrstuvwxyz"
1338 return table[x & 63];
1341 int unbase64char(char c) {
1344 if (c >= 'A' && c <= 'Z')
1347 offset = 'Z' - 'A' + 1;
1349 if (c >= 'a' && c <= 'z')
1350 return c - 'a' + offset;
1352 offset += 'z' - 'a' + 1;
1354 if (c >= '0' && c <= '9')
1355 return c - '0' + offset;
1357 offset += '9' - '0' + 1;
1370 char *base64mem(const void *p, size_t l) {
1374 /* three input bytes makes four output bytes, padding is added so we must round up */
1375 z = r = malloc(4 * (l + 2) / 3 + 1);
1379 for (x = p; x < (const uint8_t*) p + (l / 3) * 3; x += 3) {
1380 /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ */
1381 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1382 *(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4); /* 00XXYYYY */
1383 *(z++) = base64char((x[1] & 15) << 2 | x[2] >> 6); /* 00YYYYZZ */
1384 *(z++) = base64char(x[2] & 63); /* 00ZZZZZZ */
1389 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1390 *(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4); /* 00XXYYYY */
1391 *(z++) = base64char((x[1] & 15) << 2); /* 00YYYY00 */
1396 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1397 *(z++) = base64char((x[0] & 3) << 4); /* 00XX0000 */
1408 int unbase64mem(const char *p, size_t l, void **mem, size_t *_len) {
1409 _cleanup_free_ uint8_t *r = NULL;
1417 /* padding ensures any base63 input has input divisible by 4 */
1421 /* strip the padding */
1422 if (l > 0 && p[l - 1] == '=')
1424 if (l > 0 && p[l - 1] == '=')
1427 /* a group of four input bytes needs three output bytes, in case of
1428 padding we need to add two or three extra bytes */
1429 len = (l / 4) * 3 + (l % 4 ? (l % 4) - 1 : 0);
1431 z = r = malloc(len + 1);
1435 for (x = p; x < p + (l / 4) * 4; x += 4) {
1436 /* a == 00XXXXXX; b == 00YYYYYY; c == 00ZZZZZZ; d == 00WWWWWW */
1437 a = unbase64char(x[0]);
1441 b = unbase64char(x[1]);
1445 c = unbase64char(x[2]);
1449 d = unbase64char(x[3]);
1453 *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
1454 *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
1455 *(z++) = (uint8_t) c << 6 | (uint8_t) d; /* ZZWWWWWW */
1460 a = unbase64char(x[0]);
1464 b = unbase64char(x[1]);
1468 c = unbase64char(x[2]);
1476 *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
1477 *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
1481 a = unbase64char(x[0]);
1485 b = unbase64char(x[1]);
1493 *(z++) = (uint8_t) a << 2 | (uint8_t) (b >> 4); /* XXXXXXYY */
1512 char octchar(int x) {
1513 return '0' + (x & 7);
1516 int unoctchar(char c) {
1518 if (c >= '0' && c <= '7')
1524 char decchar(int x) {
1525 return '0' + (x % 10);
1528 int undecchar(char c) {
1530 if (c >= '0' && c <= '9')
1536 char *cescape(const char *s) {
1542 /* Does C style string escaping. May be reversed with
1545 r = new(char, strlen(s)*4 + 1);
1549 for (f = s, t = r; *f; f++)
1550 t += cescape_char(*f, t);
1557 static int cunescape_one(const char *p, size_t length, char *ret, uint32_t *ret_unicode) {
1564 /* Unescapes C style. Returns the unescaped character in ret,
1565 * unless we encountered a \u sequence in which case the full
1566 * unicode character is returned in ret_unicode, instead. */
1568 if (length != (size_t) -1 && length < 1)
1605 /* This is an extension of the XDG syntax files */
1610 /* hexadecimal encoding */
1613 if (length != (size_t) -1 && length < 3)
1616 a = unhexchar(p[1]);
1620 b = unhexchar(p[2]);
1624 /* Don't allow NUL bytes */
1625 if (a == 0 && b == 0)
1628 *ret = (char) ((a << 4U) | b);
1634 /* C++11 style 16bit unicode */
1640 if (length != (size_t) -1 && length < 5)
1643 for (i = 0; i < 4; i++) {
1644 a[i] = unhexchar(p[1 + i]);
1649 c = ((uint32_t) a[0] << 12U) | ((uint32_t) a[1] << 8U) | ((uint32_t) a[2] << 4U) | (uint32_t) a[3];
1651 /* Don't allow 0 chars */
1670 /* C++11 style 32bit unicode */
1676 if (length != (size_t) -1 && length < 9)
1679 for (i = 0; i < 8; i++) {
1680 a[i] = unhexchar(p[1 + i]);
1685 c = ((uint32_t) a[0] << 28U) | ((uint32_t) a[1] << 24U) | ((uint32_t) a[2] << 20U) | ((uint32_t) a[3] << 16U) |
1686 ((uint32_t) a[4] << 12U) | ((uint32_t) a[5] << 8U) | ((uint32_t) a[6] << 4U) | (uint32_t) a[7];
1688 /* Don't allow 0 chars */
1692 /* Don't allow invalid code points */
1693 if (!unichar_is_valid(c))
1718 /* octal encoding */
1722 if (length != (size_t) -1 && length < 3)
1725 a = unoctchar(p[0]);
1729 b = unoctchar(p[1]);
1733 c = unoctchar(p[2]);
1737 /* don't allow NUL bytes */
1738 if (a == 0 && b == 0 && c == 0)
1741 /* Don't allow bytes above 255 */
1742 m = ((uint32_t) a << 6U) | ((uint32_t) b << 3U) | (uint32_t) c;
1758 int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret) {
1766 /* Undoes C style string escaping, and optionally prefixes it. */
1768 pl = prefix ? strlen(prefix) : 0;
1770 r = new(char, pl+length+1);
1775 memcpy(r, prefix, pl);
1777 for (f = s, t = r + pl; f < s + length; f++) {
1783 remaining = s + length - f;
1784 assert(remaining > 0);
1787 /* A literal literal, copy verbatim */
1792 if (remaining == 1) {
1793 if (flags & UNESCAPE_RELAX) {
1794 /* A trailing backslash, copy verbatim */
1803 k = cunescape_one(f + 1, remaining - 1, &c, &u);
1805 if (flags & UNESCAPE_RELAX) {
1806 /* Invalid escape code, let's take it literal then */
1816 /* Non-Unicode? Let's encode this directly */
1819 /* Unicode? Then let's encode this in UTF-8 */
1820 t += utf8_encode_unichar(t, u);
1831 int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret) {
1832 return cunescape_length_with_prefix(s, length, NULL, flags, ret);
1835 int cunescape(const char *s, UnescapeFlags flags, char **ret) {
1836 return cunescape_length(s, strlen(s), flags, ret);
1839 char *xescape(const char *s, const char *bad) {
1843 /* Escapes all chars in bad, in addition to \ and all special
1844 * chars, in \xFF style escaping. May be reversed with
1847 r = new(char, strlen(s) * 4 + 1);
1851 for (f = s, t = r; *f; f++) {
1853 if ((*f < ' ') || (*f >= 127) ||
1854 (*f == '\\') || strchr(bad, *f)) {
1857 *(t++) = hexchar(*f >> 4);
1858 *(t++) = hexchar(*f);
1868 /// UNNEEDED by elogind
1870 char *ascii_strlower(char *t) {
1875 for (p = t; *p; p++)
1876 if (*p >= 'A' && *p <= 'Z')
1877 *p = *p - 'A' + 'a';
1883 _pure_ static bool hidden_file_allow_backup(const char *filename) {
1887 filename[0] == '.' ||
1888 streq(filename, "lost+found") ||
1889 streq(filename, "aquota.user") ||
1890 streq(filename, "aquota.group") ||
1891 endswith(filename, ".rpmnew") ||
1892 endswith(filename, ".rpmsave") ||
1893 endswith(filename, ".rpmorig") ||
1894 endswith(filename, ".dpkg-old") ||
1895 endswith(filename, ".dpkg-new") ||
1896 endswith(filename, ".dpkg-tmp") ||
1897 endswith(filename, ".dpkg-dist") ||
1898 endswith(filename, ".dpkg-bak") ||
1899 endswith(filename, ".dpkg-backup") ||
1900 endswith(filename, ".dpkg-remove") ||
1901 endswith(filename, ".swp");
1904 bool hidden_file(const char *filename) {
1907 if (endswith(filename, "~"))
1910 return hidden_file_allow_backup(filename);
1913 int fd_nonblock(int fd, bool nonblock) {
1918 flags = fcntl(fd, F_GETFL, 0);
1923 nflags = flags | O_NONBLOCK;
1925 nflags = flags & ~O_NONBLOCK;
1927 if (nflags == flags)
1930 if (fcntl(fd, F_SETFL, nflags) < 0)
1936 int fd_cloexec(int fd, bool cloexec) {
1941 flags = fcntl(fd, F_GETFD, 0);
1946 nflags = flags | FD_CLOEXEC;
1948 nflags = flags & ~FD_CLOEXEC;
1950 if (nflags == flags)
1953 if (fcntl(fd, F_SETFD, nflags) < 0)
1959 _pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
1962 assert(n_fdset == 0 || fdset);
1964 for (i = 0; i < n_fdset; i++)
1971 int close_all_fds(const int except[], unsigned n_except) {
1972 _cleanup_closedir_ DIR *d = NULL;
1976 assert(n_except == 0 || except);
1978 d = opendir("/proc/self/fd");
1983 /* When /proc isn't available (for example in chroots)
1984 * the fallback is brute forcing through the fd
1987 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
1988 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
1990 if (fd_in_set(fd, except, n_except))
1993 if (close_nointr(fd) < 0)
1994 if (errno != EBADF && r == 0)
2001 while ((de = readdir(d))) {
2004 if (hidden_file(de->d_name))
2007 if (safe_atoi(de->d_name, &fd) < 0)
2008 /* Let's better ignore this, just in case */
2017 if (fd_in_set(fd, except, n_except))
2020 if (close_nointr(fd) < 0) {
2021 /* Valgrind has its own FD and doesn't want to have it closed */
2022 if (errno != EBADF && r == 0)
2030 bool chars_intersect(const char *a, const char *b) {
2033 /* Returns true if any of the chars in a are in b. */
2034 for (p = a; *p; p++)
2041 /// UNNEEDED by elogind
2043 bool fstype_is_network(const char *fstype) {
2044 static const char table[] =
2059 x = startswith(fstype, "fuse.");
2063 return nulstr_contains(table, fstype);
2067 int flush_fd(int fd) {
2068 struct pollfd pollfd = {
2078 r = poll(&pollfd, 1, 0);
2088 l = read(fd, buf, sizeof(buf));
2094 if (errno == EAGAIN)
2103 void safe_close_pair(int p[]) {
2107 /* Special case pairs which use the same fd in both
2109 p[0] = p[1] = safe_close(p[0]);
2113 p[0] = safe_close(p[0]);
2114 p[1] = safe_close(p[1]);
2117 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
2124 while (nbytes > 0) {
2127 k = read(fd, p, nbytes);
2132 if (errno == EAGAIN && do_poll) {
2134 /* We knowingly ignore any return value here,
2135 * and expect that any error/EOF is reported
2138 fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
2142 return n > 0 ? n : -errno;
2156 int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
2159 n = loop_read(fd, buf, nbytes, do_poll);
2162 if ((size_t) n != nbytes)
2167 int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
2168 const uint8_t *p = buf;
2178 k = write(fd, p, nbytes);
2183 if (errno == EAGAIN && do_poll) {
2184 /* We knowingly ignore any return value here,
2185 * and expect that any error/EOF is reported
2188 fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
2195 if (nbytes > 0 && k == 0) /* Can't really happen */
2200 } while (nbytes > 0);
2205 int parse_size(const char *t, off_t base, off_t *size) {
2207 /* Soo, sometimes we want to parse IEC binary suffixes, and
2208 * sometimes SI decimal suffixes. This function can parse
2209 * both. Which one is the right way depends on the
2210 * context. Wikipedia suggests that SI is customary for
2211 * hardware metrics and network speeds, while IEC is
2212 * customary for most data sizes used by software and volatile
2213 * (RAM) memory. Hence be careful which one you pick!
2215 * In either case we use just K, M, G as suffix, and not Ki,
2216 * Mi, Gi or so (as IEC would suggest). That's because that's
2217 * frickin' ugly. But this means you really need to make sure
2218 * to document which base you are parsing when you use this
2223 unsigned long long factor;
2226 static const struct table iec[] = {
2227 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2228 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2229 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
2230 { "G", 1024ULL*1024ULL*1024ULL },
2231 { "M", 1024ULL*1024ULL },
2237 static const struct table si[] = {
2238 { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
2239 { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
2240 { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
2241 { "G", 1000ULL*1000ULL*1000ULL },
2242 { "M", 1000ULL*1000ULL },
2248 const struct table *table;
2250 unsigned long long r = 0;
2251 unsigned n_entries, start_pos = 0;
2254 assert(base == 1000 || base == 1024);
2259 n_entries = ELEMENTSOF(si);
2262 n_entries = ELEMENTSOF(iec);
2268 unsigned long long l2;
2274 l = strtoll(p, &e, 10);
2287 if (*e >= '0' && *e <= '9') {
2290 /* strotoull itself would accept space/+/- */
2291 l2 = strtoull(e, &e2, 10);
2293 if (errno == ERANGE)
2296 /* Ignore failure. E.g. 10.M is valid */
2303 e += strspn(e, WHITESPACE);
2305 for (i = start_pos; i < n_entries; i++)
2306 if (startswith(e, table[i].suffix)) {
2307 unsigned long long tmp;
2308 if ((unsigned long long) l + (frac > 0) > ULLONG_MAX / table[i].factor)
2310 tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
2311 if (tmp > ULLONG_MAX - r)
2315 if ((unsigned long long) (off_t) r != r)
2318 p = e + strlen(table[i].suffix);
2334 bool is_device_path(const char *path) {
2336 /* Returns true on paths that refer to a device, either in
2337 * sysfs or in /dev */
2340 path_startswith(path, "/dev/") ||
2341 path_startswith(path, "/sys/");
2344 /// UNNEEDED by elogind
2346 int dir_is_empty(const char *path) {
2347 _cleanup_closedir_ DIR *d;
2358 if (!de && errno != 0)
2364 if (!hidden_file(de->d_name))
2369 char* dirname_malloc(const char *path) {
2370 char *d, *dir, *dir2;
2387 void rename_process(const char name[8]) {
2390 /* This is a like a poor man's setproctitle(). It changes the
2391 * comm field, argv[0], and also the glibc's internally used
2392 * name of the process. For the first one a limit of 16 chars
2393 * applies, to the second one usually one of 10 (i.e. length
2394 * of "/sbin/init"), to the third one one of 7 (i.e. length of
2395 * "systemd"). If you pass a longer string it will be
2398 prctl(PR_SET_NAME, name);
2400 if (program_invocation_name)
2401 strncpy(program_invocation_name, name, strlen(program_invocation_name));
2403 if (saved_argc > 0) {
2407 strncpy(saved_argv[0], name, strlen(saved_argv[0]));
2409 for (i = 1; i < saved_argc; i++) {
2413 memzero(saved_argv[i], strlen(saved_argv[i]));
2419 char *lookup_uid(uid_t uid) {
2422 _cleanup_free_ char *buf = NULL;
2423 struct passwd pwbuf, *pw = NULL;
2425 /* Shortcut things to avoid NSS lookups */
2427 return strdup("root");
2429 bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
2433 buf = malloc(bufsize);
2437 if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
2438 return strdup(pw->pw_name);
2440 if (asprintf(&name, UID_FMT, uid) < 0)
2446 /// UNNEEDED by elogind
2448 char* getlogname_malloc(void) {
2452 if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
2457 return lookup_uid(uid);
2460 char *getusername_malloc(void) {
2467 return lookup_uid(getuid());
2471 bool is_temporary_fs(const struct statfs *s) {
2474 return F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) ||
2475 F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC);
2478 int fd_is_temporary_fs(int fd) {
2481 if (fstatfs(fd, &s) < 0)
2484 return is_temporary_fs(&s);
2487 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
2490 /* Under the assumption that we are running privileged we
2491 * first change the access mode and only then hand out
2492 * ownership to avoid a window where access is too open. */
2494 if (mode != MODE_INVALID)
2495 if (chmod(path, mode) < 0)
2498 if (uid != UID_INVALID || gid != GID_INVALID)
2499 if (chown(path, uid, gid) < 0)
2505 /// UNNEEDED by elogind
2507 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
2510 /* Under the assumption that we are running privileged we
2511 * first change the access mode and only then hand out
2512 * ownership to avoid a window where access is too open. */
2514 if (mode != MODE_INVALID)
2515 if (fchmod(fd, mode) < 0)
2518 if (uid != UID_INVALID || gid != GID_INVALID)
2519 if (fchown(fd, uid, gid) < 0)
2525 cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
2529 /* Allocates the cpuset in the right size */
2532 if (!(r = CPU_ALLOC(n)))
2535 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
2536 CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
2546 if (errno != EINVAL)
2554 int files_same(const char *filea, const char *fileb) {
2557 if (stat(filea, &a) < 0)
2560 if (stat(fileb, &b) < 0)
2563 return a.st_dev == b.st_dev &&
2564 a.st_ino == b.st_ino;
2567 /// UNNEEDED by elogind
2569 int running_in_chroot(void) {
2572 ret = files_same("/proc/1/root", "/");
2580 static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
2585 assert(percent <= 100);
2586 assert(new_length >= 3);
2588 if (old_length <= 3 || old_length <= new_length)
2589 return strndup(s, old_length);
2591 r = new0(char, new_length+1);
2595 x = (new_length * percent) / 100;
2597 if (x > new_length - 3)
2605 s + old_length - (new_length - x - 3),
2606 new_length - x - 3);
2611 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
2615 unsigned k, len, len2;
2618 assert(percent <= 100);
2619 assert(new_length >= 3);
2621 /* if no multibyte characters use ascii_ellipsize_mem for speed */
2622 if (ascii_is_valid(s))
2623 return ascii_ellipsize_mem(s, old_length, new_length, percent);
2625 if (old_length <= 3 || old_length <= new_length)
2626 return strndup(s, old_length);
2628 x = (new_length * percent) / 100;
2630 if (x > new_length - 3)
2634 for (i = s; k < x && i < s + old_length; i = utf8_next_char(i)) {
2637 c = utf8_encoded_to_unichar(i);
2640 k += unichar_iswide(c) ? 2 : 1;
2643 if (k > x) /* last character was wide and went over quota */
2646 for (j = s + old_length; k < new_length && j > i; ) {
2649 j = utf8_prev_char(j);
2650 c = utf8_encoded_to_unichar(j);
2653 k += unichar_iswide(c) ? 2 : 1;
2657 /* we don't actually need to ellipsize */
2659 return memdup(s, old_length + 1);
2661 /* make space for ellipsis */
2662 j = utf8_next_char(j);
2665 len2 = s + old_length - j;
2666 e = new(char, len + 3 + len2 + 1);
2671 printf("old_length=%zu new_length=%zu x=%zu len=%u len2=%u k=%u\n",
2672 old_length, new_length, x, len, len2, k);
2676 e[len] = 0xe2; /* tri-dot ellipsis: … */
2680 memcpy(e + len + 3, j, len2 + 1);
2685 char *ellipsize(const char *s, size_t length, unsigned percent) {
2686 return ellipsize_mem(s, strlen(s), length, percent);
2689 int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
2690 _cleanup_close_ int fd;
2696 mkdir_parents(path, 0755);
2698 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode > 0 ? mode : 0644);
2703 r = fchmod(fd, mode);
2708 if (uid != UID_INVALID || gid != GID_INVALID) {
2709 r = fchown(fd, uid, gid);
2714 if (stamp != USEC_INFINITY) {
2715 struct timespec ts[2];
2717 timespec_store(&ts[0], stamp);
2719 r = futimens(fd, ts);
2721 r = futimens(fd, NULL);
2728 int touch(const char *path) {
2729 return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, 0);
2732 /// UNNEEDED by elogind
2734 static char *unquote(const char *s, const char* quotes) {
2738 /* This is rather stupid, simply removes the heading and
2739 * trailing quotes if there is one. Doesn't care about
2740 * escaping or anything.
2742 * DON'T USE THIS FOR NEW CODE ANYMORE!*/
2748 if (strchr(quotes, s[0]) && s[l-1] == s[0])
2749 return strndup(s+1, l-2);
2755 noreturn void freeze(void) {
2757 /* Make sure nobody waits for us on a socket anymore */
2758 close_all_fds(NULL, 0);
2766 bool null_or_empty(struct stat *st) {
2769 if (S_ISREG(st->st_mode) && st->st_size <= 0)
2772 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
2778 int null_or_empty_path(const char *fn) {
2783 if (stat(fn, &st) < 0)
2786 return null_or_empty(&st);
2789 /// UNNEEDED by elogind
2791 int null_or_empty_fd(int fd) {
2796 if (fstat(fd, &st) < 0)
2799 return null_or_empty(&st);
2803 DIR *xopendirat(int fd, const char *name, int flags) {
2807 assert(!(flags & O_CREAT));
2809 nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
2822 /// UNNEEDED by elogind
2824 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
2825 _cleanup_free_ char *t = NULL, *u = NULL;
2828 u = unquote(tagvalue, QUOTES);
2832 enc_len = strlen(u) * 4 + 1;
2833 t = new(char, enc_len);
2837 if (encode_devnode_name(u, t, enc_len) < 0)
2840 return strjoin("/dev/disk/by-", by, "/", t, NULL);
2843 char *fstab_node_to_udev_node(const char *p) {
2846 if (startswith(p, "LABEL="))
2847 return tag_to_udev_node(p+6, "label");
2849 if (startswith(p, "UUID="))
2850 return tag_to_udev_node(p+5, "uuid");
2852 if (startswith(p, "PARTUUID="))
2853 return tag_to_udev_node(p+9, "partuuid");
2855 if (startswith(p, "PARTLABEL="))
2856 return tag_to_udev_node(p+10, "partlabel");
2862 bool dirent_is_file(const struct dirent *de) {
2865 if (hidden_file(de->d_name))
2868 if (de->d_type != DT_REG &&
2869 de->d_type != DT_LNK &&
2870 de->d_type != DT_UNKNOWN)
2876 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
2879 if (de->d_type != DT_REG &&
2880 de->d_type != DT_LNK &&
2881 de->d_type != DT_UNKNOWN)
2884 if (hidden_file_allow_backup(de->d_name))
2887 return endswith(de->d_name, suffix);
2890 /// UNNEEDED by elogind
2892 static int do_execute(char **directories, usec_t timeout, char *argv[]) {
2893 _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
2894 _cleanup_set_free_free_ Set *seen = NULL;
2897 /* We fork this all off from a child process so that we can
2898 * somewhat cleanly make use of SIGALRM to set a time limit */
2900 (void) reset_all_signal_handlers();
2901 (void) reset_signal_mask();
2903 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
2905 pids = hashmap_new(NULL);
2909 seen = set_new(&string_hash_ops);
2913 STRV_FOREACH(directory, directories) {
2914 _cleanup_closedir_ DIR *d;
2917 d = opendir(*directory);
2919 if (errno == ENOENT)
2922 return log_error_errno(errno, "Failed to open directory %s: %m", *directory);
2925 FOREACH_DIRENT(de, d, break) {
2926 _cleanup_free_ char *path = NULL;
2930 if (!dirent_is_file(de))
2933 if (set_contains(seen, de->d_name)) {
2934 log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name);
2938 r = set_put_strdup(seen, de->d_name);
2942 path = strjoin(*directory, "/", de->d_name, NULL);
2946 if (null_or_empty_path(path)) {
2947 log_debug("%s is empty (a mask).", path);
2953 log_error_errno(errno, "Failed to fork: %m");
2955 } else if (pid == 0) {
2958 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
2968 return log_error_errno(errno, "Failed to execute %s: %m", path);
2971 log_debug("Spawned %s as " PID_FMT ".", path, pid);
2973 r = hashmap_put(pids, UINT_TO_PTR(pid), path);
2980 /* Abort execution of this process after the timout. We simply
2981 * rely on SIGALRM as default action terminating the process,
2982 * and turn on alarm(). */
2984 if (timeout != USEC_INFINITY)
2985 alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
2987 while (!hashmap_isempty(pids)) {
2988 _cleanup_free_ char *path = NULL;
2991 pid = PTR_TO_UINT(hashmap_first_key(pids));
2994 path = hashmap_remove(pids, UINT_TO_PTR(pid));
2997 wait_for_terminate_and_warn(path, pid, true);
3003 void execute_directories(const char* const* directories, usec_t timeout, char *argv[]) {
3007 char **dirs = (char**) directories;
3009 assert(!strv_isempty(dirs));
3011 name = basename(dirs[0]);
3012 assert(!isempty(name));
3014 /* Executes all binaries in the directories in parallel and waits
3015 * for them to finish. Optionally a timeout is applied. If a file
3016 * with the same name exists in more than one directory, the
3017 * earliest one wins. */
3019 executor_pid = fork();
3020 if (executor_pid < 0) {
3021 log_error_errno(errno, "Failed to fork: %m");
3024 } else if (executor_pid == 0) {
3025 r = do_execute(dirs, timeout, argv);
3026 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
3029 wait_for_terminate_and_warn(name, executor_pid, true);
3033 bool nulstr_contains(const char*nulstr, const char *needle) {
3039 NULSTR_FOREACH(i, nulstr)
3040 if (streq(i, needle))
3046 /// UNNEEDED by elogind
3048 bool plymouth_running(void) {
3049 return access("/run/plymouth/pid", F_OK) >= 0;
3053 char* strshorten(char *s, size_t l) {
3062 int pipe_eof(int fd) {
3063 struct pollfd pollfd = {
3065 .events = POLLIN|POLLHUP,
3070 r = poll(&pollfd, 1, 0);
3077 return pollfd.revents & POLLHUP;
3080 int fd_wait_for_event(int fd, int event, usec_t t) {
3082 struct pollfd pollfd = {
3090 r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
3097 return pollfd.revents;
3100 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
3109 r = tempfn_xxxxxx(path, NULL, &t);
3113 fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC);
3119 f = fdopen(fd, "we");
3133 /// UNNEEDED by elogind
3135 int symlink_atomic(const char *from, const char *to) {
3136 _cleanup_free_ char *t = NULL;
3142 r = tempfn_random(to, NULL, &t);
3146 if (symlink(from, t) < 0)
3149 if (rename(t, to) < 0) {
3157 int symlink_idempotent(const char *from, const char *to) {
3158 _cleanup_free_ char *p = NULL;
3164 if (symlink(from, to) < 0) {
3165 if (errno != EEXIST)
3168 r = readlink_malloc(to, &p);
3172 if (!streq(p, from))
3179 int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
3180 _cleanup_free_ char *t = NULL;
3185 r = tempfn_random(path, NULL, &t);
3189 if (mknod(t, mode, dev) < 0)
3192 if (rename(t, path) < 0) {
3200 int mkfifo_atomic(const char *path, mode_t mode) {
3201 _cleanup_free_ char *t = NULL;
3206 r = tempfn_random(path, NULL, &t);
3210 if (mkfifo(t, mode) < 0)
3213 if (rename(t, path) < 0) {
3222 bool display_is_local(const char *display) {
3226 display[0] == ':' &&
3227 display[1] >= '0' &&
3231 int socket_from_display(const char *display, char **path) {
3238 if (!display_is_local(display))
3241 k = strspn(display+1, "0123456789");
3243 f = new(char, strlen("/tmp/.X11-unix/X") + k + 1);
3247 c = stpcpy(f, "/tmp/.X11-unix/X");
3248 memcpy(c, display+1, k);
3257 const char **username,
3258 uid_t *uid, gid_t *gid,
3260 const char **shell) {
3268 /* We enforce some special rules for uid=0: in order to avoid
3269 * NSS lookups for root we hardcode its data. */
3271 if (streq(*username, "root") || streq(*username, "0")) {
3289 if (parse_uid(*username, &u) >= 0) {
3293 /* If there are multiple users with the same id, make
3294 * sure to leave $USER to the configured value instead
3295 * of the first occurrence in the database. However if
3296 * the uid was configured by a numeric uid, then let's
3297 * pick the real username from /etc/passwd. */
3299 *username = p->pw_name;
3302 p = getpwnam(*username);
3306 return errno > 0 ? -errno : -ESRCH;
3318 *shell = p->pw_shell;
3323 char* uid_to_name(uid_t uid) {
3328 return strdup("root");
3332 return strdup(p->pw_name);
3334 if (asprintf(&r, UID_FMT, uid) < 0)
3340 char* gid_to_name(gid_t gid) {
3345 return strdup("root");
3349 return strdup(p->gr_name);
3351 if (asprintf(&r, GID_FMT, gid) < 0)
3357 int get_group_creds(const char **groupname, gid_t *gid) {
3363 /* We enforce some special rules for gid=0: in order to avoid
3364 * NSS lookups for root we hardcode its data. */
3366 if (streq(*groupname, "root") || streq(*groupname, "0")) {
3367 *groupname = "root";
3375 if (parse_gid(*groupname, &id) >= 0) {
3380 *groupname = g->gr_name;
3383 g = getgrnam(*groupname);
3387 return errno > 0 ? -errno : -ESRCH;
3395 int in_gid(gid_t gid) {
3397 int ngroups_max, r, i;
3399 if (getgid() == gid)
3402 if (getegid() == gid)
3405 ngroups_max = sysconf(_SC_NGROUPS_MAX);
3406 assert(ngroups_max > 0);
3408 gids = alloca(sizeof(gid_t) * ngroups_max);
3410 r = getgroups(ngroups_max, gids);
3414 for (i = 0; i < r; i++)
3421 /// UNNEEDED by elogind
3423 int in_group(const char *name) {
3427 r = get_group_creds(&name, &gid);
3434 int glob_exists(const char *path) {
3435 _cleanup_globfree_ glob_t g = {};
3441 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
3443 if (k == GLOB_NOMATCH)
3445 else if (k == GLOB_NOSPACE)
3448 return !strv_isempty(g.gl_pathv);
3450 return errno ? -errno : -EIO;
3453 int glob_extend(char ***strv, const char *path) {
3454 _cleanup_globfree_ glob_t g = {};
3459 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
3461 if (k == GLOB_NOMATCH)
3463 else if (k == GLOB_NOSPACE)
3465 else if (k != 0 || strv_isempty(g.gl_pathv))
3466 return errno ? -errno : -EIO;
3468 STRV_FOREACH(p, g.gl_pathv) {
3469 k = strv_extend(strv, *p);
3478 int dirent_ensure_type(DIR *d, struct dirent *de) {
3484 if (de->d_type != DT_UNKNOWN)
3487 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
3491 S_ISREG(st.st_mode) ? DT_REG :
3492 S_ISDIR(st.st_mode) ? DT_DIR :
3493 S_ISLNK(st.st_mode) ? DT_LNK :
3494 S_ISFIFO(st.st_mode) ? DT_FIFO :
3495 S_ISSOCK(st.st_mode) ? DT_SOCK :
3496 S_ISCHR(st.st_mode) ? DT_CHR :
3497 S_ISBLK(st.st_mode) ? DT_BLK :
3503 int get_files_in_directory(const char *path, char ***list) {
3504 _cleanup_closedir_ DIR *d = NULL;
3505 size_t bufsize = 0, n = 0;
3506 _cleanup_strv_free_ char **l = NULL;
3510 /* Returns all files in a directory in *list, and the number
3511 * of files as return value. If list is NULL returns only the
3523 if (!de && errno != 0)
3528 dirent_ensure_type(d, de);
3530 if (!dirent_is_file(de))
3534 /* one extra slot is needed for the terminating NULL */
3535 if (!GREEDY_REALLOC(l, bufsize, n + 2))
3538 l[n] = strdup(de->d_name);
3549 l = NULL; /* avoid freeing */
3555 char *strjoin(const char *x, ...) {
3569 t = va_arg(ap, const char *);
3574 if (n > ((size_t) -1) - l) {
3598 t = va_arg(ap, const char *);
3612 bool is_main_thread(void) {
3613 static thread_local int cached = 0;
3615 if (_unlikely_(cached == 0))
3616 cached = getpid() == gettid() ? 1 : -1;
3621 /// UNNEEDED by elogind
3623 int block_get_whole_disk(dev_t d, dev_t *ret) {
3630 /* If it has a queue this is good enough for us */
3631 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
3634 r = access(p, F_OK);
3642 /* If it is a partition find the originating device */
3643 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
3646 r = access(p, F_OK);
3652 /* Get parent dev_t */
3653 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
3656 r = read_one_line_file(p, &s);
3662 r = sscanf(s, "%u:%u", &m, &n);
3668 /* Only return this if it is really good enough for us. */
3669 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
3672 r = access(p, F_OK);
3676 *ret = makedev(m, n);
3684 static const char *const ioprio_class_table[] = {
3685 [IOPRIO_CLASS_NONE] = "none",
3686 [IOPRIO_CLASS_RT] = "realtime",
3687 [IOPRIO_CLASS_BE] = "best-effort",
3688 [IOPRIO_CLASS_IDLE] = "idle"
3691 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
3693 static const char *const sigchld_code_table[] = {
3694 [CLD_EXITED] = "exited",
3695 [CLD_KILLED] = "killed",
3696 [CLD_DUMPED] = "dumped",
3697 [CLD_TRAPPED] = "trapped",
3698 [CLD_STOPPED] = "stopped",
3699 [CLD_CONTINUED] = "continued",
3702 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
3704 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
3705 [LOG_FAC(LOG_KERN)] = "kern",
3706 [LOG_FAC(LOG_USER)] = "user",
3707 [LOG_FAC(LOG_MAIL)] = "mail",
3708 [LOG_FAC(LOG_DAEMON)] = "daemon",
3709 [LOG_FAC(LOG_AUTH)] = "auth",
3710 [LOG_FAC(LOG_SYSLOG)] = "syslog",
3711 [LOG_FAC(LOG_LPR)] = "lpr",
3712 [LOG_FAC(LOG_NEWS)] = "news",
3713 [LOG_FAC(LOG_UUCP)] = "uucp",
3714 [LOG_FAC(LOG_CRON)] = "cron",
3715 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
3716 [LOG_FAC(LOG_FTP)] = "ftp",
3717 [LOG_FAC(LOG_LOCAL0)] = "local0",
3718 [LOG_FAC(LOG_LOCAL1)] = "local1",
3719 [LOG_FAC(LOG_LOCAL2)] = "local2",
3720 [LOG_FAC(LOG_LOCAL3)] = "local3",
3721 [LOG_FAC(LOG_LOCAL4)] = "local4",
3722 [LOG_FAC(LOG_LOCAL5)] = "local5",
3723 [LOG_FAC(LOG_LOCAL6)] = "local6",
3724 [LOG_FAC(LOG_LOCAL7)] = "local7"
3727 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
3729 static const char *const log_level_table[] = {
3730 [LOG_EMERG] = "emerg",
3731 [LOG_ALERT] = "alert",
3732 [LOG_CRIT] = "crit",
3734 [LOG_WARNING] = "warning",
3735 [LOG_NOTICE] = "notice",
3736 [LOG_INFO] = "info",
3737 [LOG_DEBUG] = "debug"
3740 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
3742 static const char* const sched_policy_table[] = {
3743 [SCHED_OTHER] = "other",
3744 [SCHED_BATCH] = "batch",
3745 [SCHED_IDLE] = "idle",
3746 [SCHED_FIFO] = "fifo",
3750 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
3752 static const char* const rlimit_table[_RLIMIT_MAX] = {
3753 [RLIMIT_CPU] = "LimitCPU",
3754 [RLIMIT_FSIZE] = "LimitFSIZE",
3755 [RLIMIT_DATA] = "LimitDATA",
3756 [RLIMIT_STACK] = "LimitSTACK",
3757 [RLIMIT_CORE] = "LimitCORE",
3758 [RLIMIT_RSS] = "LimitRSS",
3759 [RLIMIT_NOFILE] = "LimitNOFILE",
3760 [RLIMIT_AS] = "LimitAS",
3761 [RLIMIT_NPROC] = "LimitNPROC",
3762 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
3763 [RLIMIT_LOCKS] = "LimitLOCKS",
3764 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
3765 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
3766 [RLIMIT_NICE] = "LimitNICE",
3767 [RLIMIT_RTPRIO] = "LimitRTPRIO",
3768 [RLIMIT_RTTIME] = "LimitRTTIME"
3771 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
3773 static const char* const ip_tos_table[] = {
3774 [IPTOS_LOWDELAY] = "low-delay",
3775 [IPTOS_THROUGHPUT] = "throughput",
3776 [IPTOS_RELIABILITY] = "reliability",
3777 [IPTOS_LOWCOST] = "low-cost",
3780 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
3782 bool kexec_loaded(void) {
3783 bool loaded = false;
3786 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
3794 /// UNNEEDED by elogind
3796 int prot_from_flags(int flags) {
3798 switch (flags & O_ACCMODE) {
3807 return PROT_READ|PROT_WRITE;
3814 char *format_bytes(char *buf, size_t l, off_t t) {
3817 static const struct {
3821 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
3822 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
3823 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
3824 { "G", 1024ULL*1024ULL*1024ULL },
3825 { "M", 1024ULL*1024ULL },
3829 if (t == (off_t) -1)
3832 for (i = 0; i < ELEMENTSOF(table); i++) {
3834 if (t >= table[i].factor) {
3837 (unsigned long long) (t / table[i].factor),
3838 (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
3845 snprintf(buf, l, "%lluB", (unsigned long long) t);
3854 void* memdup(const void *p, size_t l) {
3867 int fd_inc_sndbuf(int fd, size_t n) {
3869 socklen_t l = sizeof(value);
3871 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
3872 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
3875 /* If we have the privileges we will ignore the kernel limit. */
3878 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
3879 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
3885 int fd_inc_rcvbuf(int fd, size_t n) {
3887 socklen_t l = sizeof(value);
3889 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
3890 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
3893 /* If we have the privileges we will ignore the kernel limit. */
3896 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
3897 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
3902 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
3903 bool stdout_is_tty, stderr_is_tty;
3904 pid_t parent_pid, agent_pid;
3905 sigset_t ss, saved_ss;
3913 /* Spawns a temporary TTY agent, making sure it goes away when
3916 parent_pid = getpid();
3918 /* First we temporarily block all signals, so that the new
3919 * child has them blocked initially. This way, we can be sure
3920 * that SIGTERMs are not lost we might send to the agent. */
3921 assert_se(sigfillset(&ss) >= 0);
3922 assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0);
3925 if (agent_pid < 0) {
3926 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
3930 if (agent_pid != 0) {
3931 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
3938 * Make sure the agent goes away when the parent dies */
3939 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
3940 _exit(EXIT_FAILURE);
3942 /* Make sure we actually can kill the agent, if we need to, in
3943 * case somebody invoked us from a shell script that trapped
3944 * SIGTERM or so... */
3945 (void) reset_all_signal_handlers();
3946 (void) reset_signal_mask();
3948 /* Check whether our parent died before we were able
3949 * to set the death signal and unblock the signals */
3950 if (getppid() != parent_pid)
3951 _exit(EXIT_SUCCESS);
3953 /* Don't leak fds to the agent */
3954 close_all_fds(except, n_except);
3956 stdout_is_tty = isatty(STDOUT_FILENO);
3957 stderr_is_tty = isatty(STDERR_FILENO);
3959 if (!stdout_is_tty || !stderr_is_tty) {
3962 /* Detach from stdout/stderr. and reopen
3963 * /dev/tty for them. This is important to
3964 * ensure that when systemctl is started via
3965 * popen() or a similar call that expects to
3966 * read EOF we actually do generate EOF and
3967 * not delay this indefinitely by because we
3968 * keep an unused copy of stdin around. */
3969 fd = open("/dev/tty", O_WRONLY);
3971 log_error_errno(errno, "Failed to open /dev/tty: %m");
3972 _exit(EXIT_FAILURE);
3976 dup2(fd, STDOUT_FILENO);
3979 dup2(fd, STDERR_FILENO);
3985 /* Count arguments */
3987 for (n = 0; va_arg(ap, char*); n++)
3992 l = alloca(sizeof(char *) * (n + 1));
3994 /* Fill in arguments */
3996 for (i = 0; i <= n; i++)
3997 l[i] = va_arg(ap, char*);
4001 _exit(EXIT_FAILURE);
4004 /// UNNEEDED by elogind
4006 int setrlimit_closest(int resource, const struct rlimit *rlim) {
4007 struct rlimit highest, fixed;
4011 if (setrlimit(resource, rlim) >= 0)
4017 /* So we failed to set the desired setrlimit, then let's try
4018 * to get as close as we can */
4019 assert_se(getrlimit(resource, &highest) == 0);
4021 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
4022 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
4024 if (setrlimit(resource, &fixed) < 0)
4030 bool http_etag_is_valid(const char *etag) {
4034 if (!endswith(etag, "\""))
4037 if (!startswith(etag, "\"") && !startswith(etag, "W/\""))
4044 bool http_url_is_valid(const char *url) {
4050 p = startswith(url, "http://");
4052 p = startswith(url, "https://");
4059 return ascii_is_valid(p);
4062 bool documentation_url_is_valid(const char *url) {
4068 if (http_url_is_valid(url))
4071 p = startswith(url, "file:/");
4073 p = startswith(url, "info:");
4075 p = startswith(url, "man:");
4080 return ascii_is_valid(p);
4083 bool in_initrd(void) {
4084 static int saved = -1;
4090 /* We make two checks here:
4092 * 1. the flag file /etc/initrd-release must exist
4093 * 2. the root file system must be a memory file system
4095 * The second check is extra paranoia, since misdetecting an
4096 * initrd can have bad bad consequences due the initrd
4097 * emptying when transititioning to the main systemd.
4100 saved = access("/etc/initrd-release", F_OK) >= 0 &&
4101 statfs("/", &s) >= 0 &&
4102 is_temporary_fs(&s);
4107 int get_home_dir(char **_h) {
4115 /* Take the user specified one */
4116 e = secure_getenv("HOME");
4117 if (e && path_is_absolute(e)) {
4126 /* Hardcode home directory for root to avoid NSS */
4129 h = strdup("/root");
4137 /* Check the database... */
4141 return errno > 0 ? -errno : -ESRCH;
4143 if (!path_is_absolute(p->pw_dir))
4146 h = strdup(p->pw_dir);
4154 /// UNNEEDED by elogind
4156 int get_shell(char **_s) {
4164 /* Take the user specified one */
4165 e = getenv("SHELL");
4175 /* Hardcode home directory for root to avoid NSS */
4178 s = strdup("/bin/sh");
4186 /* Check the database... */
4190 return errno > 0 ? -errno : -ESRCH;
4192 if (!path_is_absolute(p->pw_shell))
4195 s = strdup(p->pw_shell);
4204 bool filename_is_valid(const char *p) {
4218 if (strlen(p) > FILENAME_MAX)
4224 bool string_is_safe(const char *p) {
4230 for (t = p; *t; t++) {
4231 if (*t > 0 && *t < ' ')
4234 if (strchr("\\\"\'\x7f", *t))
4242 * Check if a string contains control characters. If 'ok' is non-NULL
4243 * it may be a string containing additional CCs to be considered OK.
4245 bool string_has_cc(const char *p, const char *ok) {
4250 for (t = p; *t; t++) {
4251 if (ok && strchr(ok, *t))
4254 if (*t > 0 && *t < ' ')
4264 bool path_is_safe(const char *p) {
4269 if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
4272 if (strlen(p)+1 > PATH_MAX)
4275 /* The following two checks are not really dangerous, but hey, they still are confusing */
4276 if (streq(p, ".") || startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
4279 if (strstr(p, "//"))
4285 /// UNNEEDED by elogind
4287 /* hey glibc, APIs with callbacks without a user pointer are so useless */
4288 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
4289 int (*compar) (const void *, const void *, void *), void *arg) {
4298 p = (void *)(((const char *) base) + (idx * size));
4299 comparison = compar(key, p, arg);
4302 else if (comparison > 0)
4310 void init_gettext(void) {
4311 setlocale(LC_ALL, "");
4312 textdomain(GETTEXT_PACKAGE);
4316 bool is_locale_utf8(void) {
4318 static int cached_answer = -1;
4320 if (cached_answer >= 0)
4323 if (!setlocale(LC_ALL, "")) {
4324 cached_answer = true;
4328 set = nl_langinfo(CODESET);
4330 cached_answer = true;
4334 if (streq(set, "UTF-8")) {
4335 cached_answer = true;
4339 /* For LC_CTYPE=="C" return true, because CTYPE is effectly
4340 * unset and everything can do to UTF-8 nowadays. */
4341 set = setlocale(LC_CTYPE, NULL);
4343 cached_answer = true;
4347 /* Check result, but ignore the result if C was set
4350 STR_IN_SET(set, "C", "POSIX") &&
4351 !getenv("LC_ALL") &&
4352 !getenv("LC_CTYPE") &&
4356 return (bool) cached_answer;
4359 const char *draw_special_char(DrawSpecialChar ch) {
4360 static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
4363 [DRAW_TREE_VERTICAL] = "\342\224\202 ", /* │ */
4364 [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */
4365 [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */
4366 [DRAW_TREE_SPACE] = " ", /* */
4367 [DRAW_TRIANGULAR_BULLET] = "\342\200\243", /* ‣ */
4368 [DRAW_BLACK_CIRCLE] = "\342\227\217", /* ● */
4369 [DRAW_ARROW] = "\342\206\222", /* → */
4370 [DRAW_DASH] = "\342\200\223", /* – */
4373 /* ASCII fallback */ {
4374 [DRAW_TREE_VERTICAL] = "| ",
4375 [DRAW_TREE_BRANCH] = "|-",
4376 [DRAW_TREE_RIGHT] = "`-",
4377 [DRAW_TREE_SPACE] = " ",
4378 [DRAW_TRIANGULAR_BULLET] = ">",
4379 [DRAW_BLACK_CIRCLE] = "*",
4380 [DRAW_ARROW] = "->",
4385 return draw_table[!is_locale_utf8()][ch];
4388 /// UNNEEDED by elogind
4390 char *strreplace(const char *text, const char *old_string, const char *new_string) {
4393 size_t l, old_len, new_len;
4399 old_len = strlen(old_string);
4400 new_len = strlen(new_string);
4413 if (!startswith(f, old_string)) {
4419 nl = l - old_len + new_len;
4420 a = realloc(r, nl + 1);
4428 t = stpcpy(t, new_string);
4440 char *strip_tab_ansi(char **ibuf, size_t *_isz) {
4441 const char *i, *begin = NULL;
4446 } state = STATE_OTHER;
4448 size_t osz = 0, isz;
4454 /* Strips ANSI color and replaces TABs by 8 spaces */
4456 isz = _isz ? *_isz : strlen(*ibuf);
4458 f = open_memstream(&obuf, &osz);
4462 for (i = *ibuf; i < *ibuf + isz + 1; i++) {
4467 if (i >= *ibuf + isz) /* EOT */
4469 else if (*i == '\x1B')
4470 state = STATE_ESCAPE;
4471 else if (*i == '\t')
4478 if (i >= *ibuf + isz) { /* EOT */
4481 } else if (*i == '[') {
4482 state = STATE_BRACKET;
4487 state = STATE_OTHER;
4494 if (i >= *ibuf + isz || /* EOT */
4495 (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
4498 state = STATE_OTHER;
4500 } else if (*i == 'm')
4501 state = STATE_OTHER;
4523 int on_ac_power(void) {
4524 bool found_offline = false, found_online = false;
4525 _cleanup_closedir_ DIR *d = NULL;
4527 d = opendir("/sys/class/power_supply");
4529 return errno == ENOENT ? true : -errno;
4533 _cleanup_close_ int fd = -1, device = -1;
4539 if (!de && errno != 0)
4545 if (hidden_file(de->d_name))
4548 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
4550 if (errno == ENOENT || errno == ENOTDIR)
4556 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
4558 if (errno == ENOENT)
4564 n = read(fd, contents, sizeof(contents));
4568 if (n != 6 || memcmp(contents, "Mains\n", 6))
4572 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
4574 if (errno == ENOENT)
4580 n = read(fd, contents, sizeof(contents));
4584 if (n != 2 || contents[1] != '\n')
4587 if (contents[0] == '1') {
4588 found_online = true;
4590 } else if (contents[0] == '0')
4591 found_offline = true;
4596 return found_online || !found_offline;
4600 static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
4607 if (!path_strv_resolve_uniq(search, root))
4610 STRV_FOREACH(i, search) {
4611 _cleanup_free_ char *p = NULL;
4615 p = strjoin(root, *i, "/", path, NULL);
4617 p = strjoin(*i, "/", path, NULL);
4627 if (errno != ENOENT)
4634 int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
4635 _cleanup_strv_free_ char **copy = NULL;
4641 if (path_is_absolute(path)) {
4644 f = fopen(path, mode);
4653 copy = strv_copy((char**) search);
4657 return search_and_fopen_internal(path, mode, root, copy, _f);
4660 /// UNNEEDED by elogind
4662 int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
4663 _cleanup_strv_free_ char **s = NULL;
4665 if (path_is_absolute(path)) {
4668 f = fopen(path, mode);
4677 s = strv_split_nulstr(search);
4681 return search_and_fopen_internal(path, mode, root, s, _f);
4685 char *strextend(char **x, ...) {
4692 l = f = *x ? strlen(*x) : 0;
4699 t = va_arg(ap, const char *);
4704 if (n > ((size_t) -1) - l) {
4713 r = realloc(*x, l+1);
4723 t = va_arg(ap, const char *);
4737 char *strrep(const char *s, unsigned n) {
4745 p = r = malloc(l * n + 1);
4749 for (i = 0; i < n; i++)
4756 void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
4763 if (*allocated >= need)
4766 newalloc = MAX(need * 2, 64u / size);
4767 a = newalloc * size;
4769 /* check for overflows */
4770 if (a < size * need)
4778 *allocated = newalloc;
4782 void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
4791 q = greedy_realloc(p, allocated, need, size);
4795 if (*allocated > prev)
4796 memzero(q + prev * size, (*allocated - prev) * size);
4801 bool id128_is_valid(const char *s) {
4807 /* Simple formatted 128bit hex string */
4809 for (i = 0; i < l; i++) {
4812 if (!(c >= '0' && c <= '9') &&
4813 !(c >= 'a' && c <= 'z') &&
4814 !(c >= 'A' && c <= 'Z'))
4818 } else if (l == 36) {
4820 /* Formatted UUID */
4822 for (i = 0; i < l; i++) {
4825 if ((i == 8 || i == 13 || i == 18 || i == 23)) {
4829 if (!(c >= '0' && c <= '9') &&
4830 !(c >= 'a' && c <= 'z') &&
4831 !(c >= 'A' && c <= 'Z'))
4842 /// UNNEEDED by elogind
4844 int split_pair(const char *s, const char *sep, char **l, char **r) {
4859 a = strndup(s, x - s);
4863 b = strdup(x + strlen(sep));
4875 int shall_restore_state(void) {
4876 _cleanup_free_ char *value = NULL;
4879 r = get_proc_cmdline_key("systemd.restore_state=", &value);
4885 return parse_boolean(value) != 0;
4889 int proc_cmdline(char **ret) {
4892 if (detect_container(NULL) > 0)
4893 return get_process_cmdline(1, 0, false, ret);
4895 return read_one_line_file("/proc/cmdline", ret);
4898 int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
4899 _cleanup_free_ char *line = NULL;
4905 r = proc_cmdline(&line);
4911 _cleanup_free_ char *word = NULL;
4914 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
4920 /* Filter out arguments that are intended only for the
4922 if (!in_initrd() && startswith(word, "rd."))
4925 value = strchr(word, '=');
4929 r = parse_item(word, value);
4937 int get_proc_cmdline_key(const char *key, char **value) {
4938 _cleanup_free_ char *line = NULL, *ret = NULL;
4945 r = proc_cmdline(&line);
4951 _cleanup_free_ char *word = NULL;
4954 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
4960 /* Filter out arguments that are intended only for the
4962 if (!in_initrd() && startswith(word, "rd."))
4966 e = startswith(word, key);
4970 r = free_and_strdup(&ret, e);
4976 if (streq(word, key))
4990 int container_get_leader(const char *machine, pid_t *pid) {
4991 _cleanup_free_ char *s = NULL, *class = NULL;
4999 if (!machine_name_is_valid(machine))
5002 p = strjoina("/run/systemd/machines/", machine);
5003 r = parse_env_file(p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
5011 if (!streq_ptr(class, "container"))
5014 r = parse_pid(s, &leader);
5024 int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd) {
5025 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, netnsfd = -1, usernsfd = -1;
5033 mntns = procfs_file_alloca(pid, "ns/mnt");
5034 mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5042 pidns = procfs_file_alloca(pid, "ns/pid");
5043 pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5051 netns = procfs_file_alloca(pid, "ns/net");
5052 netnsfd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5060 userns = procfs_file_alloca(pid, "ns/user");
5061 usernsfd = open(userns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5062 if (usernsfd < 0 && errno != ENOENT)
5069 root = procfs_file_alloca(pid, "root");
5070 rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
5076 *pidns_fd = pidnsfd;
5079 *mntns_fd = mntnsfd;
5082 *netns_fd = netnsfd;
5085 *userns_fd = usernsfd;
5090 pidnsfd = mntnsfd = netnsfd = usernsfd = -1;
5095 int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd) {
5096 if (userns_fd >= 0) {
5097 /* Can't setns to your own userns, since then you could
5098 * escalate from non-root to root in your own namespace, so
5099 * check if namespaces equal before attempting to enter. */
5100 _cleanup_free_ char *userns_fd_path = NULL;
5102 if (asprintf(&userns_fd_path, "/proc/self/fd/%d", userns_fd) < 0)
5105 r = files_same(userns_fd_path, "/proc/self/ns/user");
5113 if (setns(pidns_fd, CLONE_NEWPID) < 0)
5117 if (setns(mntns_fd, CLONE_NEWNS) < 0)
5121 if (setns(netns_fd, CLONE_NEWNET) < 0)
5125 if (setns(userns_fd, CLONE_NEWUSER) < 0)
5129 if (fchdir(root_fd) < 0)
5132 if (chroot(".") < 0)
5136 return reset_uid_gid();
5139 int getpeercred(int fd, struct ucred *ucred) {
5140 socklen_t n = sizeof(struct ucred);
5147 r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
5151 if (n != sizeof(struct ucred))
5154 /* Check if the data is actually useful and not suppressed due
5155 * to namespacing issues */
5158 if (u.uid == UID_INVALID)
5160 if (u.gid == GID_INVALID)
5167 int getpeersec(int fd, char **ret) {
5179 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
5183 if (errno != ERANGE)
5190 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
5206 /* This is much like like mkostemp() but is subject to umask(). */
5207 int mkostemp_safe(char *pattern, int flags) {
5208 _cleanup_umask_ mode_t u;
5215 fd = mkostemp(pattern, flags);
5222 /// UNNEEDED by elogind
5224 int open_tmpfile(const char *path, int flags) {
5231 /* Try O_TMPFILE first, if it is supported */
5232 fd = open(path, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
5237 /* Fall back to unguessable name + unlinking */
5238 p = strjoina(path, "/systemd-tmp-XXXXXX");
5240 fd = mkostemp_safe(p, flags);
5249 int fd_warn_permissions(const char *path, int fd) {
5252 if (fstat(fd, &st) < 0)
5255 if (st.st_mode & 0111)
5256 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
5258 if (st.st_mode & 0002)
5259 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
5261 if (getpid() == 1 && (st.st_mode & 0044) != 0044)
5262 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);
5267 /// UNNEEDED by elogind
5269 unsigned long personality_from_string(const char *p) {
5271 /* Parse a personality specifier. We introduce our own
5272 * identifiers that indicate specific ABIs, rather than just
5273 * hints regarding the register size, since we want to keep
5274 * things open for multiple locally supported ABIs for the
5275 * same register size. We try to reuse the ABI identifiers
5276 * used by libseccomp. */
5278 #if defined(__x86_64__)
5280 if (streq(p, "x86"))
5283 if (streq(p, "x86-64"))
5286 #elif defined(__i386__)
5288 if (streq(p, "x86"))
5292 return PERSONALITY_INVALID;
5295 const char* personality_to_string(unsigned long p) {
5297 #if defined(__x86_64__)
5299 if (p == PER_LINUX32)
5305 #elif defined(__i386__)
5315 uint64_t physical_memory(void) {
5318 /* We return this as uint64_t in case we are running as 32bit
5319 * process on a 64bit kernel with huge amounts of memory */
5321 mem = sysconf(_SC_PHYS_PAGES);
5324 return (uint64_t) mem * (uint64_t) page_size();
5327 /// UNNEEDED by elogind
5329 void hexdump(FILE *f, const void *p, size_t s) {
5330 const uint8_t *b = p;
5333 assert(s == 0 || b);
5338 fprintf(f, "%04x ", n);
5340 for (i = 0; i < 16; i++) {
5345 fprintf(f, "%02x ", b[i]);
5353 for (i = 0; i < 16; i++) {
5358 fputc(isprint(b[i]) ? (char) b[i] : '.', f);
5372 int update_reboot_param_file(const char *param) {
5377 r = write_string_file(REBOOT_PARAM_FILE, param, WRITE_STRING_FILE_CREATE);
5379 log_error("Failed to write reboot param to "
5380 REBOOT_PARAM_FILE": %s", strerror(-r));
5382 unlink(REBOOT_PARAM_FILE);
5387 int umount_recursive(const char *prefix, int flags) {
5391 /* Try to umount everything recursively below a
5392 * directory. Also, take care of stacked mounts, and keep
5393 * unmounting them until they are gone. */
5396 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
5401 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
5402 if (!proc_self_mountinfo)
5406 _cleanup_free_ char *path = NULL, *p = NULL;
5409 k = fscanf(proc_self_mountinfo,
5410 "%*s " /* (1) mount id */
5411 "%*s " /* (2) parent id */
5412 "%*s " /* (3) major:minor */
5413 "%*s " /* (4) root */
5414 "%ms " /* (5) mount point */
5415 "%*s" /* (6) mount options */
5416 "%*[^-]" /* (7) optional fields */
5417 "- " /* (8) separator */
5418 "%*s " /* (9) file system type */
5419 "%*s" /* (10) mount source */
5420 "%*s" /* (11) mount options 2 */
5421 "%*[^\n]", /* some rubbish at the end */
5430 r = cunescape(path, UNESCAPE_RELAX, &p);
5434 if (!path_startswith(p, prefix))
5437 if (umount2(p, flags) < 0) {
5453 static int get_mount_flags(const char *path, unsigned long *flags) {
5456 if (statvfs(path, &buf) < 0)
5458 *flags = buf.f_flag;
5462 int bind_remount_recursive(const char *prefix, bool ro) {
5463 _cleanup_set_free_free_ Set *done = NULL;
5464 _cleanup_free_ char *cleaned = NULL;
5467 /* Recursively remount a directory (and all its submounts)
5468 * read-only or read-write. If the directory is already
5469 * mounted, we reuse the mount and simply mark it
5470 * MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write
5471 * operation). If it isn't we first make it one. Afterwards we
5472 * apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to all
5473 * submounts we can access, too. When mounts are stacked on
5474 * the same mount point we only care for each individual
5475 * "top-level" mount on each point, as we cannot
5476 * influence/access the underlying mounts anyway. We do not
5477 * have any effect on future submounts that might get
5478 * propagated, they migt be writable. This includes future
5479 * submounts that have been triggered via autofs. */
5481 cleaned = strdup(prefix);
5485 path_kill_slashes(cleaned);
5487 done = set_new(&string_hash_ops);
5492 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
5493 _cleanup_set_free_free_ Set *todo = NULL;
5494 bool top_autofs = false;
5496 unsigned long orig_flags;
5498 todo = set_new(&string_hash_ops);
5502 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
5503 if (!proc_self_mountinfo)
5507 _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
5510 k = fscanf(proc_self_mountinfo,
5511 "%*s " /* (1) mount id */
5512 "%*s " /* (2) parent id */
5513 "%*s " /* (3) major:minor */
5514 "%*s " /* (4) root */
5515 "%ms " /* (5) mount point */
5516 "%*s" /* (6) mount options (superblock) */
5517 "%*[^-]" /* (7) optional fields */
5518 "- " /* (8) separator */
5519 "%ms " /* (9) file system type */
5520 "%*s" /* (10) mount source */
5521 "%*s" /* (11) mount options (bind mount) */
5522 "%*[^\n]", /* some rubbish at the end */
5532 r = cunescape(path, UNESCAPE_RELAX, &p);
5536 /* Let's ignore autofs mounts. If they aren't
5537 * triggered yet, we want to avoid triggering
5538 * them, as we don't make any guarantees for
5539 * future submounts anyway. If they are
5540 * already triggered, then we will find
5541 * another entry for this. */
5542 if (streq(type, "autofs")) {
5543 top_autofs = top_autofs || path_equal(cleaned, p);
5547 if (path_startswith(p, cleaned) &&
5548 !set_contains(done, p)) {
5550 r = set_consume(todo, p);
5560 /* If we have no submounts to process anymore and if
5561 * the root is either already done, or an autofs, we
5563 if (set_isempty(todo) &&
5564 (top_autofs || set_contains(done, cleaned)))
5567 if (!set_contains(done, cleaned) &&
5568 !set_contains(todo, cleaned)) {
5569 /* The prefix directory itself is not yet a
5570 * mount, make it one. */
5571 if (mount(cleaned, cleaned, NULL, MS_BIND|MS_REC, NULL) < 0)
5575 (void) get_mount_flags(cleaned, &orig_flags);
5576 orig_flags &= ~MS_RDONLY;
5578 if (mount(NULL, prefix, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0)
5581 x = strdup(cleaned);
5585 r = set_consume(done, x);
5590 while ((x = set_steal_first(todo))) {
5592 r = set_consume(done, x);
5593 if (r == -EEXIST || r == 0)
5598 /* Try to reuse the original flag set, but
5599 * don't care for errors, in case of
5600 * obstructed mounts */
5602 (void) get_mount_flags(x, &orig_flags);
5603 orig_flags &= ~MS_RDONLY;
5605 if (mount(NULL, x, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) {
5607 /* Deal with mount points that are
5608 * obstructed by a later mount */
5610 if (errno != ENOENT)
5619 int fflush_and_check(FILE *f) {
5626 return errno ? -errno : -EIO;
5631 int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
5643 * /foo/bar/.#<extra>waldoXXXXXX
5647 if (!filename_is_valid(fn))
5653 t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
5657 strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn), "XXXXXX");
5659 *ret = path_kill_slashes(t);
5663 int tempfn_random(const char *p, const char *extra, char **ret) {
5677 * /foo/bar/.#<extra>waldobaa2a261115984a9
5681 if (!filename_is_valid(fn))
5687 t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1);
5691 x = stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn);
5694 for (i = 0; i < 16; i++) {
5695 *(x++) = hexchar(u & 0xF);
5701 *ret = path_kill_slashes(t);
5705 /// UNNEEDED by elogind
5707 int tempfn_random_child(const char *p, const char *extra, char **ret) {
5718 * /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
5724 t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1);
5728 x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra);
5731 for (i = 0; i < 16; i++) {
5732 *(x++) = hexchar(u & 0xF);
5738 *ret = path_kill_slashes(t);
5742 int take_password_lock(const char *root) {
5744 struct flock flock = {
5746 .l_whence = SEEK_SET,
5754 /* This is roughly the same as lckpwdf(), but not as awful. We
5755 * don't want to use alarm() and signals, hence we implement
5756 * our own trivial version of this.
5758 * Note that shadow-utils also takes per-database locks in
5759 * addition to lckpwdf(). However, we don't given that they
5760 * are redundant as they they invoke lckpwdf() first and keep
5761 * it during everything they do. The per-database locks are
5762 * awfully racy, and thus we just won't do them. */
5765 path = strjoina(root, "/etc/.pwd.lock");
5767 path = "/etc/.pwd.lock";
5769 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
5773 r = fcntl(fd, F_SETLKW, &flock);
5782 int is_symlink(const char *path) {
5785 if (lstat(path, &info) < 0)
5788 return !!S_ISLNK(info.st_mode);
5792 int is_dir(const char* path, bool follow) {
5797 r = stat(path, &st);
5799 r = lstat(path, &st);
5803 return !!S_ISDIR(st.st_mode);
5806 /// UNNEEDED by elogind
5808 int is_device_node(const char *path) {
5811 if (lstat(path, &info) < 0)
5814 return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode));
5818 int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) {
5819 _cleanup_free_ char *s = NULL;
5820 size_t allocated = 0, sz = 0;
5828 SINGLE_QUOTE_ESCAPE,
5830 DOUBLE_QUOTE_ESCAPE,
5838 separators = WHITESPACE;
5840 /* Bail early if called after last value or with no input */
5842 goto finish_force_terminate;
5844 /* Parses the first word of a string, and returns it in
5845 * *ret. Removes all quotes in the process. When parsing fails
5846 * (because of an uneven number of quotes or similar), leaves
5847 * the pointer *p at the first invalid character. */
5855 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
5856 if (!GREEDY_REALLOC(s, allocated, sz+1))
5860 goto finish_force_terminate;
5861 else if (strchr(separators, c)) {
5862 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
5864 goto finish_force_next;
5869 /* We found a non-blank character, so we will always
5870 * want to return a string (even if it is empty),
5871 * allocate it here. */
5872 if (!GREEDY_REALLOC(s, allocated, sz+1))
5880 goto finish_force_terminate;
5881 else if (c == '\'' && (flags & EXTRACT_QUOTES))
5882 state = SINGLE_QUOTE;
5884 state = VALUE_ESCAPE;
5885 else if (c == '\"' && (flags & EXTRACT_QUOTES))
5886 state = DOUBLE_QUOTE;
5887 else if (strchr(separators, c)) {
5888 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
5890 goto finish_force_next;
5894 if (!GREEDY_REALLOC(s, allocated, sz+2))
5904 if (flags & EXTRACT_RELAX)
5905 goto finish_force_terminate;
5907 } else if (c == '\'')
5910 state = SINGLE_QUOTE_ESCAPE;
5912 if (!GREEDY_REALLOC(s, allocated, sz+2))
5926 state = DOUBLE_QUOTE_ESCAPE;
5928 if (!GREEDY_REALLOC(s, allocated, sz+2))
5936 case SINGLE_QUOTE_ESCAPE:
5937 case DOUBLE_QUOTE_ESCAPE:
5939 if (!GREEDY_REALLOC(s, allocated, sz+7))
5943 if ((flags & EXTRACT_CUNESCAPE_RELAX) &&
5944 (state == VALUE_ESCAPE || flags & EXTRACT_RELAX)) {
5945 /* If we find an unquoted trailing backslash and we're in
5946 * EXTRACT_CUNESCAPE_RELAX mode, keep it verbatim in the
5949 * Unbalanced quotes will only be allowed in EXTRACT_RELAX
5950 * mode, EXTRACT_CUNESCAPE_RELAX mode does not allow them.
5953 goto finish_force_terminate;
5955 if (flags & EXTRACT_RELAX)
5956 goto finish_force_terminate;
5960 if (flags & EXTRACT_CUNESCAPE) {
5963 r = cunescape_one(*p, (size_t) -1, &c, &u);
5965 if (flags & EXTRACT_CUNESCAPE_RELAX) {
5976 s[sz++] = c; /* normal explicit char */
5978 sz += utf8_encode_unichar(s + sz, u); /* unicode chars we'll encode as utf8 */
5983 state = (state == SINGLE_QUOTE_ESCAPE) ? SINGLE_QUOTE :
5984 (state == DOUBLE_QUOTE_ESCAPE) ? DOUBLE_QUOTE :
5990 goto finish_force_terminate;
5991 if (!strchr(separators, c))
5999 finish_force_terminate:
6016 /// UNNEEDED by elogind
6018 int extract_first_word_and_warn(
6021 const char *separators,
6024 const char *filename,
6026 const char *rvalue) {
6027 /* Try to unquote it, if it fails, warn about it and try again but this
6028 * time using EXTRACT_CUNESCAPE_RELAX to keep the backslashes verbatim
6029 * in invalid escape sequences. */
6034 r = extract_first_word(p, ret, separators, flags);
6035 if (r < 0 && !(flags&EXTRACT_CUNESCAPE_RELAX)) {
6036 /* Retry it with EXTRACT_CUNESCAPE_RELAX. */
6038 r = extract_first_word(p, ret, separators, flags|EXTRACT_CUNESCAPE_RELAX);
6040 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
6041 "Unbalanced quoting in command line, ignoring: \"%s\"", rvalue);
6043 log_syntax(unit, LOG_WARNING, filename, line, EINVAL,
6044 "Invalid escape sequences in command line: \"%s\"", rvalue);
6049 int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) {
6054 /* Parses a number of words from a string, stripping any
6055 * quotes if necessary. */
6059 /* Count how many words are expected */
6060 va_start(ap, flags);
6062 if (!va_arg(ap, char **))
6071 /* Read all words into a temporary array */
6072 l = newa0(char*, n);
6073 for (c = 0; c < n; c++) {
6075 r = extract_first_word(p, &l[c], separators, flags);
6079 for (j = 0; j < c; j++)
6089 /* If we managed to parse all words, return them in the passed
6091 va_start(ap, flags);
6092 for (i = 0; i < n; i++) {
6095 v = va_arg(ap, char **);
6106 int free_and_strdup(char **p, const char *s) {
6111 /* Replaces a string pointer with an strdup()ed new string,
6112 * possibly freeing the old one. */
6114 if (streq_ptr(*p, s))
6130 /// UNNEEDED by elogind
6132 int ptsname_malloc(int fd, char **ret) {
6145 if (ptsname_r(fd, c, l) == 0) {
6149 if (errno != ERANGE) {
6159 int openpt_in_namespace(pid_t pid, int flags) {
6160 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1;
6161 _cleanup_close_pair_ int pair[2] = { -1, -1 };
6163 struct cmsghdr cmsghdr;
6164 uint8_t buf[CMSG_SPACE(sizeof(int))];
6166 struct msghdr mh = {
6167 .msg_control = &control,
6168 .msg_controllen = sizeof(control),
6170 struct cmsghdr *cmsg;
6177 r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &usernsfd, &rootfd);
6181 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
6191 pair[0] = safe_close(pair[0]);
6193 r = namespace_enter(pidnsfd, mntnsfd, -1, usernsfd, rootfd);
6195 _exit(EXIT_FAILURE);
6197 master = posix_openpt(flags);
6199 _exit(EXIT_FAILURE);
6201 cmsg = CMSG_FIRSTHDR(&mh);
6202 cmsg->cmsg_level = SOL_SOCKET;
6203 cmsg->cmsg_type = SCM_RIGHTS;
6204 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
6205 memcpy(CMSG_DATA(cmsg), &master, sizeof(int));
6207 mh.msg_controllen = cmsg->cmsg_len;
6209 if (sendmsg(pair[1], &mh, MSG_NOSIGNAL) < 0)
6210 _exit(EXIT_FAILURE);
6212 _exit(EXIT_SUCCESS);
6215 pair[1] = safe_close(pair[1]);
6217 r = wait_for_terminate(child, &si);
6220 if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
6223 if (recvmsg(pair[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
6226 CMSG_FOREACH(cmsg, &mh)
6227 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
6231 fds = (int*) CMSG_DATA(cmsg);
6232 n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
6235 close_many(fds, n_fds);
6246 ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) {
6247 _cleanup_close_ int fd = -1;
6250 /* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */
6252 fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOATIME|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
6256 l = fgetxattr(fd, attribute, value, size);
6263 static int parse_crtime(le64_t le, usec_t *usec) {
6269 if (u == 0 || u == (uint64_t) -1)
6276 int fd_getcrtime(int fd, usec_t *usec) {
6283 /* Until Linux gets a real concept of birthtime/creation time,
6284 * let's fake one with xattrs */
6286 n = fgetxattr(fd, "user.crtime_usec", &le, sizeof(le));
6289 if (n != sizeof(le))
6292 return parse_crtime(le, usec);
6295 /// UNNEEDED by elogind
6297 int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags) {
6301 n = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags);
6304 if (n != sizeof(le))
6307 return parse_crtime(le, usec);
6310 int path_getcrtime(const char *p, usec_t *usec) {
6317 n = getxattr(p, "user.crtime_usec", &le, sizeof(le));
6320 if (n != sizeof(le))
6323 return parse_crtime(le, usec);
6326 int fd_setcrtime(int fd, usec_t usec) {
6332 usec = now(CLOCK_REALTIME);
6334 le = htole64((uint64_t) usec);
6335 if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), 0) < 0)
6341 int same_fd(int a, int b) {
6342 struct stat sta, stb;
6349 /* Compares two file descriptors. Note that semantics are
6350 * quite different depending on whether we have kcmp() or we
6351 * don't. If we have kcmp() this will only return true for
6352 * dup()ed file descriptors, but not otherwise. If we don't
6353 * have kcmp() this will also return true for two fds of the same
6354 * file, created by separate open() calls. Since we use this
6355 * call mostly for filtering out duplicates in the fd store
6356 * this difference hopefully doesn't matter too much. */
6361 /* Try to use kcmp() if we have it. */
6363 r = kcmp(pid, pid, KCMP_FILE, a, b);
6368 if (errno != ENOSYS)
6371 /* We don't have kcmp(), use fstat() instead. */
6372 if (fstat(a, &sta) < 0)
6375 if (fstat(b, &stb) < 0)
6378 if ((sta.st_mode & S_IFMT) != (stb.st_mode & S_IFMT))
6381 /* We consider all device fds different, since two device fds
6382 * might refer to quite different device contexts even though
6383 * they share the same inode and backing dev_t. */
6385 if (S_ISCHR(sta.st_mode) || S_ISBLK(sta.st_mode))
6388 if (sta.st_dev != stb.st_dev || sta.st_ino != stb.st_ino)
6391 /* The fds refer to the same inode on disk, let's also check
6392 * if they have the same fd flags. This is useful to
6393 * distinguish the read and write side of a pipe created with
6395 fa = fcntl(a, F_GETFL);
6399 fb = fcntl(b, F_GETFL);
6407 int chattr_fd(int fd, unsigned value, unsigned mask) {
6408 unsigned old_attr, new_attr;
6413 if (fstat(fd, &st) < 0)
6416 /* Explicitly check whether this is a regular file or
6417 * directory. If it is anything else (such as a device node or
6418 * fifo), then the ioctl will not hit the file systems but
6419 * possibly drivers, where the ioctl might have different
6420 * effects. Notably, DRM is using the same ioctl() number. */
6422 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
6428 if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
6431 new_attr = (old_attr & ~mask) | (value & mask);
6432 if (new_attr == old_attr)
6435 if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
6441 /// UNNEEDED by elogind
6443 int chattr_path(const char *p, unsigned value, unsigned mask) {
6444 _cleanup_close_ int fd = -1;
6451 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
6455 return chattr_fd(fd, value, mask);
6459 int read_attr_fd(int fd, unsigned *ret) {
6464 if (fstat(fd, &st) < 0)
6467 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
6470 if (ioctl(fd, FS_IOC_GETFLAGS, ret) < 0)
6476 /// UNNEEDED by elogind
6478 int read_attr_path(const char *p, unsigned *ret) {
6479 _cleanup_close_ int fd = -1;
6484 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
6488 return read_attr_fd(fd, ret);
6491 static size_t nul_length(const uint8_t *p, size_t sz) {
6506 ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
6507 const uint8_t *q, *w, *e;
6515 n = nul_length(q, e - q);
6517 /* If there are more than the specified run length of
6518 * NUL bytes, or if this is the beginning or the end
6519 * of the buffer, then seek instead of write */
6520 if ((n > run_length) ||
6521 (n > 0 && q == p) ||
6522 (n > 0 && q + n >= e)) {
6524 l = write(fd, w, q - w);
6531 if (lseek(fd, n, SEEK_CUR) == (off_t) -1)
6543 l = write(fd, w, q - w);
6550 return q - (const uint8_t*) p;
6554 void sigkill_wait(pid_t *pid) {
6560 if (kill(*pid, SIGKILL) > 0)
6561 (void) wait_for_terminate(*pid, NULL);
6564 /// UNNEEDED by elogind
6566 int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
6567 int a = 0, b = 0, c = 0;
6577 if (!strchr(*p, '>'))
6580 if ((*p)[2] == '>') {
6581 c = undecchar((*p)[1]);
6583 } else if ((*p)[3] == '>') {
6584 b = undecchar((*p)[1]);
6585 c = undecchar((*p)[2]);
6587 } else if ((*p)[4] == '>') {
6588 a = undecchar((*p)[1]);
6589 b = undecchar((*p)[2]);
6590 c = undecchar((*p)[3]);
6595 if (a < 0 || b < 0 || c < 0 ||
6596 (!with_facility && (a || b || c > 7)))
6600 *priority = a*100 + b*10 + c;
6602 *priority = (*priority & LOG_FACMASK) | c;
6609 ssize_t string_table_lookup(const char * const *table, size_t len, const char *key) {
6615 for (i = 0; i < len; ++i)
6616 if (streq_ptr(table[i], key))
6622 /// UNNEEDED by elogind
6624 void cmsg_close_all(struct msghdr *mh) {
6625 struct cmsghdr *cmsg;
6629 CMSG_FOREACH(cmsg, mh)
6630 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
6631 close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int));
6634 int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
6638 ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
6642 /* renameat2() exists since Linux 3.15, btrfs added support for it later.
6643 * If it is not implemented, fallback to another method. */
6644 if (!IN_SET(errno, EINVAL, ENOSYS))
6647 /* The link()/unlink() fallback does not work on directories. But
6648 * renameat() without RENAME_NOREPLACE gives the same semantics on
6649 * directories, except when newpath is an *empty* directory. This is
6651 ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW);
6652 if (ret >= 0 && S_ISDIR(buf.st_mode)) {
6653 ret = renameat(olddirfd, oldpath, newdirfd, newpath);
6654 return ret >= 0 ? 0 : -errno;
6657 /* If it is not a directory, use the link()/unlink() fallback. */
6658 ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0);
6662 ret = unlinkat(olddirfd, oldpath, 0);
6664 /* backup errno before the following unlinkat() alters it */
6666 (void) unlinkat(newdirfd, newpath, 0);
6675 static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad) {
6679 if (*s == '\\' || strchr(bad, *s))
6688 char *shell_escape(const char *s, const char *bad) {
6691 r = new(char, strlen(s)*2+1);
6695 t = strcpy_backslash_escaped(r, s, bad);
6701 char *shell_maybe_quote(const char *s) {
6707 /* Encloses a string in double quotes if necessary to make it
6708 * OK as shell string. */
6710 for (p = s; *p; p++)
6713 strchr(SHELL_NEED_QUOTES, *p))
6719 r = new(char, 1+strlen(s)*2+1+1);
6725 t = mempcpy(t, s, p - s);
6727 t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE);
6735 int parse_mode(const char *s, mode_t *ret) {
6743 l = strtol(s, &x, 8);
6747 if (!x || x == s || *x)
6749 if (l < 0 || l > 07777)
6756 /// UNNEEDED by elogind
6758 int mount_move_root(const char *path) {
6761 if (chdir(path) < 0)
6764 if (mount(path, "/", NULL, MS_MOVE, NULL) < 0)
6767 if (chroot(".") < 0)
6777 int reset_uid_gid(void) {
6779 if (setgroups(0, NULL) < 0)
6782 if (setresgid(0, 0, 0) < 0)
6785 if (setresuid(0, 0, 0) < 0)
6791 int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink) {
6800 for (l = 100; ; l = (size_t) n + 1) {
6806 n = lgetxattr(path, name, v, l);
6808 n = getxattr(path, name, v, l);
6810 if (n >= 0 && (size_t) n < l) {
6817 if (n < 0 && errno != ERANGE)
6821 n = lgetxattr(path, name, NULL, 0);
6823 n = getxattr(path, name, NULL, 0);
6829 int fgetxattr_malloc(int fd, const char *name, char **value) {
6838 for (l = 100; ; l = (size_t) n + 1) {
6843 n = fgetxattr(fd, name, v, l);
6845 if (n >= 0 && (size_t) n < l) {
6852 if (n < 0 && errno != ERANGE)
6855 n = fgetxattr(fd, name, NULL, 0);