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/>.
29 //#include <libintl.h>
31 #include <linux/magic.h>
32 //#include <linux/sched.h>
34 #include <netinet/ip.h>
43 //#include <sys/file.h>
44 //#include <sys/ioctl.h>
45 //#include <sys/mman.h>
46 //#include <sys/mount.h>
47 //#include <sys/personality.h>
48 #include <sys/prctl.h>
49 //#include <sys/resource.h>
50 //#include <sys/stat.h>
51 //#include <sys/statvfs.h>
52 //#include <sys/time.h>
53 //#include <sys/types.h>
54 //#include <sys/utsname.h>
55 //#include <sys/vfs.h>
56 //#include <sys/wait.h>
57 #include <sys/xattr.h>
61 /* When we include libgen.h because we need dirname() we immediately
62 * undefine basename() since libgen.h defines it as a macro to the
63 * POSIX version which is really broken. We prefer GNU basename(). */
67 #ifdef HAVE_SYS_AUXV_H
71 /* We include linux/fs.h as last of the system headers, as it
72 * otherwise conflicts with sys/mount.h. Yay, Linux is great! */
73 //#include <linux/fs.h>
77 //#include "device-nodes.h"
78 //#include "env-util.h"
79 //#include "exit-status.h"
81 //#include "formats-util.h"
84 #include "hostname-util.h"
88 //#include "missing.h"
90 #include "path-util.h"
91 #include "process-util.h"
92 #include "random-util.h"
93 #include "signal-util.h"
94 #include "sparse-endian.h"
96 //#include "terminal-util.h"
102 /* Put this test here for a lack of better place */
103 assert_cc(EAGAIN == EWOULDBLOCK);
106 char **saved_argv = NULL;
108 size_t page_size(void) {
109 static thread_local size_t pgsz = 0;
112 if (_likely_(pgsz > 0))
115 r = sysconf(_SC_PAGESIZE);
122 int strcmp_ptr(const char *a, const char *b) {
124 /* Like strcmp(), but tries to make sense of NULL pointers */
137 bool streq_ptr(const char *a, const char *b) {
138 return strcmp_ptr(a, b) == 0;
141 char* endswith(const char *s, const char *postfix) {
148 pl = strlen(postfix);
151 return (char*) s + sl;
156 if (memcmp(s + sl - pl, postfix, pl) != 0)
159 return (char*) s + sl - pl;
162 char* endswith_no_case(const char *s, const char *postfix) {
169 pl = strlen(postfix);
172 return (char*) s + sl;
177 if (strcasecmp(s + sl - pl, postfix) != 0)
180 return (char*) s + sl - pl;
183 char* first_word(const char *s, const char *word) {
190 /* Checks if the string starts with the specified word, either
191 * followed by NUL or by whitespace. Returns a pointer to the
192 * NUL or the first character after the whitespace. */
203 if (memcmp(s, word, wl) != 0)
210 if (!strchr(WHITESPACE, *p))
213 p += strspn(p, WHITESPACE);
217 size_t cescape_char(char c, char *buf) {
218 char * buf_old = buf;
264 /* For special chars we prefer octal over
265 * hexadecimal encoding, simply because glib's
266 * g_strescape() does the same */
267 if ((c < ' ') || (c >= 127)) {
269 *(buf++) = octchar((unsigned char) c >> 6);
270 *(buf++) = octchar((unsigned char) c >> 3);
271 *(buf++) = octchar((unsigned char) c);
277 return buf - buf_old;
280 int close_nointr(int fd) {
287 * Just ignore EINTR; a retry loop is the wrong thing to do on
290 * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
291 * https://bugzilla.gnome.org/show_bug.cgi?id=682819
292 * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
293 * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
301 int safe_close(int fd) {
304 * Like close_nointr() but cannot fail. Guarantees errno is
305 * unchanged. Is a NOP with negative fds passed, and returns
306 * -1, so that it can be used in this syntax:
308 * fd = safe_close(fd);
314 /* The kernel might return pretty much any error code
315 * via close(), but the fd will be closed anyway. The
316 * only condition we want to check for here is whether
317 * the fd was invalid at all... */
319 assert_se(close_nointr(fd) != -EBADF);
325 void close_many(const int fds[], unsigned n_fd) {
328 assert(fds || n_fd <= 0);
330 for (i = 0; i < n_fd; i++)
334 int fclose_nointr(FILE *f) {
337 /* Same as close_nointr(), but for fclose() */
348 FILE* safe_fclose(FILE *f) {
350 /* Same as safe_close(), but for fclose() */
355 assert_se(fclose_nointr(f) != EBADF);
361 DIR* safe_closedir(DIR *d) {
366 assert_se(closedir(d) >= 0 || errno != EBADF);
372 int unlink_noerrno(const char *path) {
383 int parse_boolean(const char *v) {
386 if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on"))
388 else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off"))
394 int parse_pid(const char *s, pid_t* ret_pid) {
395 unsigned long ul = 0;
402 r = safe_atolu(s, &ul);
408 if ((unsigned long) pid != ul)
418 bool uid_is_valid(uid_t uid) {
420 /* Some libc APIs use UID_INVALID as special placeholder */
421 if (uid == (uid_t) 0xFFFFFFFF)
424 /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
425 if (uid == (uid_t) 0xFFFF)
431 int parse_uid(const char *s, uid_t* ret_uid) {
432 unsigned long ul = 0;
438 r = safe_atolu(s, &ul);
444 if ((unsigned long) uid != ul)
447 if (!uid_is_valid(uid))
448 return -ENXIO; /* we return ENXIO instead of EINVAL
449 * here, to make it easy to distuingish
450 * invalid numeric uids invalid
459 int safe_atou(const char *s, unsigned *ret_u) {
467 l = strtoul(s, &x, 0);
469 if (!x || x == s || *x || errno)
470 return errno > 0 ? -errno : -EINVAL;
472 if ((unsigned long) (unsigned) l != l)
475 *ret_u = (unsigned) l;
479 int safe_atoi(const char *s, int *ret_i) {
487 l = strtol(s, &x, 0);
489 if (!x || x == s || *x || errno)
490 return errno > 0 ? -errno : -EINVAL;
492 if ((long) (int) l != l)
499 int safe_atou8(const char *s, uint8_t *ret) {
507 l = strtoul(s, &x, 0);
509 if (!x || x == s || *x || errno)
510 return errno > 0 ? -errno : -EINVAL;
512 if ((unsigned long) (uint8_t) l != l)
519 int safe_atou16(const char *s, uint16_t *ret) {
527 l = strtoul(s, &x, 0);
529 if (!x || x == s || *x || errno)
530 return errno > 0 ? -errno : -EINVAL;
532 if ((unsigned long) (uint16_t) l != l)
539 int safe_atoi16(const char *s, int16_t *ret) {
547 l = strtol(s, &x, 0);
549 if (!x || x == s || *x || errno)
550 return errno > 0 ? -errno : -EINVAL;
552 if ((long) (int16_t) l != l)
559 int safe_atollu(const char *s, long long unsigned *ret_llu) {
561 unsigned long long l;
567 l = strtoull(s, &x, 0);
569 if (!x || x == s || *x || errno)
570 return errno ? -errno : -EINVAL;
576 int safe_atolli(const char *s, long long int *ret_lli) {
584 l = strtoll(s, &x, 0);
586 if (!x || x == s || *x || errno)
587 return errno ? -errno : -EINVAL;
593 int safe_atod(const char *s, double *ret_d) {
601 loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
602 if (loc == (locale_t) 0)
606 d = strtod_l(s, &x, loc);
608 if (!x || x == s || *x || errno) {
610 return errno ? -errno : -EINVAL;
618 static size_t strcspn_escaped(const char *s, const char *reject) {
619 bool escaped = false;
622 for (n=0; s[n]; n++) {
625 else if (s[n] == '\\')
627 else if (strchr(reject, s[n]))
631 /* if s ends in \, return index of previous char */
635 /* Split a string into words. */
636 const char* split(const char **state, size_t *l, const char *separator, bool quoted) {
642 assert(**state == '\0');
646 current += strspn(current, separator);
652 if (quoted && strchr("\'\"", *current)) {
653 char quotechars[2] = {*current, '\0'};
655 *l = strcspn_escaped(current + 1, quotechars);
656 if (current[*l + 1] == '\0' || current[*l + 1] != quotechars[0] ||
657 (current[*l + 2] && !strchr(separator, current[*l + 2]))) {
658 /* right quote missing or garbage at the end */
662 *state = current++ + *l + 2;
664 *l = strcspn_escaped(current, separator);
665 if (current[*l] && !strchr(separator, current[*l])) {
666 /* unfinished escape */
670 *state = current + *l;
672 *l = strcspn(current, separator);
673 *state = current + *l;
679 int fchmod_umask(int fd, mode_t m) {
684 r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
690 char *truncate_nl(char *s) {
693 s[strcspn(s, NEWLINE)] = 0;
697 char *strnappend(const char *s, const char *suffix, size_t b) {
705 return strndup(suffix, b);
714 if (b > ((size_t) -1) - a)
717 r = new(char, a+b+1);
722 memcpy(r+a, suffix, b);
728 char *strappend(const char *s, const char *suffix) {
729 return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
732 int readlinkat_malloc(int fd, const char *p, char **ret) {
747 n = readlinkat(fd, p, c, l-1);
754 if ((size_t) n < l-1) {
765 int readlink_malloc(const char *p, char **ret) {
766 return readlinkat_malloc(AT_FDCWD, p, ret);
769 /// UNNEEDED by elogind
771 int readlink_value(const char *p, char **ret) {
772 _cleanup_free_ char *link = NULL;
776 r = readlink_malloc(p, &link);
780 value = basename(link);
784 value = strdup(value);
794 int readlink_and_make_absolute(const char *p, char **r) {
795 _cleanup_free_ char *target = NULL;
802 j = readlink_malloc(p, &target);
806 k = file_in_same_dir(p, target);
814 /// UNNEEDED by elogind
816 int readlink_and_canonicalize(const char *p, char **r) {
823 j = readlink_and_make_absolute(p, &t);
827 s = canonicalize_file_name(t);
834 path_kill_slashes(*r);
840 char *strstrip(char *s) {
843 /* Drops trailing whitespace. Modifies the string in
844 * place. Returns pointer to first non-space character */
846 s += strspn(s, WHITESPACE);
848 for (e = strchr(s, 0); e > s; e --)
849 if (!strchr(WHITESPACE, e[-1]))
857 /// UNNEEDED by elogind
859 char *delete_chars(char *s, const char *bad) {
862 /* Drops all whitespace, regardless where in the string */
864 for (f = s, t = s; *f; f++) {
877 char *file_in_same_dir(const char *path, const char *filename) {
884 /* This removes the last component of path and appends
885 * filename, unless the latter is absolute anyway or the
888 if (path_is_absolute(filename))
889 return strdup(filename);
891 e = strrchr(path, '/');
893 return strdup(filename);
895 k = strlen(filename);
896 ret = new(char, (e + 1 - path) + k + 1);
900 memcpy(mempcpy(ret, path, e + 1 - path), filename, k + 1);
904 /// UNNEEDED by elogind
906 int rmdir_parents(const char *path, const char *stop) {
915 /* Skip trailing slashes */
916 while (l > 0 && path[l-1] == '/')
922 /* Skip last component */
923 while (l > 0 && path[l-1] != '/')
926 /* Skip trailing slashes */
927 while (l > 0 && path[l-1] == '/')
933 if (!(t = strndup(path, l)))
936 if (path_startswith(stop, t)) {
953 char hexchar(int x) {
954 static const char table[16] = "0123456789abcdef";
956 return table[x & 15];
959 int unhexchar(char c) {
961 if (c >= '0' && c <= '9')
964 if (c >= 'a' && c <= 'f')
967 if (c >= 'A' && c <= 'F')
973 char *hexmem(const void *p, size_t l) {
977 z = r = malloc(l * 2 + 1);
981 for (x = p; x < (const uint8_t*) p + l; x++) {
982 *(z++) = hexchar(*x >> 4);
983 *(z++) = hexchar(*x & 15);
990 int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
991 _cleanup_free_ uint8_t *r = NULL;
999 z = r = malloc((l + 1) / 2 + 1);
1003 for (x = p; x < p + l; x += 2) {
1006 a = unhexchar(x[0]);
1009 else if (x+1 < p + l) {
1010 b = unhexchar(x[1]);
1016 *(z++) = (uint8_t) a << 4 | (uint8_t) b;
1028 /* https://tools.ietf.org/html/rfc4648#section-6
1029 * Notice that base32hex differs from base32 in the alphabet it uses.
1030 * The distinction is that the base32hex representation preserves the
1031 * order of the underlying data when compared as bytestrings, this is
1032 * useful when representing NSEC3 hashes, as one can then verify the
1033 * order of hashes directly from their representation. */
1034 char base32hexchar(int x) {
1035 static const char table[32] = "0123456789"
1036 "ABCDEFGHIJKLMNOPQRSTUV";
1038 return table[x & 31];
1041 int unbase32hexchar(char c) {
1044 if (c >= '0' && c <= '9')
1047 offset = '9' - '0' + 1;
1049 if (c >= 'A' && c <= 'V')
1050 return c - 'A' + offset;
1055 char *base32hexmem(const void *p, size_t l, bool padding) {
1061 /* five input bytes makes eight output bytes, padding is added so we must round up */
1062 len = 8 * (l + 4) / 5;
1064 /* same, but round down as there is no padding */
1083 z = r = malloc(len + 1);
1087 for (x = p; x < (const uint8_t*) p + (l / 5) * 5; x += 5) {
1088 /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ
1089 x[3] == QQQQQQQQ; x[4] == WWWWWWWW */
1090 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1091 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1092 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1093 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
1094 *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */
1095 *(z++) = base32hexchar((x[3] & 127) >> 2); /* 000QQQQQ */
1096 *(z++) = base32hexchar((x[3] & 3) << 3 | x[4] >> 5); /* 000QQWWW */
1097 *(z++) = base32hexchar((x[4] & 31)); /* 000WWWWW */
1102 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1103 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1104 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1105 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
1106 *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */
1107 *(z++) = base32hexchar((x[3] & 127) >> 2); /* 000QQQQQ */
1108 *(z++) = base32hexchar((x[3] & 3) << 3); /* 000QQ000 */
1115 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1116 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1117 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1118 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
1119 *(z++) = base32hexchar((x[2] & 15) << 1); /* 000ZZZZ0 */
1129 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1130 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1131 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1132 *(z++) = base32hexchar((x[1] & 1) << 4); /* 000Y0000 */
1143 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1144 *(z++) = base32hexchar((x[0] & 7) << 2); /* 000XXX00 */
1161 int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_len) {
1162 _cleanup_free_ uint8_t *r = NULL;
1163 int a, b, c, d, e, f, g, h;
1171 /* padding ensures any base32hex input has input divisible by 8 */
1172 if (padding && l % 8 != 0)
1176 /* strip the padding */
1177 while (l > 0 && p[l - 1] == '=' && pad < 7) {
1183 /* a group of eight input bytes needs five output bytes, in case of
1184 padding we need to add some extra bytes */
1206 z = r = malloc(len + 1);
1210 for (x = p; x < p + (l / 8) * 8; x += 8) {
1211 /* a == 000XXXXX; b == 000YYYYY; c == 000ZZZZZ; d == 000WWWWW
1212 e == 000SSSSS; f == 000QQQQQ; g == 000VVVVV; h == 000RRRRR */
1213 a = unbase32hexchar(x[0]);
1217 b = unbase32hexchar(x[1]);
1221 c = unbase32hexchar(x[2]);
1225 d = unbase32hexchar(x[3]);
1229 e = unbase32hexchar(x[4]);
1233 f = unbase32hexchar(x[5]);
1237 g = unbase32hexchar(x[6]);
1241 h = unbase32hexchar(x[7]);
1245 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1246 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1247 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
1248 *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */
1249 *(z++) = (uint8_t) g << 5 | (uint8_t) h; /* VVVRRRRR */
1254 a = unbase32hexchar(x[0]);
1258 b = unbase32hexchar(x[1]);
1262 c = unbase32hexchar(x[2]);
1266 d = unbase32hexchar(x[3]);
1270 e = unbase32hexchar(x[4]);
1274 f = unbase32hexchar(x[5]);
1278 g = unbase32hexchar(x[6]);
1286 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1287 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1288 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
1289 *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */
1293 a = unbase32hexchar(x[0]);
1297 b = unbase32hexchar(x[1]);
1301 c = unbase32hexchar(x[2]);
1305 d = unbase32hexchar(x[3]);
1309 e = unbase32hexchar(x[4]);
1317 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1318 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1319 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
1323 a = unbase32hexchar(x[0]);
1327 b = unbase32hexchar(x[1]);
1331 c = unbase32hexchar(x[2]);
1335 d = unbase32hexchar(x[3]);
1343 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1344 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1348 a = unbase32hexchar(x[0]);
1352 b = unbase32hexchar(x[1]);
1360 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1378 /* https://tools.ietf.org/html/rfc4648#section-4 */
1379 char base64char(int x) {
1380 static const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1381 "abcdefghijklmnopqrstuvwxyz"
1383 return table[x & 63];
1386 int unbase64char(char c) {
1389 if (c >= 'A' && c <= 'Z')
1392 offset = 'Z' - 'A' + 1;
1394 if (c >= 'a' && c <= 'z')
1395 return c - 'a' + offset;
1397 offset += 'z' - 'a' + 1;
1399 if (c >= '0' && c <= '9')
1400 return c - '0' + offset;
1402 offset += '9' - '0' + 1;
1415 char *base64mem(const void *p, size_t l) {
1419 /* three input bytes makes four output bytes, padding is added so we must round up */
1420 z = r = malloc(4 * (l + 2) / 3 + 1);
1424 for (x = p; x < (const uint8_t*) p + (l / 3) * 3; x += 3) {
1425 /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ */
1426 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1427 *(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4); /* 00XXYYYY */
1428 *(z++) = base64char((x[1] & 15) << 2 | x[2] >> 6); /* 00YYYYZZ */
1429 *(z++) = base64char(x[2] & 63); /* 00ZZZZZZ */
1434 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1435 *(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4); /* 00XXYYYY */
1436 *(z++) = base64char((x[1] & 15) << 2); /* 00YYYY00 */
1441 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1442 *(z++) = base64char((x[0] & 3) << 4); /* 00XX0000 */
1453 int unbase64mem(const char *p, size_t l, void **mem, size_t *_len) {
1454 _cleanup_free_ uint8_t *r = NULL;
1462 /* padding ensures any base63 input has input divisible by 4 */
1466 /* strip the padding */
1467 if (l > 0 && p[l - 1] == '=')
1469 if (l > 0 && p[l - 1] == '=')
1472 /* a group of four input bytes needs three output bytes, in case of
1473 padding we need to add two or three extra bytes */
1474 len = (l / 4) * 3 + (l % 4 ? (l % 4) - 1 : 0);
1476 z = r = malloc(len + 1);
1480 for (x = p; x < p + (l / 4) * 4; x += 4) {
1481 /* a == 00XXXXXX; b == 00YYYYYY; c == 00ZZZZZZ; d == 00WWWWWW */
1482 a = unbase64char(x[0]);
1486 b = unbase64char(x[1]);
1490 c = unbase64char(x[2]);
1494 d = unbase64char(x[3]);
1498 *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
1499 *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
1500 *(z++) = (uint8_t) c << 6 | (uint8_t) d; /* ZZWWWWWW */
1505 a = unbase64char(x[0]);
1509 b = unbase64char(x[1]);
1513 c = unbase64char(x[2]);
1521 *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
1522 *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
1526 a = unbase64char(x[0]);
1530 b = unbase64char(x[1]);
1538 *(z++) = (uint8_t) a << 2 | (uint8_t) (b >> 4); /* XXXXXXYY */
1557 char octchar(int x) {
1558 return '0' + (x & 7);
1561 int unoctchar(char c) {
1563 if (c >= '0' && c <= '7')
1569 char decchar(int x) {
1570 return '0' + (x % 10);
1573 int undecchar(char c) {
1575 if (c >= '0' && c <= '9')
1581 char *cescape(const char *s) {
1587 /* Does C style string escaping. May be reversed with
1590 r = new(char, strlen(s)*4 + 1);
1594 for (f = s, t = r; *f; f++)
1595 t += cescape_char(*f, t);
1602 static int cunescape_one(const char *p, size_t length, char *ret, uint32_t *ret_unicode) {
1609 /* Unescapes C style. Returns the unescaped character in ret,
1610 * unless we encountered a \u sequence in which case the full
1611 * unicode character is returned in ret_unicode, instead. */
1613 if (length != (size_t) -1 && length < 1)
1650 /* This is an extension of the XDG syntax files */
1655 /* hexadecimal encoding */
1658 if (length != (size_t) -1 && length < 3)
1661 a = unhexchar(p[1]);
1665 b = unhexchar(p[2]);
1669 /* Don't allow NUL bytes */
1670 if (a == 0 && b == 0)
1673 *ret = (char) ((a << 4U) | b);
1679 /* C++11 style 16bit unicode */
1685 if (length != (size_t) -1 && length < 5)
1688 for (i = 0; i < 4; i++) {
1689 a[i] = unhexchar(p[1 + i]);
1694 c = ((uint32_t) a[0] << 12U) | ((uint32_t) a[1] << 8U) | ((uint32_t) a[2] << 4U) | (uint32_t) a[3];
1696 /* Don't allow 0 chars */
1715 /* C++11 style 32bit unicode */
1721 if (length != (size_t) -1 && length < 9)
1724 for (i = 0; i < 8; i++) {
1725 a[i] = unhexchar(p[1 + i]);
1730 c = ((uint32_t) a[0] << 28U) | ((uint32_t) a[1] << 24U) | ((uint32_t) a[2] << 20U) | ((uint32_t) a[3] << 16U) |
1731 ((uint32_t) a[4] << 12U) | ((uint32_t) a[5] << 8U) | ((uint32_t) a[6] << 4U) | (uint32_t) a[7];
1733 /* Don't allow 0 chars */
1737 /* Don't allow invalid code points */
1738 if (!unichar_is_valid(c))
1763 /* octal encoding */
1767 if (length != (size_t) -1 && length < 3)
1770 a = unoctchar(p[0]);
1774 b = unoctchar(p[1]);
1778 c = unoctchar(p[2]);
1782 /* don't allow NUL bytes */
1783 if (a == 0 && b == 0 && c == 0)
1786 /* Don't allow bytes above 255 */
1787 m = ((uint32_t) a << 6U) | ((uint32_t) b << 3U) | (uint32_t) c;
1803 int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret) {
1811 /* Undoes C style string escaping, and optionally prefixes it. */
1813 pl = prefix ? strlen(prefix) : 0;
1815 r = new(char, pl+length+1);
1820 memcpy(r, prefix, pl);
1822 for (f = s, t = r + pl; f < s + length; f++) {
1828 remaining = s + length - f;
1829 assert(remaining > 0);
1832 /* A literal literal, copy verbatim */
1837 if (remaining == 1) {
1838 if (flags & UNESCAPE_RELAX) {
1839 /* A trailing backslash, copy verbatim */
1848 k = cunescape_one(f + 1, remaining - 1, &c, &u);
1850 if (flags & UNESCAPE_RELAX) {
1851 /* Invalid escape code, let's take it literal then */
1861 /* Non-Unicode? Let's encode this directly */
1864 /* Unicode? Then let's encode this in UTF-8 */
1865 t += utf8_encode_unichar(t, u);
1876 int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret) {
1877 return cunescape_length_with_prefix(s, length, NULL, flags, ret);
1880 int cunescape(const char *s, UnescapeFlags flags, char **ret) {
1881 return cunescape_length(s, strlen(s), flags, ret);
1884 char *xescape(const char *s, const char *bad) {
1888 /* Escapes all chars in bad, in addition to \ and all special
1889 * chars, in \xFF style escaping. May be reversed with
1892 r = new(char, strlen(s) * 4 + 1);
1896 for (f = s, t = r; *f; f++) {
1898 if ((*f < ' ') || (*f >= 127) ||
1899 (*f == '\\') || strchr(bad, *f)) {
1902 *(t++) = hexchar(*f >> 4);
1903 *(t++) = hexchar(*f);
1913 /// UNNEEDED by elogind
1915 char *ascii_strlower(char *t) {
1920 for (p = t; *p; p++)
1921 if (*p >= 'A' && *p <= 'Z')
1922 *p = *p - 'A' + 'a';
1928 _pure_ static bool hidden_file_allow_backup(const char *filename) {
1932 filename[0] == '.' ||
1933 streq(filename, "lost+found") ||
1934 streq(filename, "aquota.user") ||
1935 streq(filename, "aquota.group") ||
1936 endswith(filename, ".rpmnew") ||
1937 endswith(filename, ".rpmsave") ||
1938 endswith(filename, ".rpmorig") ||
1939 endswith(filename, ".dpkg-old") ||
1940 endswith(filename, ".dpkg-new") ||
1941 endswith(filename, ".dpkg-tmp") ||
1942 endswith(filename, ".dpkg-dist") ||
1943 endswith(filename, ".dpkg-bak") ||
1944 endswith(filename, ".dpkg-backup") ||
1945 endswith(filename, ".dpkg-remove") ||
1946 endswith(filename, ".swp");
1949 bool hidden_file(const char *filename) {
1952 if (endswith(filename, "~"))
1955 return hidden_file_allow_backup(filename);
1958 int fd_nonblock(int fd, bool nonblock) {
1963 flags = fcntl(fd, F_GETFL, 0);
1968 nflags = flags | O_NONBLOCK;
1970 nflags = flags & ~O_NONBLOCK;
1972 if (nflags == flags)
1975 if (fcntl(fd, F_SETFL, nflags) < 0)
1981 int fd_cloexec(int fd, bool cloexec) {
1986 flags = fcntl(fd, F_GETFD, 0);
1991 nflags = flags | FD_CLOEXEC;
1993 nflags = flags & ~FD_CLOEXEC;
1995 if (nflags == flags)
1998 if (fcntl(fd, F_SETFD, nflags) < 0)
2004 _pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
2007 assert(n_fdset == 0 || fdset);
2009 for (i = 0; i < n_fdset; i++)
2016 int close_all_fds(const int except[], unsigned n_except) {
2017 _cleanup_closedir_ DIR *d = NULL;
2021 assert(n_except == 0 || except);
2023 d = opendir("/proc/self/fd");
2028 /* When /proc isn't available (for example in chroots)
2029 * the fallback is brute forcing through the fd
2032 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
2033 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
2035 if (fd_in_set(fd, except, n_except))
2038 if (close_nointr(fd) < 0)
2039 if (errno != EBADF && r == 0)
2046 while ((de = readdir(d))) {
2049 if (hidden_file(de->d_name))
2052 if (safe_atoi(de->d_name, &fd) < 0)
2053 /* Let's better ignore this, just in case */
2062 if (fd_in_set(fd, except, n_except))
2065 if (close_nointr(fd) < 0) {
2066 /* Valgrind has its own FD and doesn't want to have it closed */
2067 if (errno != EBADF && r == 0)
2075 bool chars_intersect(const char *a, const char *b) {
2078 /* Returns true if any of the chars in a are in b. */
2079 for (p = a; *p; p++)
2086 /// UNNEEDED by elogind
2088 bool fstype_is_network(const char *fstype) {
2089 static const char table[] =
2104 x = startswith(fstype, "fuse.");
2108 return nulstr_contains(table, fstype);
2112 int flush_fd(int fd) {
2113 struct pollfd pollfd = {
2123 r = poll(&pollfd, 1, 0);
2133 l = read(fd, buf, sizeof(buf));
2139 if (errno == EAGAIN)
2148 void safe_close_pair(int p[]) {
2152 /* Special case pairs which use the same fd in both
2154 p[0] = p[1] = safe_close(p[0]);
2158 p[0] = safe_close(p[0]);
2159 p[1] = safe_close(p[1]);
2162 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
2169 /* If called with nbytes == 0, let's call read() at least
2170 * once, to validate the operation */
2172 if (nbytes > (size_t) SSIZE_MAX)
2178 k = read(fd, p, nbytes);
2183 if (errno == EAGAIN && do_poll) {
2185 /* We knowingly ignore any return value here,
2186 * and expect that any error/EOF is reported
2189 (void) fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
2193 return n > 0 ? n : -errno;
2199 assert((size_t) k <= nbytes);
2204 } while (nbytes > 0);
2209 int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
2212 n = loop_read(fd, buf, nbytes, do_poll);
2215 if ((size_t) n != nbytes)
2221 int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
2222 const uint8_t *p = buf;
2227 if (nbytes > (size_t) SSIZE_MAX)
2233 k = write(fd, p, nbytes);
2238 if (errno == EAGAIN && do_poll) {
2239 /* We knowingly ignore any return value here,
2240 * and expect that any error/EOF is reported
2243 (void) fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
2250 if (_unlikely_(nbytes > 0 && k == 0)) /* Can't really happen */
2253 assert((size_t) k <= nbytes);
2257 } while (nbytes > 0);
2262 int parse_size(const char *t, uint64_t base, uint64_t *size) {
2264 /* Soo, sometimes we want to parse IEC binary suffixes, and
2265 * sometimes SI decimal suffixes. This function can parse
2266 * both. Which one is the right way depends on the
2267 * context. Wikipedia suggests that SI is customary for
2268 * hardware metrics and network speeds, while IEC is
2269 * customary for most data sizes used by software and volatile
2270 * (RAM) memory. Hence be careful which one you pick!
2272 * In either case we use just K, M, G as suffix, and not Ki,
2273 * Mi, Gi or so (as IEC would suggest). That's because that's
2274 * frickin' ugly. But this means you really need to make sure
2275 * to document which base you are parsing when you use this
2280 unsigned long long factor;
2283 static const struct table iec[] = {
2284 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2285 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2286 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
2287 { "G", 1024ULL*1024ULL*1024ULL },
2288 { "M", 1024ULL*1024ULL },
2294 static const struct table si[] = {
2295 { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
2296 { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
2297 { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
2298 { "G", 1000ULL*1000ULL*1000ULL },
2299 { "M", 1000ULL*1000ULL },
2305 const struct table *table;
2307 unsigned long long r = 0;
2308 unsigned n_entries, start_pos = 0;
2311 assert(base == 1000 || base == 1024);
2316 n_entries = ELEMENTSOF(si);
2319 n_entries = ELEMENTSOF(iec);
2324 unsigned long long l, tmp;
2329 p += strspn(p, WHITESPACE);
2334 l = strtoull(p, &e, 10);
2343 /* strtoull() itself would accept space/+/- */
2344 if (*e >= '0' && *e <= '9') {
2345 unsigned long long l2;
2348 l2 = strtoull(e, &e2, 10);
2352 /* Ignore failure. E.g. 10.M is valid */
2359 e += strspn(e, WHITESPACE);
2361 for (i = start_pos; i < n_entries; i++)
2362 if (startswith(e, table[i].suffix))
2368 if (l + (frac > 0) > ULLONG_MAX / table[i].factor)
2371 tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
2372 if (tmp > ULLONG_MAX - r)
2376 if ((unsigned long long) (uint64_t) r != r)
2379 p = e + strlen(table[i].suffix);
2390 bool is_device_path(const char *path) {
2392 /* Returns true on paths that refer to a device, either in
2393 * sysfs or in /dev */
2396 path_startswith(path, "/dev/") ||
2397 path_startswith(path, "/sys/");
2400 /// UNNEEDED by elogind
2402 int dir_is_empty(const char *path) {
2403 _cleanup_closedir_ DIR *d;
2414 if (!de && errno != 0)
2420 if (!hidden_file(de->d_name))
2425 char* dirname_malloc(const char *path) {
2426 char *d, *dir, *dir2;
2443 void rename_process(const char name[8]) {
2446 /* This is a like a poor man's setproctitle(). It changes the
2447 * comm field, argv[0], and also the glibc's internally used
2448 * name of the process. For the first one a limit of 16 chars
2449 * applies, to the second one usually one of 10 (i.e. length
2450 * of "/sbin/init"), to the third one one of 7 (i.e. length of
2451 * "systemd"). If you pass a longer string it will be
2454 prctl(PR_SET_NAME, name);
2456 if (program_invocation_name)
2457 strncpy(program_invocation_name, name, strlen(program_invocation_name));
2459 if (saved_argc > 0) {
2463 strncpy(saved_argv[0], name, strlen(saved_argv[0]));
2465 for (i = 1; i < saved_argc; i++) {
2469 memzero(saved_argv[i], strlen(saved_argv[i]));
2475 char *lookup_uid(uid_t uid) {
2478 _cleanup_free_ char *buf = NULL;
2479 struct passwd pwbuf, *pw = NULL;
2481 /* Shortcut things to avoid NSS lookups */
2483 return strdup("root");
2485 bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
2489 buf = malloc(bufsize);
2493 if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
2494 return strdup(pw->pw_name);
2496 if (asprintf(&name, UID_FMT, uid) < 0)
2502 /// UNNEEDED by elogind
2504 char* getlogname_malloc(void) {
2508 if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
2513 return lookup_uid(uid);
2516 char *getusername_malloc(void) {
2523 return lookup_uid(getuid());
2527 bool is_temporary_fs(const struct statfs *s) {
2530 return F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) ||
2531 F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC);
2534 int fd_is_temporary_fs(int fd) {
2537 if (fstatfs(fd, &s) < 0)
2540 return is_temporary_fs(&s);
2543 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
2546 /* Under the assumption that we are running privileged we
2547 * first change the access mode and only then hand out
2548 * ownership to avoid a window where access is too open. */
2550 if (mode != MODE_INVALID)
2551 if (chmod(path, mode) < 0)
2554 if (uid != UID_INVALID || gid != GID_INVALID)
2555 if (chown(path, uid, gid) < 0)
2561 /// UNNEEDED by elogind
2563 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
2566 /* Under the assumption that we are running privileged we
2567 * first change the access mode and only then hand out
2568 * ownership to avoid a window where access is too open. */
2570 if (mode != MODE_INVALID)
2571 if (fchmod(fd, mode) < 0)
2574 if (uid != UID_INVALID || gid != GID_INVALID)
2575 if (fchown(fd, uid, gid) < 0)
2583 int files_same(const char *filea, const char *fileb) {
2586 if (stat(filea, &a) < 0)
2589 if (stat(fileb, &b) < 0)
2592 return a.st_dev == b.st_dev &&
2593 a.st_ino == b.st_ino;
2596 int running_in_chroot(void) {
2599 ret = files_same("/proc/1/root", "/");
2606 static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
2611 assert(percent <= 100);
2612 assert(new_length >= 3);
2614 if (old_length <= 3 || old_length <= new_length)
2615 return strndup(s, old_length);
2617 r = new0(char, new_length+1);
2621 x = (new_length * percent) / 100;
2623 if (x > new_length - 3)
2631 s + old_length - (new_length - x - 3),
2632 new_length - x - 3);
2637 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
2641 unsigned k, len, len2;
2644 assert(percent <= 100);
2645 assert(new_length >= 3);
2647 /* if no multibyte characters use ascii_ellipsize_mem for speed */
2648 if (ascii_is_valid(s))
2649 return ascii_ellipsize_mem(s, old_length, new_length, percent);
2651 if (old_length <= 3 || old_length <= new_length)
2652 return strndup(s, old_length);
2654 x = (new_length * percent) / 100;
2656 if (x > new_length - 3)
2660 for (i = s; k < x && i < s + old_length; i = utf8_next_char(i)) {
2663 c = utf8_encoded_to_unichar(i);
2666 k += unichar_iswide(c) ? 2 : 1;
2669 if (k > x) /* last character was wide and went over quota */
2672 for (j = s + old_length; k < new_length && j > i; ) {
2675 j = utf8_prev_char(j);
2676 c = utf8_encoded_to_unichar(j);
2679 k += unichar_iswide(c) ? 2 : 1;
2683 /* we don't actually need to ellipsize */
2685 return memdup(s, old_length + 1);
2687 /* make space for ellipsis */
2688 j = utf8_next_char(j);
2691 len2 = s + old_length - j;
2692 e = new(char, len + 3 + len2 + 1);
2697 printf("old_length=%zu new_length=%zu x=%zu len=%u len2=%u k=%u\n",
2698 old_length, new_length, x, len, len2, k);
2702 e[len] = 0xe2; /* tri-dot ellipsis: … */
2706 memcpy(e + len + 3, j, len2 + 1);
2711 char *ellipsize(const char *s, size_t length, unsigned percent) {
2712 return ellipsize_mem(s, strlen(s), length, percent);
2715 int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
2716 _cleanup_close_ int fd;
2722 mkdir_parents(path, 0755);
2724 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode > 0 ? mode : 0644);
2729 r = fchmod(fd, mode);
2734 if (uid != UID_INVALID || gid != GID_INVALID) {
2735 r = fchown(fd, uid, gid);
2740 if (stamp != USEC_INFINITY) {
2741 struct timespec ts[2];
2743 timespec_store(&ts[0], stamp);
2745 r = futimens(fd, ts);
2747 r = futimens(fd, NULL);
2754 int touch(const char *path) {
2755 return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, 0);
2758 /// UNNEEDED by elogind
2760 static char *unquote(const char *s, const char* quotes) {
2764 /* This is rather stupid, simply removes the heading and
2765 * trailing quotes if there is one. Doesn't care about
2766 * escaping or anything.
2768 * DON'T USE THIS FOR NEW CODE ANYMORE!*/
2774 if (strchr(quotes, s[0]) && s[l-1] == s[0])
2775 return strndup(s+1, l-2);
2781 noreturn void freeze(void) {
2783 /* Make sure nobody waits for us on a socket anymore */
2784 close_all_fds(NULL, 0);
2792 bool null_or_empty(struct stat *st) {
2795 if (S_ISREG(st->st_mode) && st->st_size <= 0)
2798 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
2804 int null_or_empty_path(const char *fn) {
2809 if (stat(fn, &st) < 0)
2812 return null_or_empty(&st);
2815 /// UNNEEDED by elogind
2817 int null_or_empty_fd(int fd) {
2822 if (fstat(fd, &st) < 0)
2825 return null_or_empty(&st);
2829 DIR *xopendirat(int fd, const char *name, int flags) {
2833 assert(!(flags & O_CREAT));
2835 nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
2848 /// UNNEEDED by elogind
2850 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
2851 _cleanup_free_ char *t = NULL, *u = NULL;
2854 u = unquote(tagvalue, QUOTES);
2858 enc_len = strlen(u) * 4 + 1;
2859 t = new(char, enc_len);
2863 if (encode_devnode_name(u, t, enc_len) < 0)
2866 return strjoin("/dev/disk/by-", by, "/", t, NULL);
2869 char *fstab_node_to_udev_node(const char *p) {
2872 if (startswith(p, "LABEL="))
2873 return tag_to_udev_node(p+6, "label");
2875 if (startswith(p, "UUID="))
2876 return tag_to_udev_node(p+5, "uuid");
2878 if (startswith(p, "PARTUUID="))
2879 return tag_to_udev_node(p+9, "partuuid");
2881 if (startswith(p, "PARTLABEL="))
2882 return tag_to_udev_node(p+10, "partlabel");
2888 bool dirent_is_file(const struct dirent *de) {
2891 if (hidden_file(de->d_name))
2894 if (de->d_type != DT_REG &&
2895 de->d_type != DT_LNK &&
2896 de->d_type != DT_UNKNOWN)
2902 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
2905 if (de->d_type != DT_REG &&
2906 de->d_type != DT_LNK &&
2907 de->d_type != DT_UNKNOWN)
2910 if (hidden_file_allow_backup(de->d_name))
2913 return endswith(de->d_name, suffix);
2916 static int do_execute(char **directories, usec_t timeout, char *argv[]) {
2917 _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
2918 _cleanup_set_free_free_ Set *seen = NULL;
2921 /* We fork this all off from a child process so that we can
2922 * somewhat cleanly make use of SIGALRM to set a time limit */
2924 (void) reset_all_signal_handlers();
2925 (void) reset_signal_mask();
2927 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
2929 pids = hashmap_new(NULL);
2933 seen = set_new(&string_hash_ops);
2937 STRV_FOREACH(directory, directories) {
2938 _cleanup_closedir_ DIR *d;
2941 d = opendir(*directory);
2943 if (errno == ENOENT)
2946 return log_error_errno(errno, "Failed to open directory %s: %m", *directory);
2949 FOREACH_DIRENT(de, d, break) {
2950 _cleanup_free_ char *path = NULL;
2954 if (!dirent_is_file(de))
2957 if (set_contains(seen, de->d_name)) {
2958 log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name);
2962 r = set_put_strdup(seen, de->d_name);
2966 path = strjoin(*directory, "/", de->d_name, NULL);
2970 if (null_or_empty_path(path)) {
2971 log_debug("%s is empty (a mask).", path);
2977 log_error_errno(errno, "Failed to fork: %m");
2979 } else if (pid == 0) {
2982 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
2992 return log_error_errno(errno, "Failed to execute %s: %m", path);
2995 log_debug("Spawned %s as " PID_FMT ".", path, pid);
2997 r = hashmap_put(pids, UINT_TO_PTR(pid), path);
3004 /* Abort execution of this process after the timout. We simply
3005 * rely on SIGALRM as default action terminating the process,
3006 * and turn on alarm(). */
3008 if (timeout != USEC_INFINITY)
3009 alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
3011 while (!hashmap_isempty(pids)) {
3012 _cleanup_free_ char *path = NULL;
3015 pid = PTR_TO_UINT(hashmap_first_key(pids));
3018 path = hashmap_remove(pids, UINT_TO_PTR(pid));
3021 wait_for_terminate_and_warn(path, pid, true);
3027 void execute_directories(const char* const* directories, usec_t timeout, char *argv[]) {
3031 char **dirs = (char**) directories;
3033 assert(!strv_isempty(dirs));
3035 name = basename(dirs[0]);
3036 assert(!isempty(name));
3038 /* Executes all binaries in the directories in parallel and waits
3039 * for them to finish. Optionally a timeout is applied. If a file
3040 * with the same name exists in more than one directory, the
3041 * earliest one wins. */
3043 executor_pid = fork();
3044 if (executor_pid < 0) {
3045 log_error_errno(errno, "Failed to fork: %m");
3048 } else if (executor_pid == 0) {
3049 r = do_execute(dirs, timeout, argv);
3050 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
3053 wait_for_terminate_and_warn(name, executor_pid, true);
3056 bool nulstr_contains(const char*nulstr, const char *needle) {
3062 NULSTR_FOREACH(i, nulstr)
3063 if (streq(i, needle))
3069 /// UNNEEDED by elogind
3071 bool plymouth_running(void) {
3072 return access("/run/plymouth/pid", F_OK) >= 0;
3076 char* strshorten(char *s, size_t l) {
3085 int pipe_eof(int fd) {
3086 struct pollfd pollfd = {
3088 .events = POLLIN|POLLHUP,
3093 r = poll(&pollfd, 1, 0);
3100 return pollfd.revents & POLLHUP;
3103 int fd_wait_for_event(int fd, int event, usec_t t) {
3105 struct pollfd pollfd = {
3113 r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
3120 return pollfd.revents;
3123 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
3132 r = tempfn_xxxxxx(path, NULL, &t);
3136 fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC);
3142 f = fdopen(fd, "we");
3156 /// UNNEEDED by elogind
3158 int symlink_atomic(const char *from, const char *to) {
3159 _cleanup_free_ char *t = NULL;
3165 r = tempfn_random(to, NULL, &t);
3169 if (symlink(from, t) < 0)
3172 if (rename(t, to) < 0) {
3180 int symlink_idempotent(const char *from, const char *to) {
3181 _cleanup_free_ char *p = NULL;
3187 if (symlink(from, to) < 0) {
3188 if (errno != EEXIST)
3191 r = readlink_malloc(to, &p);
3195 if (!streq(p, from))
3202 int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
3203 _cleanup_free_ char *t = NULL;
3208 r = tempfn_random(path, NULL, &t);
3212 if (mknod(t, mode, dev) < 0)
3215 if (rename(t, path) < 0) {
3223 int mkfifo_atomic(const char *path, mode_t mode) {
3224 _cleanup_free_ char *t = NULL;
3229 r = tempfn_random(path, NULL, &t);
3233 if (mkfifo(t, mode) < 0)
3236 if (rename(t, path) < 0) {
3245 bool display_is_local(const char *display) {
3249 display[0] == ':' &&
3250 display[1] >= '0' &&
3254 int socket_from_display(const char *display, char **path) {
3261 if (!display_is_local(display))
3264 k = strspn(display+1, "0123456789");
3266 f = new(char, strlen("/tmp/.X11-unix/X") + k + 1);
3270 c = stpcpy(f, "/tmp/.X11-unix/X");
3271 memcpy(c, display+1, k);
3280 const char **username,
3281 uid_t *uid, gid_t *gid,
3283 const char **shell) {
3291 /* We enforce some special rules for uid=0: in order to avoid
3292 * NSS lookups for root we hardcode its data. */
3294 if (streq(*username, "root") || streq(*username, "0")) {
3312 if (parse_uid(*username, &u) >= 0) {
3316 /* If there are multiple users with the same id, make
3317 * sure to leave $USER to the configured value instead
3318 * of the first occurrence in the database. However if
3319 * the uid was configured by a numeric uid, then let's
3320 * pick the real username from /etc/passwd. */
3322 *username = p->pw_name;
3325 p = getpwnam(*username);
3329 return errno > 0 ? -errno : -ESRCH;
3341 *shell = p->pw_shell;
3346 char* uid_to_name(uid_t uid) {
3351 return strdup("root");
3355 return strdup(p->pw_name);
3357 if (asprintf(&r, UID_FMT, uid) < 0)
3363 char* gid_to_name(gid_t gid) {
3368 return strdup("root");
3372 return strdup(p->gr_name);
3374 if (asprintf(&r, GID_FMT, gid) < 0)
3380 int get_group_creds(const char **groupname, gid_t *gid) {
3386 /* We enforce some special rules for gid=0: in order to avoid
3387 * NSS lookups for root we hardcode its data. */
3389 if (streq(*groupname, "root") || streq(*groupname, "0")) {
3390 *groupname = "root";
3398 if (parse_gid(*groupname, &id) >= 0) {
3403 *groupname = g->gr_name;
3406 g = getgrnam(*groupname);
3410 return errno > 0 ? -errno : -ESRCH;
3418 int in_gid(gid_t gid) {
3420 int ngroups_max, r, i;
3422 if (getgid() == gid)
3425 if (getegid() == gid)
3428 ngroups_max = sysconf(_SC_NGROUPS_MAX);
3429 assert(ngroups_max > 0);
3431 gids = alloca(sizeof(gid_t) * ngroups_max);
3433 r = getgroups(ngroups_max, gids);
3437 for (i = 0; i < r; i++)
3444 /// UNNEEDED by elogind
3446 int in_group(const char *name) {
3450 r = get_group_creds(&name, &gid);
3457 int glob_exists(const char *path) {
3458 _cleanup_globfree_ glob_t g = {};
3464 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
3466 if (k == GLOB_NOMATCH)
3468 else if (k == GLOB_NOSPACE)
3471 return !strv_isempty(g.gl_pathv);
3473 return errno ? -errno : -EIO;
3476 int glob_extend(char ***strv, const char *path) {
3477 _cleanup_globfree_ glob_t g = {};
3482 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
3484 if (k == GLOB_NOMATCH)
3486 else if (k == GLOB_NOSPACE)
3488 else if (k != 0 || strv_isempty(g.gl_pathv))
3489 return errno ? -errno : -EIO;
3491 STRV_FOREACH(p, g.gl_pathv) {
3492 k = strv_extend(strv, *p);
3501 int dirent_ensure_type(DIR *d, struct dirent *de) {
3507 if (de->d_type != DT_UNKNOWN)
3510 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
3514 S_ISREG(st.st_mode) ? DT_REG :
3515 S_ISDIR(st.st_mode) ? DT_DIR :
3516 S_ISLNK(st.st_mode) ? DT_LNK :
3517 S_ISFIFO(st.st_mode) ? DT_FIFO :
3518 S_ISSOCK(st.st_mode) ? DT_SOCK :
3519 S_ISCHR(st.st_mode) ? DT_CHR :
3520 S_ISBLK(st.st_mode) ? DT_BLK :
3526 int get_files_in_directory(const char *path, char ***list) {
3527 _cleanup_closedir_ DIR *d = NULL;
3528 size_t bufsize = 0, n = 0;
3529 _cleanup_strv_free_ char **l = NULL;
3533 /* Returns all files in a directory in *list, and the number
3534 * of files as return value. If list is NULL returns only the
3546 if (!de && errno != 0)
3551 dirent_ensure_type(d, de);
3553 if (!dirent_is_file(de))
3557 /* one extra slot is needed for the terminating NULL */
3558 if (!GREEDY_REALLOC(l, bufsize, n + 2))
3561 l[n] = strdup(de->d_name);
3572 l = NULL; /* avoid freeing */
3578 char *strjoin(const char *x, ...) {
3592 t = va_arg(ap, const char *);
3597 if (n > ((size_t) -1) - l) {
3621 t = va_arg(ap, const char *);
3635 bool is_main_thread(void) {
3636 static thread_local int cached = 0;
3638 if (_unlikely_(cached == 0))
3639 cached = getpid() == gettid() ? 1 : -1;
3644 /// UNNEEDED by elogind
3646 int block_get_whole_disk(dev_t d, dev_t *ret) {
3653 /* If it has a queue this is good enough for us */
3654 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
3657 r = access(p, F_OK);
3665 /* If it is a partition find the originating device */
3666 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
3669 r = access(p, F_OK);
3675 /* Get parent dev_t */
3676 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
3679 r = read_one_line_file(p, &s);
3685 r = sscanf(s, "%u:%u", &m, &n);
3691 /* Only return this if it is really good enough for us. */
3692 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
3695 r = access(p, F_OK);
3699 *ret = makedev(m, n);
3706 static const char *const ioprio_class_table[] = {
3707 [IOPRIO_CLASS_NONE] = "none",
3708 [IOPRIO_CLASS_RT] = "realtime",
3709 [IOPRIO_CLASS_BE] = "best-effort",
3710 [IOPRIO_CLASS_IDLE] = "idle"
3713 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
3715 static const char *const sigchld_code_table[] = {
3716 [CLD_EXITED] = "exited",
3717 [CLD_KILLED] = "killed",
3718 [CLD_DUMPED] = "dumped",
3719 [CLD_TRAPPED] = "trapped",
3720 [CLD_STOPPED] = "stopped",
3721 [CLD_CONTINUED] = "continued",
3724 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
3726 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
3727 [LOG_FAC(LOG_KERN)] = "kern",
3728 [LOG_FAC(LOG_USER)] = "user",
3729 [LOG_FAC(LOG_MAIL)] = "mail",
3730 [LOG_FAC(LOG_DAEMON)] = "daemon",
3731 [LOG_FAC(LOG_AUTH)] = "auth",
3732 [LOG_FAC(LOG_SYSLOG)] = "syslog",
3733 [LOG_FAC(LOG_LPR)] = "lpr",
3734 [LOG_FAC(LOG_NEWS)] = "news",
3735 [LOG_FAC(LOG_UUCP)] = "uucp",
3736 [LOG_FAC(LOG_CRON)] = "cron",
3737 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
3738 [LOG_FAC(LOG_FTP)] = "ftp",
3739 [LOG_FAC(LOG_LOCAL0)] = "local0",
3740 [LOG_FAC(LOG_LOCAL1)] = "local1",
3741 [LOG_FAC(LOG_LOCAL2)] = "local2",
3742 [LOG_FAC(LOG_LOCAL3)] = "local3",
3743 [LOG_FAC(LOG_LOCAL4)] = "local4",
3744 [LOG_FAC(LOG_LOCAL5)] = "local5",
3745 [LOG_FAC(LOG_LOCAL6)] = "local6",
3746 [LOG_FAC(LOG_LOCAL7)] = "local7"
3749 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
3752 static const char *const log_level_table[] = {
3753 [LOG_EMERG] = "emerg",
3754 [LOG_ALERT] = "alert",
3755 [LOG_CRIT] = "crit",
3757 [LOG_WARNING] = "warning",
3758 [LOG_NOTICE] = "notice",
3759 [LOG_INFO] = "info",
3760 [LOG_DEBUG] = "debug"
3763 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
3765 /// UNNEEDED by elogind
3767 static const char* const sched_policy_table[] = {
3768 [SCHED_OTHER] = "other",
3769 [SCHED_BATCH] = "batch",
3770 [SCHED_IDLE] = "idle",
3771 [SCHED_FIFO] = "fifo",
3775 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
3778 static const char* const rlimit_table[_RLIMIT_MAX] = {
3779 [RLIMIT_CPU] = "LimitCPU",
3780 [RLIMIT_FSIZE] = "LimitFSIZE",
3781 [RLIMIT_DATA] = "LimitDATA",
3782 [RLIMIT_STACK] = "LimitSTACK",
3783 [RLIMIT_CORE] = "LimitCORE",
3784 [RLIMIT_RSS] = "LimitRSS",
3785 [RLIMIT_NOFILE] = "LimitNOFILE",
3786 [RLIMIT_AS] = "LimitAS",
3787 [RLIMIT_NPROC] = "LimitNPROC",
3788 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
3789 [RLIMIT_LOCKS] = "LimitLOCKS",
3790 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
3791 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
3792 [RLIMIT_NICE] = "LimitNICE",
3793 [RLIMIT_RTPRIO] = "LimitRTPRIO",
3794 [RLIMIT_RTTIME] = "LimitRTTIME"
3797 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
3799 /// UNNEEDED by elogind
3801 static const char* const ip_tos_table[] = {
3802 [IPTOS_LOWDELAY] = "low-delay",
3803 [IPTOS_THROUGHPUT] = "throughput",
3804 [IPTOS_RELIABILITY] = "reliability",
3805 [IPTOS_LOWCOST] = "low-cost",
3808 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
3810 bool kexec_loaded(void) {
3811 bool loaded = false;
3814 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
3822 int prot_from_flags(int flags) {
3824 switch (flags & O_ACCMODE) {
3833 return PROT_READ|PROT_WRITE;
3840 char *format_bytes(char *buf, size_t l, uint64_t t) {
3843 static const struct {
3847 { "E", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
3848 { "P", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
3849 { "T", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
3850 { "G", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
3851 { "M", UINT64_C(1024)*UINT64_C(1024) },
3852 { "K", UINT64_C(1024) },
3855 if (t == (uint64_t) -1)
3858 for (i = 0; i < ELEMENTSOF(table); i++) {
3860 if (t >= table[i].factor) {
3862 "%" PRIu64 ".%" PRIu64 "%s",
3863 t / table[i].factor,
3864 ((t*UINT64_C(10)) / table[i].factor) % UINT64_C(10),
3871 snprintf(buf, l, "%" PRIu64 "B", t);
3880 void* memdup(const void *p, size_t l) {
3893 int fd_inc_sndbuf(int fd, size_t n) {
3895 socklen_t l = sizeof(value);
3897 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
3898 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
3901 /* If we have the privileges we will ignore the kernel limit. */
3904 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
3905 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
3911 int fd_inc_rcvbuf(int fd, size_t n) {
3913 socklen_t l = sizeof(value);
3915 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
3916 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
3919 /* If we have the privileges we will ignore the kernel limit. */
3922 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
3923 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
3928 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
3929 bool stdout_is_tty, stderr_is_tty;
3930 pid_t parent_pid, agent_pid;
3931 sigset_t ss, saved_ss;
3939 /* Spawns a temporary TTY agent, making sure it goes away when
3942 parent_pid = getpid();
3944 /* First we temporarily block all signals, so that the new
3945 * child has them blocked initially. This way, we can be sure
3946 * that SIGTERMs are not lost we might send to the agent. */
3947 assert_se(sigfillset(&ss) >= 0);
3948 assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0);
3951 if (agent_pid < 0) {
3952 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
3956 if (agent_pid != 0) {
3957 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
3964 * Make sure the agent goes away when the parent dies */
3965 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
3966 _exit(EXIT_FAILURE);
3968 /* Make sure we actually can kill the agent, if we need to, in
3969 * case somebody invoked us from a shell script that trapped
3970 * SIGTERM or so... */
3971 (void) reset_all_signal_handlers();
3972 (void) reset_signal_mask();
3974 /* Check whether our parent died before we were able
3975 * to set the death signal and unblock the signals */
3976 if (getppid() != parent_pid)
3977 _exit(EXIT_SUCCESS);
3979 /* Don't leak fds to the agent */
3980 close_all_fds(except, n_except);
3982 stdout_is_tty = isatty(STDOUT_FILENO);
3983 stderr_is_tty = isatty(STDERR_FILENO);
3985 if (!stdout_is_tty || !stderr_is_tty) {
3988 /* Detach from stdout/stderr. and reopen
3989 * /dev/tty for them. This is important to
3990 * ensure that when systemctl is started via
3991 * popen() or a similar call that expects to
3992 * read EOF we actually do generate EOF and
3993 * not delay this indefinitely by because we
3994 * keep an unused copy of stdin around. */
3995 fd = open("/dev/tty", O_WRONLY);
3997 log_error_errno(errno, "Failed to open /dev/tty: %m");
3998 _exit(EXIT_FAILURE);
4002 dup2(fd, STDOUT_FILENO);
4005 dup2(fd, STDERR_FILENO);
4011 /* Count arguments */
4013 for (n = 0; va_arg(ap, char*); n++)
4018 l = alloca(sizeof(char *) * (n + 1));
4020 /* Fill in arguments */
4022 for (i = 0; i <= n; i++)
4023 l[i] = va_arg(ap, char*);
4027 _exit(EXIT_FAILURE);
4030 /// UNNEEDED by elogind
4032 int setrlimit_closest(int resource, const struct rlimit *rlim) {
4033 struct rlimit highest, fixed;
4037 if (setrlimit(resource, rlim) >= 0)
4043 /* So we failed to set the desired setrlimit, then let's try
4044 * to get as close as we can */
4045 assert_se(getrlimit(resource, &highest) == 0);
4047 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
4048 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
4050 if (setrlimit(resource, &fixed) < 0)
4056 bool http_etag_is_valid(const char *etag) {
4060 if (!endswith(etag, "\""))
4063 if (!startswith(etag, "\"") && !startswith(etag, "W/\""))
4070 bool http_url_is_valid(const char *url) {
4076 p = startswith(url, "http://");
4078 p = startswith(url, "https://");
4085 return ascii_is_valid(p);
4088 bool documentation_url_is_valid(const char *url) {
4094 if (http_url_is_valid(url))
4097 p = startswith(url, "file:/");
4099 p = startswith(url, "info:");
4101 p = startswith(url, "man:");
4106 return ascii_is_valid(p);
4109 bool in_initrd(void) {
4110 static int saved = -1;
4116 /* We make two checks here:
4118 * 1. the flag file /etc/initrd-release must exist
4119 * 2. the root file system must be a memory file system
4121 * The second check is extra paranoia, since misdetecting an
4122 * initrd can have bad bad consequences due the initrd
4123 * emptying when transititioning to the main systemd.
4126 saved = access("/etc/initrd-release", F_OK) >= 0 &&
4127 statfs("/", &s) >= 0 &&
4128 is_temporary_fs(&s);
4133 int get_home_dir(char **_h) {
4141 /* Take the user specified one */
4142 e = secure_getenv("HOME");
4143 if (e && path_is_absolute(e)) {
4152 /* Hardcode home directory for root to avoid NSS */
4155 h = strdup("/root");
4163 /* Check the database... */
4167 return errno > 0 ? -errno : -ESRCH;
4169 if (!path_is_absolute(p->pw_dir))
4172 h = strdup(p->pw_dir);
4180 /// UNNEEDED by elogind
4182 int get_shell(char **_s) {
4190 /* Take the user specified one */
4191 e = getenv("SHELL");
4201 /* Hardcode home directory for root to avoid NSS */
4204 s = strdup("/bin/sh");
4212 /* Check the database... */
4216 return errno > 0 ? -errno : -ESRCH;
4218 if (!path_is_absolute(p->pw_shell))
4221 s = strdup(p->pw_shell);
4230 bool filename_is_valid(const char *p) {
4244 if (strlen(p) > FILENAME_MAX)
4250 bool string_is_safe(const char *p) {
4256 for (t = p; *t; t++) {
4257 if (*t > 0 && *t < ' ')
4260 if (strchr("\\\"\'\x7f", *t))
4268 * Check if a string contains control characters. If 'ok' is non-NULL
4269 * it may be a string containing additional CCs to be considered OK.
4271 bool string_has_cc(const char *p, const char *ok) {
4276 for (t = p; *t; t++) {
4277 if (ok && strchr(ok, *t))
4280 if (*t > 0 && *t < ' ')
4290 bool path_is_safe(const char *p) {
4295 if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
4298 if (strlen(p)+1 > PATH_MAX)
4301 /* The following two checks are not really dangerous, but hey, they still are confusing */
4302 if (streq(p, ".") || startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
4305 if (strstr(p, "//"))
4311 /// UNNEEDED by elogind
4313 /* hey glibc, APIs with callbacks without a user pointer are so useless */
4314 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
4315 int (*compar) (const void *, const void *, void *), void *arg) {
4324 p = (void *)(((const char *) base) + (idx * size));
4325 comparison = compar(key, p, arg);
4328 else if (comparison > 0)
4336 void init_gettext(void) {
4337 setlocale(LC_ALL, "");
4338 textdomain(GETTEXT_PACKAGE);
4342 bool is_locale_utf8(void) {
4344 static int cached_answer = -1;
4346 if (cached_answer >= 0)
4349 if (!setlocale(LC_ALL, "")) {
4350 cached_answer = true;
4354 set = nl_langinfo(CODESET);
4356 cached_answer = true;
4360 if (streq(set, "UTF-8")) {
4361 cached_answer = true;
4365 /* For LC_CTYPE=="C" return true, because CTYPE is effectly
4366 * unset and everything can do to UTF-8 nowadays. */
4367 set = setlocale(LC_CTYPE, NULL);
4369 cached_answer = true;
4373 /* Check result, but ignore the result if C was set
4376 STR_IN_SET(set, "C", "POSIX") &&
4377 !getenv("LC_ALL") &&
4378 !getenv("LC_CTYPE") &&
4382 return (bool) cached_answer;
4385 const char *draw_special_char(DrawSpecialChar ch) {
4386 static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
4389 [DRAW_TREE_VERTICAL] = "\342\224\202 ", /* │ */
4390 [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */
4391 [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */
4392 [DRAW_TREE_SPACE] = " ", /* */
4393 [DRAW_TRIANGULAR_BULLET] = "\342\200\243", /* ‣ */
4394 [DRAW_BLACK_CIRCLE] = "\342\227\217", /* ● */
4395 [DRAW_ARROW] = "\342\206\222", /* → */
4396 [DRAW_DASH] = "\342\200\223", /* – */
4399 /* ASCII fallback */ {
4400 [DRAW_TREE_VERTICAL] = "| ",
4401 [DRAW_TREE_BRANCH] = "|-",
4402 [DRAW_TREE_RIGHT] = "`-",
4403 [DRAW_TREE_SPACE] = " ",
4404 [DRAW_TRIANGULAR_BULLET] = ">",
4405 [DRAW_BLACK_CIRCLE] = "*",
4406 [DRAW_ARROW] = "->",
4411 return draw_table[!is_locale_utf8()][ch];
4414 /// UNNEEDED by elogind
4416 char *strreplace(const char *text, const char *old_string, const char *new_string) {
4419 size_t l, old_len, new_len;
4425 old_len = strlen(old_string);
4426 new_len = strlen(new_string);
4439 if (!startswith(f, old_string)) {
4445 nl = l - old_len + new_len;
4446 a = realloc(r, nl + 1);
4454 t = stpcpy(t, new_string);
4466 char *strip_tab_ansi(char **ibuf, size_t *_isz) {
4467 const char *i, *begin = NULL;
4472 } state = STATE_OTHER;
4474 size_t osz = 0, isz;
4480 /* Strips ANSI color and replaces TABs by 8 spaces */
4482 isz = _isz ? *_isz : strlen(*ibuf);
4484 f = open_memstream(&obuf, &osz);
4488 for (i = *ibuf; i < *ibuf + isz + 1; i++) {
4493 if (i >= *ibuf + isz) /* EOT */
4495 else if (*i == '\x1B')
4496 state = STATE_ESCAPE;
4497 else if (*i == '\t')
4504 if (i >= *ibuf + isz) { /* EOT */
4507 } else if (*i == '[') {
4508 state = STATE_BRACKET;
4513 state = STATE_OTHER;
4520 if (i >= *ibuf + isz || /* EOT */
4521 (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
4524 state = STATE_OTHER;
4526 } else if (*i == 'm')
4527 state = STATE_OTHER;
4549 int on_ac_power(void) {
4550 bool found_offline = false, found_online = false;
4551 _cleanup_closedir_ DIR *d = NULL;
4553 d = opendir("/sys/class/power_supply");
4555 return errno == ENOENT ? true : -errno;
4559 _cleanup_close_ int fd = -1, device = -1;
4565 if (!de && errno != 0)
4571 if (hidden_file(de->d_name))
4574 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
4576 if (errno == ENOENT || errno == ENOTDIR)
4582 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
4584 if (errno == ENOENT)
4590 n = read(fd, contents, sizeof(contents));
4594 if (n != 6 || memcmp(contents, "Mains\n", 6))
4598 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
4600 if (errno == ENOENT)
4606 n = read(fd, contents, sizeof(contents));
4610 if (n != 2 || contents[1] != '\n')
4613 if (contents[0] == '1') {
4614 found_online = true;
4616 } else if (contents[0] == '0')
4617 found_offline = true;
4622 return found_online || !found_offline;
4626 static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
4633 if (!path_strv_resolve_uniq(search, root))
4636 STRV_FOREACH(i, search) {
4637 _cleanup_free_ char *p = NULL;
4641 p = strjoin(root, *i, "/", path, NULL);
4643 p = strjoin(*i, "/", path, NULL);
4653 if (errno != ENOENT)
4660 int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
4661 _cleanup_strv_free_ char **copy = NULL;
4667 if (path_is_absolute(path)) {
4670 f = fopen(path, mode);
4679 copy = strv_copy((char**) search);
4683 return search_and_fopen_internal(path, mode, root, copy, _f);
4686 /// UNNEEDED by elogind
4688 int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
4689 _cleanup_strv_free_ char **s = NULL;
4691 if (path_is_absolute(path)) {
4694 f = fopen(path, mode);
4703 s = strv_split_nulstr(search);
4707 return search_and_fopen_internal(path, mode, root, s, _f);
4711 char *strextend(char **x, ...) {
4718 l = f = *x ? strlen(*x) : 0;
4725 t = va_arg(ap, const char *);
4730 if (n > ((size_t) -1) - l) {
4739 r = realloc(*x, l+1);
4749 t = va_arg(ap, const char *);
4763 char *strrep(const char *s, unsigned n) {
4771 p = r = malloc(l * n + 1);
4775 for (i = 0; i < n; i++)
4782 void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
4789 if (*allocated >= need)
4792 newalloc = MAX(need * 2, 64u / size);
4793 a = newalloc * size;
4795 /* check for overflows */
4796 if (a < size * need)
4804 *allocated = newalloc;
4808 void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
4817 q = greedy_realloc(p, allocated, need, size);
4821 if (*allocated > prev)
4822 memzero(q + prev * size, (*allocated - prev) * size);
4827 bool id128_is_valid(const char *s) {
4833 /* Simple formatted 128bit hex string */
4835 for (i = 0; i < l; i++) {
4838 if (!(c >= '0' && c <= '9') &&
4839 !(c >= 'a' && c <= 'z') &&
4840 !(c >= 'A' && c <= 'Z'))
4844 } else if (l == 36) {
4846 /* Formatted UUID */
4848 for (i = 0; i < l; i++) {
4851 if ((i == 8 || i == 13 || i == 18 || i == 23)) {
4855 if (!(c >= '0' && c <= '9') &&
4856 !(c >= 'a' && c <= 'z') &&
4857 !(c >= 'A' && c <= 'Z'))
4868 /// UNNEEDED by elogind
4870 int split_pair(const char *s, const char *sep, char **l, char **r) {
4885 a = strndup(s, x - s);
4889 b = strdup(x + strlen(sep));
4901 int shall_restore_state(void) {
4902 _cleanup_free_ char *value = NULL;
4905 r = get_proc_cmdline_key("systemd.restore_state=", &value);
4911 return parse_boolean(value) != 0;
4915 int proc_cmdline(char **ret) {
4918 if (detect_container() > 0)
4919 return get_process_cmdline(1, 0, false, ret);
4921 return read_one_line_file("/proc/cmdline", ret);
4924 int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
4925 _cleanup_free_ char *line = NULL;
4931 r = proc_cmdline(&line);
4937 _cleanup_free_ char *word = NULL;
4940 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
4946 /* Filter out arguments that are intended only for the
4948 if (!in_initrd() && startswith(word, "rd."))
4951 value = strchr(word, '=');
4955 r = parse_item(word, value);
4963 int get_proc_cmdline_key(const char *key, char **value) {
4964 _cleanup_free_ char *line = NULL, *ret = NULL;
4971 r = proc_cmdline(&line);
4977 _cleanup_free_ char *word = NULL;
4980 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
4986 /* Filter out arguments that are intended only for the
4988 if (!in_initrd() && startswith(word, "rd."))
4992 e = startswith(word, key);
4996 r = free_and_strdup(&ret, e);
5002 if (streq(word, key))
5016 int container_get_leader(const char *machine, pid_t *pid) {
5017 _cleanup_free_ char *s = NULL, *class = NULL;
5025 if (!machine_name_is_valid(machine))
5028 p = strjoina("/run/systemd/machines/", machine);
5029 r = parse_env_file(p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
5037 if (!streq_ptr(class, "container"))
5040 r = parse_pid(s, &leader);
5050 int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd) {
5051 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, netnsfd = -1, usernsfd = -1;
5059 mntns = procfs_file_alloca(pid, "ns/mnt");
5060 mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5068 pidns = procfs_file_alloca(pid, "ns/pid");
5069 pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5077 netns = procfs_file_alloca(pid, "ns/net");
5078 netnsfd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5086 userns = procfs_file_alloca(pid, "ns/user");
5087 usernsfd = open(userns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5088 if (usernsfd < 0 && errno != ENOENT)
5095 root = procfs_file_alloca(pid, "root");
5096 rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
5102 *pidns_fd = pidnsfd;
5105 *mntns_fd = mntnsfd;
5108 *netns_fd = netnsfd;
5111 *userns_fd = usernsfd;
5116 pidnsfd = mntnsfd = netnsfd = usernsfd = -1;
5121 int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd) {
5122 if (userns_fd >= 0) {
5123 /* Can't setns to your own userns, since then you could
5124 * escalate from non-root to root in your own namespace, so
5125 * check if namespaces equal before attempting to enter. */
5126 _cleanup_free_ char *userns_fd_path = NULL;
5128 if (asprintf(&userns_fd_path, "/proc/self/fd/%d", userns_fd) < 0)
5131 r = files_same(userns_fd_path, "/proc/self/ns/user");
5139 if (setns(pidns_fd, CLONE_NEWPID) < 0)
5143 if (setns(mntns_fd, CLONE_NEWNS) < 0)
5147 if (setns(netns_fd, CLONE_NEWNET) < 0)
5151 if (setns(userns_fd, CLONE_NEWUSER) < 0)
5155 if (fchdir(root_fd) < 0)
5158 if (chroot(".") < 0)
5162 return reset_uid_gid();
5165 int getpeercred(int fd, struct ucred *ucred) {
5166 socklen_t n = sizeof(struct ucred);
5173 r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
5177 if (n != sizeof(struct ucred))
5180 /* Check if the data is actually useful and not suppressed due
5181 * to namespacing issues */
5184 if (u.uid == UID_INVALID)
5186 if (u.gid == GID_INVALID)
5193 int getpeersec(int fd, char **ret) {
5205 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
5209 if (errno != ERANGE)
5216 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
5232 /* This is much like like mkostemp() but is subject to umask(). */
5233 int mkostemp_safe(char *pattern, int flags) {
5234 _cleanup_umask_ mode_t u;
5241 fd = mkostemp(pattern, flags);
5248 /// UNNEEDED by elogind
5250 int open_tmpfile(const char *path, int flags) {
5257 /* Try O_TMPFILE first, if it is supported */
5258 fd = open(path, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
5263 /* Fall back to unguessable name + unlinking */
5264 p = strjoina(path, "/systemd-tmp-XXXXXX");
5266 fd = mkostemp_safe(p, flags);
5275 int fd_warn_permissions(const char *path, int fd) {
5278 if (fstat(fd, &st) < 0)
5281 if (st.st_mode & 0111)
5282 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
5284 if (st.st_mode & 0002)
5285 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
5287 if (getpid() == 1 && (st.st_mode & 0044) != 0044)
5288 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);
5293 /// UNNEEDED by elogind
5295 unsigned long personality_from_string(const char *p) {
5297 /* Parse a personality specifier. We introduce our own
5298 * identifiers that indicate specific ABIs, rather than just
5299 * hints regarding the register size, since we want to keep
5300 * things open for multiple locally supported ABIs for the
5301 * same register size. We try to reuse the ABI identifiers
5302 * used by libseccomp. */
5304 #if defined(__x86_64__)
5306 if (streq(p, "x86"))
5309 if (streq(p, "x86-64"))
5312 #elif defined(__i386__)
5314 if (streq(p, "x86"))
5317 #elif defined(__s390x__)
5319 if (streq(p, "s390"))
5322 if (streq(p, "s390x"))
5325 #elif defined(__s390__)
5327 if (streq(p, "s390"))
5331 return PERSONALITY_INVALID;
5334 const char* personality_to_string(unsigned long p) {
5336 #if defined(__x86_64__)
5338 if (p == PER_LINUX32)
5344 #elif defined(__i386__)
5349 #elif defined(__s390x__)
5354 if (p == PER_LINUX32)
5357 #elif defined(__s390__)
5368 uint64_t physical_memory(void) {
5371 /* We return this as uint64_t in case we are running as 32bit
5372 * process on a 64bit kernel with huge amounts of memory */
5374 mem = sysconf(_SC_PHYS_PAGES);
5377 return (uint64_t) mem * (uint64_t) page_size();
5380 /// UNNEEDED by elogind
5382 void hexdump(FILE *f, const void *p, size_t s) {
5383 const uint8_t *b = p;
5386 assert(s == 0 || b);
5391 fprintf(f, "%04x ", n);
5393 for (i = 0; i < 16; i++) {
5398 fprintf(f, "%02x ", b[i]);
5406 for (i = 0; i < 16; i++) {
5411 fputc(isprint(b[i]) ? (char) b[i] : '.', f);
5425 int update_reboot_param_file(const char *param) {
5429 r = write_string_file(REBOOT_PARAM_FILE, param, WRITE_STRING_FILE_CREATE);
5431 return log_error_errno(r, "Failed to write reboot param to "REBOOT_PARAM_FILE": %m");
5433 (void) unlink(REBOOT_PARAM_FILE);
5438 int umount_recursive(const char *prefix, int flags) {
5442 /* Try to umount everything recursively below a
5443 * directory. Also, take care of stacked mounts, and keep
5444 * unmounting them until they are gone. */
5447 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
5452 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
5453 if (!proc_self_mountinfo)
5457 _cleanup_free_ char *path = NULL, *p = NULL;
5460 k = fscanf(proc_self_mountinfo,
5461 "%*s " /* (1) mount id */
5462 "%*s " /* (2) parent id */
5463 "%*s " /* (3) major:minor */
5464 "%*s " /* (4) root */
5465 "%ms " /* (5) mount point */
5466 "%*s" /* (6) mount options */
5467 "%*[^-]" /* (7) optional fields */
5468 "- " /* (8) separator */
5469 "%*s " /* (9) file system type */
5470 "%*s" /* (10) mount source */
5471 "%*s" /* (11) mount options 2 */
5472 "%*[^\n]", /* some rubbish at the end */
5481 r = cunescape(path, UNESCAPE_RELAX, &p);
5485 if (!path_startswith(p, prefix))
5488 if (umount2(p, flags) < 0) {
5504 static int get_mount_flags(const char *path, unsigned long *flags) {
5507 if (statvfs(path, &buf) < 0)
5509 *flags = buf.f_flag;
5513 int bind_remount_recursive(const char *prefix, bool ro) {
5514 _cleanup_set_free_free_ Set *done = NULL;
5515 _cleanup_free_ char *cleaned = NULL;
5518 /* Recursively remount a directory (and all its submounts)
5519 * read-only or read-write. If the directory is already
5520 * mounted, we reuse the mount and simply mark it
5521 * MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write
5522 * operation). If it isn't we first make it one. Afterwards we
5523 * apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to all
5524 * submounts we can access, too. When mounts are stacked on
5525 * the same mount point we only care for each individual
5526 * "top-level" mount on each point, as we cannot
5527 * influence/access the underlying mounts anyway. We do not
5528 * have any effect on future submounts that might get
5529 * propagated, they migt be writable. This includes future
5530 * submounts that have been triggered via autofs. */
5532 cleaned = strdup(prefix);
5536 path_kill_slashes(cleaned);
5538 done = set_new(&string_hash_ops);
5543 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
5544 _cleanup_set_free_free_ Set *todo = NULL;
5545 bool top_autofs = false;
5547 unsigned long orig_flags;
5549 todo = set_new(&string_hash_ops);
5553 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
5554 if (!proc_self_mountinfo)
5558 _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
5561 k = fscanf(proc_self_mountinfo,
5562 "%*s " /* (1) mount id */
5563 "%*s " /* (2) parent id */
5564 "%*s " /* (3) major:minor */
5565 "%*s " /* (4) root */
5566 "%ms " /* (5) mount point */
5567 "%*s" /* (6) mount options (superblock) */
5568 "%*[^-]" /* (7) optional fields */
5569 "- " /* (8) separator */
5570 "%ms " /* (9) file system type */
5571 "%*s" /* (10) mount source */
5572 "%*s" /* (11) mount options (bind mount) */
5573 "%*[^\n]", /* some rubbish at the end */
5583 r = cunescape(path, UNESCAPE_RELAX, &p);
5587 /* Let's ignore autofs mounts. If they aren't
5588 * triggered yet, we want to avoid triggering
5589 * them, as we don't make any guarantees for
5590 * future submounts anyway. If they are
5591 * already triggered, then we will find
5592 * another entry for this. */
5593 if (streq(type, "autofs")) {
5594 top_autofs = top_autofs || path_equal(cleaned, p);
5598 if (path_startswith(p, cleaned) &&
5599 !set_contains(done, p)) {
5601 r = set_consume(todo, p);
5611 /* If we have no submounts to process anymore and if
5612 * the root is either already done, or an autofs, we
5614 if (set_isempty(todo) &&
5615 (top_autofs || set_contains(done, cleaned)))
5618 if (!set_contains(done, cleaned) &&
5619 !set_contains(todo, cleaned)) {
5620 /* The prefix directory itself is not yet a
5621 * mount, make it one. */
5622 if (mount(cleaned, cleaned, NULL, MS_BIND|MS_REC, NULL) < 0)
5626 (void) get_mount_flags(cleaned, &orig_flags);
5627 orig_flags &= ~MS_RDONLY;
5629 if (mount(NULL, prefix, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0)
5632 x = strdup(cleaned);
5636 r = set_consume(done, x);
5641 while ((x = set_steal_first(todo))) {
5643 r = set_consume(done, x);
5644 if (r == -EEXIST || r == 0)
5649 /* Try to reuse the original flag set, but
5650 * don't care for errors, in case of
5651 * obstructed mounts */
5653 (void) get_mount_flags(x, &orig_flags);
5654 orig_flags &= ~MS_RDONLY;
5656 if (mount(NULL, x, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) {
5658 /* Deal with mount points that are
5659 * obstructed by a later mount */
5661 if (errno != ENOENT)
5670 int fflush_and_check(FILE *f) {
5677 return errno ? -errno : -EIO;
5682 int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
5694 * /foo/bar/.#<extra>waldoXXXXXX
5698 if (!filename_is_valid(fn))
5704 t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
5708 strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn), "XXXXXX");
5710 *ret = path_kill_slashes(t);
5714 int tempfn_random(const char *p, const char *extra, char **ret) {
5728 * /foo/bar/.#<extra>waldobaa2a261115984a9
5732 if (!filename_is_valid(fn))
5738 t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1);
5742 x = stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn);
5745 for (i = 0; i < 16; i++) {
5746 *(x++) = hexchar(u & 0xF);
5752 *ret = path_kill_slashes(t);
5756 /// UNNEEDED by elogind
5758 int tempfn_random_child(const char *p, const char *extra, char **ret) {
5769 * /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
5775 t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1);
5779 x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra);
5782 for (i = 0; i < 16; i++) {
5783 *(x++) = hexchar(u & 0xF);
5789 *ret = path_kill_slashes(t);
5793 int take_password_lock(const char *root) {
5795 struct flock flock = {
5797 .l_whence = SEEK_SET,
5805 /* This is roughly the same as lckpwdf(), but not as awful. We
5806 * don't want to use alarm() and signals, hence we implement
5807 * our own trivial version of this.
5809 * Note that shadow-utils also takes per-database locks in
5810 * addition to lckpwdf(). However, we don't given that they
5811 * are redundant as they they invoke lckpwdf() first and keep
5812 * it during everything they do. The per-database locks are
5813 * awfully racy, and thus we just won't do them. */
5816 path = strjoina(root, "/etc/.pwd.lock");
5818 path = "/etc/.pwd.lock";
5820 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
5824 r = fcntl(fd, F_SETLKW, &flock);
5833 int is_symlink(const char *path) {
5836 if (lstat(path, &info) < 0)
5839 return !!S_ISLNK(info.st_mode);
5843 int is_dir(const char* path, bool follow) {
5848 r = stat(path, &st);
5850 r = lstat(path, &st);
5854 return !!S_ISDIR(st.st_mode);
5857 /// UNNEEDED by elogind
5859 int is_device_node(const char *path) {
5862 if (lstat(path, &info) < 0)
5865 return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode));
5869 int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) {
5870 _cleanup_free_ char *s = NULL;
5871 size_t allocated = 0, sz = 0;
5879 SINGLE_QUOTE_ESCAPE,
5881 DOUBLE_QUOTE_ESCAPE,
5889 separators = WHITESPACE;
5891 /* Bail early if called after last value or with no input */
5893 goto finish_force_terminate;
5895 /* Parses the first word of a string, and returns it in
5896 * *ret. Removes all quotes in the process. When parsing fails
5897 * (because of an uneven number of quotes or similar), leaves
5898 * the pointer *p at the first invalid character. */
5906 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
5907 if (!GREEDY_REALLOC(s, allocated, sz+1))
5911 goto finish_force_terminate;
5912 else if (strchr(separators, c)) {
5913 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
5915 goto finish_force_next;
5920 /* We found a non-blank character, so we will always
5921 * want to return a string (even if it is empty),
5922 * allocate it here. */
5923 if (!GREEDY_REALLOC(s, allocated, sz+1))
5931 goto finish_force_terminate;
5932 else if (c == '\'' && (flags & EXTRACT_QUOTES))
5933 state = SINGLE_QUOTE;
5935 state = VALUE_ESCAPE;
5936 else if (c == '\"' && (flags & EXTRACT_QUOTES))
5937 state = DOUBLE_QUOTE;
5938 else if (strchr(separators, c)) {
5939 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
5941 goto finish_force_next;
5945 if (!GREEDY_REALLOC(s, allocated, sz+2))
5955 if (flags & EXTRACT_RELAX)
5956 goto finish_force_terminate;
5958 } else if (c == '\'')
5961 state = SINGLE_QUOTE_ESCAPE;
5963 if (!GREEDY_REALLOC(s, allocated, sz+2))
5977 state = DOUBLE_QUOTE_ESCAPE;
5979 if (!GREEDY_REALLOC(s, allocated, sz+2))
5987 case SINGLE_QUOTE_ESCAPE:
5988 case DOUBLE_QUOTE_ESCAPE:
5990 if (!GREEDY_REALLOC(s, allocated, sz+7))
5994 if ((flags & EXTRACT_CUNESCAPE_RELAX) &&
5995 (state == VALUE_ESCAPE || flags & EXTRACT_RELAX)) {
5996 /* If we find an unquoted trailing backslash and we're in
5997 * EXTRACT_CUNESCAPE_RELAX mode, keep it verbatim in the
6000 * Unbalanced quotes will only be allowed in EXTRACT_RELAX
6001 * mode, EXTRACT_CUNESCAPE_RELAX mode does not allow them.
6004 goto finish_force_terminate;
6006 if (flags & EXTRACT_RELAX)
6007 goto finish_force_terminate;
6011 if (flags & EXTRACT_CUNESCAPE) {
6014 r = cunescape_one(*p, (size_t) -1, &c, &u);
6016 if (flags & EXTRACT_CUNESCAPE_RELAX) {
6027 s[sz++] = c; /* normal explicit char */
6029 sz += utf8_encode_unichar(s + sz, u); /* unicode chars we'll encode as utf8 */
6034 state = (state == SINGLE_QUOTE_ESCAPE) ? SINGLE_QUOTE :
6035 (state == DOUBLE_QUOTE_ESCAPE) ? DOUBLE_QUOTE :
6041 goto finish_force_terminate;
6042 if (!strchr(separators, c))
6050 finish_force_terminate:
6067 /// UNNEEDED by elogind
6069 int extract_first_word_and_warn(
6072 const char *separators,
6075 const char *filename,
6077 const char *rvalue) {
6079 /* Try to unquote it, if it fails, warn about it and try again but this
6080 * time using EXTRACT_CUNESCAPE_RELAX to keep the backslashes verbatim
6081 * in invalid escape sequences. */
6086 r = extract_first_word(p, ret, separators, flags);
6087 if (r < 0 && !(flags&EXTRACT_CUNESCAPE_RELAX)) {
6089 /* Retry it with EXTRACT_CUNESCAPE_RELAX. */
6091 r = extract_first_word(p, ret, separators, flags|EXTRACT_CUNESCAPE_RELAX);
6093 log_syntax(unit, LOG_ERR, filename, line, r, "Unbalanced quoting in command line, ignoring: \"%s\"", rvalue);
6095 log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid escape sequences in command line: \"%s\"", rvalue);
6101 int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) {
6106 /* Parses a number of words from a string, stripping any
6107 * quotes if necessary. */
6111 /* Count how many words are expected */
6112 va_start(ap, flags);
6114 if (!va_arg(ap, char **))
6123 /* Read all words into a temporary array */
6124 l = newa0(char*, n);
6125 for (c = 0; c < n; c++) {
6127 r = extract_first_word(p, &l[c], separators, flags);
6131 for (j = 0; j < c; j++)
6141 /* If we managed to parse all words, return them in the passed
6143 va_start(ap, flags);
6144 for (i = 0; i < n; i++) {
6147 v = va_arg(ap, char **);
6158 int free_and_strdup(char **p, const char *s) {
6163 /* Replaces a string pointer with an strdup()ed new string,
6164 * possibly freeing the old one. */
6166 if (streq_ptr(*p, s))
6182 /// UNNEEDED by elogind
6184 int ptsname_malloc(int fd, char **ret) {
6197 if (ptsname_r(fd, c, l) == 0) {
6201 if (errno != ERANGE) {
6211 int openpt_in_namespace(pid_t pid, int flags) {
6212 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1;
6213 _cleanup_close_pair_ int pair[2] = { -1, -1 };
6220 r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &usernsfd, &rootfd);
6224 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
6234 pair[0] = safe_close(pair[0]);
6236 r = namespace_enter(pidnsfd, mntnsfd, -1, usernsfd, rootfd);
6238 _exit(EXIT_FAILURE);
6240 master = posix_openpt(flags|O_NOCTTY|O_CLOEXEC);
6242 _exit(EXIT_FAILURE);
6244 if (unlockpt(master) < 0)
6245 _exit(EXIT_FAILURE);
6247 if (send_one_fd(pair[1], master, 0) < 0)
6248 _exit(EXIT_FAILURE);
6250 _exit(EXIT_SUCCESS);
6253 pair[1] = safe_close(pair[1]);
6255 r = wait_for_terminate(child, &si);
6258 if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
6261 return receive_one_fd(pair[0], 0);
6265 ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) {
6266 char fn[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
6267 _cleanup_close_ int fd = -1;
6270 /* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */
6272 fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
6276 xsprintf(fn, "/proc/self/fd/%i", fd);
6278 l = getxattr(fn, attribute, value, size);
6285 static int parse_crtime(le64_t le, usec_t *usec) {
6291 if (u == 0 || u == (uint64_t) -1)
6298 int fd_getcrtime(int fd, usec_t *usec) {
6305 /* Until Linux gets a real concept of birthtime/creation time,
6306 * let's fake one with xattrs */
6308 n = fgetxattr(fd, "user.crtime_usec", &le, sizeof(le));
6311 if (n != sizeof(le))
6314 return parse_crtime(le, usec);
6317 /// UNNEEDED by elogind
6319 int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags) {
6323 n = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags);
6326 if (n != sizeof(le))
6329 return parse_crtime(le, usec);
6332 int path_getcrtime(const char *p, usec_t *usec) {
6339 n = getxattr(p, "user.crtime_usec", &le, sizeof(le));
6342 if (n != sizeof(le))
6345 return parse_crtime(le, usec);
6348 int fd_setcrtime(int fd, usec_t usec) {
6354 usec = now(CLOCK_REALTIME);
6356 le = htole64((uint64_t) usec);
6357 if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), 0) < 0)
6363 int same_fd(int a, int b) {
6364 struct stat sta, stb;
6371 /* Compares two file descriptors. Note that semantics are
6372 * quite different depending on whether we have kcmp() or we
6373 * don't. If we have kcmp() this will only return true for
6374 * dup()ed file descriptors, but not otherwise. If we don't
6375 * have kcmp() this will also return true for two fds of the same
6376 * file, created by separate open() calls. Since we use this
6377 * call mostly for filtering out duplicates in the fd store
6378 * this difference hopefully doesn't matter too much. */
6383 /* Try to use kcmp() if we have it. */
6385 r = kcmp(pid, pid, KCMP_FILE, a, b);
6390 if (errno != ENOSYS)
6393 /* We don't have kcmp(), use fstat() instead. */
6394 if (fstat(a, &sta) < 0)
6397 if (fstat(b, &stb) < 0)
6400 if ((sta.st_mode & S_IFMT) != (stb.st_mode & S_IFMT))
6403 /* We consider all device fds different, since two device fds
6404 * might refer to quite different device contexts even though
6405 * they share the same inode and backing dev_t. */
6407 if (S_ISCHR(sta.st_mode) || S_ISBLK(sta.st_mode))
6410 if (sta.st_dev != stb.st_dev || sta.st_ino != stb.st_ino)
6413 /* The fds refer to the same inode on disk, let's also check
6414 * if they have the same fd flags. This is useful to
6415 * distinguish the read and write side of a pipe created with
6417 fa = fcntl(a, F_GETFL);
6421 fb = fcntl(b, F_GETFL);
6428 int chattr_fd(int fd, unsigned value, unsigned mask) {
6429 unsigned old_attr, new_attr;
6434 if (fstat(fd, &st) < 0)
6437 /* Explicitly check whether this is a regular file or
6438 * directory. If it is anything else (such as a device node or
6439 * fifo), then the ioctl will not hit the file systems but
6440 * possibly drivers, where the ioctl might have different
6441 * effects. Notably, DRM is using the same ioctl() number. */
6443 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
6449 if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
6452 new_attr = (old_attr & ~mask) | (value & mask);
6453 if (new_attr == old_attr)
6456 if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
6462 int chattr_path(const char *p, unsigned value, unsigned mask) {
6463 _cleanup_close_ int fd = -1;
6470 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
6474 return chattr_fd(fd, value, mask);
6477 int read_attr_fd(int fd, unsigned *ret) {
6482 if (fstat(fd, &st) < 0)
6485 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
6488 if (ioctl(fd, FS_IOC_GETFLAGS, ret) < 0)
6494 int read_attr_path(const char *p, unsigned *ret) {
6495 _cleanup_close_ int fd = -1;
6500 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
6504 return read_attr_fd(fd, ret);
6507 static size_t nul_length(const uint8_t *p, size_t sz) {
6522 ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
6523 const uint8_t *q, *w, *e;
6531 n = nul_length(q, e - q);
6533 /* If there are more than the specified run length of
6534 * NUL bytes, or if this is the beginning or the end
6535 * of the buffer, then seek instead of write */
6536 if ((n > run_length) ||
6537 (n > 0 && q == p) ||
6538 (n > 0 && q + n >= e)) {
6540 l = write(fd, w, q - w);
6547 if (lseek(fd, n, SEEK_CUR) == (off_t) -1)
6559 l = write(fd, w, q - w);
6566 return q - (const uint8_t*) p;
6570 void sigkill_wait(pid_t *pid) {
6576 if (kill(*pid, SIGKILL) > 0)
6577 (void) wait_for_terminate(*pid, NULL);
6580 /// UNNEEDED by elogind
6582 int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
6583 int a = 0, b = 0, c = 0;
6593 if (!strchr(*p, '>'))
6596 if ((*p)[2] == '>') {
6597 c = undecchar((*p)[1]);
6599 } else if ((*p)[3] == '>') {
6600 b = undecchar((*p)[1]);
6601 c = undecchar((*p)[2]);
6603 } else if ((*p)[4] == '>') {
6604 a = undecchar((*p)[1]);
6605 b = undecchar((*p)[2]);
6606 c = undecchar((*p)[3]);
6611 if (a < 0 || b < 0 || c < 0 ||
6612 (!with_facility && (a || b || c > 7)))
6616 *priority = a*100 + b*10 + c;
6618 *priority = (*priority & LOG_FACMASK) | c;
6625 ssize_t string_table_lookup(const char * const *table, size_t len, const char *key) {
6631 for (i = 0; i < len; ++i)
6632 if (streq_ptr(table[i], key))
6638 /// UNNEEDED by elogind
6640 void cmsg_close_all(struct msghdr *mh) {
6641 struct cmsghdr *cmsg;
6645 CMSG_FOREACH(cmsg, mh)
6646 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
6647 close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int));
6650 int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
6654 ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
6658 /* renameat2() exists since Linux 3.15, btrfs added support for it later.
6659 * If it is not implemented, fallback to another method. */
6660 if (!IN_SET(errno, EINVAL, ENOSYS))
6663 /* The link()/unlink() fallback does not work on directories. But
6664 * renameat() without RENAME_NOREPLACE gives the same semantics on
6665 * directories, except when newpath is an *empty* directory. This is
6667 ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW);
6668 if (ret >= 0 && S_ISDIR(buf.st_mode)) {
6669 ret = renameat(olddirfd, oldpath, newdirfd, newpath);
6670 return ret >= 0 ? 0 : -errno;
6673 /* If it is not a directory, use the link()/unlink() fallback. */
6674 ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0);
6678 ret = unlinkat(olddirfd, oldpath, 0);
6680 /* backup errno before the following unlinkat() alters it */
6682 (void) unlinkat(newdirfd, newpath, 0);
6690 static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad) {
6694 if (*s == '\\' || strchr(bad, *s))
6703 char *shell_escape(const char *s, const char *bad) {
6706 r = new(char, strlen(s)*2+1);
6710 t = strcpy_backslash_escaped(r, s, bad);
6716 char *shell_maybe_quote(const char *s) {
6722 /* Encloses a string in double quotes if necessary to make it
6723 * OK as shell string. */
6725 for (p = s; *p; p++)
6728 strchr(SHELL_NEED_QUOTES, *p))
6734 r = new(char, 1+strlen(s)*2+1+1);
6740 t = mempcpy(t, s, p - s);
6742 t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE);
6751 int parse_mode(const char *s, mode_t *ret) {
6759 l = strtol(s, &x, 8);
6763 if (!x || x == s || *x)
6765 if (l < 0 || l > 07777)
6772 /// UNNEEDED by elogind
6774 int mount_move_root(const char *path) {
6777 if (chdir(path) < 0)
6780 if (mount(path, "/", NULL, MS_MOVE, NULL) < 0)
6783 if (chroot(".") < 0)
6793 int reset_uid_gid(void) {
6795 if (setgroups(0, NULL) < 0)
6798 if (setresgid(0, 0, 0) < 0)
6801 if (setresuid(0, 0, 0) < 0)
6807 int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink) {
6816 for (l = 100; ; l = (size_t) n + 1) {
6822 n = lgetxattr(path, name, v, l);
6824 n = getxattr(path, name, v, l);
6826 if (n >= 0 && (size_t) n < l) {
6833 if (n < 0 && errno != ERANGE)
6837 n = lgetxattr(path, name, NULL, 0);
6839 n = getxattr(path, name, NULL, 0);
6845 int fgetxattr_malloc(int fd, const char *name, char **value) {
6854 for (l = 100; ; l = (size_t) n + 1) {
6859 n = fgetxattr(fd, name, v, l);
6861 if (n >= 0 && (size_t) n < l) {
6868 if (n < 0 && errno != ERANGE)
6871 n = fgetxattr(fd, name, NULL, 0);
6877 int send_one_fd(int transport_fd, int fd, int flags) {
6879 struct cmsghdr cmsghdr;
6880 uint8_t buf[CMSG_SPACE(sizeof(int))];
6882 struct msghdr mh = {
6883 .msg_control = &control,
6884 .msg_controllen = sizeof(control),
6886 struct cmsghdr *cmsg;
6888 assert(transport_fd >= 0);
6891 cmsg = CMSG_FIRSTHDR(&mh);
6892 cmsg->cmsg_level = SOL_SOCKET;
6893 cmsg->cmsg_type = SCM_RIGHTS;
6894 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
6895 memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
6897 mh.msg_controllen = CMSG_SPACE(sizeof(int));
6898 if (sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags) < 0)
6904 /// UNNEEDED by elogind
6906 int receive_one_fd(int transport_fd, int flags) {
6908 struct cmsghdr cmsghdr;
6909 uint8_t buf[CMSG_SPACE(sizeof(int))];
6911 struct msghdr mh = {
6912 .msg_control = &control,
6913 .msg_controllen = sizeof(control),
6915 struct cmsghdr *cmsg, *found = NULL;
6917 assert(transport_fd >= 0);
6920 * Receive a single FD via @transport_fd. We don't care for
6921 * the transport-type. We retrieve a single FD at most, so for
6922 * packet-based transports, the caller must ensure to send
6923 * only a single FD per packet. This is best used in
6924 * combination with send_one_fd().
6927 if (recvmsg(transport_fd, &mh, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC | flags) < 0)
6930 CMSG_FOREACH(cmsg, &mh) {
6931 if (cmsg->cmsg_level == SOL_SOCKET &&
6932 cmsg->cmsg_type == SCM_RIGHTS &&
6933 cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
6941 cmsg_close_all(&mh);
6945 return *(int*) CMSG_DATA(found);
6948 void nop_signal_handler(int sig) {
6954 puts(PACKAGE_STRING "\n"
6959 /// UNNEEDED by elogind
6961 bool fdname_is_valid(const char *s) {
6964 /* Validates a name for $LISTEN_FDNAMES. We basically allow
6965 * everything ASCII that's not a control character. Also, as
6966 * special exception the ":" character is not allowed, as we
6967 * use that as field separator in $LISTEN_FDNAMES.
6969 * Note that the empty string is explicitly allowed
6970 * here. However, we limit the length of the names to 255
6976 for (p = s; *p; p++) {