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))
406 return -ENXIO; /* we return ENXIO instead of EINVAL
407 * here, to make it easy to distuingish
408 * invalid numeric uids invalid
417 int safe_atou(const char *s, unsigned *ret_u) {
425 l = strtoul(s, &x, 0);
427 if (!x || x == s || *x || errno)
428 return errno > 0 ? -errno : -EINVAL;
430 if ((unsigned long) (unsigned) l != l)
433 *ret_u = (unsigned) l;
437 int safe_atoi(const char *s, int *ret_i) {
445 l = strtol(s, &x, 0);
447 if (!x || x == s || *x || errno)
448 return errno > 0 ? -errno : -EINVAL;
450 if ((long) (int) l != l)
457 int safe_atou8(const char *s, uint8_t *ret) {
465 l = strtoul(s, &x, 0);
467 if (!x || x == s || *x || errno)
468 return errno > 0 ? -errno : -EINVAL;
470 if ((unsigned long) (uint8_t) l != l)
477 int safe_atou16(const char *s, uint16_t *ret) {
485 l = strtoul(s, &x, 0);
487 if (!x || x == s || *x || errno)
488 return errno > 0 ? -errno : -EINVAL;
490 if ((unsigned long) (uint16_t) l != l)
497 int safe_atoi16(const char *s, int16_t *ret) {
505 l = strtol(s, &x, 0);
507 if (!x || x == s || *x || errno)
508 return errno > 0 ? -errno : -EINVAL;
510 if ((long) (int16_t) l != l)
517 int safe_atollu(const char *s, long long unsigned *ret_llu) {
519 unsigned long long l;
525 l = strtoull(s, &x, 0);
527 if (!x || x == s || *x || errno)
528 return errno ? -errno : -EINVAL;
534 int safe_atolli(const char *s, long long int *ret_lli) {
542 l = strtoll(s, &x, 0);
544 if (!x || x == s || *x || errno)
545 return errno ? -errno : -EINVAL;
551 int safe_atod(const char *s, double *ret_d) {
559 loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
560 if (loc == (locale_t) 0)
564 d = strtod_l(s, &x, loc);
566 if (!x || x == s || *x || errno) {
568 return errno ? -errno : -EINVAL;
576 static size_t strcspn_escaped(const char *s, const char *reject) {
577 bool escaped = false;
580 for (n=0; s[n]; n++) {
583 else if (s[n] == '\\')
585 else if (strchr(reject, s[n]))
589 /* if s ends in \, return index of previous char */
593 /* Split a string into words. */
594 const char* split(const char **state, size_t *l, const char *separator, bool quoted) {
600 assert(**state == '\0');
604 current += strspn(current, separator);
610 if (quoted && strchr("\'\"", *current)) {
611 char quotechars[2] = {*current, '\0'};
613 *l = strcspn_escaped(current + 1, quotechars);
614 if (current[*l + 1] == '\0' || current[*l + 1] != quotechars[0] ||
615 (current[*l + 2] && !strchr(separator, current[*l + 2]))) {
616 /* right quote missing or garbage at the end */
620 *state = current++ + *l + 2;
622 *l = strcspn_escaped(current, separator);
623 if (current[*l] && !strchr(separator, current[*l])) {
624 /* unfinished escape */
628 *state = current + *l;
630 *l = strcspn(current, separator);
631 *state = current + *l;
637 int fchmod_umask(int fd, mode_t m) {
642 r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
648 char *truncate_nl(char *s) {
651 s[strcspn(s, NEWLINE)] = 0;
655 char *strnappend(const char *s, const char *suffix, size_t b) {
663 return strndup(suffix, b);
672 if (b > ((size_t) -1) - a)
675 r = new(char, a+b+1);
680 memcpy(r+a, suffix, b);
686 char *strappend(const char *s, const char *suffix) {
687 return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
690 int readlinkat_malloc(int fd, const char *p, char **ret) {
705 n = readlinkat(fd, p, c, l-1);
712 if ((size_t) n < l-1) {
723 int readlink_malloc(const char *p, char **ret) {
724 return readlinkat_malloc(AT_FDCWD, p, ret);
727 /// UNNEEDED by elogind
729 int readlink_value(const char *p, char **ret) {
730 _cleanup_free_ char *link = NULL;
734 r = readlink_malloc(p, &link);
738 value = basename(link);
742 value = strdup(value);
752 int readlink_and_make_absolute(const char *p, char **r) {
753 _cleanup_free_ char *target = NULL;
760 j = readlink_malloc(p, &target);
764 k = file_in_same_dir(p, target);
772 /// UNNEEDED by elogind
774 int readlink_and_canonicalize(const char *p, char **r) {
781 j = readlink_and_make_absolute(p, &t);
785 s = canonicalize_file_name(t);
792 path_kill_slashes(*r);
798 char *strstrip(char *s) {
801 /* Drops trailing whitespace. Modifies the string in
802 * place. Returns pointer to first non-space character */
804 s += strspn(s, WHITESPACE);
806 for (e = strchr(s, 0); e > s; e --)
807 if (!strchr(WHITESPACE, e[-1]))
815 /// UNNEEDED by elogind
817 char *delete_chars(char *s, const char *bad) {
820 /* Drops all whitespace, regardless where in the string */
822 for (f = s, t = s; *f; f++) {
835 char *file_in_same_dir(const char *path, const char *filename) {
842 /* This removes the last component of path and appends
843 * filename, unless the latter is absolute anyway or the
846 if (path_is_absolute(filename))
847 return strdup(filename);
849 e = strrchr(path, '/');
851 return strdup(filename);
853 k = strlen(filename);
854 ret = new(char, (e + 1 - path) + k + 1);
858 memcpy(mempcpy(ret, path, e + 1 - path), filename, k + 1);
862 /// UNNEEDED by elogind
864 int rmdir_parents(const char *path, const char *stop) {
873 /* Skip trailing slashes */
874 while (l > 0 && path[l-1] == '/')
880 /* Skip last component */
881 while (l > 0 && path[l-1] != '/')
884 /* Skip trailing slashes */
885 while (l > 0 && path[l-1] == '/')
891 if (!(t = strndup(path, l)))
894 if (path_startswith(stop, t)) {
911 char hexchar(int x) {
912 static const char table[16] = "0123456789abcdef";
914 return table[x & 15];
917 int unhexchar(char c) {
919 if (c >= '0' && c <= '9')
922 if (c >= 'a' && c <= 'f')
925 if (c >= 'A' && c <= 'F')
931 char *hexmem(const void *p, size_t l) {
935 z = r = malloc(l * 2 + 1);
939 for (x = p; x < (const uint8_t*) p + l; x++) {
940 *(z++) = hexchar(*x >> 4);
941 *(z++) = hexchar(*x & 15);
948 int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
949 _cleanup_free_ uint8_t *r = NULL;
957 z = r = malloc((l + 1) / 2 + 1);
961 for (x = p; x < p + l; x += 2) {
967 else if (x+1 < p + l) {
974 *(z++) = (uint8_t) a << 4 | (uint8_t) b;
986 /* https://tools.ietf.org/html/rfc4648#section-6
987 * Notice that base32hex differs from base32 in the alphabet it uses.
988 * The distinction is that the base32hex representation preserves the
989 * order of the underlying data when compared as bytestrings, this is
990 * useful when representing NSEC3 hashes, as one can then verify the
991 * order of hashes directly from their representation. */
992 char base32hexchar(int x) {
993 static const char table[32] = "0123456789"
994 "ABCDEFGHIJKLMNOPQRSTUV";
996 return table[x & 31];
999 int unbase32hexchar(char c) {
1002 if (c >= '0' && c <= '9')
1005 offset = '9' - '0' + 1;
1007 if (c >= 'A' && c <= 'V')
1008 return c - 'A' + offset;
1013 char *base32hexmem(const void *p, size_t l, bool padding) {
1019 /* five input bytes makes eight output bytes, padding is added so we must round up */
1020 len = 8 * (l + 4) / 5;
1022 /* same, but round down as there is no padding */
1041 z = r = malloc(len + 1);
1045 for (x = p; x < (const uint8_t*) p + (l / 5) * 5; x += 5) {
1046 /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ
1047 x[3] == QQQQQQQQ; x[4] == WWWWWWWW */
1048 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1049 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1050 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1051 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
1052 *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */
1053 *(z++) = base32hexchar((x[3] & 127) >> 2); /* 000QQQQQ */
1054 *(z++) = base32hexchar((x[3] & 3) << 3 | x[4] >> 5); /* 000QQWWW */
1055 *(z++) = base32hexchar((x[4] & 31)); /* 000WWWWW */
1060 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1061 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1062 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1063 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
1064 *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */
1065 *(z++) = base32hexchar((x[3] & 127) >> 2); /* 000QQQQQ */
1066 *(z++) = base32hexchar((x[3] & 3) << 3); /* 000QQ000 */
1073 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1074 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1075 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1076 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
1077 *(z++) = base32hexchar((x[2] & 15) << 1); /* 000ZZZZ0 */
1087 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1088 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1089 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1090 *(z++) = base32hexchar((x[1] & 1) << 4); /* 000Y0000 */
1101 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1102 *(z++) = base32hexchar((x[0] & 7) << 2); /* 000XXX00 */
1119 int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_len) {
1120 _cleanup_free_ uint8_t *r = NULL;
1121 int a, b, c, d, e, f, g, h;
1129 /* padding ensures any base32hex input has input divisible by 8 */
1130 if (padding && l % 8 != 0)
1134 /* strip the padding */
1135 while (l > 0 && p[l - 1] == '=' && pad < 7) {
1141 /* a group of eight input bytes needs five output bytes, in case of
1142 padding we need to add some extra bytes */
1164 z = r = malloc(len + 1);
1168 for (x = p; x < p + (l / 8) * 8; x += 8) {
1169 /* a == 000XXXXX; b == 000YYYYY; c == 000ZZZZZ; d == 000WWWWW
1170 e == 000SSSSS; f == 000QQQQQ; g == 000VVVVV; h == 000RRRRR */
1171 a = unbase32hexchar(x[0]);
1175 b = unbase32hexchar(x[1]);
1179 c = unbase32hexchar(x[2]);
1183 d = unbase32hexchar(x[3]);
1187 e = unbase32hexchar(x[4]);
1191 f = unbase32hexchar(x[5]);
1195 g = unbase32hexchar(x[6]);
1199 h = unbase32hexchar(x[7]);
1203 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1204 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1205 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
1206 *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */
1207 *(z++) = (uint8_t) g << 5 | (uint8_t) h; /* VVVRRRRR */
1212 a = unbase32hexchar(x[0]);
1216 b = unbase32hexchar(x[1]);
1220 c = unbase32hexchar(x[2]);
1224 d = unbase32hexchar(x[3]);
1228 e = unbase32hexchar(x[4]);
1232 f = unbase32hexchar(x[5]);
1236 g = unbase32hexchar(x[6]);
1244 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1245 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1246 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
1247 *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */
1251 a = unbase32hexchar(x[0]);
1255 b = unbase32hexchar(x[1]);
1259 c = unbase32hexchar(x[2]);
1263 d = unbase32hexchar(x[3]);
1267 e = unbase32hexchar(x[4]);
1275 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1276 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1277 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
1281 a = unbase32hexchar(x[0]);
1285 b = unbase32hexchar(x[1]);
1289 c = unbase32hexchar(x[2]);
1293 d = unbase32hexchar(x[3]);
1301 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1302 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1306 a = unbase32hexchar(x[0]);
1310 b = unbase32hexchar(x[1]);
1318 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1336 /* https://tools.ietf.org/html/rfc4648#section-4 */
1337 char base64char(int x) {
1338 static const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1339 "abcdefghijklmnopqrstuvwxyz"
1341 return table[x & 63];
1344 int unbase64char(char c) {
1347 if (c >= 'A' && c <= 'Z')
1350 offset = 'Z' - 'A' + 1;
1352 if (c >= 'a' && c <= 'z')
1353 return c - 'a' + offset;
1355 offset += 'z' - 'a' + 1;
1357 if (c >= '0' && c <= '9')
1358 return c - '0' + offset;
1360 offset += '9' - '0' + 1;
1373 char *base64mem(const void *p, size_t l) {
1377 /* three input bytes makes four output bytes, padding is added so we must round up */
1378 z = r = malloc(4 * (l + 2) / 3 + 1);
1382 for (x = p; x < (const uint8_t*) p + (l / 3) * 3; x += 3) {
1383 /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ */
1384 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1385 *(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4); /* 00XXYYYY */
1386 *(z++) = base64char((x[1] & 15) << 2 | x[2] >> 6); /* 00YYYYZZ */
1387 *(z++) = base64char(x[2] & 63); /* 00ZZZZZZ */
1392 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1393 *(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4); /* 00XXYYYY */
1394 *(z++) = base64char((x[1] & 15) << 2); /* 00YYYY00 */
1399 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1400 *(z++) = base64char((x[0] & 3) << 4); /* 00XX0000 */
1411 int unbase64mem(const char *p, size_t l, void **mem, size_t *_len) {
1412 _cleanup_free_ uint8_t *r = NULL;
1420 /* padding ensures any base63 input has input divisible by 4 */
1424 /* strip the padding */
1425 if (l > 0 && p[l - 1] == '=')
1427 if (l > 0 && p[l - 1] == '=')
1430 /* a group of four input bytes needs three output bytes, in case of
1431 padding we need to add two or three extra bytes */
1432 len = (l / 4) * 3 + (l % 4 ? (l % 4) - 1 : 0);
1434 z = r = malloc(len + 1);
1438 for (x = p; x < p + (l / 4) * 4; x += 4) {
1439 /* a == 00XXXXXX; b == 00YYYYYY; c == 00ZZZZZZ; d == 00WWWWWW */
1440 a = unbase64char(x[0]);
1444 b = unbase64char(x[1]);
1448 c = unbase64char(x[2]);
1452 d = unbase64char(x[3]);
1456 *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
1457 *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
1458 *(z++) = (uint8_t) c << 6 | (uint8_t) d; /* ZZWWWWWW */
1463 a = unbase64char(x[0]);
1467 b = unbase64char(x[1]);
1471 c = unbase64char(x[2]);
1479 *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
1480 *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
1484 a = unbase64char(x[0]);
1488 b = unbase64char(x[1]);
1496 *(z++) = (uint8_t) a << 2 | (uint8_t) (b >> 4); /* XXXXXXYY */
1515 char octchar(int x) {
1516 return '0' + (x & 7);
1519 int unoctchar(char c) {
1521 if (c >= '0' && c <= '7')
1527 char decchar(int x) {
1528 return '0' + (x % 10);
1531 int undecchar(char c) {
1533 if (c >= '0' && c <= '9')
1539 char *cescape(const char *s) {
1545 /* Does C style string escaping. May be reversed with
1548 r = new(char, strlen(s)*4 + 1);
1552 for (f = s, t = r; *f; f++)
1553 t += cescape_char(*f, t);
1560 static int cunescape_one(const char *p, size_t length, char *ret, uint32_t *ret_unicode) {
1567 /* Unescapes C style. Returns the unescaped character in ret,
1568 * unless we encountered a \u sequence in which case the full
1569 * unicode character is returned in ret_unicode, instead. */
1571 if (length != (size_t) -1 && length < 1)
1608 /* This is an extension of the XDG syntax files */
1613 /* hexadecimal encoding */
1616 if (length != (size_t) -1 && length < 3)
1619 a = unhexchar(p[1]);
1623 b = unhexchar(p[2]);
1627 /* Don't allow NUL bytes */
1628 if (a == 0 && b == 0)
1631 *ret = (char) ((a << 4U) | b);
1637 /* C++11 style 16bit unicode */
1643 if (length != (size_t) -1 && length < 5)
1646 for (i = 0; i < 4; i++) {
1647 a[i] = unhexchar(p[1 + i]);
1652 c = ((uint32_t) a[0] << 12U) | ((uint32_t) a[1] << 8U) | ((uint32_t) a[2] << 4U) | (uint32_t) a[3];
1654 /* Don't allow 0 chars */
1673 /* C++11 style 32bit unicode */
1679 if (length != (size_t) -1 && length < 9)
1682 for (i = 0; i < 8; i++) {
1683 a[i] = unhexchar(p[1 + i]);
1688 c = ((uint32_t) a[0] << 28U) | ((uint32_t) a[1] << 24U) | ((uint32_t) a[2] << 20U) | ((uint32_t) a[3] << 16U) |
1689 ((uint32_t) a[4] << 12U) | ((uint32_t) a[5] << 8U) | ((uint32_t) a[6] << 4U) | (uint32_t) a[7];
1691 /* Don't allow 0 chars */
1695 /* Don't allow invalid code points */
1696 if (!unichar_is_valid(c))
1721 /* octal encoding */
1725 if (length != (size_t) -1 && length < 3)
1728 a = unoctchar(p[0]);
1732 b = unoctchar(p[1]);
1736 c = unoctchar(p[2]);
1740 /* don't allow NUL bytes */
1741 if (a == 0 && b == 0 && c == 0)
1744 /* Don't allow bytes above 255 */
1745 m = ((uint32_t) a << 6U) | ((uint32_t) b << 3U) | (uint32_t) c;
1761 int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret) {
1769 /* Undoes C style string escaping, and optionally prefixes it. */
1771 pl = prefix ? strlen(prefix) : 0;
1773 r = new(char, pl+length+1);
1778 memcpy(r, prefix, pl);
1780 for (f = s, t = r + pl; f < s + length; f++) {
1786 remaining = s + length - f;
1787 assert(remaining > 0);
1790 /* A literal literal, copy verbatim */
1795 if (remaining == 1) {
1796 if (flags & UNESCAPE_RELAX) {
1797 /* A trailing backslash, copy verbatim */
1806 k = cunescape_one(f + 1, remaining - 1, &c, &u);
1808 if (flags & UNESCAPE_RELAX) {
1809 /* Invalid escape code, let's take it literal then */
1819 /* Non-Unicode? Let's encode this directly */
1822 /* Unicode? Then let's encode this in UTF-8 */
1823 t += utf8_encode_unichar(t, u);
1834 int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret) {
1835 return cunescape_length_with_prefix(s, length, NULL, flags, ret);
1838 int cunescape(const char *s, UnescapeFlags flags, char **ret) {
1839 return cunescape_length(s, strlen(s), flags, ret);
1842 char *xescape(const char *s, const char *bad) {
1846 /* Escapes all chars in bad, in addition to \ and all special
1847 * chars, in \xFF style escaping. May be reversed with
1850 r = new(char, strlen(s) * 4 + 1);
1854 for (f = s, t = r; *f; f++) {
1856 if ((*f < ' ') || (*f >= 127) ||
1857 (*f == '\\') || strchr(bad, *f)) {
1860 *(t++) = hexchar(*f >> 4);
1861 *(t++) = hexchar(*f);
1871 /// UNNEEDED by elogind
1873 char *ascii_strlower(char *t) {
1878 for (p = t; *p; p++)
1879 if (*p >= 'A' && *p <= 'Z')
1880 *p = *p - 'A' + 'a';
1886 _pure_ static bool hidden_file_allow_backup(const char *filename) {
1890 filename[0] == '.' ||
1891 streq(filename, "lost+found") ||
1892 streq(filename, "aquota.user") ||
1893 streq(filename, "aquota.group") ||
1894 endswith(filename, ".rpmnew") ||
1895 endswith(filename, ".rpmsave") ||
1896 endswith(filename, ".rpmorig") ||
1897 endswith(filename, ".dpkg-old") ||
1898 endswith(filename, ".dpkg-new") ||
1899 endswith(filename, ".dpkg-tmp") ||
1900 endswith(filename, ".dpkg-dist") ||
1901 endswith(filename, ".dpkg-bak") ||
1902 endswith(filename, ".dpkg-backup") ||
1903 endswith(filename, ".dpkg-remove") ||
1904 endswith(filename, ".swp");
1907 bool hidden_file(const char *filename) {
1910 if (endswith(filename, "~"))
1913 return hidden_file_allow_backup(filename);
1916 int fd_nonblock(int fd, bool nonblock) {
1921 flags = fcntl(fd, F_GETFL, 0);
1926 nflags = flags | O_NONBLOCK;
1928 nflags = flags & ~O_NONBLOCK;
1930 if (nflags == flags)
1933 if (fcntl(fd, F_SETFL, nflags) < 0)
1939 int fd_cloexec(int fd, bool cloexec) {
1944 flags = fcntl(fd, F_GETFD, 0);
1949 nflags = flags | FD_CLOEXEC;
1951 nflags = flags & ~FD_CLOEXEC;
1953 if (nflags == flags)
1956 if (fcntl(fd, F_SETFD, nflags) < 0)
1962 _pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
1965 assert(n_fdset == 0 || fdset);
1967 for (i = 0; i < n_fdset; i++)
1974 int close_all_fds(const int except[], unsigned n_except) {
1975 _cleanup_closedir_ DIR *d = NULL;
1979 assert(n_except == 0 || except);
1981 d = opendir("/proc/self/fd");
1986 /* When /proc isn't available (for example in chroots)
1987 * the fallback is brute forcing through the fd
1990 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
1991 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
1993 if (fd_in_set(fd, except, n_except))
1996 if (close_nointr(fd) < 0)
1997 if (errno != EBADF && r == 0)
2004 while ((de = readdir(d))) {
2007 if (hidden_file(de->d_name))
2010 if (safe_atoi(de->d_name, &fd) < 0)
2011 /* Let's better ignore this, just in case */
2020 if (fd_in_set(fd, except, n_except))
2023 if (close_nointr(fd) < 0) {
2024 /* Valgrind has its own FD and doesn't want to have it closed */
2025 if (errno != EBADF && r == 0)
2033 bool chars_intersect(const char *a, const char *b) {
2036 /* Returns true if any of the chars in a are in b. */
2037 for (p = a; *p; p++)
2044 /// UNNEEDED by elogind
2046 bool fstype_is_network(const char *fstype) {
2047 static const char table[] =
2062 x = startswith(fstype, "fuse.");
2066 return nulstr_contains(table, fstype);
2070 int flush_fd(int fd) {
2071 struct pollfd pollfd = {
2081 r = poll(&pollfd, 1, 0);
2091 l = read(fd, buf, sizeof(buf));
2097 if (errno == EAGAIN)
2106 void safe_close_pair(int p[]) {
2110 /* Special case pairs which use the same fd in both
2112 p[0] = p[1] = safe_close(p[0]);
2116 p[0] = safe_close(p[0]);
2117 p[1] = safe_close(p[1]);
2120 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
2127 while (nbytes > 0) {
2130 k = read(fd, p, nbytes);
2135 if (errno == EAGAIN && do_poll) {
2137 /* We knowingly ignore any return value here,
2138 * and expect that any error/EOF is reported
2141 fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
2145 return n > 0 ? n : -errno;
2159 int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
2162 n = loop_read(fd, buf, nbytes, do_poll);
2165 if ((size_t) n != nbytes)
2170 int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
2171 const uint8_t *p = buf;
2181 k = write(fd, p, nbytes);
2186 if (errno == EAGAIN && do_poll) {
2187 /* We knowingly ignore any return value here,
2188 * and expect that any error/EOF is reported
2191 fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
2198 if (nbytes > 0 && k == 0) /* Can't really happen */
2203 } while (nbytes > 0);
2208 int parse_size(const char *t, off_t base, off_t *size) {
2210 /* Soo, sometimes we want to parse IEC binary suffixes, and
2211 * sometimes SI decimal suffixes. This function can parse
2212 * both. Which one is the right way depends on the
2213 * context. Wikipedia suggests that SI is customary for
2214 * hardware metrics and network speeds, while IEC is
2215 * customary for most data sizes used by software and volatile
2216 * (RAM) memory. Hence be careful which one you pick!
2218 * In either case we use just K, M, G as suffix, and not Ki,
2219 * Mi, Gi or so (as IEC would suggest). That's because that's
2220 * frickin' ugly. But this means you really need to make sure
2221 * to document which base you are parsing when you use this
2226 unsigned long long factor;
2229 static const struct table iec[] = {
2230 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2231 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2232 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
2233 { "G", 1024ULL*1024ULL*1024ULL },
2234 { "M", 1024ULL*1024ULL },
2240 static const struct table si[] = {
2241 { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
2242 { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
2243 { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
2244 { "G", 1000ULL*1000ULL*1000ULL },
2245 { "M", 1000ULL*1000ULL },
2251 const struct table *table;
2253 unsigned long long r = 0;
2254 unsigned n_entries, start_pos = 0;
2257 assert(base == 1000 || base == 1024);
2262 n_entries = ELEMENTSOF(si);
2265 n_entries = ELEMENTSOF(iec);
2271 unsigned long long l2;
2277 l = strtoll(p, &e, 10);
2290 if (*e >= '0' && *e <= '9') {
2293 /* strotoull itself would accept space/+/- */
2294 l2 = strtoull(e, &e2, 10);
2296 if (errno == ERANGE)
2299 /* Ignore failure. E.g. 10.M is valid */
2306 e += strspn(e, WHITESPACE);
2308 for (i = start_pos; i < n_entries; i++)
2309 if (startswith(e, table[i].suffix)) {
2310 unsigned long long tmp;
2311 if ((unsigned long long) l + (frac > 0) > ULLONG_MAX / table[i].factor)
2313 tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
2314 if (tmp > ULLONG_MAX - r)
2318 if ((unsigned long long) (off_t) r != r)
2321 p = e + strlen(table[i].suffix);
2337 bool is_device_path(const char *path) {
2339 /* Returns true on paths that refer to a device, either in
2340 * sysfs or in /dev */
2343 path_startswith(path, "/dev/") ||
2344 path_startswith(path, "/sys/");
2347 /// UNNEEDED by elogind
2349 int dir_is_empty(const char *path) {
2350 _cleanup_closedir_ DIR *d;
2361 if (!de && errno != 0)
2367 if (!hidden_file(de->d_name))
2372 char* dirname_malloc(const char *path) {
2373 char *d, *dir, *dir2;
2390 void rename_process(const char name[8]) {
2393 /* This is a like a poor man's setproctitle(). It changes the
2394 * comm field, argv[0], and also the glibc's internally used
2395 * name of the process. For the first one a limit of 16 chars
2396 * applies, to the second one usually one of 10 (i.e. length
2397 * of "/sbin/init"), to the third one one of 7 (i.e. length of
2398 * "systemd"). If you pass a longer string it will be
2401 prctl(PR_SET_NAME, name);
2403 if (program_invocation_name)
2404 strncpy(program_invocation_name, name, strlen(program_invocation_name));
2406 if (saved_argc > 0) {
2410 strncpy(saved_argv[0], name, strlen(saved_argv[0]));
2412 for (i = 1; i < saved_argc; i++) {
2416 memzero(saved_argv[i], strlen(saved_argv[i]));
2422 char *lookup_uid(uid_t uid) {
2425 _cleanup_free_ char *buf = NULL;
2426 struct passwd pwbuf, *pw = NULL;
2428 /* Shortcut things to avoid NSS lookups */
2430 return strdup("root");
2432 bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
2436 buf = malloc(bufsize);
2440 if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
2441 return strdup(pw->pw_name);
2443 if (asprintf(&name, UID_FMT, uid) < 0)
2449 /// UNNEEDED by elogind
2451 char* getlogname_malloc(void) {
2455 if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
2460 return lookup_uid(uid);
2463 char *getusername_malloc(void) {
2470 return lookup_uid(getuid());
2474 bool is_temporary_fs(const struct statfs *s) {
2477 return F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) ||
2478 F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC);
2481 int fd_is_temporary_fs(int fd) {
2484 if (fstatfs(fd, &s) < 0)
2487 return is_temporary_fs(&s);
2490 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
2493 /* Under the assumption that we are running privileged we
2494 * first change the access mode and only then hand out
2495 * ownership to avoid a window where access is too open. */
2497 if (mode != MODE_INVALID)
2498 if (chmod(path, mode) < 0)
2501 if (uid != UID_INVALID || gid != GID_INVALID)
2502 if (chown(path, uid, gid) < 0)
2508 /// UNNEEDED by elogind
2510 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
2513 /* Under the assumption that we are running privileged we
2514 * first change the access mode and only then hand out
2515 * ownership to avoid a window where access is too open. */
2517 if (mode != MODE_INVALID)
2518 if (fchmod(fd, mode) < 0)
2521 if (uid != UID_INVALID || gid != GID_INVALID)
2522 if (fchown(fd, uid, gid) < 0)
2528 cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
2532 /* Allocates the cpuset in the right size */
2535 if (!(r = CPU_ALLOC(n)))
2538 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
2539 CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
2549 if (errno != EINVAL)
2557 int files_same(const char *filea, const char *fileb) {
2560 if (stat(filea, &a) < 0)
2563 if (stat(fileb, &b) < 0)
2566 return a.st_dev == b.st_dev &&
2567 a.st_ino == b.st_ino;
2570 /// UNNEEDED by elogind
2572 int running_in_chroot(void) {
2575 ret = files_same("/proc/1/root", "/");
2583 static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
2588 assert(percent <= 100);
2589 assert(new_length >= 3);
2591 if (old_length <= 3 || old_length <= new_length)
2592 return strndup(s, old_length);
2594 r = new0(char, new_length+1);
2598 x = (new_length * percent) / 100;
2600 if (x > new_length - 3)
2608 s + old_length - (new_length - x - 3),
2609 new_length - x - 3);
2614 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
2618 unsigned k, len, len2;
2621 assert(percent <= 100);
2622 assert(new_length >= 3);
2624 /* if no multibyte characters use ascii_ellipsize_mem for speed */
2625 if (ascii_is_valid(s))
2626 return ascii_ellipsize_mem(s, old_length, new_length, percent);
2628 if (old_length <= 3 || old_length <= new_length)
2629 return strndup(s, old_length);
2631 x = (new_length * percent) / 100;
2633 if (x > new_length - 3)
2637 for (i = s; k < x && i < s + old_length; i = utf8_next_char(i)) {
2640 c = utf8_encoded_to_unichar(i);
2643 k += unichar_iswide(c) ? 2 : 1;
2646 if (k > x) /* last character was wide and went over quota */
2649 for (j = s + old_length; k < new_length && j > i; ) {
2652 j = utf8_prev_char(j);
2653 c = utf8_encoded_to_unichar(j);
2656 k += unichar_iswide(c) ? 2 : 1;
2660 /* we don't actually need to ellipsize */
2662 return memdup(s, old_length + 1);
2664 /* make space for ellipsis */
2665 j = utf8_next_char(j);
2668 len2 = s + old_length - j;
2669 e = new(char, len + 3 + len2 + 1);
2674 printf("old_length=%zu new_length=%zu x=%zu len=%u len2=%u k=%u\n",
2675 old_length, new_length, x, len, len2, k);
2679 e[len] = 0xe2; /* tri-dot ellipsis: … */
2683 memcpy(e + len + 3, j, len2 + 1);
2688 char *ellipsize(const char *s, size_t length, unsigned percent) {
2689 return ellipsize_mem(s, strlen(s), length, percent);
2692 int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
2693 _cleanup_close_ int fd;
2699 mkdir_parents(path, 0755);
2701 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode > 0 ? mode : 0644);
2706 r = fchmod(fd, mode);
2711 if (uid != UID_INVALID || gid != GID_INVALID) {
2712 r = fchown(fd, uid, gid);
2717 if (stamp != USEC_INFINITY) {
2718 struct timespec ts[2];
2720 timespec_store(&ts[0], stamp);
2722 r = futimens(fd, ts);
2724 r = futimens(fd, NULL);
2731 int touch(const char *path) {
2732 return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, 0);
2735 /// UNNEEDED by elogind
2737 static char *unquote(const char *s, const char* quotes) {
2741 /* This is rather stupid, simply removes the heading and
2742 * trailing quotes if there is one. Doesn't care about
2743 * escaping or anything.
2745 * DON'T USE THIS FOR NEW CODE ANYMORE!*/
2751 if (strchr(quotes, s[0]) && s[l-1] == s[0])
2752 return strndup(s+1, l-2);
2758 noreturn void freeze(void) {
2760 /* Make sure nobody waits for us on a socket anymore */
2761 close_all_fds(NULL, 0);
2769 bool null_or_empty(struct stat *st) {
2772 if (S_ISREG(st->st_mode) && st->st_size <= 0)
2775 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
2781 int null_or_empty_path(const char *fn) {
2786 if (stat(fn, &st) < 0)
2789 return null_or_empty(&st);
2792 /// UNNEEDED by elogind
2794 int null_or_empty_fd(int fd) {
2799 if (fstat(fd, &st) < 0)
2802 return null_or_empty(&st);
2806 DIR *xopendirat(int fd, const char *name, int flags) {
2810 assert(!(flags & O_CREAT));
2812 nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
2825 /// UNNEEDED by elogind
2827 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
2828 _cleanup_free_ char *t = NULL, *u = NULL;
2831 u = unquote(tagvalue, QUOTES);
2835 enc_len = strlen(u) * 4 + 1;
2836 t = new(char, enc_len);
2840 if (encode_devnode_name(u, t, enc_len) < 0)
2843 return strjoin("/dev/disk/by-", by, "/", t, NULL);
2846 char *fstab_node_to_udev_node(const char *p) {
2849 if (startswith(p, "LABEL="))
2850 return tag_to_udev_node(p+6, "label");
2852 if (startswith(p, "UUID="))
2853 return tag_to_udev_node(p+5, "uuid");
2855 if (startswith(p, "PARTUUID="))
2856 return tag_to_udev_node(p+9, "partuuid");
2858 if (startswith(p, "PARTLABEL="))
2859 return tag_to_udev_node(p+10, "partlabel");
2865 bool dirent_is_file(const struct dirent *de) {
2868 if (hidden_file(de->d_name))
2871 if (de->d_type != DT_REG &&
2872 de->d_type != DT_LNK &&
2873 de->d_type != DT_UNKNOWN)
2879 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
2882 if (de->d_type != DT_REG &&
2883 de->d_type != DT_LNK &&
2884 de->d_type != DT_UNKNOWN)
2887 if (hidden_file_allow_backup(de->d_name))
2890 return endswith(de->d_name, suffix);
2893 /// UNNEEDED by elogind
2895 static int do_execute(char **directories, usec_t timeout, char *argv[]) {
2896 _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
2897 _cleanup_set_free_free_ Set *seen = NULL;
2900 /* We fork this all off from a child process so that we can
2901 * somewhat cleanly make use of SIGALRM to set a time limit */
2903 (void) reset_all_signal_handlers();
2904 (void) reset_signal_mask();
2906 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
2908 pids = hashmap_new(NULL);
2912 seen = set_new(&string_hash_ops);
2916 STRV_FOREACH(directory, directories) {
2917 _cleanup_closedir_ DIR *d;
2920 d = opendir(*directory);
2922 if (errno == ENOENT)
2925 return log_error_errno(errno, "Failed to open directory %s: %m", *directory);
2928 FOREACH_DIRENT(de, d, break) {
2929 _cleanup_free_ char *path = NULL;
2933 if (!dirent_is_file(de))
2936 if (set_contains(seen, de->d_name)) {
2937 log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name);
2941 r = set_put_strdup(seen, de->d_name);
2945 path = strjoin(*directory, "/", de->d_name, NULL);
2949 if (null_or_empty_path(path)) {
2950 log_debug("%s is empty (a mask).", path);
2956 log_error_errno(errno, "Failed to fork: %m");
2958 } else if (pid == 0) {
2961 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
2971 return log_error_errno(errno, "Failed to execute %s: %m", path);
2974 log_debug("Spawned %s as " PID_FMT ".", path, pid);
2976 r = hashmap_put(pids, UINT_TO_PTR(pid), path);
2983 /* Abort execution of this process after the timout. We simply
2984 * rely on SIGALRM as default action terminating the process,
2985 * and turn on alarm(). */
2987 if (timeout != USEC_INFINITY)
2988 alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
2990 while (!hashmap_isempty(pids)) {
2991 _cleanup_free_ char *path = NULL;
2994 pid = PTR_TO_UINT(hashmap_first_key(pids));
2997 path = hashmap_remove(pids, UINT_TO_PTR(pid));
3000 wait_for_terminate_and_warn(path, pid, true);
3006 void execute_directories(const char* const* directories, usec_t timeout, char *argv[]) {
3010 char **dirs = (char**) directories;
3012 assert(!strv_isempty(dirs));
3014 name = basename(dirs[0]);
3015 assert(!isempty(name));
3017 /* Executes all binaries in the directories in parallel and waits
3018 * for them to finish. Optionally a timeout is applied. If a file
3019 * with the same name exists in more than one directory, the
3020 * earliest one wins. */
3022 executor_pid = fork();
3023 if (executor_pid < 0) {
3024 log_error_errno(errno, "Failed to fork: %m");
3027 } else if (executor_pid == 0) {
3028 r = do_execute(dirs, timeout, argv);
3029 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
3032 wait_for_terminate_and_warn(name, executor_pid, true);
3036 bool nulstr_contains(const char*nulstr, const char *needle) {
3042 NULSTR_FOREACH(i, nulstr)
3043 if (streq(i, needle))
3049 /// UNNEEDED by elogind
3051 bool plymouth_running(void) {
3052 return access("/run/plymouth/pid", F_OK) >= 0;
3056 char* strshorten(char *s, size_t l) {
3065 int pipe_eof(int fd) {
3066 struct pollfd pollfd = {
3068 .events = POLLIN|POLLHUP,
3073 r = poll(&pollfd, 1, 0);
3080 return pollfd.revents & POLLHUP;
3083 int fd_wait_for_event(int fd, int event, usec_t t) {
3085 struct pollfd pollfd = {
3093 r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
3100 return pollfd.revents;
3103 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
3112 r = tempfn_xxxxxx(path, NULL, &t);
3116 fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC);
3122 f = fdopen(fd, "we");
3136 /// UNNEEDED by elogind
3138 int symlink_atomic(const char *from, const char *to) {
3139 _cleanup_free_ char *t = NULL;
3145 r = tempfn_random(to, NULL, &t);
3149 if (symlink(from, t) < 0)
3152 if (rename(t, to) < 0) {
3160 int symlink_idempotent(const char *from, const char *to) {
3161 _cleanup_free_ char *p = NULL;
3167 if (symlink(from, to) < 0) {
3168 if (errno != EEXIST)
3171 r = readlink_malloc(to, &p);
3175 if (!streq(p, from))
3182 int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
3183 _cleanup_free_ char *t = NULL;
3188 r = tempfn_random(path, NULL, &t);
3192 if (mknod(t, mode, dev) < 0)
3195 if (rename(t, path) < 0) {
3203 int mkfifo_atomic(const char *path, mode_t mode) {
3204 _cleanup_free_ char *t = NULL;
3209 r = tempfn_random(path, NULL, &t);
3213 if (mkfifo(t, mode) < 0)
3216 if (rename(t, path) < 0) {
3225 bool display_is_local(const char *display) {
3229 display[0] == ':' &&
3230 display[1] >= '0' &&
3234 int socket_from_display(const char *display, char **path) {
3241 if (!display_is_local(display))
3244 k = strspn(display+1, "0123456789");
3246 f = new(char, strlen("/tmp/.X11-unix/X") + k + 1);
3250 c = stpcpy(f, "/tmp/.X11-unix/X");
3251 memcpy(c, display+1, k);
3260 const char **username,
3261 uid_t *uid, gid_t *gid,
3263 const char **shell) {
3271 /* We enforce some special rules for uid=0: in order to avoid
3272 * NSS lookups for root we hardcode its data. */
3274 if (streq(*username, "root") || streq(*username, "0")) {
3292 if (parse_uid(*username, &u) >= 0) {
3296 /* If there are multiple users with the same id, make
3297 * sure to leave $USER to the configured value instead
3298 * of the first occurrence in the database. However if
3299 * the uid was configured by a numeric uid, then let's
3300 * pick the real username from /etc/passwd. */
3302 *username = p->pw_name;
3305 p = getpwnam(*username);
3309 return errno > 0 ? -errno : -ESRCH;
3321 *shell = p->pw_shell;
3326 char* uid_to_name(uid_t uid) {
3331 return strdup("root");
3335 return strdup(p->pw_name);
3337 if (asprintf(&r, UID_FMT, uid) < 0)
3343 char* gid_to_name(gid_t gid) {
3348 return strdup("root");
3352 return strdup(p->gr_name);
3354 if (asprintf(&r, GID_FMT, gid) < 0)
3360 int get_group_creds(const char **groupname, gid_t *gid) {
3366 /* We enforce some special rules for gid=0: in order to avoid
3367 * NSS lookups for root we hardcode its data. */
3369 if (streq(*groupname, "root") || streq(*groupname, "0")) {
3370 *groupname = "root";
3378 if (parse_gid(*groupname, &id) >= 0) {
3383 *groupname = g->gr_name;
3386 g = getgrnam(*groupname);
3390 return errno > 0 ? -errno : -ESRCH;
3398 int in_gid(gid_t gid) {
3400 int ngroups_max, r, i;
3402 if (getgid() == gid)
3405 if (getegid() == gid)
3408 ngroups_max = sysconf(_SC_NGROUPS_MAX);
3409 assert(ngroups_max > 0);
3411 gids = alloca(sizeof(gid_t) * ngroups_max);
3413 r = getgroups(ngroups_max, gids);
3417 for (i = 0; i < r; i++)
3424 /// UNNEEDED by elogind
3426 int in_group(const char *name) {
3430 r = get_group_creds(&name, &gid);
3437 int glob_exists(const char *path) {
3438 _cleanup_globfree_ glob_t g = {};
3444 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
3446 if (k == GLOB_NOMATCH)
3448 else if (k == GLOB_NOSPACE)
3451 return !strv_isempty(g.gl_pathv);
3453 return errno ? -errno : -EIO;
3456 int glob_extend(char ***strv, const char *path) {
3457 _cleanup_globfree_ glob_t g = {};
3462 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
3464 if (k == GLOB_NOMATCH)
3466 else if (k == GLOB_NOSPACE)
3468 else if (k != 0 || strv_isempty(g.gl_pathv))
3469 return errno ? -errno : -EIO;
3471 STRV_FOREACH(p, g.gl_pathv) {
3472 k = strv_extend(strv, *p);
3481 int dirent_ensure_type(DIR *d, struct dirent *de) {
3487 if (de->d_type != DT_UNKNOWN)
3490 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
3494 S_ISREG(st.st_mode) ? DT_REG :
3495 S_ISDIR(st.st_mode) ? DT_DIR :
3496 S_ISLNK(st.st_mode) ? DT_LNK :
3497 S_ISFIFO(st.st_mode) ? DT_FIFO :
3498 S_ISSOCK(st.st_mode) ? DT_SOCK :
3499 S_ISCHR(st.st_mode) ? DT_CHR :
3500 S_ISBLK(st.st_mode) ? DT_BLK :
3506 int get_files_in_directory(const char *path, char ***list) {
3507 _cleanup_closedir_ DIR *d = NULL;
3508 size_t bufsize = 0, n = 0;
3509 _cleanup_strv_free_ char **l = NULL;
3513 /* Returns all files in a directory in *list, and the number
3514 * of files as return value. If list is NULL returns only the
3526 if (!de && errno != 0)
3531 dirent_ensure_type(d, de);
3533 if (!dirent_is_file(de))
3537 /* one extra slot is needed for the terminating NULL */
3538 if (!GREEDY_REALLOC(l, bufsize, n + 2))
3541 l[n] = strdup(de->d_name);
3552 l = NULL; /* avoid freeing */
3558 char *strjoin(const char *x, ...) {
3572 t = va_arg(ap, const char *);
3577 if (n > ((size_t) -1) - l) {
3601 t = va_arg(ap, const char *);
3615 bool is_main_thread(void) {
3616 static thread_local int cached = 0;
3618 if (_unlikely_(cached == 0))
3619 cached = getpid() == gettid() ? 1 : -1;
3624 /// UNNEEDED by elogind
3626 int block_get_whole_disk(dev_t d, dev_t *ret) {
3633 /* If it has a queue this is good enough for us */
3634 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
3637 r = access(p, F_OK);
3645 /* If it is a partition find the originating device */
3646 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
3649 r = access(p, F_OK);
3655 /* Get parent dev_t */
3656 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
3659 r = read_one_line_file(p, &s);
3665 r = sscanf(s, "%u:%u", &m, &n);
3671 /* Only return this if it is really good enough for us. */
3672 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
3675 r = access(p, F_OK);
3679 *ret = makedev(m, n);
3687 static const char *const ioprio_class_table[] = {
3688 [IOPRIO_CLASS_NONE] = "none",
3689 [IOPRIO_CLASS_RT] = "realtime",
3690 [IOPRIO_CLASS_BE] = "best-effort",
3691 [IOPRIO_CLASS_IDLE] = "idle"
3694 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
3696 static const char *const sigchld_code_table[] = {
3697 [CLD_EXITED] = "exited",
3698 [CLD_KILLED] = "killed",
3699 [CLD_DUMPED] = "dumped",
3700 [CLD_TRAPPED] = "trapped",
3701 [CLD_STOPPED] = "stopped",
3702 [CLD_CONTINUED] = "continued",
3705 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
3707 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
3708 [LOG_FAC(LOG_KERN)] = "kern",
3709 [LOG_FAC(LOG_USER)] = "user",
3710 [LOG_FAC(LOG_MAIL)] = "mail",
3711 [LOG_FAC(LOG_DAEMON)] = "daemon",
3712 [LOG_FAC(LOG_AUTH)] = "auth",
3713 [LOG_FAC(LOG_SYSLOG)] = "syslog",
3714 [LOG_FAC(LOG_LPR)] = "lpr",
3715 [LOG_FAC(LOG_NEWS)] = "news",
3716 [LOG_FAC(LOG_UUCP)] = "uucp",
3717 [LOG_FAC(LOG_CRON)] = "cron",
3718 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
3719 [LOG_FAC(LOG_FTP)] = "ftp",
3720 [LOG_FAC(LOG_LOCAL0)] = "local0",
3721 [LOG_FAC(LOG_LOCAL1)] = "local1",
3722 [LOG_FAC(LOG_LOCAL2)] = "local2",
3723 [LOG_FAC(LOG_LOCAL3)] = "local3",
3724 [LOG_FAC(LOG_LOCAL4)] = "local4",
3725 [LOG_FAC(LOG_LOCAL5)] = "local5",
3726 [LOG_FAC(LOG_LOCAL6)] = "local6",
3727 [LOG_FAC(LOG_LOCAL7)] = "local7"
3730 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
3732 static const char *const log_level_table[] = {
3733 [LOG_EMERG] = "emerg",
3734 [LOG_ALERT] = "alert",
3735 [LOG_CRIT] = "crit",
3737 [LOG_WARNING] = "warning",
3738 [LOG_NOTICE] = "notice",
3739 [LOG_INFO] = "info",
3740 [LOG_DEBUG] = "debug"
3743 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
3745 static const char* const sched_policy_table[] = {
3746 [SCHED_OTHER] = "other",
3747 [SCHED_BATCH] = "batch",
3748 [SCHED_IDLE] = "idle",
3749 [SCHED_FIFO] = "fifo",
3753 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
3755 static const char* const rlimit_table[_RLIMIT_MAX] = {
3756 [RLIMIT_CPU] = "LimitCPU",
3757 [RLIMIT_FSIZE] = "LimitFSIZE",
3758 [RLIMIT_DATA] = "LimitDATA",
3759 [RLIMIT_STACK] = "LimitSTACK",
3760 [RLIMIT_CORE] = "LimitCORE",
3761 [RLIMIT_RSS] = "LimitRSS",
3762 [RLIMIT_NOFILE] = "LimitNOFILE",
3763 [RLIMIT_AS] = "LimitAS",
3764 [RLIMIT_NPROC] = "LimitNPROC",
3765 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
3766 [RLIMIT_LOCKS] = "LimitLOCKS",
3767 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
3768 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
3769 [RLIMIT_NICE] = "LimitNICE",
3770 [RLIMIT_RTPRIO] = "LimitRTPRIO",
3771 [RLIMIT_RTTIME] = "LimitRTTIME"
3774 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
3776 static const char* const ip_tos_table[] = {
3777 [IPTOS_LOWDELAY] = "low-delay",
3778 [IPTOS_THROUGHPUT] = "throughput",
3779 [IPTOS_RELIABILITY] = "reliability",
3780 [IPTOS_LOWCOST] = "low-cost",
3783 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
3785 bool kexec_loaded(void) {
3786 bool loaded = false;
3789 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
3797 /// UNNEEDED by elogind
3799 int prot_from_flags(int flags) {
3801 switch (flags & O_ACCMODE) {
3810 return PROT_READ|PROT_WRITE;
3817 char *format_bytes(char *buf, size_t l, off_t t) {
3820 static const struct {
3824 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
3825 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
3826 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
3827 { "G", 1024ULL*1024ULL*1024ULL },
3828 { "M", 1024ULL*1024ULL },
3832 if (t == (off_t) -1)
3835 for (i = 0; i < ELEMENTSOF(table); i++) {
3837 if (t >= table[i].factor) {
3840 (unsigned long long) (t / table[i].factor),
3841 (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
3848 snprintf(buf, l, "%lluB", (unsigned long long) t);
3857 void* memdup(const void *p, size_t l) {
3870 int fd_inc_sndbuf(int fd, size_t n) {
3872 socklen_t l = sizeof(value);
3874 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
3875 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
3878 /* If we have the privileges we will ignore the kernel limit. */
3881 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
3882 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
3888 int fd_inc_rcvbuf(int fd, size_t n) {
3890 socklen_t l = sizeof(value);
3892 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
3893 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
3896 /* If we have the privileges we will ignore the kernel limit. */
3899 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
3900 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
3905 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
3906 bool stdout_is_tty, stderr_is_tty;
3907 pid_t parent_pid, agent_pid;
3908 sigset_t ss, saved_ss;
3916 /* Spawns a temporary TTY agent, making sure it goes away when
3919 parent_pid = getpid();
3921 /* First we temporarily block all signals, so that the new
3922 * child has them blocked initially. This way, we can be sure
3923 * that SIGTERMs are not lost we might send to the agent. */
3924 assert_se(sigfillset(&ss) >= 0);
3925 assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0);
3928 if (agent_pid < 0) {
3929 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
3933 if (agent_pid != 0) {
3934 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
3941 * Make sure the agent goes away when the parent dies */
3942 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
3943 _exit(EXIT_FAILURE);
3945 /* Make sure we actually can kill the agent, if we need to, in
3946 * case somebody invoked us from a shell script that trapped
3947 * SIGTERM or so... */
3948 (void) reset_all_signal_handlers();
3949 (void) reset_signal_mask();
3951 /* Check whether our parent died before we were able
3952 * to set the death signal and unblock the signals */
3953 if (getppid() != parent_pid)
3954 _exit(EXIT_SUCCESS);
3956 /* Don't leak fds to the agent */
3957 close_all_fds(except, n_except);
3959 stdout_is_tty = isatty(STDOUT_FILENO);
3960 stderr_is_tty = isatty(STDERR_FILENO);
3962 if (!stdout_is_tty || !stderr_is_tty) {
3965 /* Detach from stdout/stderr. and reopen
3966 * /dev/tty for them. This is important to
3967 * ensure that when systemctl is started via
3968 * popen() or a similar call that expects to
3969 * read EOF we actually do generate EOF and
3970 * not delay this indefinitely by because we
3971 * keep an unused copy of stdin around. */
3972 fd = open("/dev/tty", O_WRONLY);
3974 log_error_errno(errno, "Failed to open /dev/tty: %m");
3975 _exit(EXIT_FAILURE);
3979 dup2(fd, STDOUT_FILENO);
3982 dup2(fd, STDERR_FILENO);
3988 /* Count arguments */
3990 for (n = 0; va_arg(ap, char*); n++)
3995 l = alloca(sizeof(char *) * (n + 1));
3997 /* Fill in arguments */
3999 for (i = 0; i <= n; i++)
4000 l[i] = va_arg(ap, char*);
4004 _exit(EXIT_FAILURE);
4007 /// UNNEEDED by elogind
4009 int setrlimit_closest(int resource, const struct rlimit *rlim) {
4010 struct rlimit highest, fixed;
4014 if (setrlimit(resource, rlim) >= 0)
4020 /* So we failed to set the desired setrlimit, then let's try
4021 * to get as close as we can */
4022 assert_se(getrlimit(resource, &highest) == 0);
4024 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
4025 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
4027 if (setrlimit(resource, &fixed) < 0)
4033 bool http_etag_is_valid(const char *etag) {
4037 if (!endswith(etag, "\""))
4040 if (!startswith(etag, "\"") && !startswith(etag, "W/\""))
4047 bool http_url_is_valid(const char *url) {
4053 p = startswith(url, "http://");
4055 p = startswith(url, "https://");
4062 return ascii_is_valid(p);
4065 bool documentation_url_is_valid(const char *url) {
4071 if (http_url_is_valid(url))
4074 p = startswith(url, "file:/");
4076 p = startswith(url, "info:");
4078 p = startswith(url, "man:");
4083 return ascii_is_valid(p);
4086 bool in_initrd(void) {
4087 static int saved = -1;
4093 /* We make two checks here:
4095 * 1. the flag file /etc/initrd-release must exist
4096 * 2. the root file system must be a memory file system
4098 * The second check is extra paranoia, since misdetecting an
4099 * initrd can have bad bad consequences due the initrd
4100 * emptying when transititioning to the main systemd.
4103 saved = access("/etc/initrd-release", F_OK) >= 0 &&
4104 statfs("/", &s) >= 0 &&
4105 is_temporary_fs(&s);
4110 int get_home_dir(char **_h) {
4118 /* Take the user specified one */
4119 e = secure_getenv("HOME");
4120 if (e && path_is_absolute(e)) {
4129 /* Hardcode home directory for root to avoid NSS */
4132 h = strdup("/root");
4140 /* Check the database... */
4144 return errno > 0 ? -errno : -ESRCH;
4146 if (!path_is_absolute(p->pw_dir))
4149 h = strdup(p->pw_dir);
4157 /// UNNEEDED by elogind
4159 int get_shell(char **_s) {
4167 /* Take the user specified one */
4168 e = getenv("SHELL");
4178 /* Hardcode home directory for root to avoid NSS */
4181 s = strdup("/bin/sh");
4189 /* Check the database... */
4193 return errno > 0 ? -errno : -ESRCH;
4195 if (!path_is_absolute(p->pw_shell))
4198 s = strdup(p->pw_shell);
4207 bool filename_is_valid(const char *p) {
4221 if (strlen(p) > FILENAME_MAX)
4227 bool string_is_safe(const char *p) {
4233 for (t = p; *t; t++) {
4234 if (*t > 0 && *t < ' ')
4237 if (strchr("\\\"\'\x7f", *t))
4245 * Check if a string contains control characters. If 'ok' is non-NULL
4246 * it may be a string containing additional CCs to be considered OK.
4248 bool string_has_cc(const char *p, const char *ok) {
4253 for (t = p; *t; t++) {
4254 if (ok && strchr(ok, *t))
4257 if (*t > 0 && *t < ' ')
4267 bool path_is_safe(const char *p) {
4272 if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
4275 if (strlen(p)+1 > PATH_MAX)
4278 /* The following two checks are not really dangerous, but hey, they still are confusing */
4279 if (streq(p, ".") || startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
4282 if (strstr(p, "//"))
4288 /// UNNEEDED by elogind
4290 /* hey glibc, APIs with callbacks without a user pointer are so useless */
4291 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
4292 int (*compar) (const void *, const void *, void *), void *arg) {
4301 p = (void *)(((const char *) base) + (idx * size));
4302 comparison = compar(key, p, arg);
4305 else if (comparison > 0)
4313 void init_gettext(void) {
4314 setlocale(LC_ALL, "");
4315 textdomain(GETTEXT_PACKAGE);
4319 bool is_locale_utf8(void) {
4321 static int cached_answer = -1;
4323 if (cached_answer >= 0)
4326 if (!setlocale(LC_ALL, "")) {
4327 cached_answer = true;
4331 set = nl_langinfo(CODESET);
4333 cached_answer = true;
4337 if (streq(set, "UTF-8")) {
4338 cached_answer = true;
4342 /* For LC_CTYPE=="C" return true, because CTYPE is effectly
4343 * unset and everything can do to UTF-8 nowadays. */
4344 set = setlocale(LC_CTYPE, NULL);
4346 cached_answer = true;
4350 /* Check result, but ignore the result if C was set
4353 STR_IN_SET(set, "C", "POSIX") &&
4354 !getenv("LC_ALL") &&
4355 !getenv("LC_CTYPE") &&
4359 return (bool) cached_answer;
4362 const char *draw_special_char(DrawSpecialChar ch) {
4363 static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
4366 [DRAW_TREE_VERTICAL] = "\342\224\202 ", /* │ */
4367 [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */
4368 [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */
4369 [DRAW_TREE_SPACE] = " ", /* */
4370 [DRAW_TRIANGULAR_BULLET] = "\342\200\243", /* ‣ */
4371 [DRAW_BLACK_CIRCLE] = "\342\227\217", /* ● */
4372 [DRAW_ARROW] = "\342\206\222", /* → */
4373 [DRAW_DASH] = "\342\200\223", /* – */
4376 /* ASCII fallback */ {
4377 [DRAW_TREE_VERTICAL] = "| ",
4378 [DRAW_TREE_BRANCH] = "|-",
4379 [DRAW_TREE_RIGHT] = "`-",
4380 [DRAW_TREE_SPACE] = " ",
4381 [DRAW_TRIANGULAR_BULLET] = ">",
4382 [DRAW_BLACK_CIRCLE] = "*",
4383 [DRAW_ARROW] = "->",
4388 return draw_table[!is_locale_utf8()][ch];
4391 /// UNNEEDED by elogind
4393 char *strreplace(const char *text, const char *old_string, const char *new_string) {
4396 size_t l, old_len, new_len;
4402 old_len = strlen(old_string);
4403 new_len = strlen(new_string);
4416 if (!startswith(f, old_string)) {
4422 nl = l - old_len + new_len;
4423 a = realloc(r, nl + 1);
4431 t = stpcpy(t, new_string);
4443 char *strip_tab_ansi(char **ibuf, size_t *_isz) {
4444 const char *i, *begin = NULL;
4449 } state = STATE_OTHER;
4451 size_t osz = 0, isz;
4457 /* Strips ANSI color and replaces TABs by 8 spaces */
4459 isz = _isz ? *_isz : strlen(*ibuf);
4461 f = open_memstream(&obuf, &osz);
4465 for (i = *ibuf; i < *ibuf + isz + 1; i++) {
4470 if (i >= *ibuf + isz) /* EOT */
4472 else if (*i == '\x1B')
4473 state = STATE_ESCAPE;
4474 else if (*i == '\t')
4481 if (i >= *ibuf + isz) { /* EOT */
4484 } else if (*i == '[') {
4485 state = STATE_BRACKET;
4490 state = STATE_OTHER;
4497 if (i >= *ibuf + isz || /* EOT */
4498 (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
4501 state = STATE_OTHER;
4503 } else if (*i == 'm')
4504 state = STATE_OTHER;
4526 int on_ac_power(void) {
4527 bool found_offline = false, found_online = false;
4528 _cleanup_closedir_ DIR *d = NULL;
4530 d = opendir("/sys/class/power_supply");
4532 return errno == ENOENT ? true : -errno;
4536 _cleanup_close_ int fd = -1, device = -1;
4542 if (!de && errno != 0)
4548 if (hidden_file(de->d_name))
4551 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
4553 if (errno == ENOENT || errno == ENOTDIR)
4559 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
4561 if (errno == ENOENT)
4567 n = read(fd, contents, sizeof(contents));
4571 if (n != 6 || memcmp(contents, "Mains\n", 6))
4575 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
4577 if (errno == ENOENT)
4583 n = read(fd, contents, sizeof(contents));
4587 if (n != 2 || contents[1] != '\n')
4590 if (contents[0] == '1') {
4591 found_online = true;
4593 } else if (contents[0] == '0')
4594 found_offline = true;
4599 return found_online || !found_offline;
4603 static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
4610 if (!path_strv_resolve_uniq(search, root))
4613 STRV_FOREACH(i, search) {
4614 _cleanup_free_ char *p = NULL;
4618 p = strjoin(root, *i, "/", path, NULL);
4620 p = strjoin(*i, "/", path, NULL);
4630 if (errno != ENOENT)
4637 int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
4638 _cleanup_strv_free_ char **copy = NULL;
4644 if (path_is_absolute(path)) {
4647 f = fopen(path, mode);
4656 copy = strv_copy((char**) search);
4660 return search_and_fopen_internal(path, mode, root, copy, _f);
4663 /// UNNEEDED by elogind
4665 int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
4666 _cleanup_strv_free_ char **s = NULL;
4668 if (path_is_absolute(path)) {
4671 f = fopen(path, mode);
4680 s = strv_split_nulstr(search);
4684 return search_and_fopen_internal(path, mode, root, s, _f);
4688 char *strextend(char **x, ...) {
4695 l = f = *x ? strlen(*x) : 0;
4702 t = va_arg(ap, const char *);
4707 if (n > ((size_t) -1) - l) {
4716 r = realloc(*x, l+1);
4726 t = va_arg(ap, const char *);
4740 char *strrep(const char *s, unsigned n) {
4748 p = r = malloc(l * n + 1);
4752 for (i = 0; i < n; i++)
4759 void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
4766 if (*allocated >= need)
4769 newalloc = MAX(need * 2, 64u / size);
4770 a = newalloc * size;
4772 /* check for overflows */
4773 if (a < size * need)
4781 *allocated = newalloc;
4785 void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
4794 q = greedy_realloc(p, allocated, need, size);
4798 if (*allocated > prev)
4799 memzero(q + prev * size, (*allocated - prev) * size);
4804 bool id128_is_valid(const char *s) {
4810 /* Simple formatted 128bit hex string */
4812 for (i = 0; i < l; i++) {
4815 if (!(c >= '0' && c <= '9') &&
4816 !(c >= 'a' && c <= 'z') &&
4817 !(c >= 'A' && c <= 'Z'))
4821 } else if (l == 36) {
4823 /* Formatted UUID */
4825 for (i = 0; i < l; i++) {
4828 if ((i == 8 || i == 13 || i == 18 || i == 23)) {
4832 if (!(c >= '0' && c <= '9') &&
4833 !(c >= 'a' && c <= 'z') &&
4834 !(c >= 'A' && c <= 'Z'))
4845 /// UNNEEDED by elogind
4847 int split_pair(const char *s, const char *sep, char **l, char **r) {
4862 a = strndup(s, x - s);
4866 b = strdup(x + strlen(sep));
4878 int shall_restore_state(void) {
4879 _cleanup_free_ char *value = NULL;
4882 r = get_proc_cmdline_key("systemd.restore_state=", &value);
4888 return parse_boolean(value) != 0;
4892 int proc_cmdline(char **ret) {
4895 if (detect_container(NULL) > 0)
4896 return get_process_cmdline(1, 0, false, ret);
4898 return read_one_line_file("/proc/cmdline", ret);
4901 int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
4902 _cleanup_free_ char *line = NULL;
4908 r = proc_cmdline(&line);
4914 _cleanup_free_ char *word = NULL;
4917 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
4923 /* Filter out arguments that are intended only for the
4925 if (!in_initrd() && startswith(word, "rd."))
4928 value = strchr(word, '=');
4932 r = parse_item(word, value);
4940 int get_proc_cmdline_key(const char *key, char **value) {
4941 _cleanup_free_ char *line = NULL, *ret = NULL;
4948 r = proc_cmdline(&line);
4954 _cleanup_free_ char *word = NULL;
4957 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
4963 /* Filter out arguments that are intended only for the
4965 if (!in_initrd() && startswith(word, "rd."))
4969 e = startswith(word, key);
4973 r = free_and_strdup(&ret, e);
4979 if (streq(word, key))
4993 int container_get_leader(const char *machine, pid_t *pid) {
4994 _cleanup_free_ char *s = NULL, *class = NULL;
5002 if (!machine_name_is_valid(machine))
5005 p = strjoina("/run/systemd/machines/", machine);
5006 r = parse_env_file(p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
5014 if (!streq_ptr(class, "container"))
5017 r = parse_pid(s, &leader);
5027 int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd) {
5028 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, netnsfd = -1, usernsfd = -1;
5036 mntns = procfs_file_alloca(pid, "ns/mnt");
5037 mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5045 pidns = procfs_file_alloca(pid, "ns/pid");
5046 pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5054 netns = procfs_file_alloca(pid, "ns/net");
5055 netnsfd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5063 userns = procfs_file_alloca(pid, "ns/user");
5064 usernsfd = open(userns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5065 if (usernsfd < 0 && errno != ENOENT)
5072 root = procfs_file_alloca(pid, "root");
5073 rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
5079 *pidns_fd = pidnsfd;
5082 *mntns_fd = mntnsfd;
5085 *netns_fd = netnsfd;
5088 *userns_fd = usernsfd;
5093 pidnsfd = mntnsfd = netnsfd = usernsfd = -1;
5098 int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd) {
5099 if (userns_fd >= 0) {
5100 /* Can't setns to your own userns, since then you could
5101 * escalate from non-root to root in your own namespace, so
5102 * check if namespaces equal before attempting to enter. */
5103 _cleanup_free_ char *userns_fd_path = NULL;
5105 if (asprintf(&userns_fd_path, "/proc/self/fd/%d", userns_fd) < 0)
5108 r = files_same(userns_fd_path, "/proc/self/ns/user");
5116 if (setns(pidns_fd, CLONE_NEWPID) < 0)
5120 if (setns(mntns_fd, CLONE_NEWNS) < 0)
5124 if (setns(netns_fd, CLONE_NEWNET) < 0)
5128 if (setns(userns_fd, CLONE_NEWUSER) < 0)
5132 if (fchdir(root_fd) < 0)
5135 if (chroot(".") < 0)
5139 return reset_uid_gid();
5142 int getpeercred(int fd, struct ucred *ucred) {
5143 socklen_t n = sizeof(struct ucred);
5150 r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
5154 if (n != sizeof(struct ucred))
5157 /* Check if the data is actually useful and not suppressed due
5158 * to namespacing issues */
5161 if (u.uid == UID_INVALID)
5163 if (u.gid == GID_INVALID)
5170 int getpeersec(int fd, char **ret) {
5182 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
5186 if (errno != ERANGE)
5193 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
5209 /* This is much like like mkostemp() but is subject to umask(). */
5210 int mkostemp_safe(char *pattern, int flags) {
5211 _cleanup_umask_ mode_t u;
5218 fd = mkostemp(pattern, flags);
5225 /// UNNEEDED by elogind
5227 int open_tmpfile(const char *path, int flags) {
5234 /* Try O_TMPFILE first, if it is supported */
5235 fd = open(path, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
5240 /* Fall back to unguessable name + unlinking */
5241 p = strjoina(path, "/systemd-tmp-XXXXXX");
5243 fd = mkostemp_safe(p, flags);
5252 int fd_warn_permissions(const char *path, int fd) {
5255 if (fstat(fd, &st) < 0)
5258 if (st.st_mode & 0111)
5259 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
5261 if (st.st_mode & 0002)
5262 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
5264 if (getpid() == 1 && (st.st_mode & 0044) != 0044)
5265 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);
5270 /// UNNEEDED by elogind
5272 unsigned long personality_from_string(const char *p) {
5274 /* Parse a personality specifier. We introduce our own
5275 * identifiers that indicate specific ABIs, rather than just
5276 * hints regarding the register size, since we want to keep
5277 * things open for multiple locally supported ABIs for the
5278 * same register size. We try to reuse the ABI identifiers
5279 * used by libseccomp. */
5281 #if defined(__x86_64__)
5283 if (streq(p, "x86"))
5286 if (streq(p, "x86-64"))
5289 #elif defined(__i386__)
5291 if (streq(p, "x86"))
5295 return PERSONALITY_INVALID;
5298 const char* personality_to_string(unsigned long p) {
5300 #if defined(__x86_64__)
5302 if (p == PER_LINUX32)
5308 #elif defined(__i386__)
5318 uint64_t physical_memory(void) {
5321 /* We return this as uint64_t in case we are running as 32bit
5322 * process on a 64bit kernel with huge amounts of memory */
5324 mem = sysconf(_SC_PHYS_PAGES);
5327 return (uint64_t) mem * (uint64_t) page_size();
5330 /// UNNEEDED by elogind
5332 void hexdump(FILE *f, const void *p, size_t s) {
5333 const uint8_t *b = p;
5336 assert(s == 0 || b);
5341 fprintf(f, "%04x ", n);
5343 for (i = 0; i < 16; i++) {
5348 fprintf(f, "%02x ", b[i]);
5356 for (i = 0; i < 16; i++) {
5361 fputc(isprint(b[i]) ? (char) b[i] : '.', f);
5375 int update_reboot_param_file(const char *param) {
5380 r = write_string_file(REBOOT_PARAM_FILE, param, WRITE_STRING_FILE_CREATE);
5382 log_error("Failed to write reboot param to "
5383 REBOOT_PARAM_FILE": %s", strerror(-r));
5385 unlink(REBOOT_PARAM_FILE);
5390 int umount_recursive(const char *prefix, int flags) {
5394 /* Try to umount everything recursively below a
5395 * directory. Also, take care of stacked mounts, and keep
5396 * unmounting them until they are gone. */
5399 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
5404 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
5405 if (!proc_self_mountinfo)
5409 _cleanup_free_ char *path = NULL, *p = NULL;
5412 k = fscanf(proc_self_mountinfo,
5413 "%*s " /* (1) mount id */
5414 "%*s " /* (2) parent id */
5415 "%*s " /* (3) major:minor */
5416 "%*s " /* (4) root */
5417 "%ms " /* (5) mount point */
5418 "%*s" /* (6) mount options */
5419 "%*[^-]" /* (7) optional fields */
5420 "- " /* (8) separator */
5421 "%*s " /* (9) file system type */
5422 "%*s" /* (10) mount source */
5423 "%*s" /* (11) mount options 2 */
5424 "%*[^\n]", /* some rubbish at the end */
5433 r = cunescape(path, UNESCAPE_RELAX, &p);
5437 if (!path_startswith(p, prefix))
5440 if (umount2(p, flags) < 0) {
5456 static int get_mount_flags(const char *path, unsigned long *flags) {
5459 if (statvfs(path, &buf) < 0)
5461 *flags = buf.f_flag;
5465 int bind_remount_recursive(const char *prefix, bool ro) {
5466 _cleanup_set_free_free_ Set *done = NULL;
5467 _cleanup_free_ char *cleaned = NULL;
5470 /* Recursively remount a directory (and all its submounts)
5471 * read-only or read-write. If the directory is already
5472 * mounted, we reuse the mount and simply mark it
5473 * MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write
5474 * operation). If it isn't we first make it one. Afterwards we
5475 * apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to all
5476 * submounts we can access, too. When mounts are stacked on
5477 * the same mount point we only care for each individual
5478 * "top-level" mount on each point, as we cannot
5479 * influence/access the underlying mounts anyway. We do not
5480 * have any effect on future submounts that might get
5481 * propagated, they migt be writable. This includes future
5482 * submounts that have been triggered via autofs. */
5484 cleaned = strdup(prefix);
5488 path_kill_slashes(cleaned);
5490 done = set_new(&string_hash_ops);
5495 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
5496 _cleanup_set_free_free_ Set *todo = NULL;
5497 bool top_autofs = false;
5499 unsigned long orig_flags;
5501 todo = set_new(&string_hash_ops);
5505 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
5506 if (!proc_self_mountinfo)
5510 _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
5513 k = fscanf(proc_self_mountinfo,
5514 "%*s " /* (1) mount id */
5515 "%*s " /* (2) parent id */
5516 "%*s " /* (3) major:minor */
5517 "%*s " /* (4) root */
5518 "%ms " /* (5) mount point */
5519 "%*s" /* (6) mount options (superblock) */
5520 "%*[^-]" /* (7) optional fields */
5521 "- " /* (8) separator */
5522 "%ms " /* (9) file system type */
5523 "%*s" /* (10) mount source */
5524 "%*s" /* (11) mount options (bind mount) */
5525 "%*[^\n]", /* some rubbish at the end */
5535 r = cunescape(path, UNESCAPE_RELAX, &p);
5539 /* Let's ignore autofs mounts. If they aren't
5540 * triggered yet, we want to avoid triggering
5541 * them, as we don't make any guarantees for
5542 * future submounts anyway. If they are
5543 * already triggered, then we will find
5544 * another entry for this. */
5545 if (streq(type, "autofs")) {
5546 top_autofs = top_autofs || path_equal(cleaned, p);
5550 if (path_startswith(p, cleaned) &&
5551 !set_contains(done, p)) {
5553 r = set_consume(todo, p);
5563 /* If we have no submounts to process anymore and if
5564 * the root is either already done, or an autofs, we
5566 if (set_isempty(todo) &&
5567 (top_autofs || set_contains(done, cleaned)))
5570 if (!set_contains(done, cleaned) &&
5571 !set_contains(todo, cleaned)) {
5572 /* The prefix directory itself is not yet a
5573 * mount, make it one. */
5574 if (mount(cleaned, cleaned, NULL, MS_BIND|MS_REC, NULL) < 0)
5578 (void) get_mount_flags(cleaned, &orig_flags);
5579 orig_flags &= ~MS_RDONLY;
5581 if (mount(NULL, prefix, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0)
5584 x = strdup(cleaned);
5588 r = set_consume(done, x);
5593 while ((x = set_steal_first(todo))) {
5595 r = set_consume(done, x);
5596 if (r == -EEXIST || r == 0)
5601 /* Try to reuse the original flag set, but
5602 * don't care for errors, in case of
5603 * obstructed mounts */
5605 (void) get_mount_flags(x, &orig_flags);
5606 orig_flags &= ~MS_RDONLY;
5608 if (mount(NULL, x, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) {
5610 /* Deal with mount points that are
5611 * obstructed by a later mount */
5613 if (errno != ENOENT)
5622 int fflush_and_check(FILE *f) {
5629 return errno ? -errno : -EIO;
5634 int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
5646 * /foo/bar/.#<extra>waldoXXXXXX
5650 if (!filename_is_valid(fn))
5656 t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
5660 strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn), "XXXXXX");
5662 *ret = path_kill_slashes(t);
5666 int tempfn_random(const char *p, const char *extra, char **ret) {
5680 * /foo/bar/.#<extra>waldobaa2a261115984a9
5684 if (!filename_is_valid(fn))
5690 t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1);
5694 x = stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn);
5697 for (i = 0; i < 16; i++) {
5698 *(x++) = hexchar(u & 0xF);
5704 *ret = path_kill_slashes(t);
5708 /// UNNEEDED by elogind
5710 int tempfn_random_child(const char *p, const char *extra, char **ret) {
5721 * /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
5727 t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1);
5731 x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra);
5734 for (i = 0; i < 16; i++) {
5735 *(x++) = hexchar(u & 0xF);
5741 *ret = path_kill_slashes(t);
5745 int take_password_lock(const char *root) {
5747 struct flock flock = {
5749 .l_whence = SEEK_SET,
5757 /* This is roughly the same as lckpwdf(), but not as awful. We
5758 * don't want to use alarm() and signals, hence we implement
5759 * our own trivial version of this.
5761 * Note that shadow-utils also takes per-database locks in
5762 * addition to lckpwdf(). However, we don't given that they
5763 * are redundant as they they invoke lckpwdf() first and keep
5764 * it during everything they do. The per-database locks are
5765 * awfully racy, and thus we just won't do them. */
5768 path = strjoina(root, "/etc/.pwd.lock");
5770 path = "/etc/.pwd.lock";
5772 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
5776 r = fcntl(fd, F_SETLKW, &flock);
5785 int is_symlink(const char *path) {
5788 if (lstat(path, &info) < 0)
5791 return !!S_ISLNK(info.st_mode);
5795 int is_dir(const char* path, bool follow) {
5800 r = stat(path, &st);
5802 r = lstat(path, &st);
5806 return !!S_ISDIR(st.st_mode);
5809 /// UNNEEDED by elogind
5811 int is_device_node(const char *path) {
5814 if (lstat(path, &info) < 0)
5817 return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode));
5821 int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) {
5822 _cleanup_free_ char *s = NULL;
5823 size_t allocated = 0, sz = 0;
5831 SINGLE_QUOTE_ESCAPE,
5833 DOUBLE_QUOTE_ESCAPE,
5841 separators = WHITESPACE;
5843 /* Bail early if called after last value or with no input */
5845 goto finish_force_terminate;
5847 /* Parses the first word of a string, and returns it in
5848 * *ret. Removes all quotes in the process. When parsing fails
5849 * (because of an uneven number of quotes or similar), leaves
5850 * the pointer *p at the first invalid character. */
5858 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
5859 if (!GREEDY_REALLOC(s, allocated, sz+1))
5863 goto finish_force_terminate;
5864 else if (strchr(separators, c)) {
5865 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
5867 goto finish_force_next;
5872 /* We found a non-blank character, so we will always
5873 * want to return a string (even if it is empty),
5874 * allocate it here. */
5875 if (!GREEDY_REALLOC(s, allocated, sz+1))
5883 goto finish_force_terminate;
5884 else if (c == '\'' && (flags & EXTRACT_QUOTES))
5885 state = SINGLE_QUOTE;
5887 state = VALUE_ESCAPE;
5888 else if (c == '\"' && (flags & EXTRACT_QUOTES))
5889 state = DOUBLE_QUOTE;
5890 else if (strchr(separators, c)) {
5891 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
5893 goto finish_force_next;
5897 if (!GREEDY_REALLOC(s, allocated, sz+2))
5907 if (flags & EXTRACT_RELAX)
5908 goto finish_force_terminate;
5910 } else if (c == '\'')
5913 state = SINGLE_QUOTE_ESCAPE;
5915 if (!GREEDY_REALLOC(s, allocated, sz+2))
5929 state = DOUBLE_QUOTE_ESCAPE;
5931 if (!GREEDY_REALLOC(s, allocated, sz+2))
5939 case SINGLE_QUOTE_ESCAPE:
5940 case DOUBLE_QUOTE_ESCAPE:
5942 if (!GREEDY_REALLOC(s, allocated, sz+7))
5946 if ((flags & EXTRACT_CUNESCAPE_RELAX) &&
5947 (state == VALUE_ESCAPE || flags & EXTRACT_RELAX)) {
5948 /* If we find an unquoted trailing backslash and we're in
5949 * EXTRACT_CUNESCAPE_RELAX mode, keep it verbatim in the
5952 * Unbalanced quotes will only be allowed in EXTRACT_RELAX
5953 * mode, EXTRACT_CUNESCAPE_RELAX mode does not allow them.
5956 goto finish_force_terminate;
5958 if (flags & EXTRACT_RELAX)
5959 goto finish_force_terminate;
5963 if (flags & EXTRACT_CUNESCAPE) {
5966 r = cunescape_one(*p, (size_t) -1, &c, &u);
5968 if (flags & EXTRACT_CUNESCAPE_RELAX) {
5979 s[sz++] = c; /* normal explicit char */
5981 sz += utf8_encode_unichar(s + sz, u); /* unicode chars we'll encode as utf8 */
5986 state = (state == SINGLE_QUOTE_ESCAPE) ? SINGLE_QUOTE :
5987 (state == DOUBLE_QUOTE_ESCAPE) ? DOUBLE_QUOTE :
5993 goto finish_force_terminate;
5994 if (!strchr(separators, c))
6002 finish_force_terminate:
6019 /// UNNEEDED by elogind
6021 int extract_first_word_and_warn(
6024 const char *separators,
6027 const char *filename,
6029 const char *rvalue) {
6030 /* Try to unquote it, if it fails, warn about it and try again but this
6031 * time using EXTRACT_CUNESCAPE_RELAX to keep the backslashes verbatim
6032 * in invalid escape sequences. */
6037 r = extract_first_word(p, ret, separators, flags);
6038 if (r < 0 && !(flags&EXTRACT_CUNESCAPE_RELAX)) {
6039 /* Retry it with EXTRACT_CUNESCAPE_RELAX. */
6041 r = extract_first_word(p, ret, separators, flags|EXTRACT_CUNESCAPE_RELAX);
6043 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
6044 "Unbalanced quoting in command line, ignoring: \"%s\"", rvalue);
6046 log_syntax(unit, LOG_WARNING, filename, line, EINVAL,
6047 "Invalid escape sequences in command line: \"%s\"", rvalue);
6052 int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) {
6057 /* Parses a number of words from a string, stripping any
6058 * quotes if necessary. */
6062 /* Count how many words are expected */
6063 va_start(ap, flags);
6065 if (!va_arg(ap, char **))
6074 /* Read all words into a temporary array */
6075 l = newa0(char*, n);
6076 for (c = 0; c < n; c++) {
6078 r = extract_first_word(p, &l[c], separators, flags);
6082 for (j = 0; j < c; j++)
6092 /* If we managed to parse all words, return them in the passed
6094 va_start(ap, flags);
6095 for (i = 0; i < n; i++) {
6098 v = va_arg(ap, char **);
6109 int free_and_strdup(char **p, const char *s) {
6114 /* Replaces a string pointer with an strdup()ed new string,
6115 * possibly freeing the old one. */
6117 if (streq_ptr(*p, s))
6133 /// UNNEEDED by elogind
6135 int ptsname_malloc(int fd, char **ret) {
6148 if (ptsname_r(fd, c, l) == 0) {
6152 if (errno != ERANGE) {
6162 int openpt_in_namespace(pid_t pid, int flags) {
6163 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1;
6164 _cleanup_close_pair_ int pair[2] = { -1, -1 };
6166 struct cmsghdr cmsghdr;
6167 uint8_t buf[CMSG_SPACE(sizeof(int))];
6169 struct msghdr mh = {
6170 .msg_control = &control,
6171 .msg_controllen = sizeof(control),
6173 struct cmsghdr *cmsg;
6180 r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &usernsfd, &rootfd);
6184 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
6194 pair[0] = safe_close(pair[0]);
6196 r = namespace_enter(pidnsfd, mntnsfd, -1, usernsfd, rootfd);
6198 _exit(EXIT_FAILURE);
6200 master = posix_openpt(flags);
6202 _exit(EXIT_FAILURE);
6204 if (unlockpt(master) < 0)
6205 _exit(EXIT_FAILURE);
6207 cmsg = CMSG_FIRSTHDR(&mh);
6208 cmsg->cmsg_level = SOL_SOCKET;
6209 cmsg->cmsg_type = SCM_RIGHTS;
6210 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
6211 memcpy(CMSG_DATA(cmsg), &master, sizeof(int));
6213 mh.msg_controllen = cmsg->cmsg_len;
6215 if (sendmsg(pair[1], &mh, MSG_NOSIGNAL) < 0)
6216 _exit(EXIT_FAILURE);
6218 _exit(EXIT_SUCCESS);
6221 pair[1] = safe_close(pair[1]);
6223 r = wait_for_terminate(child, &si);
6226 if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
6229 if (recvmsg(pair[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
6232 CMSG_FOREACH(cmsg, &mh)
6233 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
6237 fds = (int*) CMSG_DATA(cmsg);
6238 n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
6241 close_many(fds, n_fds);
6252 ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) {
6253 _cleanup_close_ int fd = -1;
6256 /* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */
6258 fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOATIME|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
6262 l = fgetxattr(fd, attribute, value, size);
6269 static int parse_crtime(le64_t le, usec_t *usec) {
6275 if (u == 0 || u == (uint64_t) -1)
6282 int fd_getcrtime(int fd, usec_t *usec) {
6289 /* Until Linux gets a real concept of birthtime/creation time,
6290 * let's fake one with xattrs */
6292 n = fgetxattr(fd, "user.crtime_usec", &le, sizeof(le));
6295 if (n != sizeof(le))
6298 return parse_crtime(le, usec);
6301 /// UNNEEDED by elogind
6303 int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags) {
6307 n = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags);
6310 if (n != sizeof(le))
6313 return parse_crtime(le, usec);
6316 int path_getcrtime(const char *p, usec_t *usec) {
6323 n = getxattr(p, "user.crtime_usec", &le, sizeof(le));
6326 if (n != sizeof(le))
6329 return parse_crtime(le, usec);
6332 int fd_setcrtime(int fd, usec_t usec) {
6338 usec = now(CLOCK_REALTIME);
6340 le = htole64((uint64_t) usec);
6341 if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), 0) < 0)
6347 int same_fd(int a, int b) {
6348 struct stat sta, stb;
6355 /* Compares two file descriptors. Note that semantics are
6356 * quite different depending on whether we have kcmp() or we
6357 * don't. If we have kcmp() this will only return true for
6358 * dup()ed file descriptors, but not otherwise. If we don't
6359 * have kcmp() this will also return true for two fds of the same
6360 * file, created by separate open() calls. Since we use this
6361 * call mostly for filtering out duplicates in the fd store
6362 * this difference hopefully doesn't matter too much. */
6367 /* Try to use kcmp() if we have it. */
6369 r = kcmp(pid, pid, KCMP_FILE, a, b);
6374 if (errno != ENOSYS)
6377 /* We don't have kcmp(), use fstat() instead. */
6378 if (fstat(a, &sta) < 0)
6381 if (fstat(b, &stb) < 0)
6384 if ((sta.st_mode & S_IFMT) != (stb.st_mode & S_IFMT))
6387 /* We consider all device fds different, since two device fds
6388 * might refer to quite different device contexts even though
6389 * they share the same inode and backing dev_t. */
6391 if (S_ISCHR(sta.st_mode) || S_ISBLK(sta.st_mode))
6394 if (sta.st_dev != stb.st_dev || sta.st_ino != stb.st_ino)
6397 /* The fds refer to the same inode on disk, let's also check
6398 * if they have the same fd flags. This is useful to
6399 * distinguish the read and write side of a pipe created with
6401 fa = fcntl(a, F_GETFL);
6405 fb = fcntl(b, F_GETFL);
6413 int chattr_fd(int fd, unsigned value, unsigned mask) {
6414 unsigned old_attr, new_attr;
6419 if (fstat(fd, &st) < 0)
6422 /* Explicitly check whether this is a regular file or
6423 * directory. If it is anything else (such as a device node or
6424 * fifo), then the ioctl will not hit the file systems but
6425 * possibly drivers, where the ioctl might have different
6426 * effects. Notably, DRM is using the same ioctl() number. */
6428 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
6434 if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
6437 new_attr = (old_attr & ~mask) | (value & mask);
6438 if (new_attr == old_attr)
6441 if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
6447 /// UNNEEDED by elogind
6449 int chattr_path(const char *p, unsigned value, unsigned mask) {
6450 _cleanup_close_ int fd = -1;
6457 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
6461 return chattr_fd(fd, value, mask);
6465 int read_attr_fd(int fd, unsigned *ret) {
6470 if (fstat(fd, &st) < 0)
6473 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
6476 if (ioctl(fd, FS_IOC_GETFLAGS, ret) < 0)
6482 /// UNNEEDED by elogind
6484 int read_attr_path(const char *p, unsigned *ret) {
6485 _cleanup_close_ int fd = -1;
6490 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
6494 return read_attr_fd(fd, ret);
6497 static size_t nul_length(const uint8_t *p, size_t sz) {
6512 ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
6513 const uint8_t *q, *w, *e;
6521 n = nul_length(q, e - q);
6523 /* If there are more than the specified run length of
6524 * NUL bytes, or if this is the beginning or the end
6525 * of the buffer, then seek instead of write */
6526 if ((n > run_length) ||
6527 (n > 0 && q == p) ||
6528 (n > 0 && q + n >= e)) {
6530 l = write(fd, w, q - w);
6537 if (lseek(fd, n, SEEK_CUR) == (off_t) -1)
6549 l = write(fd, w, q - w);
6556 return q - (const uint8_t*) p;
6560 void sigkill_wait(pid_t *pid) {
6566 if (kill(*pid, SIGKILL) > 0)
6567 (void) wait_for_terminate(*pid, NULL);
6570 /// UNNEEDED by elogind
6572 int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
6573 int a = 0, b = 0, c = 0;
6583 if (!strchr(*p, '>'))
6586 if ((*p)[2] == '>') {
6587 c = undecchar((*p)[1]);
6589 } else if ((*p)[3] == '>') {
6590 b = undecchar((*p)[1]);
6591 c = undecchar((*p)[2]);
6593 } else if ((*p)[4] == '>') {
6594 a = undecchar((*p)[1]);
6595 b = undecchar((*p)[2]);
6596 c = undecchar((*p)[3]);
6601 if (a < 0 || b < 0 || c < 0 ||
6602 (!with_facility && (a || b || c > 7)))
6606 *priority = a*100 + b*10 + c;
6608 *priority = (*priority & LOG_FACMASK) | c;
6615 ssize_t string_table_lookup(const char * const *table, size_t len, const char *key) {
6621 for (i = 0; i < len; ++i)
6622 if (streq_ptr(table[i], key))
6628 /// UNNEEDED by elogind
6630 void cmsg_close_all(struct msghdr *mh) {
6631 struct cmsghdr *cmsg;
6635 CMSG_FOREACH(cmsg, mh)
6636 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
6637 close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int));
6640 int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
6644 ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
6648 /* renameat2() exists since Linux 3.15, btrfs added support for it later.
6649 * If it is not implemented, fallback to another method. */
6650 if (!IN_SET(errno, EINVAL, ENOSYS))
6653 /* The link()/unlink() fallback does not work on directories. But
6654 * renameat() without RENAME_NOREPLACE gives the same semantics on
6655 * directories, except when newpath is an *empty* directory. This is
6657 ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW);
6658 if (ret >= 0 && S_ISDIR(buf.st_mode)) {
6659 ret = renameat(olddirfd, oldpath, newdirfd, newpath);
6660 return ret >= 0 ? 0 : -errno;
6663 /* If it is not a directory, use the link()/unlink() fallback. */
6664 ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0);
6668 ret = unlinkat(olddirfd, oldpath, 0);
6670 /* backup errno before the following unlinkat() alters it */
6672 (void) unlinkat(newdirfd, newpath, 0);
6681 static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad) {
6685 if (*s == '\\' || strchr(bad, *s))
6694 char *shell_escape(const char *s, const char *bad) {
6697 r = new(char, strlen(s)*2+1);
6701 t = strcpy_backslash_escaped(r, s, bad);
6707 char *shell_maybe_quote(const char *s) {
6713 /* Encloses a string in double quotes if necessary to make it
6714 * OK as shell string. */
6716 for (p = s; *p; p++)
6719 strchr(SHELL_NEED_QUOTES, *p))
6725 r = new(char, 1+strlen(s)*2+1+1);
6731 t = mempcpy(t, s, p - s);
6733 t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE);
6741 int parse_mode(const char *s, mode_t *ret) {
6749 l = strtol(s, &x, 8);
6753 if (!x || x == s || *x)
6755 if (l < 0 || l > 07777)
6762 /// UNNEEDED by elogind
6764 int mount_move_root(const char *path) {
6767 if (chdir(path) < 0)
6770 if (mount(path, "/", NULL, MS_MOVE, NULL) < 0)
6773 if (chroot(".") < 0)
6783 int reset_uid_gid(void) {
6785 if (setgroups(0, NULL) < 0)
6788 if (setresgid(0, 0, 0) < 0)
6791 if (setresuid(0, 0, 0) < 0)
6797 int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink) {
6806 for (l = 100; ; l = (size_t) n + 1) {
6812 n = lgetxattr(path, name, v, l);
6814 n = getxattr(path, name, v, l);
6816 if (n >= 0 && (size_t) n < l) {
6823 if (n < 0 && errno != ERANGE)
6827 n = lgetxattr(path, name, NULL, 0);
6829 n = getxattr(path, name, NULL, 0);
6835 int fgetxattr_malloc(int fd, const char *name, char **value) {
6844 for (l = 100; ; l = (size_t) n + 1) {
6849 n = fgetxattr(fd, name, v, l);
6851 if (n >= 0 && (size_t) n < l) {
6858 if (n < 0 && errno != ERANGE)
6861 n = fgetxattr(fd, name, NULL, 0);