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 int parse_uid(const char *s, uid_t* ret_uid) {
377 unsigned long ul = 0;
383 r = safe_atolu(s, &ul);
389 if ((unsigned long) uid != ul)
392 /* Some libc APIs use UID_INVALID as special placeholder */
393 if (uid == (uid_t) 0xFFFFFFFF)
396 /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
397 if (uid == (uid_t) 0xFFFF)
406 int safe_atou(const char *s, unsigned *ret_u) {
414 l = strtoul(s, &x, 0);
416 if (!x || x == s || *x || errno)
417 return errno > 0 ? -errno : -EINVAL;
419 if ((unsigned long) (unsigned) l != l)
422 *ret_u = (unsigned) l;
426 int safe_atoi(const char *s, int *ret_i) {
434 l = strtol(s, &x, 0);
436 if (!x || x == s || *x || errno)
437 return errno > 0 ? -errno : -EINVAL;
439 if ((long) (int) l != l)
446 int safe_atou8(const char *s, uint8_t *ret) {
454 l = strtoul(s, &x, 0);
456 if (!x || x == s || *x || errno)
457 return errno > 0 ? -errno : -EINVAL;
459 if ((unsigned long) (uint8_t) l != l)
466 int safe_atou16(const char *s, uint16_t *ret) {
474 l = strtoul(s, &x, 0);
476 if (!x || x == s || *x || errno)
477 return errno > 0 ? -errno : -EINVAL;
479 if ((unsigned long) (uint16_t) l != l)
486 int safe_atoi16(const char *s, int16_t *ret) {
494 l = strtol(s, &x, 0);
496 if (!x || x == s || *x || errno)
497 return errno > 0 ? -errno : -EINVAL;
499 if ((long) (int16_t) l != l)
506 int safe_atollu(const char *s, long long unsigned *ret_llu) {
508 unsigned long long l;
514 l = strtoull(s, &x, 0);
516 if (!x || x == s || *x || errno)
517 return errno ? -errno : -EINVAL;
523 int safe_atolli(const char *s, long long int *ret_lli) {
531 l = strtoll(s, &x, 0);
533 if (!x || x == s || *x || errno)
534 return errno ? -errno : -EINVAL;
540 int safe_atod(const char *s, double *ret_d) {
548 loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
549 if (loc == (locale_t) 0)
553 d = strtod_l(s, &x, loc);
555 if (!x || x == s || *x || errno) {
557 return errno ? -errno : -EINVAL;
565 static size_t strcspn_escaped(const char *s, const char *reject) {
566 bool escaped = false;
569 for (n=0; s[n]; n++) {
572 else if (s[n] == '\\')
574 else if (strchr(reject, s[n]))
578 /* if s ends in \, return index of previous char */
582 /* Split a string into words. */
583 const char* split(const char **state, size_t *l, const char *separator, bool quoted) {
589 assert(**state == '\0');
593 current += strspn(current, separator);
599 if (quoted && strchr("\'\"", *current)) {
600 char quotechars[2] = {*current, '\0'};
602 *l = strcspn_escaped(current + 1, quotechars);
603 if (current[*l + 1] == '\0' || current[*l + 1] != quotechars[0] ||
604 (current[*l + 2] && !strchr(separator, current[*l + 2]))) {
605 /* right quote missing or garbage at the end */
609 *state = current++ + *l + 2;
611 *l = strcspn_escaped(current, separator);
612 if (current[*l] && !strchr(separator, current[*l])) {
613 /* unfinished escape */
617 *state = current + *l;
619 *l = strcspn(current, separator);
620 *state = current + *l;
626 int fchmod_umask(int fd, mode_t m) {
631 r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
637 char *truncate_nl(char *s) {
640 s[strcspn(s, NEWLINE)] = 0;
644 char *strnappend(const char *s, const char *suffix, size_t b) {
652 return strndup(suffix, b);
661 if (b > ((size_t) -1) - a)
664 r = new(char, a+b+1);
669 memcpy(r+a, suffix, b);
675 char *strappend(const char *s, const char *suffix) {
676 return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
679 int readlinkat_malloc(int fd, const char *p, char **ret) {
694 n = readlinkat(fd, p, c, l-1);
701 if ((size_t) n < l-1) {
712 int readlink_malloc(const char *p, char **ret) {
713 return readlinkat_malloc(AT_FDCWD, p, ret);
716 /// UNNEEDED by elogind
718 int readlink_value(const char *p, char **ret) {
719 _cleanup_free_ char *link = NULL;
723 r = readlink_malloc(p, &link);
727 value = basename(link);
731 value = strdup(value);
741 int readlink_and_make_absolute(const char *p, char **r) {
742 _cleanup_free_ char *target = NULL;
749 j = readlink_malloc(p, &target);
753 k = file_in_same_dir(p, target);
761 /// UNNEEDED by elogind
763 int readlink_and_canonicalize(const char *p, char **r) {
770 j = readlink_and_make_absolute(p, &t);
774 s = canonicalize_file_name(t);
781 path_kill_slashes(*r);
787 char *strstrip(char *s) {
790 /* Drops trailing whitespace. Modifies the string in
791 * place. Returns pointer to first non-space character */
793 s += strspn(s, WHITESPACE);
795 for (e = strchr(s, 0); e > s; e --)
796 if (!strchr(WHITESPACE, e[-1]))
804 /// UNNEEDED by elogind
806 char *delete_chars(char *s, const char *bad) {
809 /* Drops all whitespace, regardless where in the string */
811 for (f = s, t = s; *f; f++) {
824 char *file_in_same_dir(const char *path, const char *filename) {
831 /* This removes the last component of path and appends
832 * filename, unless the latter is absolute anyway or the
835 if (path_is_absolute(filename))
836 return strdup(filename);
838 e = strrchr(path, '/');
840 return strdup(filename);
842 k = strlen(filename);
843 ret = new(char, (e + 1 - path) + k + 1);
847 memcpy(mempcpy(ret, path, e + 1 - path), filename, k + 1);
851 /// UNNEEDED by elogind
853 int rmdir_parents(const char *path, const char *stop) {
862 /* Skip trailing slashes */
863 while (l > 0 && path[l-1] == '/')
869 /* Skip last component */
870 while (l > 0 && path[l-1] != '/')
873 /* Skip trailing slashes */
874 while (l > 0 && path[l-1] == '/')
880 if (!(t = strndup(path, l)))
883 if (path_startswith(stop, t)) {
900 char hexchar(int x) {
901 static const char table[16] = "0123456789abcdef";
903 return table[x & 15];
906 int unhexchar(char c) {
908 if (c >= '0' && c <= '9')
911 if (c >= 'a' && c <= 'f')
914 if (c >= 'A' && c <= 'F')
920 char *hexmem(const void *p, size_t l) {
924 z = r = malloc(l * 2 + 1);
928 for (x = p; x < (const uint8_t*) p + l; x++) {
929 *(z++) = hexchar(*x >> 4);
930 *(z++) = hexchar(*x & 15);
937 int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
938 _cleanup_free_ uint8_t *r = NULL;
946 z = r = malloc((l + 1) / 2 + 1);
950 for (x = p; x < p + l; x += 2) {
956 else if (x+1 < p + l) {
963 *(z++) = (uint8_t) a << 4 | (uint8_t) b;
975 /* https://tools.ietf.org/html/rfc4648#section-6
976 * Notice that base32hex differs from base32 in the alphabet it uses.
977 * The distinction is that the base32hex representation preserves the
978 * order of the underlying data when compared as bytestrings, this is
979 * useful when representing NSEC3 hashes, as one can then verify the
980 * order of hashes directly from their representation. */
981 char base32hexchar(int x) {
982 static const char table[32] = "0123456789"
983 "ABCDEFGHIJKLMNOPQRSTUV";
985 return table[x & 31];
988 int unbase32hexchar(char c) {
991 if (c >= '0' && c <= '9')
994 offset = '9' - '0' + 1;
996 if (c >= 'A' && c <= 'V')
997 return c - 'A' + offset;
1002 char *base32hexmem(const void *p, size_t l, bool padding) {
1008 /* five input bytes makes eight output bytes, padding is added so we must round up */
1009 len = 8 * (l + 4) / 5;
1011 /* same, but round down as there is no padding */
1030 z = r = malloc(len + 1);
1034 for (x = p; x < (const uint8_t*) p + (l / 5) * 5; x += 5) {
1035 /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ
1036 x[3] == QQQQQQQQ; x[4] == WWWWWWWW */
1037 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1038 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1039 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1040 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
1041 *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */
1042 *(z++) = base32hexchar((x[3] & 127) >> 2); /* 000QQQQQ */
1043 *(z++) = base32hexchar((x[3] & 3) << 3 | x[4] >> 5); /* 000QQWWW */
1044 *(z++) = base32hexchar((x[4] & 31)); /* 000WWWWW */
1049 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1050 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1051 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1052 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
1053 *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */
1054 *(z++) = base32hexchar((x[3] & 127) >> 2); /* 000QQQQQ */
1055 *(z++) = base32hexchar((x[3] & 3) << 3); /* 000QQ000 */
1062 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1063 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1064 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1065 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
1066 *(z++) = base32hexchar((x[2] & 15) << 1); /* 000ZZZZ0 */
1076 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1077 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1078 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1079 *(z++) = base32hexchar((x[1] & 1) << 4); /* 000Y0000 */
1090 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1091 *(z++) = base32hexchar((x[0] & 7) << 2); /* 000XXX00 */
1108 int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_len) {
1109 _cleanup_free_ uint8_t *r = NULL;
1110 int a, b, c, d, e, f, g, h;
1118 /* padding ensures any base32hex input has input divisible by 8 */
1119 if (padding && l % 8 != 0)
1123 /* strip the padding */
1124 while (l > 0 && p[l - 1] == '=' && pad < 7) {
1130 /* a group of eight input bytes needs five output bytes, in case of
1131 padding we need to add some extra bytes */
1153 z = r = malloc(len + 1);
1157 for (x = p; x < p + (l / 8) * 8; x += 8) {
1158 /* a == 000XXXXX; b == 000YYYYY; c == 000ZZZZZ; d == 000WWWWW
1159 e == 000SSSSS; f == 000QQQQQ; g == 000VVVVV; h == 000RRRRR */
1160 a = unbase32hexchar(x[0]);
1164 b = unbase32hexchar(x[1]);
1168 c = unbase32hexchar(x[2]);
1172 d = unbase32hexchar(x[3]);
1176 e = unbase32hexchar(x[4]);
1180 f = unbase32hexchar(x[5]);
1184 g = unbase32hexchar(x[6]);
1188 h = unbase32hexchar(x[7]);
1192 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1193 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1194 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
1195 *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */
1196 *(z++) = (uint8_t) g << 5 | (uint8_t) h; /* VVVRRRRR */
1201 a = unbase32hexchar(x[0]);
1205 b = unbase32hexchar(x[1]);
1209 c = unbase32hexchar(x[2]);
1213 d = unbase32hexchar(x[3]);
1217 e = unbase32hexchar(x[4]);
1221 f = unbase32hexchar(x[5]);
1225 g = unbase32hexchar(x[6]);
1233 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1234 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1235 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
1236 *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */
1240 a = unbase32hexchar(x[0]);
1244 b = unbase32hexchar(x[1]);
1248 c = unbase32hexchar(x[2]);
1252 d = unbase32hexchar(x[3]);
1256 e = unbase32hexchar(x[4]);
1264 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1265 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1266 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
1270 a = unbase32hexchar(x[0]);
1274 b = unbase32hexchar(x[1]);
1278 c = unbase32hexchar(x[2]);
1282 d = unbase32hexchar(x[3]);
1290 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1291 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1295 a = unbase32hexchar(x[0]);
1299 b = unbase32hexchar(x[1]);
1307 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1325 /* https://tools.ietf.org/html/rfc4648#section-4 */
1326 char base64char(int x) {
1327 static const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1328 "abcdefghijklmnopqrstuvwxyz"
1330 return table[x & 63];
1333 int unbase64char(char c) {
1336 if (c >= 'A' && c <= 'Z')
1339 offset = 'Z' - 'A' + 1;
1341 if (c >= 'a' && c <= 'z')
1342 return c - 'a' + offset;
1344 offset += 'z' - 'a' + 1;
1346 if (c >= '0' && c <= '9')
1347 return c - '0' + offset;
1349 offset += '9' - '0' + 1;
1362 char *base64mem(const void *p, size_t l) {
1366 /* three input bytes makes four output bytes, padding is added so we must round up */
1367 z = r = malloc(4 * (l + 2) / 3 + 1);
1371 for (x = p; x < (const uint8_t*) p + (l / 3) * 3; x += 3) {
1372 /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ */
1373 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1374 *(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4); /* 00XXYYYY */
1375 *(z++) = base64char((x[1] & 15) << 2 | x[2] >> 6); /* 00YYYYZZ */
1376 *(z++) = base64char(x[2] & 63); /* 00ZZZZZZ */
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); /* 00YYYY00 */
1388 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1389 *(z++) = base64char((x[0] & 3) << 4); /* 00XX0000 */
1400 int unbase64mem(const char *p, size_t l, void **mem, size_t *_len) {
1401 _cleanup_free_ uint8_t *r = NULL;
1409 /* padding ensures any base63 input has input divisible by 4 */
1413 /* strip the padding */
1414 if (l > 0 && p[l - 1] == '=')
1416 if (l > 0 && p[l - 1] == '=')
1419 /* a group of four input bytes needs three output bytes, in case of
1420 padding we need to add two or three extra bytes */
1421 len = (l / 4) * 3 + (l % 4 ? (l % 4) - 1 : 0);
1423 z = r = malloc(len + 1);
1427 for (x = p; x < p + (l / 4) * 4; x += 4) {
1428 /* a == 00XXXXXX; b == 00YYYYYY; c == 00ZZZZZZ; d == 00WWWWWW */
1429 a = unbase64char(x[0]);
1433 b = unbase64char(x[1]);
1437 c = unbase64char(x[2]);
1441 d = unbase64char(x[3]);
1445 *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
1446 *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
1447 *(z++) = (uint8_t) c << 6 | (uint8_t) d; /* ZZWWWWWW */
1452 a = unbase64char(x[0]);
1456 b = unbase64char(x[1]);
1460 c = unbase64char(x[2]);
1468 *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
1469 *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
1473 a = unbase64char(x[0]);
1477 b = unbase64char(x[1]);
1485 *(z++) = (uint8_t) a << 2 | (uint8_t) (b >> 4); /* XXXXXXYY */
1504 char octchar(int x) {
1505 return '0' + (x & 7);
1508 int unoctchar(char c) {
1510 if (c >= '0' && c <= '7')
1516 char decchar(int x) {
1517 return '0' + (x % 10);
1520 int undecchar(char c) {
1522 if (c >= '0' && c <= '9')
1528 char *cescape(const char *s) {
1534 /* Does C style string escaping. May be reversed with
1537 r = new(char, strlen(s)*4 + 1);
1541 for (f = s, t = r; *f; f++)
1542 t += cescape_char(*f, t);
1549 static int cunescape_one(const char *p, size_t length, char *ret, uint32_t *ret_unicode) {
1556 /* Unescapes C style. Returns the unescaped character in ret,
1557 * unless we encountered a \u sequence in which case the full
1558 * unicode character is returned in ret_unicode, instead. */
1560 if (length != (size_t) -1 && length < 1)
1597 /* This is an extension of the XDG syntax files */
1602 /* hexadecimal encoding */
1605 if (length != (size_t) -1 && length < 3)
1608 a = unhexchar(p[1]);
1612 b = unhexchar(p[2]);
1616 /* Don't allow NUL bytes */
1617 if (a == 0 && b == 0)
1620 *ret = (char) ((a << 4U) | b);
1626 /* C++11 style 16bit unicode */
1632 if (length != (size_t) -1 && length < 5)
1635 for (i = 0; i < 4; i++) {
1636 a[i] = unhexchar(p[1 + i]);
1641 c = ((uint32_t) a[0] << 12U) | ((uint32_t) a[1] << 8U) | ((uint32_t) a[2] << 4U) | (uint32_t) a[3];
1643 /* Don't allow 0 chars */
1662 /* C++11 style 32bit unicode */
1668 if (length != (size_t) -1 && length < 9)
1671 for (i = 0; i < 8; i++) {
1672 a[i] = unhexchar(p[1 + i]);
1677 c = ((uint32_t) a[0] << 28U) | ((uint32_t) a[1] << 24U) | ((uint32_t) a[2] << 20U) | ((uint32_t) a[3] << 16U) |
1678 ((uint32_t) a[4] << 12U) | ((uint32_t) a[5] << 8U) | ((uint32_t) a[6] << 4U) | (uint32_t) a[7];
1680 /* Don't allow 0 chars */
1684 /* Don't allow invalid code points */
1685 if (!unichar_is_valid(c))
1710 /* octal encoding */
1714 if (length != (size_t) -1 && length < 3)
1717 a = unoctchar(p[0]);
1721 b = unoctchar(p[1]);
1725 c = unoctchar(p[2]);
1729 /* don't allow NUL bytes */
1730 if (a == 0 && b == 0 && c == 0)
1733 /* Don't allow bytes above 255 */
1734 m = ((uint32_t) a << 6U) | ((uint32_t) b << 3U) | (uint32_t) c;
1750 int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret) {
1758 /* Undoes C style string escaping, and optionally prefixes it. */
1760 pl = prefix ? strlen(prefix) : 0;
1762 r = new(char, pl+length+1);
1767 memcpy(r, prefix, pl);
1769 for (f = s, t = r + pl; f < s + length; f++) {
1775 remaining = s + length - f;
1776 assert(remaining > 0);
1779 /* A literal literal, copy verbatim */
1784 if (remaining == 1) {
1785 if (flags & UNESCAPE_RELAX) {
1786 /* A trailing backslash, copy verbatim */
1795 k = cunescape_one(f + 1, remaining - 1, &c, &u);
1797 if (flags & UNESCAPE_RELAX) {
1798 /* Invalid escape code, let's take it literal then */
1808 /* Non-Unicode? Let's encode this directly */
1811 /* Unicode? Then let's encode this in UTF-8 */
1812 t += utf8_encode_unichar(t, u);
1823 int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret) {
1824 return cunescape_length_with_prefix(s, length, NULL, flags, ret);
1827 int cunescape(const char *s, UnescapeFlags flags, char **ret) {
1828 return cunescape_length(s, strlen(s), flags, ret);
1831 char *xescape(const char *s, const char *bad) {
1835 /* Escapes all chars in bad, in addition to \ and all special
1836 * chars, in \xFF style escaping. May be reversed with
1839 r = new(char, strlen(s) * 4 + 1);
1843 for (f = s, t = r; *f; f++) {
1845 if ((*f < ' ') || (*f >= 127) ||
1846 (*f == '\\') || strchr(bad, *f)) {
1849 *(t++) = hexchar(*f >> 4);
1850 *(t++) = hexchar(*f);
1860 /// UNNEEDED by elogind
1862 char *ascii_strlower(char *t) {
1867 for (p = t; *p; p++)
1868 if (*p >= 'A' && *p <= 'Z')
1869 *p = *p - 'A' + 'a';
1875 _pure_ static bool hidden_file_allow_backup(const char *filename) {
1879 filename[0] == '.' ||
1880 streq(filename, "lost+found") ||
1881 streq(filename, "aquota.user") ||
1882 streq(filename, "aquota.group") ||
1883 endswith(filename, ".rpmnew") ||
1884 endswith(filename, ".rpmsave") ||
1885 endswith(filename, ".rpmorig") ||
1886 endswith(filename, ".dpkg-old") ||
1887 endswith(filename, ".dpkg-new") ||
1888 endswith(filename, ".dpkg-tmp") ||
1889 endswith(filename, ".dpkg-dist") ||
1890 endswith(filename, ".dpkg-bak") ||
1891 endswith(filename, ".dpkg-backup") ||
1892 endswith(filename, ".dpkg-remove") ||
1893 endswith(filename, ".swp");
1896 bool hidden_file(const char *filename) {
1899 if (endswith(filename, "~"))
1902 return hidden_file_allow_backup(filename);
1905 int fd_nonblock(int fd, bool nonblock) {
1910 flags = fcntl(fd, F_GETFL, 0);
1915 nflags = flags | O_NONBLOCK;
1917 nflags = flags & ~O_NONBLOCK;
1919 if (nflags == flags)
1922 if (fcntl(fd, F_SETFL, nflags) < 0)
1928 int fd_cloexec(int fd, bool cloexec) {
1933 flags = fcntl(fd, F_GETFD, 0);
1938 nflags = flags | FD_CLOEXEC;
1940 nflags = flags & ~FD_CLOEXEC;
1942 if (nflags == flags)
1945 if (fcntl(fd, F_SETFD, nflags) < 0)
1951 _pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
1954 assert(n_fdset == 0 || fdset);
1956 for (i = 0; i < n_fdset; i++)
1963 int close_all_fds(const int except[], unsigned n_except) {
1964 _cleanup_closedir_ DIR *d = NULL;
1968 assert(n_except == 0 || except);
1970 d = opendir("/proc/self/fd");
1975 /* When /proc isn't available (for example in chroots)
1976 * the fallback is brute forcing through the fd
1979 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
1980 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
1982 if (fd_in_set(fd, except, n_except))
1985 if (close_nointr(fd) < 0)
1986 if (errno != EBADF && r == 0)
1993 while ((de = readdir(d))) {
1996 if (hidden_file(de->d_name))
1999 if (safe_atoi(de->d_name, &fd) < 0)
2000 /* Let's better ignore this, just in case */
2009 if (fd_in_set(fd, except, n_except))
2012 if (close_nointr(fd) < 0) {
2013 /* Valgrind has its own FD and doesn't want to have it closed */
2014 if (errno != EBADF && r == 0)
2022 bool chars_intersect(const char *a, const char *b) {
2025 /* Returns true if any of the chars in a are in b. */
2026 for (p = a; *p; p++)
2033 /// UNNEEDED by elogind
2035 bool fstype_is_network(const char *fstype) {
2036 static const char table[] =
2051 x = startswith(fstype, "fuse.");
2055 return nulstr_contains(table, fstype);
2059 int flush_fd(int fd) {
2060 struct pollfd pollfd = {
2070 r = poll(&pollfd, 1, 0);
2080 l = read(fd, buf, sizeof(buf));
2086 if (errno == EAGAIN)
2095 void safe_close_pair(int p[]) {
2099 /* Special case pairs which use the same fd in both
2101 p[0] = p[1] = safe_close(p[0]);
2105 p[0] = safe_close(p[0]);
2106 p[1] = safe_close(p[1]);
2109 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
2116 while (nbytes > 0) {
2119 k = read(fd, p, nbytes);
2124 if (errno == EAGAIN && do_poll) {
2126 /* We knowingly ignore any return value here,
2127 * and expect that any error/EOF is reported
2130 fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
2134 return n > 0 ? n : -errno;
2148 int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
2151 n = loop_read(fd, buf, nbytes, do_poll);
2154 if ((size_t) n != nbytes)
2159 int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
2160 const uint8_t *p = buf;
2170 k = write(fd, p, nbytes);
2175 if (errno == EAGAIN && do_poll) {
2176 /* We knowingly ignore any return value here,
2177 * and expect that any error/EOF is reported
2180 fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
2187 if (nbytes > 0 && k == 0) /* Can't really happen */
2192 } while (nbytes > 0);
2197 int parse_size(const char *t, off_t base, off_t *size) {
2199 /* Soo, sometimes we want to parse IEC binary suffixes, and
2200 * sometimes SI decimal suffixes. This function can parse
2201 * both. Which one is the right way depends on the
2202 * context. Wikipedia suggests that SI is customary for
2203 * hardware metrics and network speeds, while IEC is
2204 * customary for most data sizes used by software and volatile
2205 * (RAM) memory. Hence be careful which one you pick!
2207 * In either case we use just K, M, G as suffix, and not Ki,
2208 * Mi, Gi or so (as IEC would suggest). That's because that's
2209 * frickin' ugly. But this means you really need to make sure
2210 * to document which base you are parsing when you use this
2215 unsigned long long factor;
2218 static const struct table iec[] = {
2219 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2220 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2221 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
2222 { "G", 1024ULL*1024ULL*1024ULL },
2223 { "M", 1024ULL*1024ULL },
2229 static const struct table si[] = {
2230 { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
2231 { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
2232 { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
2233 { "G", 1000ULL*1000ULL*1000ULL },
2234 { "M", 1000ULL*1000ULL },
2240 const struct table *table;
2242 unsigned long long r = 0;
2243 unsigned n_entries, start_pos = 0;
2246 assert(base == 1000 || base == 1024);
2251 n_entries = ELEMENTSOF(si);
2254 n_entries = ELEMENTSOF(iec);
2260 unsigned long long l2;
2266 l = strtoll(p, &e, 10);
2279 if (*e >= '0' && *e <= '9') {
2282 /* strotoull itself would accept space/+/- */
2283 l2 = strtoull(e, &e2, 10);
2285 if (errno == ERANGE)
2288 /* Ignore failure. E.g. 10.M is valid */
2295 e += strspn(e, WHITESPACE);
2297 for (i = start_pos; i < n_entries; i++)
2298 if (startswith(e, table[i].suffix)) {
2299 unsigned long long tmp;
2300 if ((unsigned long long) l + (frac > 0) > ULLONG_MAX / table[i].factor)
2302 tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
2303 if (tmp > ULLONG_MAX - r)
2307 if ((unsigned long long) (off_t) r != r)
2310 p = e + strlen(table[i].suffix);
2326 bool is_device_path(const char *path) {
2328 /* Returns true on paths that refer to a device, either in
2329 * sysfs or in /dev */
2332 path_startswith(path, "/dev/") ||
2333 path_startswith(path, "/sys/");
2336 /// UNNEEDED by elogind
2338 int dir_is_empty(const char *path) {
2339 _cleanup_closedir_ DIR *d;
2350 if (!de && errno != 0)
2356 if (!hidden_file(de->d_name))
2361 char* dirname_malloc(const char *path) {
2362 char *d, *dir, *dir2;
2379 void rename_process(const char name[8]) {
2382 /* This is a like a poor man's setproctitle(). It changes the
2383 * comm field, argv[0], and also the glibc's internally used
2384 * name of the process. For the first one a limit of 16 chars
2385 * applies, to the second one usually one of 10 (i.e. length
2386 * of "/sbin/init"), to the third one one of 7 (i.e. length of
2387 * "systemd"). If you pass a longer string it will be
2390 prctl(PR_SET_NAME, name);
2392 if (program_invocation_name)
2393 strncpy(program_invocation_name, name, strlen(program_invocation_name));
2395 if (saved_argc > 0) {
2399 strncpy(saved_argv[0], name, strlen(saved_argv[0]));
2401 for (i = 1; i < saved_argc; i++) {
2405 memzero(saved_argv[i], strlen(saved_argv[i]));
2411 char *lookup_uid(uid_t uid) {
2414 _cleanup_free_ char *buf = NULL;
2415 struct passwd pwbuf, *pw = NULL;
2417 /* Shortcut things to avoid NSS lookups */
2419 return strdup("root");
2421 bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
2425 buf = malloc(bufsize);
2429 if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
2430 return strdup(pw->pw_name);
2432 if (asprintf(&name, UID_FMT, uid) < 0)
2438 /// UNNEEDED by elogind
2440 char* getlogname_malloc(void) {
2444 if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
2449 return lookup_uid(uid);
2452 char *getusername_malloc(void) {
2459 return lookup_uid(getuid());
2463 bool is_temporary_fs(const struct statfs *s) {
2466 return F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) ||
2467 F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC);
2470 int fd_is_temporary_fs(int fd) {
2473 if (fstatfs(fd, &s) < 0)
2476 return is_temporary_fs(&s);
2479 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
2482 /* Under the assumption that we are running privileged we
2483 * first change the access mode and only then hand out
2484 * ownership to avoid a window where access is too open. */
2486 if (mode != MODE_INVALID)
2487 if (chmod(path, mode) < 0)
2490 if (uid != UID_INVALID || gid != GID_INVALID)
2491 if (chown(path, uid, gid) < 0)
2497 /// UNNEEDED by elogind
2499 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
2502 /* Under the assumption that we are running privileged we
2503 * first change the access mode and only then hand out
2504 * ownership to avoid a window where access is too open. */
2506 if (mode != MODE_INVALID)
2507 if (fchmod(fd, mode) < 0)
2510 if (uid != UID_INVALID || gid != GID_INVALID)
2511 if (fchown(fd, uid, gid) < 0)
2517 cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
2521 /* Allocates the cpuset in the right size */
2524 if (!(r = CPU_ALLOC(n)))
2527 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
2528 CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
2538 if (errno != EINVAL)
2546 int files_same(const char *filea, const char *fileb) {
2549 if (stat(filea, &a) < 0)
2552 if (stat(fileb, &b) < 0)
2555 return a.st_dev == b.st_dev &&
2556 a.st_ino == b.st_ino;
2559 /// UNNEEDED by elogind
2561 int running_in_chroot(void) {
2564 ret = files_same("/proc/1/root", "/");
2572 static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
2577 assert(percent <= 100);
2578 assert(new_length >= 3);
2580 if (old_length <= 3 || old_length <= new_length)
2581 return strndup(s, old_length);
2583 r = new0(char, new_length+1);
2587 x = (new_length * percent) / 100;
2589 if (x > new_length - 3)
2597 s + old_length - (new_length - x - 3),
2598 new_length - x - 3);
2603 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
2607 unsigned k, len, len2;
2610 assert(percent <= 100);
2611 assert(new_length >= 3);
2613 /* if no multibyte characters use ascii_ellipsize_mem for speed */
2614 if (ascii_is_valid(s))
2615 return ascii_ellipsize_mem(s, old_length, new_length, percent);
2617 if (old_length <= 3 || old_length <= new_length)
2618 return strndup(s, old_length);
2620 x = (new_length * percent) / 100;
2622 if (x > new_length - 3)
2626 for (i = s; k < x && i < s + old_length; i = utf8_next_char(i)) {
2629 c = utf8_encoded_to_unichar(i);
2632 k += unichar_iswide(c) ? 2 : 1;
2635 if (k > x) /* last character was wide and went over quota */
2638 for (j = s + old_length; k < new_length && j > i; ) {
2641 j = utf8_prev_char(j);
2642 c = utf8_encoded_to_unichar(j);
2645 k += unichar_iswide(c) ? 2 : 1;
2649 /* we don't actually need to ellipsize */
2651 return memdup(s, old_length + 1);
2653 /* make space for ellipsis */
2654 j = utf8_next_char(j);
2657 len2 = s + old_length - j;
2658 e = new(char, len + 3 + len2 + 1);
2663 printf("old_length=%zu new_length=%zu x=%zu len=%u len2=%u k=%u\n",
2664 old_length, new_length, x, len, len2, k);
2668 e[len] = 0xe2; /* tri-dot ellipsis: … */
2672 memcpy(e + len + 3, j, len2 + 1);
2677 char *ellipsize(const char *s, size_t length, unsigned percent) {
2678 return ellipsize_mem(s, strlen(s), length, percent);
2681 int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
2682 _cleanup_close_ int fd;
2688 mkdir_parents(path, 0755);
2690 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode > 0 ? mode : 0644);
2695 r = fchmod(fd, mode);
2700 if (uid != UID_INVALID || gid != GID_INVALID) {
2701 r = fchown(fd, uid, gid);
2706 if (stamp != USEC_INFINITY) {
2707 struct timespec ts[2];
2709 timespec_store(&ts[0], stamp);
2711 r = futimens(fd, ts);
2713 r = futimens(fd, NULL);
2720 int touch(const char *path) {
2721 return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, 0);
2724 /// UNNEEDED by elogind
2726 static char *unquote(const char *s, const char* quotes) {
2730 /* This is rather stupid, simply removes the heading and
2731 * trailing quotes if there is one. Doesn't care about
2732 * escaping or anything.
2734 * DON'T USE THIS FOR NEW CODE ANYMORE!*/
2740 if (strchr(quotes, s[0]) && s[l-1] == s[0])
2741 return strndup(s+1, l-2);
2747 noreturn void freeze(void) {
2749 /* Make sure nobody waits for us on a socket anymore */
2750 close_all_fds(NULL, 0);
2758 bool null_or_empty(struct stat *st) {
2761 if (S_ISREG(st->st_mode) && st->st_size <= 0)
2764 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
2770 int null_or_empty_path(const char *fn) {
2775 if (stat(fn, &st) < 0)
2778 return null_or_empty(&st);
2781 /// UNNEEDED by elogind
2783 int null_or_empty_fd(int fd) {
2788 if (fstat(fd, &st) < 0)
2791 return null_or_empty(&st);
2795 DIR *xopendirat(int fd, const char *name, int flags) {
2799 assert(!(flags & O_CREAT));
2801 nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
2814 /// UNNEEDED by elogind
2816 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
2817 _cleanup_free_ char *t = NULL, *u = NULL;
2820 u = unquote(tagvalue, QUOTES);
2824 enc_len = strlen(u) * 4 + 1;
2825 t = new(char, enc_len);
2829 if (encode_devnode_name(u, t, enc_len) < 0)
2832 return strjoin("/dev/disk/by-", by, "/", t, NULL);
2835 char *fstab_node_to_udev_node(const char *p) {
2838 if (startswith(p, "LABEL="))
2839 return tag_to_udev_node(p+6, "label");
2841 if (startswith(p, "UUID="))
2842 return tag_to_udev_node(p+5, "uuid");
2844 if (startswith(p, "PARTUUID="))
2845 return tag_to_udev_node(p+9, "partuuid");
2847 if (startswith(p, "PARTLABEL="))
2848 return tag_to_udev_node(p+10, "partlabel");
2854 bool dirent_is_file(const struct dirent *de) {
2857 if (hidden_file(de->d_name))
2860 if (de->d_type != DT_REG &&
2861 de->d_type != DT_LNK &&
2862 de->d_type != DT_UNKNOWN)
2868 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
2871 if (de->d_type != DT_REG &&
2872 de->d_type != DT_LNK &&
2873 de->d_type != DT_UNKNOWN)
2876 if (hidden_file_allow_backup(de->d_name))
2879 return endswith(de->d_name, suffix);
2882 /// UNNEEDED by elogind
2884 static int do_execute(char **directories, usec_t timeout, char *argv[]) {
2885 _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
2886 _cleanup_set_free_free_ Set *seen = NULL;
2889 /* We fork this all off from a child process so that we can
2890 * somewhat cleanly make use of SIGALRM to set a time limit */
2892 (void) reset_all_signal_handlers();
2893 (void) reset_signal_mask();
2895 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
2897 pids = hashmap_new(NULL);
2901 seen = set_new(&string_hash_ops);
2905 STRV_FOREACH(directory, directories) {
2906 _cleanup_closedir_ DIR *d;
2909 d = opendir(*directory);
2911 if (errno == ENOENT)
2914 return log_error_errno(errno, "Failed to open directory %s: %m", *directory);
2917 FOREACH_DIRENT(de, d, break) {
2918 _cleanup_free_ char *path = NULL;
2922 if (!dirent_is_file(de))
2925 if (set_contains(seen, de->d_name)) {
2926 log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name);
2930 r = set_put_strdup(seen, de->d_name);
2934 path = strjoin(*directory, "/", de->d_name, NULL);
2938 if (null_or_empty_path(path)) {
2939 log_debug("%s is empty (a mask).", path);
2945 log_error_errno(errno, "Failed to fork: %m");
2947 } else if (pid == 0) {
2950 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
2960 return log_error_errno(errno, "Failed to execute %s: %m", path);
2963 log_debug("Spawned %s as " PID_FMT ".", path, pid);
2965 r = hashmap_put(pids, UINT_TO_PTR(pid), path);
2972 /* Abort execution of this process after the timout. We simply
2973 * rely on SIGALRM as default action terminating the process,
2974 * and turn on alarm(). */
2976 if (timeout != USEC_INFINITY)
2977 alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
2979 while (!hashmap_isempty(pids)) {
2980 _cleanup_free_ char *path = NULL;
2983 pid = PTR_TO_UINT(hashmap_first_key(pids));
2986 path = hashmap_remove(pids, UINT_TO_PTR(pid));
2989 wait_for_terminate_and_warn(path, pid, true);
2995 void execute_directories(const char* const* directories, usec_t timeout, char *argv[]) {
2999 char **dirs = (char**) directories;
3001 assert(!strv_isempty(dirs));
3003 name = basename(dirs[0]);
3004 assert(!isempty(name));
3006 /* Executes all binaries in the directories in parallel and waits
3007 * for them to finish. Optionally a timeout is applied. If a file
3008 * with the same name exists in more than one directory, the
3009 * earliest one wins. */
3011 executor_pid = fork();
3012 if (executor_pid < 0) {
3013 log_error_errno(errno, "Failed to fork: %m");
3016 } else if (executor_pid == 0) {
3017 r = do_execute(dirs, timeout, argv);
3018 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
3021 wait_for_terminate_and_warn(name, executor_pid, true);
3025 bool nulstr_contains(const char*nulstr, const char *needle) {
3031 NULSTR_FOREACH(i, nulstr)
3032 if (streq(i, needle))
3038 /// UNNEEDED by elogind
3040 bool plymouth_running(void) {
3041 return access("/run/plymouth/pid", F_OK) >= 0;
3045 char* strshorten(char *s, size_t l) {
3054 int pipe_eof(int fd) {
3055 struct pollfd pollfd = {
3057 .events = POLLIN|POLLHUP,
3062 r = poll(&pollfd, 1, 0);
3069 return pollfd.revents & POLLHUP;
3072 int fd_wait_for_event(int fd, int event, usec_t t) {
3074 struct pollfd pollfd = {
3082 r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
3089 return pollfd.revents;
3092 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
3101 r = tempfn_xxxxxx(path, NULL, &t);
3105 fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC);
3111 f = fdopen(fd, "we");
3125 /// UNNEEDED by elogind
3127 int symlink_atomic(const char *from, const char *to) {
3128 _cleanup_free_ char *t = NULL;
3134 r = tempfn_random(to, NULL, &t);
3138 if (symlink(from, t) < 0)
3141 if (rename(t, to) < 0) {
3149 int symlink_idempotent(const char *from, const char *to) {
3150 _cleanup_free_ char *p = NULL;
3156 if (symlink(from, to) < 0) {
3157 if (errno != EEXIST)
3160 r = readlink_malloc(to, &p);
3164 if (!streq(p, from))
3171 int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
3172 _cleanup_free_ char *t = NULL;
3177 r = tempfn_random(path, NULL, &t);
3181 if (mknod(t, mode, dev) < 0)
3184 if (rename(t, path) < 0) {
3192 int mkfifo_atomic(const char *path, mode_t mode) {
3193 _cleanup_free_ char *t = NULL;
3198 r = tempfn_random(path, NULL, &t);
3202 if (mkfifo(t, mode) < 0)
3205 if (rename(t, path) < 0) {
3214 bool display_is_local(const char *display) {
3218 display[0] == ':' &&
3219 display[1] >= '0' &&
3223 int socket_from_display(const char *display, char **path) {
3230 if (!display_is_local(display))
3233 k = strspn(display+1, "0123456789");
3235 f = new(char, strlen("/tmp/.X11-unix/X") + k + 1);
3239 c = stpcpy(f, "/tmp/.X11-unix/X");
3240 memcpy(c, display+1, k);
3249 const char **username,
3250 uid_t *uid, gid_t *gid,
3252 const char **shell) {
3260 /* We enforce some special rules for uid=0: in order to avoid
3261 * NSS lookups for root we hardcode its data. */
3263 if (streq(*username, "root") || streq(*username, "0")) {
3281 if (parse_uid(*username, &u) >= 0) {
3285 /* If there are multiple users with the same id, make
3286 * sure to leave $USER to the configured value instead
3287 * of the first occurrence in the database. However if
3288 * the uid was configured by a numeric uid, then let's
3289 * pick the real username from /etc/passwd. */
3291 *username = p->pw_name;
3294 p = getpwnam(*username);
3298 return errno > 0 ? -errno : -ESRCH;
3310 *shell = p->pw_shell;
3315 char* uid_to_name(uid_t uid) {
3320 return strdup("root");
3324 return strdup(p->pw_name);
3326 if (asprintf(&r, UID_FMT, uid) < 0)
3332 char* gid_to_name(gid_t gid) {
3337 return strdup("root");
3341 return strdup(p->gr_name);
3343 if (asprintf(&r, GID_FMT, gid) < 0)
3349 int get_group_creds(const char **groupname, gid_t *gid) {
3355 /* We enforce some special rules for gid=0: in order to avoid
3356 * NSS lookups for root we hardcode its data. */
3358 if (streq(*groupname, "root") || streq(*groupname, "0")) {
3359 *groupname = "root";
3367 if (parse_gid(*groupname, &id) >= 0) {
3372 *groupname = g->gr_name;
3375 g = getgrnam(*groupname);
3379 return errno > 0 ? -errno : -ESRCH;
3387 int in_gid(gid_t gid) {
3389 int ngroups_max, r, i;
3391 if (getgid() == gid)
3394 if (getegid() == gid)
3397 ngroups_max = sysconf(_SC_NGROUPS_MAX);
3398 assert(ngroups_max > 0);
3400 gids = alloca(sizeof(gid_t) * ngroups_max);
3402 r = getgroups(ngroups_max, gids);
3406 for (i = 0; i < r; i++)
3413 /// UNNEEDED by elogind
3415 int in_group(const char *name) {
3419 r = get_group_creds(&name, &gid);
3426 int glob_exists(const char *path) {
3427 _cleanup_globfree_ glob_t g = {};
3433 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
3435 if (k == GLOB_NOMATCH)
3437 else if (k == GLOB_NOSPACE)
3440 return !strv_isempty(g.gl_pathv);
3442 return errno ? -errno : -EIO;
3445 int glob_extend(char ***strv, const char *path) {
3446 _cleanup_globfree_ glob_t g = {};
3451 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
3453 if (k == GLOB_NOMATCH)
3455 else if (k == GLOB_NOSPACE)
3457 else if (k != 0 || strv_isempty(g.gl_pathv))
3458 return errno ? -errno : -EIO;
3460 STRV_FOREACH(p, g.gl_pathv) {
3461 k = strv_extend(strv, *p);
3470 int dirent_ensure_type(DIR *d, struct dirent *de) {
3476 if (de->d_type != DT_UNKNOWN)
3479 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
3483 S_ISREG(st.st_mode) ? DT_REG :
3484 S_ISDIR(st.st_mode) ? DT_DIR :
3485 S_ISLNK(st.st_mode) ? DT_LNK :
3486 S_ISFIFO(st.st_mode) ? DT_FIFO :
3487 S_ISSOCK(st.st_mode) ? DT_SOCK :
3488 S_ISCHR(st.st_mode) ? DT_CHR :
3489 S_ISBLK(st.st_mode) ? DT_BLK :
3495 int get_files_in_directory(const char *path, char ***list) {
3496 _cleanup_closedir_ DIR *d = NULL;
3497 size_t bufsize = 0, n = 0;
3498 _cleanup_strv_free_ char **l = NULL;
3502 /* Returns all files in a directory in *list, and the number
3503 * of files as return value. If list is NULL returns only the
3515 if (!de && errno != 0)
3520 dirent_ensure_type(d, de);
3522 if (!dirent_is_file(de))
3526 /* one extra slot is needed for the terminating NULL */
3527 if (!GREEDY_REALLOC(l, bufsize, n + 2))
3530 l[n] = strdup(de->d_name);
3541 l = NULL; /* avoid freeing */
3547 char *strjoin(const char *x, ...) {
3561 t = va_arg(ap, const char *);
3566 if (n > ((size_t) -1) - l) {
3590 t = va_arg(ap, const char *);
3604 bool is_main_thread(void) {
3605 static thread_local int cached = 0;
3607 if (_unlikely_(cached == 0))
3608 cached = getpid() == gettid() ? 1 : -1;
3613 /// UNNEEDED by elogind
3615 int block_get_whole_disk(dev_t d, dev_t *ret) {
3622 /* If it has a queue this is good enough for us */
3623 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
3626 r = access(p, F_OK);
3634 /* If it is a partition find the originating device */
3635 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
3638 r = access(p, F_OK);
3644 /* Get parent dev_t */
3645 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
3648 r = read_one_line_file(p, &s);
3654 r = sscanf(s, "%u:%u", &m, &n);
3660 /* Only return this if it is really good enough for us. */
3661 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
3664 r = access(p, F_OK);
3668 *ret = makedev(m, n);
3676 static const char *const ioprio_class_table[] = {
3677 [IOPRIO_CLASS_NONE] = "none",
3678 [IOPRIO_CLASS_RT] = "realtime",
3679 [IOPRIO_CLASS_BE] = "best-effort",
3680 [IOPRIO_CLASS_IDLE] = "idle"
3683 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
3685 static const char *const sigchld_code_table[] = {
3686 [CLD_EXITED] = "exited",
3687 [CLD_KILLED] = "killed",
3688 [CLD_DUMPED] = "dumped",
3689 [CLD_TRAPPED] = "trapped",
3690 [CLD_STOPPED] = "stopped",
3691 [CLD_CONTINUED] = "continued",
3694 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
3696 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
3697 [LOG_FAC(LOG_KERN)] = "kern",
3698 [LOG_FAC(LOG_USER)] = "user",
3699 [LOG_FAC(LOG_MAIL)] = "mail",
3700 [LOG_FAC(LOG_DAEMON)] = "daemon",
3701 [LOG_FAC(LOG_AUTH)] = "auth",
3702 [LOG_FAC(LOG_SYSLOG)] = "syslog",
3703 [LOG_FAC(LOG_LPR)] = "lpr",
3704 [LOG_FAC(LOG_NEWS)] = "news",
3705 [LOG_FAC(LOG_UUCP)] = "uucp",
3706 [LOG_FAC(LOG_CRON)] = "cron",
3707 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
3708 [LOG_FAC(LOG_FTP)] = "ftp",
3709 [LOG_FAC(LOG_LOCAL0)] = "local0",
3710 [LOG_FAC(LOG_LOCAL1)] = "local1",
3711 [LOG_FAC(LOG_LOCAL2)] = "local2",
3712 [LOG_FAC(LOG_LOCAL3)] = "local3",
3713 [LOG_FAC(LOG_LOCAL4)] = "local4",
3714 [LOG_FAC(LOG_LOCAL5)] = "local5",
3715 [LOG_FAC(LOG_LOCAL6)] = "local6",
3716 [LOG_FAC(LOG_LOCAL7)] = "local7"
3719 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
3721 static const char *const log_level_table[] = {
3722 [LOG_EMERG] = "emerg",
3723 [LOG_ALERT] = "alert",
3724 [LOG_CRIT] = "crit",
3726 [LOG_WARNING] = "warning",
3727 [LOG_NOTICE] = "notice",
3728 [LOG_INFO] = "info",
3729 [LOG_DEBUG] = "debug"
3732 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
3734 static const char* const sched_policy_table[] = {
3735 [SCHED_OTHER] = "other",
3736 [SCHED_BATCH] = "batch",
3737 [SCHED_IDLE] = "idle",
3738 [SCHED_FIFO] = "fifo",
3742 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
3744 static const char* const rlimit_table[_RLIMIT_MAX] = {
3745 [RLIMIT_CPU] = "LimitCPU",
3746 [RLIMIT_FSIZE] = "LimitFSIZE",
3747 [RLIMIT_DATA] = "LimitDATA",
3748 [RLIMIT_STACK] = "LimitSTACK",
3749 [RLIMIT_CORE] = "LimitCORE",
3750 [RLIMIT_RSS] = "LimitRSS",
3751 [RLIMIT_NOFILE] = "LimitNOFILE",
3752 [RLIMIT_AS] = "LimitAS",
3753 [RLIMIT_NPROC] = "LimitNPROC",
3754 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
3755 [RLIMIT_LOCKS] = "LimitLOCKS",
3756 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
3757 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
3758 [RLIMIT_NICE] = "LimitNICE",
3759 [RLIMIT_RTPRIO] = "LimitRTPRIO",
3760 [RLIMIT_RTTIME] = "LimitRTTIME"
3763 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
3765 static const char* const ip_tos_table[] = {
3766 [IPTOS_LOWDELAY] = "low-delay",
3767 [IPTOS_THROUGHPUT] = "throughput",
3768 [IPTOS_RELIABILITY] = "reliability",
3769 [IPTOS_LOWCOST] = "low-cost",
3772 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
3774 bool kexec_loaded(void) {
3775 bool loaded = false;
3778 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
3786 /// UNNEEDED by elogind
3788 int prot_from_flags(int flags) {
3790 switch (flags & O_ACCMODE) {
3799 return PROT_READ|PROT_WRITE;
3806 char *format_bytes(char *buf, size_t l, off_t t) {
3809 static const struct {
3813 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
3814 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
3815 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
3816 { "G", 1024ULL*1024ULL*1024ULL },
3817 { "M", 1024ULL*1024ULL },
3821 if (t == (off_t) -1)
3824 for (i = 0; i < ELEMENTSOF(table); i++) {
3826 if (t >= table[i].factor) {
3829 (unsigned long long) (t / table[i].factor),
3830 (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
3837 snprintf(buf, l, "%lluB", (unsigned long long) t);
3846 void* memdup(const void *p, size_t l) {
3859 int fd_inc_sndbuf(int fd, size_t n) {
3861 socklen_t l = sizeof(value);
3863 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
3864 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
3867 /* If we have the privileges we will ignore the kernel limit. */
3870 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
3871 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
3877 int fd_inc_rcvbuf(int fd, size_t n) {
3879 socklen_t l = sizeof(value);
3881 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
3882 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
3885 /* If we have the privileges we will ignore the kernel limit. */
3888 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
3889 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
3894 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
3895 bool stdout_is_tty, stderr_is_tty;
3896 pid_t parent_pid, agent_pid;
3897 sigset_t ss, saved_ss;
3905 /* Spawns a temporary TTY agent, making sure it goes away when
3908 parent_pid = getpid();
3910 /* First we temporarily block all signals, so that the new
3911 * child has them blocked initially. This way, we can be sure
3912 * that SIGTERMs are not lost we might send to the agent. */
3913 assert_se(sigfillset(&ss) >= 0);
3914 assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0);
3917 if (agent_pid < 0) {
3918 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
3922 if (agent_pid != 0) {
3923 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
3930 * Make sure the agent goes away when the parent dies */
3931 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
3932 _exit(EXIT_FAILURE);
3934 /* Make sure we actually can kill the agent, if we need to, in
3935 * case somebody invoked us from a shell script that trapped
3936 * SIGTERM or so... */
3937 (void) reset_all_signal_handlers();
3938 (void) reset_signal_mask();
3940 /* Check whether our parent died before we were able
3941 * to set the death signal and unblock the signals */
3942 if (getppid() != parent_pid)
3943 _exit(EXIT_SUCCESS);
3945 /* Don't leak fds to the agent */
3946 close_all_fds(except, n_except);
3948 stdout_is_tty = isatty(STDOUT_FILENO);
3949 stderr_is_tty = isatty(STDERR_FILENO);
3951 if (!stdout_is_tty || !stderr_is_tty) {
3954 /* Detach from stdout/stderr. and reopen
3955 * /dev/tty for them. This is important to
3956 * ensure that when systemctl is started via
3957 * popen() or a similar call that expects to
3958 * read EOF we actually do generate EOF and
3959 * not delay this indefinitely by because we
3960 * keep an unused copy of stdin around. */
3961 fd = open("/dev/tty", O_WRONLY);
3963 log_error_errno(errno, "Failed to open /dev/tty: %m");
3964 _exit(EXIT_FAILURE);
3968 dup2(fd, STDOUT_FILENO);
3971 dup2(fd, STDERR_FILENO);
3977 /* Count arguments */
3979 for (n = 0; va_arg(ap, char*); n++)
3984 l = alloca(sizeof(char *) * (n + 1));
3986 /* Fill in arguments */
3988 for (i = 0; i <= n; i++)
3989 l[i] = va_arg(ap, char*);
3993 _exit(EXIT_FAILURE);
3996 /// UNNEEDED by elogind
3998 int setrlimit_closest(int resource, const struct rlimit *rlim) {
3999 struct rlimit highest, fixed;
4003 if (setrlimit(resource, rlim) >= 0)
4009 /* So we failed to set the desired setrlimit, then let's try
4010 * to get as close as we can */
4011 assert_se(getrlimit(resource, &highest) == 0);
4013 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
4014 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
4016 if (setrlimit(resource, &fixed) < 0)
4022 bool http_etag_is_valid(const char *etag) {
4026 if (!endswith(etag, "\""))
4029 if (!startswith(etag, "\"") && !startswith(etag, "W/\""))
4036 bool http_url_is_valid(const char *url) {
4042 p = startswith(url, "http://");
4044 p = startswith(url, "https://");
4051 return ascii_is_valid(p);
4054 bool documentation_url_is_valid(const char *url) {
4060 if (http_url_is_valid(url))
4063 p = startswith(url, "file:/");
4065 p = startswith(url, "info:");
4067 p = startswith(url, "man:");
4072 return ascii_is_valid(p);
4075 bool in_initrd(void) {
4076 static int saved = -1;
4082 /* We make two checks here:
4084 * 1. the flag file /etc/initrd-release must exist
4085 * 2. the root file system must be a memory file system
4087 * The second check is extra paranoia, since misdetecting an
4088 * initrd can have bad bad consequences due the initrd
4089 * emptying when transititioning to the main systemd.
4092 saved = access("/etc/initrd-release", F_OK) >= 0 &&
4093 statfs("/", &s) >= 0 &&
4094 is_temporary_fs(&s);
4099 int get_home_dir(char **_h) {
4107 /* Take the user specified one */
4108 e = secure_getenv("HOME");
4109 if (e && path_is_absolute(e)) {
4118 /* Hardcode home directory for root to avoid NSS */
4121 h = strdup("/root");
4129 /* Check the database... */
4133 return errno > 0 ? -errno : -ESRCH;
4135 if (!path_is_absolute(p->pw_dir))
4138 h = strdup(p->pw_dir);
4146 /// UNNEEDED by elogind
4148 int get_shell(char **_s) {
4156 /* Take the user specified one */
4157 e = getenv("SHELL");
4167 /* Hardcode home directory for root to avoid NSS */
4170 s = strdup("/bin/sh");
4178 /* Check the database... */
4182 return errno > 0 ? -errno : -ESRCH;
4184 if (!path_is_absolute(p->pw_shell))
4187 s = strdup(p->pw_shell);
4196 bool filename_is_valid(const char *p) {
4210 if (strlen(p) > FILENAME_MAX)
4216 bool string_is_safe(const char *p) {
4222 for (t = p; *t; t++) {
4223 if (*t > 0 && *t < ' ')
4226 if (strchr("\\\"\'\x7f", *t))
4234 * Check if a string contains control characters. If 'ok' is non-NULL
4235 * it may be a string containing additional CCs to be considered OK.
4237 bool string_has_cc(const char *p, const char *ok) {
4242 for (t = p; *t; t++) {
4243 if (ok && strchr(ok, *t))
4246 if (*t > 0 && *t < ' ')
4256 bool path_is_safe(const char *p) {
4261 if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
4264 if (strlen(p)+1 > PATH_MAX)
4267 /* The following two checks are not really dangerous, but hey, they still are confusing */
4268 if (streq(p, ".") || startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
4271 if (strstr(p, "//"))
4277 /// UNNEEDED by elogind
4279 /* hey glibc, APIs with callbacks without a user pointer are so useless */
4280 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
4281 int (*compar) (const void *, const void *, void *), void *arg) {
4290 p = (void *)(((const char *) base) + (idx * size));
4291 comparison = compar(key, p, arg);
4294 else if (comparison > 0)
4302 void init_gettext(void) {
4303 setlocale(LC_ALL, "");
4304 textdomain(GETTEXT_PACKAGE);
4308 bool is_locale_utf8(void) {
4310 static int cached_answer = -1;
4312 if (cached_answer >= 0)
4315 if (!setlocale(LC_ALL, "")) {
4316 cached_answer = true;
4320 set = nl_langinfo(CODESET);
4322 cached_answer = true;
4326 if (streq(set, "UTF-8")) {
4327 cached_answer = true;
4331 /* For LC_CTYPE=="C" return true, because CTYPE is effectly
4332 * unset and everything can do to UTF-8 nowadays. */
4333 set = setlocale(LC_CTYPE, NULL);
4335 cached_answer = true;
4339 /* Check result, but ignore the result if C was set
4342 STR_IN_SET(set, "C", "POSIX") &&
4343 !getenv("LC_ALL") &&
4344 !getenv("LC_CTYPE") &&
4348 return (bool) cached_answer;
4351 const char *draw_special_char(DrawSpecialChar ch) {
4352 static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
4355 [DRAW_TREE_VERTICAL] = "\342\224\202 ", /* │ */
4356 [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */
4357 [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */
4358 [DRAW_TREE_SPACE] = " ", /* */
4359 [DRAW_TRIANGULAR_BULLET] = "\342\200\243", /* ‣ */
4360 [DRAW_BLACK_CIRCLE] = "\342\227\217", /* ● */
4361 [DRAW_ARROW] = "\342\206\222", /* → */
4362 [DRAW_DASH] = "\342\200\223", /* – */
4365 /* ASCII fallback */ {
4366 [DRAW_TREE_VERTICAL] = "| ",
4367 [DRAW_TREE_BRANCH] = "|-",
4368 [DRAW_TREE_RIGHT] = "`-",
4369 [DRAW_TREE_SPACE] = " ",
4370 [DRAW_TRIANGULAR_BULLET] = ">",
4371 [DRAW_BLACK_CIRCLE] = "*",
4372 [DRAW_ARROW] = "->",
4377 return draw_table[!is_locale_utf8()][ch];
4380 /// UNNEEDED by elogind
4382 char *strreplace(const char *text, const char *old_string, const char *new_string) {
4385 size_t l, old_len, new_len;
4391 old_len = strlen(old_string);
4392 new_len = strlen(new_string);
4405 if (!startswith(f, old_string)) {
4411 nl = l - old_len + new_len;
4412 a = realloc(r, nl + 1);
4420 t = stpcpy(t, new_string);
4432 char *strip_tab_ansi(char **ibuf, size_t *_isz) {
4433 const char *i, *begin = NULL;
4438 } state = STATE_OTHER;
4440 size_t osz = 0, isz;
4446 /* Strips ANSI color and replaces TABs by 8 spaces */
4448 isz = _isz ? *_isz : strlen(*ibuf);
4450 f = open_memstream(&obuf, &osz);
4454 for (i = *ibuf; i < *ibuf + isz + 1; i++) {
4459 if (i >= *ibuf + isz) /* EOT */
4461 else if (*i == '\x1B')
4462 state = STATE_ESCAPE;
4463 else if (*i == '\t')
4470 if (i >= *ibuf + isz) { /* EOT */
4473 } else if (*i == '[') {
4474 state = STATE_BRACKET;
4479 state = STATE_OTHER;
4486 if (i >= *ibuf + isz || /* EOT */
4487 (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
4490 state = STATE_OTHER;
4492 } else if (*i == 'm')
4493 state = STATE_OTHER;
4515 int on_ac_power(void) {
4516 bool found_offline = false, found_online = false;
4517 _cleanup_closedir_ DIR *d = NULL;
4519 d = opendir("/sys/class/power_supply");
4521 return errno == ENOENT ? true : -errno;
4525 _cleanup_close_ int fd = -1, device = -1;
4531 if (!de && errno != 0)
4537 if (hidden_file(de->d_name))
4540 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
4542 if (errno == ENOENT || errno == ENOTDIR)
4548 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
4550 if (errno == ENOENT)
4556 n = read(fd, contents, sizeof(contents));
4560 if (n != 6 || memcmp(contents, "Mains\n", 6))
4564 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
4566 if (errno == ENOENT)
4572 n = read(fd, contents, sizeof(contents));
4576 if (n != 2 || contents[1] != '\n')
4579 if (contents[0] == '1') {
4580 found_online = true;
4582 } else if (contents[0] == '0')
4583 found_offline = true;
4588 return found_online || !found_offline;
4592 static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
4599 if (!path_strv_resolve_uniq(search, root))
4602 STRV_FOREACH(i, search) {
4603 _cleanup_free_ char *p = NULL;
4607 p = strjoin(root, *i, "/", path, NULL);
4609 p = strjoin(*i, "/", path, NULL);
4619 if (errno != ENOENT)
4626 int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
4627 _cleanup_strv_free_ char **copy = NULL;
4633 if (path_is_absolute(path)) {
4636 f = fopen(path, mode);
4645 copy = strv_copy((char**) search);
4649 return search_and_fopen_internal(path, mode, root, copy, _f);
4652 /// UNNEEDED by elogind
4654 int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
4655 _cleanup_strv_free_ char **s = NULL;
4657 if (path_is_absolute(path)) {
4660 f = fopen(path, mode);
4669 s = strv_split_nulstr(search);
4673 return search_and_fopen_internal(path, mode, root, s, _f);
4677 char *strextend(char **x, ...) {
4684 l = f = *x ? strlen(*x) : 0;
4691 t = va_arg(ap, const char *);
4696 if (n > ((size_t) -1) - l) {
4705 r = realloc(*x, l+1);
4715 t = va_arg(ap, const char *);
4729 char *strrep(const char *s, unsigned n) {
4737 p = r = malloc(l * n + 1);
4741 for (i = 0; i < n; i++)
4748 void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
4755 if (*allocated >= need)
4758 newalloc = MAX(need * 2, 64u / size);
4759 a = newalloc * size;
4761 /* check for overflows */
4762 if (a < size * need)
4770 *allocated = newalloc;
4774 void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
4783 q = greedy_realloc(p, allocated, need, size);
4787 if (*allocated > prev)
4788 memzero(q + prev * size, (*allocated - prev) * size);
4793 bool id128_is_valid(const char *s) {
4799 /* Simple formatted 128bit hex string */
4801 for (i = 0; i < l; i++) {
4804 if (!(c >= '0' && c <= '9') &&
4805 !(c >= 'a' && c <= 'z') &&
4806 !(c >= 'A' && c <= 'Z'))
4810 } else if (l == 36) {
4812 /* Formatted UUID */
4814 for (i = 0; i < l; i++) {
4817 if ((i == 8 || i == 13 || i == 18 || i == 23)) {
4821 if (!(c >= '0' && c <= '9') &&
4822 !(c >= 'a' && c <= 'z') &&
4823 !(c >= 'A' && c <= 'Z'))
4834 /// UNNEEDED by elogind
4836 int split_pair(const char *s, const char *sep, char **l, char **r) {
4851 a = strndup(s, x - s);
4855 b = strdup(x + strlen(sep));
4867 int shall_restore_state(void) {
4868 _cleanup_free_ char *value = NULL;
4871 r = get_proc_cmdline_key("systemd.restore_state=", &value);
4877 return parse_boolean(value) != 0;
4881 int proc_cmdline(char **ret) {
4884 if (detect_container(NULL) > 0)
4885 return get_process_cmdline(1, 0, false, ret);
4887 return read_one_line_file("/proc/cmdline", ret);
4890 int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
4891 _cleanup_free_ char *line = NULL;
4897 r = proc_cmdline(&line);
4903 _cleanup_free_ char *word = NULL;
4906 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
4912 /* Filter out arguments that are intended only for the
4914 if (!in_initrd() && startswith(word, "rd."))
4917 value = strchr(word, '=');
4921 r = parse_item(word, value);
4929 int get_proc_cmdline_key(const char *key, char **value) {
4930 _cleanup_free_ char *line = NULL, *ret = NULL;
4937 r = proc_cmdline(&line);
4943 _cleanup_free_ char *word = NULL;
4946 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
4952 /* Filter out arguments that are intended only for the
4954 if (!in_initrd() && startswith(word, "rd."))
4958 e = startswith(word, key);
4962 r = free_and_strdup(&ret, e);
4968 if (streq(word, key))
4982 int container_get_leader(const char *machine, pid_t *pid) {
4983 _cleanup_free_ char *s = NULL, *class = NULL;
4991 if (!machine_name_is_valid(machine))
4994 p = strjoina("/run/systemd/machines/", machine);
4995 r = parse_env_file(p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
5003 if (!streq_ptr(class, "container"))
5006 r = parse_pid(s, &leader);
5016 int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd) {
5017 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, netnsfd = -1, usernsfd = -1;
5025 mntns = procfs_file_alloca(pid, "ns/mnt");
5026 mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5034 pidns = procfs_file_alloca(pid, "ns/pid");
5035 pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5043 netns = procfs_file_alloca(pid, "ns/net");
5044 netnsfd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5052 userns = procfs_file_alloca(pid, "ns/user");
5053 usernsfd = open(userns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5054 if (usernsfd < 0 && errno != ENOENT)
5061 root = procfs_file_alloca(pid, "root");
5062 rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
5068 *pidns_fd = pidnsfd;
5071 *mntns_fd = mntnsfd;
5074 *netns_fd = netnsfd;
5077 *userns_fd = usernsfd;
5082 pidnsfd = mntnsfd = netnsfd = usernsfd = -1;
5087 int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd) {
5088 if (userns_fd >= 0) {
5089 /* Can't setns to your own userns, since then you could
5090 * escalate from non-root to root in your own namespace, so
5091 * check if namespaces equal before attempting to enter. */
5092 _cleanup_free_ char *userns_fd_path = NULL;
5094 if (asprintf(&userns_fd_path, "/proc/self/fd/%d", userns_fd) < 0)
5097 r = files_same(userns_fd_path, "/proc/self/ns/user");
5105 if (setns(pidns_fd, CLONE_NEWPID) < 0)
5109 if (setns(mntns_fd, CLONE_NEWNS) < 0)
5113 if (setns(netns_fd, CLONE_NEWNET) < 0)
5117 if (setns(userns_fd, CLONE_NEWUSER) < 0)
5121 if (fchdir(root_fd) < 0)
5124 if (chroot(".") < 0)
5128 return reset_uid_gid();
5131 int getpeercred(int fd, struct ucred *ucred) {
5132 socklen_t n = sizeof(struct ucred);
5139 r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
5143 if (n != sizeof(struct ucred))
5146 /* Check if the data is actually useful and not suppressed due
5147 * to namespacing issues */
5150 if (u.uid == UID_INVALID)
5152 if (u.gid == GID_INVALID)
5159 int getpeersec(int fd, char **ret) {
5171 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
5175 if (errno != ERANGE)
5182 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
5198 /* This is much like like mkostemp() but is subject to umask(). */
5199 int mkostemp_safe(char *pattern, int flags) {
5200 _cleanup_umask_ mode_t u;
5207 fd = mkostemp(pattern, flags);
5214 /// UNNEEDED by elogind
5216 int open_tmpfile(const char *path, int flags) {
5223 /* Try O_TMPFILE first, if it is supported */
5224 fd = open(path, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
5229 /* Fall back to unguessable name + unlinking */
5230 p = strjoina(path, "/systemd-tmp-XXXXXX");
5232 fd = mkostemp_safe(p, flags);
5241 int fd_warn_permissions(const char *path, int fd) {
5244 if (fstat(fd, &st) < 0)
5247 if (st.st_mode & 0111)
5248 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
5250 if (st.st_mode & 0002)
5251 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
5253 if (getpid() == 1 && (st.st_mode & 0044) != 0044)
5254 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);
5259 /// UNNEEDED by elogind
5261 unsigned long personality_from_string(const char *p) {
5263 /* Parse a personality specifier. We introduce our own
5264 * identifiers that indicate specific ABIs, rather than just
5265 * hints regarding the register size, since we want to keep
5266 * things open for multiple locally supported ABIs for the
5267 * same register size. We try to reuse the ABI identifiers
5268 * used by libseccomp. */
5270 #if defined(__x86_64__)
5272 if (streq(p, "x86"))
5275 if (streq(p, "x86-64"))
5278 #elif defined(__i386__)
5280 if (streq(p, "x86"))
5284 return PERSONALITY_INVALID;
5287 const char* personality_to_string(unsigned long p) {
5289 #if defined(__x86_64__)
5291 if (p == PER_LINUX32)
5297 #elif defined(__i386__)
5307 uint64_t physical_memory(void) {
5310 /* We return this as uint64_t in case we are running as 32bit
5311 * process on a 64bit kernel with huge amounts of memory */
5313 mem = sysconf(_SC_PHYS_PAGES);
5316 return (uint64_t) mem * (uint64_t) page_size();
5319 /// UNNEEDED by elogind
5321 void hexdump(FILE *f, const void *p, size_t s) {
5322 const uint8_t *b = p;
5325 assert(s == 0 || b);
5330 fprintf(f, "%04x ", n);
5332 for (i = 0; i < 16; i++) {
5337 fprintf(f, "%02x ", b[i]);
5345 for (i = 0; i < 16; i++) {
5350 fputc(isprint(b[i]) ? (char) b[i] : '.', f);
5364 int update_reboot_param_file(const char *param) {
5369 r = write_string_file(REBOOT_PARAM_FILE, param, WRITE_STRING_FILE_CREATE);
5371 log_error("Failed to write reboot param to "
5372 REBOOT_PARAM_FILE": %s", strerror(-r));
5374 unlink(REBOOT_PARAM_FILE);
5379 int umount_recursive(const char *prefix, int flags) {
5383 /* Try to umount everything recursively below a
5384 * directory. Also, take care of stacked mounts, and keep
5385 * unmounting them until they are gone. */
5388 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
5393 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
5394 if (!proc_self_mountinfo)
5398 _cleanup_free_ char *path = NULL, *p = NULL;
5401 k = fscanf(proc_self_mountinfo,
5402 "%*s " /* (1) mount id */
5403 "%*s " /* (2) parent id */
5404 "%*s " /* (3) major:minor */
5405 "%*s " /* (4) root */
5406 "%ms " /* (5) mount point */
5407 "%*s" /* (6) mount options */
5408 "%*[^-]" /* (7) optional fields */
5409 "- " /* (8) separator */
5410 "%*s " /* (9) file system type */
5411 "%*s" /* (10) mount source */
5412 "%*s" /* (11) mount options 2 */
5413 "%*[^\n]", /* some rubbish at the end */
5422 r = cunescape(path, UNESCAPE_RELAX, &p);
5426 if (!path_startswith(p, prefix))
5429 if (umount2(p, flags) < 0) {
5445 static int get_mount_flags(const char *path, unsigned long *flags) {
5448 if (statvfs(path, &buf) < 0)
5450 *flags = buf.f_flag;
5454 int bind_remount_recursive(const char *prefix, bool ro) {
5455 _cleanup_set_free_free_ Set *done = NULL;
5456 _cleanup_free_ char *cleaned = NULL;
5459 /* Recursively remount a directory (and all its submounts)
5460 * read-only or read-write. If the directory is already
5461 * mounted, we reuse the mount and simply mark it
5462 * MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write
5463 * operation). If it isn't we first make it one. Afterwards we
5464 * apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to all
5465 * submounts we can access, too. When mounts are stacked on
5466 * the same mount point we only care for each individual
5467 * "top-level" mount on each point, as we cannot
5468 * influence/access the underlying mounts anyway. We do not
5469 * have any effect on future submounts that might get
5470 * propagated, they migt be writable. This includes future
5471 * submounts that have been triggered via autofs. */
5473 cleaned = strdup(prefix);
5477 path_kill_slashes(cleaned);
5479 done = set_new(&string_hash_ops);
5484 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
5485 _cleanup_set_free_free_ Set *todo = NULL;
5486 bool top_autofs = false;
5488 unsigned long orig_flags;
5490 todo = set_new(&string_hash_ops);
5494 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
5495 if (!proc_self_mountinfo)
5499 _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
5502 k = fscanf(proc_self_mountinfo,
5503 "%*s " /* (1) mount id */
5504 "%*s " /* (2) parent id */
5505 "%*s " /* (3) major:minor */
5506 "%*s " /* (4) root */
5507 "%ms " /* (5) mount point */
5508 "%*s" /* (6) mount options (superblock) */
5509 "%*[^-]" /* (7) optional fields */
5510 "- " /* (8) separator */
5511 "%ms " /* (9) file system type */
5512 "%*s" /* (10) mount source */
5513 "%*s" /* (11) mount options (bind mount) */
5514 "%*[^\n]", /* some rubbish at the end */
5524 r = cunescape(path, UNESCAPE_RELAX, &p);
5528 /* Let's ignore autofs mounts. If they aren't
5529 * triggered yet, we want to avoid triggering
5530 * them, as we don't make any guarantees for
5531 * future submounts anyway. If they are
5532 * already triggered, then we will find
5533 * another entry for this. */
5534 if (streq(type, "autofs")) {
5535 top_autofs = top_autofs || path_equal(cleaned, p);
5539 if (path_startswith(p, cleaned) &&
5540 !set_contains(done, p)) {
5542 r = set_consume(todo, p);
5552 /* If we have no submounts to process anymore and if
5553 * the root is either already done, or an autofs, we
5555 if (set_isempty(todo) &&
5556 (top_autofs || set_contains(done, cleaned)))
5559 if (!set_contains(done, cleaned) &&
5560 !set_contains(todo, cleaned)) {
5561 /* The prefix directory itself is not yet a
5562 * mount, make it one. */
5563 if (mount(cleaned, cleaned, NULL, MS_BIND|MS_REC, NULL) < 0)
5567 (void) get_mount_flags(cleaned, &orig_flags);
5568 orig_flags &= ~MS_RDONLY;
5570 if (mount(NULL, prefix, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0)
5573 x = strdup(cleaned);
5577 r = set_consume(done, x);
5582 while ((x = set_steal_first(todo))) {
5584 r = set_consume(done, x);
5585 if (r == -EEXIST || r == 0)
5590 /* Try to reuse the original flag set, but
5591 * don't care for errors, in case of
5592 * obstructed mounts */
5594 (void) get_mount_flags(x, &orig_flags);
5595 orig_flags &= ~MS_RDONLY;
5597 if (mount(NULL, x, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) {
5599 /* Deal with mount points that are
5600 * obstructed by a later mount */
5602 if (errno != ENOENT)
5611 int fflush_and_check(FILE *f) {
5618 return errno ? -errno : -EIO;
5623 int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
5635 * /foo/bar/.#<extra>waldoXXXXXX
5639 if (!filename_is_valid(fn))
5645 t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
5649 strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn), "XXXXXX");
5651 *ret = path_kill_slashes(t);
5655 int tempfn_random(const char *p, const char *extra, char **ret) {
5669 * /foo/bar/.#<extra>waldobaa2a261115984a9
5673 if (!filename_is_valid(fn))
5679 t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1);
5683 x = stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn);
5686 for (i = 0; i < 16; i++) {
5687 *(x++) = hexchar(u & 0xF);
5693 *ret = path_kill_slashes(t);
5697 /// UNNEEDED by elogind
5699 int tempfn_random_child(const char *p, const char *extra, char **ret) {
5710 * /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
5716 t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1);
5720 x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra);
5723 for (i = 0; i < 16; i++) {
5724 *(x++) = hexchar(u & 0xF);
5730 *ret = path_kill_slashes(t);
5734 int take_password_lock(const char *root) {
5736 struct flock flock = {
5738 .l_whence = SEEK_SET,
5746 /* This is roughly the same as lckpwdf(), but not as awful. We
5747 * don't want to use alarm() and signals, hence we implement
5748 * our own trivial version of this.
5750 * Note that shadow-utils also takes per-database locks in
5751 * addition to lckpwdf(). However, we don't given that they
5752 * are redundant as they they invoke lckpwdf() first and keep
5753 * it during everything they do. The per-database locks are
5754 * awfully racy, and thus we just won't do them. */
5757 path = strjoina(root, "/etc/.pwd.lock");
5759 path = "/etc/.pwd.lock";
5761 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
5765 r = fcntl(fd, F_SETLKW, &flock);
5774 int is_symlink(const char *path) {
5777 if (lstat(path, &info) < 0)
5780 return !!S_ISLNK(info.st_mode);
5784 int is_dir(const char* path, bool follow) {
5789 r = stat(path, &st);
5791 r = lstat(path, &st);
5795 return !!S_ISDIR(st.st_mode);
5798 /// UNNEEDED by elogind
5800 int is_device_node(const char *path) {
5803 if (lstat(path, &info) < 0)
5806 return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode));
5810 int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) {
5811 _cleanup_free_ char *s = NULL;
5812 size_t allocated = 0, sz = 0;
5820 SINGLE_QUOTE_ESCAPE,
5822 DOUBLE_QUOTE_ESCAPE,
5830 separators = WHITESPACE;
5832 /* Bail early if called after last value or with no input */
5834 goto finish_force_terminate;
5836 /* Parses the first word of a string, and returns it in
5837 * *ret. Removes all quotes in the process. When parsing fails
5838 * (because of an uneven number of quotes or similar), leaves
5839 * the pointer *p at the first invalid character. */
5847 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
5848 if (!GREEDY_REALLOC(s, allocated, sz+1))
5852 goto finish_force_terminate;
5853 else if (strchr(separators, c)) {
5854 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
5856 goto finish_force_next;
5861 /* We found a non-blank character, so we will always
5862 * want to return a string (even if it is empty),
5863 * allocate it here. */
5864 if (!GREEDY_REALLOC(s, allocated, sz+1))
5872 goto finish_force_terminate;
5873 else if (c == '\'' && (flags & EXTRACT_QUOTES))
5874 state = SINGLE_QUOTE;
5876 state = VALUE_ESCAPE;
5877 else if (c == '\"' && (flags & EXTRACT_QUOTES))
5878 state = DOUBLE_QUOTE;
5879 else if (strchr(separators, c)) {
5880 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
5882 goto finish_force_next;
5886 if (!GREEDY_REALLOC(s, allocated, sz+2))
5896 if (flags & EXTRACT_RELAX)
5897 goto finish_force_terminate;
5899 } else if (c == '\'')
5902 state = SINGLE_QUOTE_ESCAPE;
5904 if (!GREEDY_REALLOC(s, allocated, sz+2))
5918 state = DOUBLE_QUOTE_ESCAPE;
5920 if (!GREEDY_REALLOC(s, allocated, sz+2))
5928 case SINGLE_QUOTE_ESCAPE:
5929 case DOUBLE_QUOTE_ESCAPE:
5931 if (!GREEDY_REALLOC(s, allocated, sz+7))
5935 if ((flags & EXTRACT_CUNESCAPE_RELAX) &&
5936 (state == VALUE_ESCAPE || flags & EXTRACT_RELAX)) {
5937 /* If we find an unquoted trailing backslash and we're in
5938 * EXTRACT_CUNESCAPE_RELAX mode, keep it verbatim in the
5941 * Unbalanced quotes will only be allowed in EXTRACT_RELAX
5942 * mode, EXTRACT_CUNESCAPE_RELAX mode does not allow them.
5945 goto finish_force_terminate;
5947 if (flags & EXTRACT_RELAX)
5948 goto finish_force_terminate;
5952 if (flags & EXTRACT_CUNESCAPE) {
5955 r = cunescape_one(*p, (size_t) -1, &c, &u);
5957 if (flags & EXTRACT_CUNESCAPE_RELAX) {
5968 s[sz++] = c; /* normal explicit char */
5970 sz += utf8_encode_unichar(s + sz, u); /* unicode chars we'll encode as utf8 */
5975 state = (state == SINGLE_QUOTE_ESCAPE) ? SINGLE_QUOTE :
5976 (state == DOUBLE_QUOTE_ESCAPE) ? DOUBLE_QUOTE :
5982 goto finish_force_terminate;
5983 if (!strchr(separators, c))
5991 finish_force_terminate:
6008 /// UNNEEDED by elogind
6010 int extract_first_word_and_warn(
6013 const char *separators,
6016 const char *filename,
6018 const char *rvalue) {
6019 /* Try to unquote it, if it fails, warn about it and try again but this
6020 * time using EXTRACT_CUNESCAPE_RELAX to keep the backslashes verbatim
6021 * in invalid escape sequences. */
6026 r = extract_first_word(p, ret, separators, flags);
6027 if (r < 0 && !(flags&EXTRACT_CUNESCAPE_RELAX)) {
6028 /* Retry it with EXTRACT_CUNESCAPE_RELAX. */
6030 r = extract_first_word(p, ret, separators, flags|EXTRACT_CUNESCAPE_RELAX);
6032 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
6033 "Unbalanced quoting in command line, ignoring: \"%s\"", rvalue);
6035 log_syntax(unit, LOG_WARNING, filename, line, EINVAL,
6036 "Invalid escape sequences in command line: \"%s\"", rvalue);
6041 int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) {
6046 /* Parses a number of words from a string, stripping any
6047 * quotes if necessary. */
6051 /* Count how many words are expected */
6052 va_start(ap, flags);
6054 if (!va_arg(ap, char **))
6063 /* Read all words into a temporary array */
6064 l = newa0(char*, n);
6065 for (c = 0; c < n; c++) {
6067 r = extract_first_word(p, &l[c], separators, flags);
6071 for (j = 0; j < c; j++)
6081 /* If we managed to parse all words, return them in the passed
6083 va_start(ap, flags);
6084 for (i = 0; i < n; i++) {
6087 v = va_arg(ap, char **);
6098 int free_and_strdup(char **p, const char *s) {
6103 /* Replaces a string pointer with an strdup()ed new string,
6104 * possibly freeing the old one. */
6106 if (streq_ptr(*p, s))
6122 /// UNNEEDED by elogind
6124 int ptsname_malloc(int fd, char **ret) {
6137 if (ptsname_r(fd, c, l) == 0) {
6141 if (errno != ERANGE) {
6151 int openpt_in_namespace(pid_t pid, int flags) {
6152 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1;
6153 _cleanup_close_pair_ int pair[2] = { -1, -1 };
6155 struct cmsghdr cmsghdr;
6156 uint8_t buf[CMSG_SPACE(sizeof(int))];
6158 struct msghdr mh = {
6159 .msg_control = &control,
6160 .msg_controllen = sizeof(control),
6162 struct cmsghdr *cmsg;
6169 r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &usernsfd, &rootfd);
6173 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
6183 pair[0] = safe_close(pair[0]);
6185 r = namespace_enter(pidnsfd, mntnsfd, -1, usernsfd, rootfd);
6187 _exit(EXIT_FAILURE);
6189 master = posix_openpt(flags);
6191 _exit(EXIT_FAILURE);
6193 cmsg = CMSG_FIRSTHDR(&mh);
6194 cmsg->cmsg_level = SOL_SOCKET;
6195 cmsg->cmsg_type = SCM_RIGHTS;
6196 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
6197 memcpy(CMSG_DATA(cmsg), &master, sizeof(int));
6199 mh.msg_controllen = cmsg->cmsg_len;
6201 if (sendmsg(pair[1], &mh, MSG_NOSIGNAL) < 0)
6202 _exit(EXIT_FAILURE);
6204 _exit(EXIT_SUCCESS);
6207 pair[1] = safe_close(pair[1]);
6209 r = wait_for_terminate(child, &si);
6212 if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
6215 if (recvmsg(pair[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
6218 CMSG_FOREACH(cmsg, &mh)
6219 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
6223 fds = (int*) CMSG_DATA(cmsg);
6224 n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
6227 close_many(fds, n_fds);
6238 ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) {
6239 _cleanup_close_ int fd = -1;
6242 /* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */
6244 fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOATIME|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
6248 l = fgetxattr(fd, attribute, value, size);
6255 static int parse_crtime(le64_t le, usec_t *usec) {
6261 if (u == 0 || u == (uint64_t) -1)
6268 int fd_getcrtime(int fd, usec_t *usec) {
6275 /* Until Linux gets a real concept of birthtime/creation time,
6276 * let's fake one with xattrs */
6278 n = fgetxattr(fd, "user.crtime_usec", &le, sizeof(le));
6281 if (n != sizeof(le))
6284 return parse_crtime(le, usec);
6287 /// UNNEEDED by elogind
6289 int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags) {
6293 n = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags);
6296 if (n != sizeof(le))
6299 return parse_crtime(le, usec);
6302 int path_getcrtime(const char *p, usec_t *usec) {
6309 n = getxattr(p, "user.crtime_usec", &le, sizeof(le));
6312 if (n != sizeof(le))
6315 return parse_crtime(le, usec);
6318 int fd_setcrtime(int fd, usec_t usec) {
6324 usec = now(CLOCK_REALTIME);
6326 le = htole64((uint64_t) usec);
6327 if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), 0) < 0)
6333 int same_fd(int a, int b) {
6334 struct stat sta, stb;
6341 /* Compares two file descriptors. Note that semantics are
6342 * quite different depending on whether we have kcmp() or we
6343 * don't. If we have kcmp() this will only return true for
6344 * dup()ed file descriptors, but not otherwise. If we don't
6345 * have kcmp() this will also return true for two fds of the same
6346 * file, created by separate open() calls. Since we use this
6347 * call mostly for filtering out duplicates in the fd store
6348 * this difference hopefully doesn't matter too much. */
6353 /* Try to use kcmp() if we have it. */
6355 r = kcmp(pid, pid, KCMP_FILE, a, b);
6360 if (errno != ENOSYS)
6363 /* We don't have kcmp(), use fstat() instead. */
6364 if (fstat(a, &sta) < 0)
6367 if (fstat(b, &stb) < 0)
6370 if ((sta.st_mode & S_IFMT) != (stb.st_mode & S_IFMT))
6373 /* We consider all device fds different, since two device fds
6374 * might refer to quite different device contexts even though
6375 * they share the same inode and backing dev_t. */
6377 if (S_ISCHR(sta.st_mode) || S_ISBLK(sta.st_mode))
6380 if (sta.st_dev != stb.st_dev || sta.st_ino != stb.st_ino)
6383 /* The fds refer to the same inode on disk, let's also check
6384 * if they have the same fd flags. This is useful to
6385 * distinguish the read and write side of a pipe created with
6387 fa = fcntl(a, F_GETFL);
6391 fb = fcntl(b, F_GETFL);
6399 int chattr_fd(int fd, unsigned value, unsigned mask) {
6400 unsigned old_attr, new_attr;
6405 if (fstat(fd, &st) < 0)
6408 /* Explicitly check whether this is a regular file or
6409 * directory. If it is anything else (such as a device node or
6410 * fifo), then the ioctl will not hit the file systems but
6411 * possibly drivers, where the ioctl might have different
6412 * effects. Notably, DRM is using the same ioctl() number. */
6414 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
6420 if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
6423 new_attr = (old_attr & ~mask) | (value & mask);
6424 if (new_attr == old_attr)
6427 if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
6433 /// UNNEEDED by elogind
6435 int chattr_path(const char *p, unsigned value, unsigned mask) {
6436 _cleanup_close_ int fd = -1;
6443 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
6447 return chattr_fd(fd, value, mask);
6451 int read_attr_fd(int fd, unsigned *ret) {
6456 if (fstat(fd, &st) < 0)
6459 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
6462 if (ioctl(fd, FS_IOC_GETFLAGS, ret) < 0)
6468 /// UNNEEDED by elogind
6470 int read_attr_path(const char *p, unsigned *ret) {
6471 _cleanup_close_ int fd = -1;
6476 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
6480 return read_attr_fd(fd, ret);
6483 static size_t nul_length(const uint8_t *p, size_t sz) {
6498 ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
6499 const uint8_t *q, *w, *e;
6507 n = nul_length(q, e - q);
6509 /* If there are more than the specified run length of
6510 * NUL bytes, or if this is the beginning or the end
6511 * of the buffer, then seek instead of write */
6512 if ((n > run_length) ||
6513 (n > 0 && q == p) ||
6514 (n > 0 && q + n >= e)) {
6516 l = write(fd, w, q - w);
6523 if (lseek(fd, n, SEEK_CUR) == (off_t) -1)
6535 l = write(fd, w, q - w);
6542 return q - (const uint8_t*) p;
6546 void sigkill_wait(pid_t *pid) {
6552 if (kill(*pid, SIGKILL) > 0)
6553 (void) wait_for_terminate(*pid, NULL);
6556 /// UNNEEDED by elogind
6558 int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
6559 int a = 0, b = 0, c = 0;
6569 if (!strchr(*p, '>'))
6572 if ((*p)[2] == '>') {
6573 c = undecchar((*p)[1]);
6575 } else if ((*p)[3] == '>') {
6576 b = undecchar((*p)[1]);
6577 c = undecchar((*p)[2]);
6579 } else if ((*p)[4] == '>') {
6580 a = undecchar((*p)[1]);
6581 b = undecchar((*p)[2]);
6582 c = undecchar((*p)[3]);
6587 if (a < 0 || b < 0 || c < 0 ||
6588 (!with_facility && (a || b || c > 7)))
6592 *priority = a*100 + b*10 + c;
6594 *priority = (*priority & LOG_FACMASK) | c;
6601 ssize_t string_table_lookup(const char * const *table, size_t len, const char *key) {
6607 for (i = 0; i < len; ++i)
6608 if (streq_ptr(table[i], key))
6614 /// UNNEEDED by elogind
6616 void cmsg_close_all(struct msghdr *mh) {
6617 struct cmsghdr *cmsg;
6621 CMSG_FOREACH(cmsg, mh)
6622 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
6623 close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int));
6626 int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
6630 ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
6634 /* renameat2() exists since Linux 3.15, btrfs added support for it later.
6635 * If it is not implemented, fallback to another method. */
6636 if (!IN_SET(errno, EINVAL, ENOSYS))
6639 /* The link()/unlink() fallback does not work on directories. But
6640 * renameat() without RENAME_NOREPLACE gives the same semantics on
6641 * directories, except when newpath is an *empty* directory. This is
6643 ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW);
6644 if (ret >= 0 && S_ISDIR(buf.st_mode)) {
6645 ret = renameat(olddirfd, oldpath, newdirfd, newpath);
6646 return ret >= 0 ? 0 : -errno;
6649 /* If it is not a directory, use the link()/unlink() fallback. */
6650 ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0);
6654 ret = unlinkat(olddirfd, oldpath, 0);
6656 /* backup errno before the following unlinkat() alters it */
6658 (void) unlinkat(newdirfd, newpath, 0);
6667 static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad) {
6671 if (*s == '\\' || strchr(bad, *s))
6680 char *shell_escape(const char *s, const char *bad) {
6683 r = new(char, strlen(s)*2+1);
6687 t = strcpy_backslash_escaped(r, s, bad);
6693 char *shell_maybe_quote(const char *s) {
6699 /* Encloses a string in double quotes if necessary to make it
6700 * OK as shell string. */
6702 for (p = s; *p; p++)
6705 strchr(SHELL_NEED_QUOTES, *p))
6711 r = new(char, 1+strlen(s)*2+1+1);
6717 t = mempcpy(t, s, p - s);
6719 t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE);
6727 int parse_mode(const char *s, mode_t *ret) {
6735 l = strtol(s, &x, 8);
6739 if (!x || x == s || *x)
6741 if (l < 0 || l > 07777)
6748 /// UNNEEDED by elogind
6750 int mount_move_root(const char *path) {
6753 if (chdir(path) < 0)
6756 if (mount(path, "/", NULL, MS_MOVE, NULL) < 0)
6759 if (chroot(".") < 0)
6769 int reset_uid_gid(void) {
6771 if (setgroups(0, NULL) < 0)
6774 if (setresgid(0, 0, 0) < 0)
6777 if (setresuid(0, 0, 0) < 0)
6783 int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink) {
6792 for (l = 100; ; l = (size_t) n + 1) {
6798 n = lgetxattr(path, name, v, l);
6800 n = getxattr(path, name, v, l);
6802 if (n >= 0 && (size_t) n < l) {
6809 if (n < 0 && errno != ERANGE)
6813 n = lgetxattr(path, name, NULL, 0);
6815 n = getxattr(path, name, NULL, 0);
6821 int fgetxattr_malloc(int fd, const char *name, char **value) {
6830 for (l = 100; ; l = (size_t) n + 1) {
6835 n = fgetxattr(fd, name, v, l);
6837 if (n >= 0 && (size_t) n < l) {
6844 if (n < 0 && errno != ERANGE)
6847 n = fgetxattr(fd, name, NULL, 0);