]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/util.c
util-lib: split out fd-related operations into fd-util.[ch]
[thirdparty/systemd.git] / src / basic / util.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
60918275 2
a7334b09
LP
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
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
a7334b09
LP
11 (at your option) any later version.
12
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
5430f7f2 16 Lesser General Public License for more details.
a7334b09 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
f6c2284a
LP
22#include <ctype.h>
23#include <dirent.h>
60918275 24#include <errno.h>
f6c2284a
LP
25#include <fcntl.h>
26#include <glob.h>
27#include <grp.h>
28#include <langinfo.h>
20f56fdd 29#include <libintl.h>
f6c2284a
LP
30#include <limits.h>
31#include <linux/magic.h>
257b0719 32#include <linux/oom.h>
ef886c6a 33#include <linux/sched.h>
f6c2284a
LP
34#include <locale.h>
35#include <netinet/ip.h>
0a6f50c0 36#include <poll.h>
ef2f1067 37#include <pwd.h>
f6c2284a
LP
38#include <sched.h>
39#include <signal.h>
40#include <stdarg.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <string.h>
44#include <sys/file.h>
45#include <sys/ioctl.h>
87d2c1ff 46#include <sys/mman.h>
6d313367 47#include <sys/mount.h>
6afc95b7 48#include <sys/personality.h>
f6c2284a
LP
49#include <sys/prctl.h>
50#include <sys/resource.h>
51#include <sys/stat.h>
abe4aa14 52#include <sys/statvfs.h>
f6c2284a
LP
53#include <sys/time.h>
54#include <sys/types.h>
55#include <sys/utsname.h>
56#include <sys/vfs.h>
57#include <sys/wait.h>
58#include <sys/xattr.h>
59#include <syslog.h>
60#include <unistd.h>
eef46c37
LP
61
62/* When we include libgen.h because we need dirname() we immediately
f6c2284a
LP
63 * undefine basename() since libgen.h defines it as a macro to the
64 * POSIX version which is really broken. We prefer GNU basename(). */
eef46c37 65#include <libgen.h>
2b6bf07d 66#undef basename
60918275 67
9bf3b535
LP
68#ifdef HAVE_SYS_AUXV_H
69#include <sys/auxv.h>
70#endif
71
f6c2284a
LP
72/* We include linux/fs.h as last of the system headers, as it
73 * otherwise conflicts with sys/mount.h. Yay, Linux is great! */
74#include <linux/fs.h>
75
3f6fd1ba 76#include "build.h"
f6c2284a
LP
77#include "def.h"
78#include "device-nodes.h"
79#include "env-util.h"
4f5dd394 80#include "escape.h"
f6c2284a 81#include "exit-status.h"
3ffd4af2 82#include "fd-util.h"
f6c2284a
LP
83#include "fileio.h"
84#include "formats-util.h"
85#include "gunicode.h"
86#include "hashmap.h"
87#include "hostname-util.h"
1dccbe19 88#include "ioprio.h"
a9f5d454 89#include "log.h"
f6c2284a
LP
90#include "macro.h"
91#include "missing.h"
c38dfac9 92#include "mkdir.h"
9eb977db 93#include "path-util.h"
0b452006 94#include "process-util.h"
3df3e884 95#include "random-util.h"
24882e06 96#include "signal-util.h"
f6c2284a 97#include "sparse-endian.h"
07630cea 98#include "string-util.h"
f6c2284a
LP
99#include "strv.h"
100#include "terminal-util.h"
101#include "utf8.h"
4f5dd394 102#include "util.h"
3ffd4af2 103#include "virt.h"
56cf987f 104
012d7b42
ZJS
105/* Put this test here for a lack of better place */
106assert_cc(EAGAIN == EWOULDBLOCK);
107
9a0e6896
LP
108int saved_argc = 0;
109char **saved_argv = NULL;
9086e840 110
37f85e66 111size_t page_size(void) {
ec202eae 112 static thread_local size_t pgsz = 0;
37f85e66 113 long r;
114
87d2c1ff 115 if (_likely_(pgsz > 0))
37f85e66 116 return pgsz;
117
e67f47e5
LP
118 r = sysconf(_SC_PAGESIZE);
119 assert(r > 0);
37f85e66 120
121 pgsz = (size_t) r;
37f85e66 122 return pgsz;
123}
124
4b73a0c0
LP
125int unlink_noerrno(const char *path) {
126 PROTECT_ERRNO;
127 int r;
128
129 r = unlink(path);
130 if (r < 0)
131 return -errno;
132
133 return 0;
134}
135
85261803
LP
136int parse_boolean(const char *v) {
137 assert(v);
138
0f625d0b 139 if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on"))
85261803 140 return 1;
0f625d0b 141 else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off"))
85261803
LP
142 return 0;
143
144 return -EINVAL;
145}
146
3ba686c1 147int parse_pid(const char *s, pid_t* ret_pid) {
0b172489 148 unsigned long ul = 0;
3ba686c1
LP
149 pid_t pid;
150 int r;
151
152 assert(s);
153 assert(ret_pid);
154
e67f47e5
LP
155 r = safe_atolu(s, &ul);
156 if (r < 0)
3ba686c1
LP
157 return r;
158
159 pid = (pid_t) ul;
160
161 if ((unsigned long) pid != ul)
162 return -ERANGE;
163
164 if (pid <= 0)
165 return -ERANGE;
166
167 *ret_pid = pid;
168 return 0;
169}
170
a1f686da
LP
171bool uid_is_valid(uid_t uid) {
172
173 /* Some libc APIs use UID_INVALID as special placeholder */
174 if (uid == (uid_t) 0xFFFFFFFF)
175 return false;
176
177 /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
178 if (uid == (uid_t) 0xFFFF)
179 return false;
180
181 return true;
182}
183
034a2a52
LP
184int parse_uid(const char *s, uid_t* ret_uid) {
185 unsigned long ul = 0;
186 uid_t uid;
187 int r;
188
189 assert(s);
034a2a52 190
e67f47e5
LP
191 r = safe_atolu(s, &ul);
192 if (r < 0)
034a2a52
LP
193 return r;
194
195 uid = (uid_t) ul;
196
197 if ((unsigned long) uid != ul)
198 return -ERANGE;
199
a1f686da 200 if (!uid_is_valid(uid))
ef5c570e
LP
201 return -ENXIO; /* we return ENXIO instead of EINVAL
202 * here, to make it easy to distuingish
203 * invalid numeric uids invalid
204 * strings. */
306a55c8 205
8b0849e9
LP
206 if (ret_uid)
207 *ret_uid = uid;
208
034a2a52
LP
209 return 0;
210}
211
85261803
LP
212int safe_atou(const char *s, unsigned *ret_u) {
213 char *x = NULL;
034c6ed7 214 unsigned long l;
85261803
LP
215
216 assert(s);
217 assert(ret_u);
218
219 errno = 0;
220 l = strtoul(s, &x, 0);
221
f3910003 222 if (!x || x == s || *x || errno)
48deb058 223 return errno > 0 ? -errno : -EINVAL;
85261803 224
034c6ed7 225 if ((unsigned long) (unsigned) l != l)
85261803
LP
226 return -ERANGE;
227
228 *ret_u = (unsigned) l;
229 return 0;
230}
231
232int safe_atoi(const char *s, int *ret_i) {
233 char *x = NULL;
034c6ed7 234 long l;
85261803
LP
235
236 assert(s);
237 assert(ret_i);
238
239 errno = 0;
240 l = strtol(s, &x, 0);
241
f3910003 242 if (!x || x == s || *x || errno)
48deb058 243 return errno > 0 ? -errno : -EINVAL;
85261803 244
034c6ed7 245 if ((long) (int) l != l)
85261803
LP
246 return -ERANGE;
247
034c6ed7
LP
248 *ret_i = (int) l;
249 return 0;
250}
251
b914e211
LP
252int safe_atou8(const char *s, uint8_t *ret) {
253 char *x = NULL;
254 unsigned long l;
255
256 assert(s);
257 assert(ret);
258
259 errno = 0;
260 l = strtoul(s, &x, 0);
261
262 if (!x || x == s || *x || errno)
263 return errno > 0 ? -errno : -EINVAL;
264
265 if ((unsigned long) (uint8_t) l != l)
266 return -ERANGE;
267
268 *ret = (uint8_t) l;
269 return 0;
270}
271
781fa938
LP
272int safe_atou16(const char *s, uint16_t *ret) {
273 char *x = NULL;
274 unsigned long l;
275
276 assert(s);
277 assert(ret);
278
279 errno = 0;
280 l = strtoul(s, &x, 0);
281
282 if (!x || x == s || *x || errno)
283 return errno > 0 ? -errno : -EINVAL;
284
285 if ((unsigned long) (uint16_t) l != l)
286 return -ERANGE;
287
288 *ret = (uint16_t) l;
289 return 0;
290}
291
292int safe_atoi16(const char *s, int16_t *ret) {
293 char *x = NULL;
294 long l;
295
296 assert(s);
297 assert(ret);
298
299 errno = 0;
300 l = strtol(s, &x, 0);
301
302 if (!x || x == s || *x || errno)
303 return errno > 0 ? -errno : -EINVAL;
304
305 if ((long) (int16_t) l != l)
306 return -ERANGE;
307
308 *ret = (int16_t) l;
309 return 0;
310}
311
034c6ed7
LP
312int safe_atollu(const char *s, long long unsigned *ret_llu) {
313 char *x = NULL;
314 unsigned long long l;
315
316 assert(s);
317 assert(ret_llu);
318
319 errno = 0;
320 l = strtoull(s, &x, 0);
321
f3910003 322 if (!x || x == s || *x || errno)
034c6ed7
LP
323 return errno ? -errno : -EINVAL;
324
325 *ret_llu = l;
326 return 0;
327}
328
329int safe_atolli(const char *s, long long int *ret_lli) {
330 char *x = NULL;
331 long long l;
332
333 assert(s);
334 assert(ret_lli);
335
336 errno = 0;
337 l = strtoll(s, &x, 0);
338
f3910003 339 if (!x || x == s || *x || errno)
034c6ed7
LP
340 return errno ? -errno : -EINVAL;
341
342 *ret_lli = l;
85261803
LP
343 return 0;
344}
a41e8209 345
f7900e25
TA
346int safe_atod(const char *s, double *ret_d) {
347 char *x = NULL;
32b2634e 348 double d = 0;
0193ad26 349 locale_t loc;
f7900e25
TA
350
351 assert(s);
352 assert(ret_d);
353
0193ad26
CR
354 loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
355 if (loc == (locale_t) 0)
356 return -errno;
f7900e25 357
0193ad26
CR
358 errno = 0;
359 d = strtod_l(s, &x, loc);
360
361 if (!x || x == s || *x || errno) {
362 freelocale(loc);
f7900e25 363 return errno ? -errno : -EINVAL;
0193ad26 364 }
f7900e25 365
0193ad26 366 freelocale(loc);
f7900e25
TA
367 *ret_d = (double) d;
368 return 0;
369}
370
034c6ed7 371
34ca941c
LP
372int fchmod_umask(int fd, mode_t m) {
373 mode_t u;
374 int r;
375
376 u = umask(0777);
377 r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
378 umask(u);
379
380 return r;
381}
382
849958d1 383int readlinkat_malloc(int fd, const char *p, char **ret) {
87f0e418 384 size_t l = 100;
2d2ebd6b 385 int r;
87f0e418
LP
386
387 assert(p);
2d2ebd6b 388 assert(ret);
87f0e418
LP
389
390 for (;;) {
391 char *c;
392 ssize_t n;
393
2d2ebd6b
LP
394 c = new(char, l);
395 if (!c)
87f0e418
LP
396 return -ENOMEM;
397
849958d1 398 n = readlinkat(fd, p, c, l-1);
2d2ebd6b
LP
399 if (n < 0) {
400 r = -errno;
87f0e418 401 free(c);
2d2ebd6b 402 return r;
87f0e418
LP
403 }
404
405 if ((size_t) n < l-1) {
406 c[n] = 0;
2d2ebd6b 407 *ret = c;
87f0e418
LP
408 return 0;
409 }
410
411 free(c);
412 l *= 2;
413 }
414}
415
849958d1
LP
416int readlink_malloc(const char *p, char **ret) {
417 return readlinkat_malloc(AT_FDCWD, p, ret);
418}
419
9a67bcf2
TG
420int readlink_value(const char *p, char **ret) {
421 _cleanup_free_ char *link = NULL;
422 char *value;
423 int r;
424
425 r = readlink_malloc(p, &link);
426 if (r < 0)
427 return r;
428
429 value = basename(link);
430 if (!value)
431 return -ENOENT;
432
433 value = strdup(value);
434 if (!value)
435 return -ENOMEM;
436
437 *ret = value;
438
439 return 0;
440}
441
2c7108c4 442int readlink_and_make_absolute(const char *p, char **r) {
1058cbf2
ZJS
443 _cleanup_free_ char *target = NULL;
444 char *k;
2c7108c4
LP
445 int j;
446
447 assert(p);
448 assert(r);
449
1058cbf2
ZJS
450 j = readlink_malloc(p, &target);
451 if (j < 0)
2c7108c4
LP
452 return j;
453
454 k = file_in_same_dir(p, target);
2c7108c4
LP
455 if (!k)
456 return -ENOMEM;
457
458 *r = k;
459 return 0;
460}
461
83096483
LP
462int readlink_and_canonicalize(const char *p, char **r) {
463 char *t, *s;
464 int j;
465
466 assert(p);
467 assert(r);
468
469 j = readlink_and_make_absolute(p, &t);
470 if (j < 0)
471 return j;
472
473 s = canonicalize_file_name(t);
474 if (s) {
475 free(t);
476 *r = s;
477 } else
478 *r = t;
479
480 path_kill_slashes(*r);
481
482 return 0;
483}
484
4a72ff34 485char *file_in_same_dir(const char *path, const char *filename) {
ebd93cb6 486 char *e, *ret;
4a72ff34
LP
487 size_t k;
488
489 assert(path);
490 assert(filename);
491
492 /* This removes the last component of path and appends
493 * filename, unless the latter is absolute anyway or the
494 * former isn't */
495
496 if (path_is_absolute(filename))
497 return strdup(filename);
498
ebd93cb6
LP
499 e = strrchr(path, '/');
500 if (!e)
4a72ff34
LP
501 return strdup(filename);
502
503 k = strlen(filename);
ebd93cb6
LP
504 ret = new(char, (e + 1 - path) + k + 1);
505 if (!ret)
4a72ff34
LP
506 return NULL;
507
ebd93cb6
LP
508 memcpy(mempcpy(ret, path, e + 1 - path), filename, k + 1);
509 return ret;
4a72ff34 510}
fb624d04 511
c32dd69b
LP
512int rmdir_parents(const char *path, const char *stop) {
513 size_t l;
514 int r = 0;
515
516 assert(path);
517 assert(stop);
518
519 l = strlen(path);
520
521 /* Skip trailing slashes */
522 while (l > 0 && path[l-1] == '/')
523 l--;
524
525 while (l > 0) {
526 char *t;
527
528 /* Skip last component */
529 while (l > 0 && path[l-1] != '/')
530 l--;
531
532 /* Skip trailing slashes */
533 while (l > 0 && path[l-1] == '/')
534 l--;
535
536 if (l <= 0)
537 break;
538
539 if (!(t = strndup(path, l)))
540 return -ENOMEM;
541
542 if (path_startswith(stop, t)) {
543 free(t);
544 return 0;
545 }
546
547 r = rmdir(t);
548 free(t);
549
550 if (r < 0)
551 if (errno != ENOENT)
552 return -errno;
553 }
554
555 return 0;
556}
557
fb624d04
LP
558char hexchar(int x) {
559 static const char table[16] = "0123456789abcdef";
560
561 return table[x & 15];
562}
4fe88d28
LP
563
564int unhexchar(char c) {
565
566 if (c >= '0' && c <= '9')
567 return c - '0';
568
569 if (c >= 'a' && c <= 'f')
ea430986 570 return c - 'a' + 10;
4fe88d28
LP
571
572 if (c >= 'A' && c <= 'F')
ea430986 573 return c - 'A' + 10;
4fe88d28 574
7e8185ef 575 return -EINVAL;
4fe88d28
LP
576}
577
66e35261
LP
578char *hexmem(const void *p, size_t l) {
579 char *r, *z;
580 const uint8_t *x;
581
582 z = r = malloc(l * 2 + 1);
583 if (!r)
584 return NULL;
585
586 for (x = p; x < (const uint8_t*) p + l; x++) {
587 *(z++) = hexchar(*x >> 4);
588 *(z++) = hexchar(*x & 15);
589 }
590
591 *z = 0;
592 return r;
593}
594
30494563
TG
595int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
596 _cleanup_free_ uint8_t *r = NULL;
597 uint8_t *z;
2181a7f5
LP
598 const char *x;
599
30494563
TG
600 assert(mem);
601 assert(len);
2181a7f5
LP
602 assert(p);
603
604 z = r = malloc((l + 1) / 2 + 1);
605 if (!r)
30494563 606 return -ENOMEM;
2181a7f5
LP
607
608 for (x = p; x < p + l; x += 2) {
609 int a, b;
610
611 a = unhexchar(x[0]);
30494563
TG
612 if (a < 0)
613 return a;
614 else if (x+1 < p + l) {
2181a7f5 615 b = unhexchar(x[1]);
30494563
TG
616 if (b < 0)
617 return b;
618 } else
2181a7f5
LP
619 b = 0;
620
621 *(z++) = (uint8_t) a << 4 | (uint8_t) b;
622 }
623
624 *z = 0;
30494563
TG
625
626 *mem = r;
627 r = NULL;
628 *len = (l + 1) / 2;
629
630 return 0;
2181a7f5
LP
631}
632
75c0cab1
TG
633/* https://tools.ietf.org/html/rfc4648#section-6
634 * Notice that base32hex differs from base32 in the alphabet it uses.
635 * The distinction is that the base32hex representation preserves the
636 * order of the underlying data when compared as bytestrings, this is
637 * useful when representing NSEC3 hashes, as one can then verify the
638 * order of hashes directly from their representation. */
919a7f5f
TG
639char base32hexchar(int x) {
640 static const char table[32] = "0123456789"
641 "ABCDEFGHIJKLMNOPQRSTUV";
642
643 return table[x & 31];
644}
645
646int unbase32hexchar(char c) {
647 unsigned offset;
648
649 if (c >= '0' && c <= '9')
650 return c - '0';
651
652 offset = '9' - '0' + 1;
653
654 if (c >= 'A' && c <= 'V')
655 return c - 'A' + offset;
656
657 return -EINVAL;
658}
659
660char *base32hexmem(const void *p, size_t l, bool padding) {
661 char *r, *z;
662 const uint8_t *x;
663 size_t len;
664
665 if (padding)
666 /* five input bytes makes eight output bytes, padding is added so we must round up */
667 len = 8 * (l + 4) / 5;
668 else {
669 /* same, but round down as there is no padding */
670 len = 8 * l / 5;
671
672 switch (l % 5) {
673 case 4:
674 len += 7;
675 break;
676 case 3:
677 len += 5;
678 break;
679 case 2:
680 len += 4;
681 break;
682 case 1:
683 len += 2;
684 break;
685 }
686 }
687
688 z = r = malloc(len + 1);
689 if (!r)
690 return NULL;
691
692 for (x = p; x < (const uint8_t*) p + (l / 5) * 5; x += 5) {
693 /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ
694 x[3] == QQQQQQQQ; x[4] == WWWWWWWW */
695 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
696 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
697 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
698 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
699 *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */
700 *(z++) = base32hexchar((x[3] & 127) >> 2); /* 000QQQQQ */
701 *(z++) = base32hexchar((x[3] & 3) << 3 | x[4] >> 5); /* 000QQWWW */
702 *(z++) = base32hexchar((x[4] & 31)); /* 000WWWWW */
703 }
704
705 switch (l % 5) {
706 case 4:
707 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
708 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
709 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
710 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
711 *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */
712 *(z++) = base32hexchar((x[3] & 127) >> 2); /* 000QQQQQ */
713 *(z++) = base32hexchar((x[3] & 3) << 3); /* 000QQ000 */
714 if (padding)
715 *(z++) = '=';
716
717 break;
718
719 case 3:
720 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
721 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
722 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
723 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
724 *(z++) = base32hexchar((x[2] & 15) << 1); /* 000ZZZZ0 */
725 if (padding) {
726 *(z++) = '=';
727 *(z++) = '=';
728 *(z++) = '=';
729 }
730
731 break;
732
733 case 2:
734 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
735 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
736 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
737 *(z++) = base32hexchar((x[1] & 1) << 4); /* 000Y0000 */
738 if (padding) {
739 *(z++) = '=';
740 *(z++) = '=';
741 *(z++) = '=';
742 *(z++) = '=';
743 }
744
745 break;
746
747 case 1:
748 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
749 *(z++) = base32hexchar((x[0] & 7) << 2); /* 000XXX00 */
750 if (padding) {
751 *(z++) = '=';
752 *(z++) = '=';
753 *(z++) = '=';
754 *(z++) = '=';
755 *(z++) = '=';
756 *(z++) = '=';
757 }
758
759 break;
760 }
761
762 *z = 0;
763 return r;
764}
765
766int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_len) {
767 _cleanup_free_ uint8_t *r = NULL;
768 int a, b, c, d, e, f, g, h;
769 uint8_t *z;
770 const char *x;
771 size_t len;
772 unsigned pad = 0;
773
774 assert(p);
775
776 /* padding ensures any base32hex input has input divisible by 8 */
777 if (padding && l % 8 != 0)
778 return -EINVAL;
779
780 if (padding) {
781 /* strip the padding */
782 while (l > 0 && p[l - 1] == '=' && pad < 7) {
783 pad ++;
784 l --;
785 }
786 }
787
788 /* a group of eight input bytes needs five output bytes, in case of
789 padding we need to add some extra bytes */
790 len = (l / 8) * 5;
791
792 switch (l % 8) {
793 case 7:
794 len += 4;
795 break;
796 case 5:
797 len += 3;
798 break;
799 case 4:
800 len += 2;
801 break;
802 case 2:
803 len += 1;
804 break;
805 case 0:
806 break;
807 default:
808 return -EINVAL;
809 }
810
811 z = r = malloc(len + 1);
812 if (!r)
813 return -ENOMEM;
814
815 for (x = p; x < p + (l / 8) * 8; x += 8) {
816 /* a == 000XXXXX; b == 000YYYYY; c == 000ZZZZZ; d == 000WWWWW
817 e == 000SSSSS; f == 000QQQQQ; g == 000VVVVV; h == 000RRRRR */
818 a = unbase32hexchar(x[0]);
819 if (a < 0)
820 return -EINVAL;
821
822 b = unbase32hexchar(x[1]);
823 if (b < 0)
824 return -EINVAL;
825
826 c = unbase32hexchar(x[2]);
827 if (c < 0)
828 return -EINVAL;
829
830 d = unbase32hexchar(x[3]);
831 if (d < 0)
832 return -EINVAL;
833
834 e = unbase32hexchar(x[4]);
835 if (e < 0)
836 return -EINVAL;
837
838 f = unbase32hexchar(x[5]);
839 if (f < 0)
840 return -EINVAL;
841
842 g = unbase32hexchar(x[6]);
843 if (g < 0)
844 return -EINVAL;
845
846 h = unbase32hexchar(x[7]);
847 if (h < 0)
848 return -EINVAL;
849
850 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
851 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
852 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
853 *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */
854 *(z++) = (uint8_t) g << 5 | (uint8_t) h; /* VVVRRRRR */
855 }
856
857 switch (l % 8) {
858 case 7:
859 a = unbase32hexchar(x[0]);
860 if (a < 0)
861 return -EINVAL;
862
863 b = unbase32hexchar(x[1]);
864 if (b < 0)
865 return -EINVAL;
866
867 c = unbase32hexchar(x[2]);
868 if (c < 0)
869 return -EINVAL;
870
871 d = unbase32hexchar(x[3]);
872 if (d < 0)
873 return -EINVAL;
874
875 e = unbase32hexchar(x[4]);
876 if (e < 0)
877 return -EINVAL;
878
879 f = unbase32hexchar(x[5]);
880 if (f < 0)
881 return -EINVAL;
882
883 g = unbase32hexchar(x[6]);
884 if (g < 0)
885 return -EINVAL;
886
887 /* g == 000VV000 */
888 if (g & 7)
889 return -EINVAL;
890
891 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
892 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
893 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
894 *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */
895
896 break;
897 case 5:
898 a = unbase32hexchar(x[0]);
899 if (a < 0)
900 return -EINVAL;
901
902 b = unbase32hexchar(x[1]);
903 if (b < 0)
904 return -EINVAL;
905
906 c = unbase32hexchar(x[2]);
907 if (c < 0)
908 return -EINVAL;
909
910 d = unbase32hexchar(x[3]);
911 if (d < 0)
912 return -EINVAL;
913
914 e = unbase32hexchar(x[4]);
915 if (e < 0)
916 return -EINVAL;
917
918 /* e == 000SSSS0 */
919 if (e & 1)
920 return -EINVAL;
921
922 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
923 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
924 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
925
926 break;
927 case 4:
928 a = unbase32hexchar(x[0]);
929 if (a < 0)
930 return -EINVAL;
931
932 b = unbase32hexchar(x[1]);
933 if (b < 0)
934 return -EINVAL;
935
936 c = unbase32hexchar(x[2]);
937 if (c < 0)
938 return -EINVAL;
939
940 d = unbase32hexchar(x[3]);
941 if (d < 0)
942 return -EINVAL;
943
944 /* d == 000W0000 */
945 if (d & 15)
946 return -EINVAL;
947
948 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
949 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
950
951 break;
952 case 2:
953 a = unbase32hexchar(x[0]);
954 if (a < 0)
955 return -EINVAL;
956
957 b = unbase32hexchar(x[1]);
958 if (b < 0)
959 return -EINVAL;
960
961 /* b == 000YYY00 */
962 if (b & 3)
963 return -EINVAL;
964
965 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
966
967 break;
968 case 0:
969 break;
970 default:
971 return -EINVAL;
972 }
973
974 *z = 0;
975
976 *mem = r;
977 r = NULL;
978 *_len = len;
979
980 return 0;
981}
982
13a5d76b
TG
983/* https://tools.ietf.org/html/rfc4648#section-4 */
984char base64char(int x) {
985 static const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
986 "abcdefghijklmnopqrstuvwxyz"
987 "0123456789+/";
988 return table[x & 63];
989}
990
991int unbase64char(char c) {
992 unsigned offset;
993
994 if (c >= 'A' && c <= 'Z')
995 return c - 'A';
996
997 offset = 'Z' - 'A' + 1;
998
999 if (c >= 'a' && c <= 'z')
1000 return c - 'a' + offset;
1001
1002 offset += 'z' - 'a' + 1;
1003
1004 if (c >= '0' && c <= '9')
1005 return c - '0' + offset;
1006
1007 offset += '9' - '0' + 1;
1008
1009 if (c == '+')
1010 return offset;
1011
1012 offset ++;
1013
1014 if (c == '/')
1015 return offset;
1016
1017 return -EINVAL;
1018}
1019
1020char *base64mem(const void *p, size_t l) {
1021 char *r, *z;
1022 const uint8_t *x;
1023
1024 /* three input bytes makes four output bytes, padding is added so we must round up */
1025 z = r = malloc(4 * (l + 2) / 3 + 1);
1026 if (!r)
1027 return NULL;
1028
1029 for (x = p; x < (const uint8_t*) p + (l / 3) * 3; x += 3) {
1030 /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ */
1031 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1032 *(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4); /* 00XXYYYY */
1033 *(z++) = base64char((x[1] & 15) << 2 | x[2] >> 6); /* 00YYYYZZ */
1034 *(z++) = base64char(x[2] & 63); /* 00ZZZZZZ */
1035 }
1036
1037 switch (l % 3) {
1038 case 2:
1039 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1040 *(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4); /* 00XXYYYY */
1041 *(z++) = base64char((x[1] & 15) << 2); /* 00YYYY00 */
1042 *(z++) = '=';
1043
1044 break;
1045 case 1:
1046 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1047 *(z++) = base64char((x[0] & 3) << 4); /* 00XX0000 */
1048 *(z++) = '=';
1049 *(z++) = '=';
1050
1051 break;
1052 }
1053
1054 *z = 0;
1055 return r;
1056}
1057
1058int unbase64mem(const char *p, size_t l, void **mem, size_t *_len) {
2a2953b3 1059 _cleanup_free_ uint8_t *r = NULL;
13a5d76b 1060 int a, b, c, d;
2a2953b3 1061 uint8_t *z;
13a5d76b
TG
1062 const char *x;
1063 size_t len;
1064
1065 assert(p);
1066
1067 /* padding ensures any base63 input has input divisible by 4 */
1068 if (l % 4 != 0)
1069 return -EINVAL;
1070
1071 /* strip the padding */
1072 if (l > 0 && p[l - 1] == '=')
1073 l --;
1074 if (l > 0 && p[l - 1] == '=')
1075 l --;
1076
1077 /* a group of four input bytes needs three output bytes, in case of
1078 padding we need to add two or three extra bytes */
1079 len = (l / 4) * 3 + (l % 4 ? (l % 4) - 1 : 0);
1080
1081 z = r = malloc(len + 1);
1082 if (!r)
1083 return -ENOMEM;
1084
1085 for (x = p; x < p + (l / 4) * 4; x += 4) {
1086 /* a == 00XXXXXX; b == 00YYYYYY; c == 00ZZZZZZ; d == 00WWWWWW */
1087 a = unbase64char(x[0]);
1088 if (a < 0)
1089 return -EINVAL;
1090
1091 b = unbase64char(x[1]);
1092 if (b < 0)
1093 return -EINVAL;
1094
1095 c = unbase64char(x[2]);
1096 if (c < 0)
1097 return -EINVAL;
1098
1099 d = unbase64char(x[3]);
1100 if (d < 0)
1101 return -EINVAL;
1102
1103 *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
1104 *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
1105 *(z++) = (uint8_t) c << 6 | (uint8_t) d; /* ZZWWWWWW */
1106 }
1107
1108 switch (l % 4) {
1109 case 3:
1110 a = unbase64char(x[0]);
1111 if (a < 0)
1112 return -EINVAL;
1113
1114 b = unbase64char(x[1]);
1115 if (b < 0)
1116 return -EINVAL;
1117
1118 c = unbase64char(x[2]);
1119 if (c < 0)
1120 return -EINVAL;
1121
1122 /* c == 00ZZZZ00 */
1123 if (c & 3)
1124 return -EINVAL;
1125
1126 *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
1127 *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
1128
1129 break;
1130 case 2:
1131 a = unbase64char(x[0]);
1132 if (a < 0)
1133 return -EINVAL;
1134
1135 b = unbase64char(x[1]);
1136 if (b < 0)
1137 return -EINVAL;
1138
1139 /* b == 00YY0000 */
1140 if (b & 15)
1141 return -EINVAL;
1142
1143 *(z++) = (uint8_t) a << 2 | (uint8_t) (b >> 4); /* XXXXXXYY */
1144
1145 break;
919a7f5f
TG
1146 case 0:
1147
1148 break;
1149 default:
1150 return -EINVAL;
13a5d76b
TG
1151 }
1152
1153 *z = 0;
1154
1155 *mem = r;
1156 r = NULL;
1157 *_len = len;
1158
1159 return 0;
1160}
1161
4fe88d28
LP
1162char octchar(int x) {
1163 return '0' + (x & 7);
1164}
1165
1166int unoctchar(char c) {
1167
1168 if (c >= '0' && c <= '7')
1169 return c - '0';
1170
7e8185ef 1171 return -EINVAL;
4fe88d28
LP
1172}
1173
5af98f82
LP
1174char decchar(int x) {
1175 return '0' + (x % 10);
1176}
1177
1178int undecchar(char c) {
1179
1180 if (c >= '0' && c <= '9')
1181 return c - '0';
1182
7e8185ef 1183 return -EINVAL;
5af98f82
LP
1184}
1185
a34bf9db 1186_pure_ static bool hidden_file_allow_backup(const char *filename) {
c85dc17b
LP
1187 assert(filename);
1188
1189 return
1190 filename[0] == '.' ||
6c78be3c 1191 streq(filename, "lost+found") ||
e472d476
LP
1192 streq(filename, "aquota.user") ||
1193 streq(filename, "aquota.group") ||
c85dc17b
LP
1194 endswith(filename, ".rpmnew") ||
1195 endswith(filename, ".rpmsave") ||
1196 endswith(filename, ".rpmorig") ||
1197 endswith(filename, ".dpkg-old") ||
1198 endswith(filename, ".dpkg-new") ||
0cdfd26e 1199 endswith(filename, ".dpkg-tmp") ||
c7088e49
MP
1200 endswith(filename, ".dpkg-dist") ||
1201 endswith(filename, ".dpkg-bak") ||
1202 endswith(filename, ".dpkg-backup") ||
1203 endswith(filename, ".dpkg-remove") ||
c85dc17b
LP
1204 endswith(filename, ".swp");
1205}
1206
a34bf9db 1207bool hidden_file(const char *filename) {
a228a22f
LP
1208 assert(filename);
1209
1210 if (endswith(filename, "~"))
93f1a063 1211 return true;
a228a22f 1212
a34bf9db 1213 return hidden_file_allow_backup(filename);
a228a22f
LP
1214}
1215
42856c10 1216bool fstype_is_network(const char *fstype) {
a05f97b3 1217 static const char table[] =
ba89821c 1218 "afs\0"
a05f97b3
LP
1219 "cifs\0"
1220 "smbfs\0"
da92ca5e 1221 "sshfs\0"
a05f97b3 1222 "ncpfs\0"
dac70dc7 1223 "ncp\0"
a05f97b3
LP
1224 "nfs\0"
1225 "nfs4\0"
1226 "gfs\0"
67608cad
LP
1227 "gfs2\0"
1228 "glusterfs\0";
1229
1230 const char *x;
1231
1232 x = startswith(fstype, "fuse.");
1233 if (x)
1234 fstype = x;
42856c10 1235
a05f97b3 1236 return nulstr_contains(table, fstype);
42856c10
LP
1237}
1238
80876c20 1239int flush_fd(int fd) {
b92bea5d
ZJS
1240 struct pollfd pollfd = {
1241 .fd = fd,
1242 .events = POLLIN,
1243 };
80876c20
LP
1244
1245 for (;;) {
20c03b7b 1246 char buf[LINE_MAX];
80876c20
LP
1247 ssize_t l;
1248 int r;
1249
e62d8c39
ZJS
1250 r = poll(&pollfd, 1, 0);
1251 if (r < 0) {
80876c20
LP
1252 if (errno == EINTR)
1253 continue;
1254
1255 return -errno;
80876c20 1256
e62d8c39 1257 } else if (r == 0)
80876c20
LP
1258 return 0;
1259
e62d8c39
ZJS
1260 l = read(fd, buf, sizeof(buf));
1261 if (l < 0) {
80876c20
LP
1262
1263 if (errno == EINTR)
1264 continue;
1265
1266 if (errno == EAGAIN)
1267 return 0;
1268
1269 return -errno;
e62d8c39 1270 } else if (l == 0)
80876c20
LP
1271 return 0;
1272 }
1273}
1274
eb22ac37 1275ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
7d5dd5e0 1276 uint8_t *p = buf;
8d567588
LP
1277 ssize_t n = 0;
1278
1279 assert(fd >= 0);
1280 assert(buf);
1281
4fdae6c8
LP
1282 /* If called with nbytes == 0, let's call read() at least
1283 * once, to validate the operation */
1284
1285 if (nbytes > (size_t) SSIZE_MAX)
1286 return -EINVAL;
1287
1288 do {
8d567588
LP
1289 ssize_t k;
1290
7d5dd5e0 1291 k = read(fd, p, nbytes);
6ce830fa
LP
1292 if (k < 0) {
1293 if (errno == EINTR)
1294 continue;
8d567588 1295
6ce830fa 1296 if (errno == EAGAIN && do_poll) {
8d567588 1297
6ce830fa
LP
1298 /* We knowingly ignore any return value here,
1299 * and expect that any error/EOF is reported
1300 * via read() */
8d567588 1301
4fdae6c8 1302 (void) fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
6ce830fa
LP
1303 continue;
1304 }
1305
1306 return n > 0 ? n : -errno;
7d5dd5e0 1307 }
8d567588 1308
6ce830fa
LP
1309 if (k == 0)
1310 return n;
8d567588 1311
4fdae6c8
LP
1312 assert((size_t) k <= nbytes);
1313
8d567588
LP
1314 p += k;
1315 nbytes -= k;
1316 n += k;
4fdae6c8 1317 } while (nbytes > 0);
8d567588
LP
1318
1319 return n;
1320}
1321
a6dcc7e5
ZJS
1322int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
1323 ssize_t n;
1324
1325 n = loop_read(fd, buf, nbytes, do_poll);
1326 if (n < 0)
4fdae6c8 1327 return (int) n;
a6dcc7e5
ZJS
1328 if ((size_t) n != nbytes)
1329 return -EIO;
4fdae6c8 1330
a6dcc7e5
ZJS
1331 return 0;
1332}
1333
553acb7b 1334int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
7d5dd5e0 1335 const uint8_t *p = buf;
eb22ac37
LP
1336
1337 assert(fd >= 0);
1338 assert(buf);
1339
4fdae6c8
LP
1340 if (nbytes > (size_t) SSIZE_MAX)
1341 return -EINVAL;
553acb7b 1342
8c7e28a1 1343 do {
eb22ac37
LP
1344 ssize_t k;
1345
fe652127 1346 k = write(fd, p, nbytes);
6ce830fa
LP
1347 if (k < 0) {
1348 if (errno == EINTR)
1349 continue;
eb22ac37 1350
6ce830fa
LP
1351 if (errno == EAGAIN && do_poll) {
1352 /* We knowingly ignore any return value here,
1353 * and expect that any error/EOF is reported
1354 * via write() */
eb22ac37 1355
4fdae6c8 1356 (void) fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
6ce830fa
LP
1357 continue;
1358 }
eb22ac37 1359
6ce830fa 1360 return -errno;
7d5dd5e0 1361 }
eb22ac37 1362
4fdae6c8 1363 if (_unlikely_(nbytes > 0 && k == 0)) /* Can't really happen */
6ce830fa 1364 return -EIO;
eb22ac37 1365
4fdae6c8
LP
1366 assert((size_t) k <= nbytes);
1367
eb22ac37
LP
1368 p += k;
1369 nbytes -= k;
8c7e28a1 1370 } while (nbytes > 0);
eb22ac37 1371
553acb7b 1372 return 0;
eb22ac37
LP
1373}
1374
59f448cf 1375int parse_size(const char *t, uint64_t base, uint64_t *size) {
5556b5fe 1376
55ede093 1377 /* Soo, sometimes we want to parse IEC binary suffixes, and
5556b5fe
LP
1378 * sometimes SI decimal suffixes. This function can parse
1379 * both. Which one is the right way depends on the
1380 * context. Wikipedia suggests that SI is customary for
30a5b782 1381 * hardware metrics and network speeds, while IEC is
5556b5fe
LP
1382 * customary for most data sizes used by software and volatile
1383 * (RAM) memory. Hence be careful which one you pick!
1384 *
1385 * In either case we use just K, M, G as suffix, and not Ki,
1386 * Mi, Gi or so (as IEC would suggest). That's because that's
1387 * frickin' ugly. But this means you really need to make sure
1388 * to document which base you are parsing when you use this
1389 * call. */
1390
1391 struct table {
ab1f0633 1392 const char *suffix;
b32ff512 1393 unsigned long long factor;
5556b5fe
LP
1394 };
1395
1396 static const struct table iec[] = {
32895bb3 1397 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
840292be
ZJS
1398 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
1399 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
1400 { "G", 1024ULL*1024ULL*1024ULL },
1401 { "M", 1024ULL*1024ULL },
1402 { "K", 1024ULL },
59f448cf
LP
1403 { "B", 1ULL },
1404 { "", 1ULL },
ab1f0633
LP
1405 };
1406
5556b5fe 1407 static const struct table si[] = {
5556b5fe 1408 { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
840292be
ZJS
1409 { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
1410 { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
1411 { "G", 1000ULL*1000ULL*1000ULL },
1412 { "M", 1000ULL*1000ULL },
1413 { "K", 1000ULL },
59f448cf
LP
1414 { "B", 1ULL },
1415 { "", 1ULL },
5556b5fe
LP
1416 };
1417
1418 const struct table *table;
ab1f0633 1419 const char *p;
b32ff512 1420 unsigned long long r = 0;
840292be 1421 unsigned n_entries, start_pos = 0;
ab1f0633
LP
1422
1423 assert(t);
5556b5fe
LP
1424 assert(base == 1000 || base == 1024);
1425 assert(size);
1426
1427 if (base == 1000) {
1428 table = si;
1429 n_entries = ELEMENTSOF(si);
1430 } else {
1431 table = iec;
1432 n_entries = ELEMENTSOF(iec);
1433 }
ab1f0633
LP
1434
1435 p = t;
1436 do {
59f448cf 1437 unsigned long long l, tmp;
9480794b 1438 double frac = 0;
ab1f0633
LP
1439 char *e;
1440 unsigned i;
1441
59f448cf
LP
1442 p += strspn(p, WHITESPACE);
1443 if (*p == '-')
1444 return -ERANGE;
ab1f0633 1445
59f448cf
LP
1446 errno = 0;
1447 l = strtoull(p, &e, 10);
8333c77e 1448 if (errno > 0)
ab1f0633 1449 return -errno;
ab1f0633
LP
1450 if (e == p)
1451 return -EINVAL;
1452
9480794b
ZJS
1453 if (*e == '.') {
1454 e++;
59f448cf
LP
1455
1456 /* strtoull() itself would accept space/+/- */
9480794b 1457 if (*e >= '0' && *e <= '9') {
59f448cf 1458 unsigned long long l2;
9480794b
ZJS
1459 char *e2;
1460
9480794b 1461 l2 = strtoull(e, &e2, 10);
59f448cf 1462 if (errno > 0)
9480794b
ZJS
1463 return -errno;
1464
1465 /* Ignore failure. E.g. 10.M is valid */
1466 frac = l2;
1467 for (; e < e2; e++)
1468 frac /= 10;
1469 }
1470 }
1471
ab1f0633
LP
1472 e += strspn(e, WHITESPACE);
1473
840292be 1474 for (i = start_pos; i < n_entries; i++)
59f448cf 1475 if (startswith(e, table[i].suffix))
ab1f0633 1476 break;
ab1f0633 1477
5556b5fe 1478 if (i >= n_entries)
ab1f0633
LP
1479 return -EINVAL;
1480
59f448cf
LP
1481 if (l + (frac > 0) > ULLONG_MAX / table[i].factor)
1482 return -ERANGE;
1483
1484 tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
1485 if (tmp > ULLONG_MAX - r)
1486 return -ERANGE;
1487
1488 r += tmp;
1489 if ((unsigned long long) (uint64_t) r != r)
1490 return -ERANGE;
1491
1492 p = e + strlen(table[i].suffix);
1493
1494 start_pos = i + 1;
1495
b32ff512 1496 } while (*p);
ab1f0633 1497
5556b5fe 1498 *size = r;
ab1f0633
LP
1499
1500 return 0;
1501}
1502
8407a5d0
LP
1503bool is_device_path(const char *path) {
1504
1505 /* Returns true on paths that refer to a device, either in
1506 * sysfs or in /dev */
1507
1508 return
1509 path_startswith(path, "/dev/") ||
1510 path_startswith(path, "/sys/");
1511}
1512
01f78473 1513int dir_is_empty(const char *path) {
a05f97b3 1514 _cleanup_closedir_ DIR *d;
ac7edd91 1515 struct dirent *de;
01f78473 1516
a05f97b3
LP
1517 d = opendir(path);
1518 if (!d)
01f78473
LP
1519 return -errno;
1520
ac7edd91
LP
1521 FOREACH_DIRENT(de, d, return -errno)
1522 return 0;
01f78473 1523
ac7edd91 1524 return 1;
01f78473
LP
1525}
1526
844ec79b
ZJS
1527char* dirname_malloc(const char *path) {
1528 char *d, *dir, *dir2;
1529
1530 d = strdup(path);
1531 if (!d)
1532 return NULL;
1533 dir = dirname(d);
1534 assert(dir);
1535
1536 if (dir != d) {
1537 dir2 = strdup(dir);
1538 free(d);
1539 return dir2;
1540 }
1541
1542 return dir;
1543}
1544
5b6319dc
LP
1545void rename_process(const char name[8]) {
1546 assert(name);
1547
5d6b1584
LP
1548 /* This is a like a poor man's setproctitle(). It changes the
1549 * comm field, argv[0], and also the glibc's internally used
1550 * name of the process. For the first one a limit of 16 chars
1551 * applies, to the second one usually one of 10 (i.e. length
1552 * of "/sbin/init"), to the third one one of 7 (i.e. length of
1553 * "systemd"). If you pass a longer string it will be
1554 * truncated */
5b6319dc 1555
5d6b1584 1556 prctl(PR_SET_NAME, name);
5b6319dc
LP
1557
1558 if (program_invocation_name)
1559 strncpy(program_invocation_name, name, strlen(program_invocation_name));
9a0e6896
LP
1560
1561 if (saved_argc > 0) {
1562 int i;
1563
1564 if (saved_argv[0])
1565 strncpy(saved_argv[0], name, strlen(saved_argv[0]));
1566
1567 for (i = 1; i < saved_argc; i++) {
1568 if (!saved_argv[i])
1569 break;
1570
29804cc1 1571 memzero(saved_argv[i], strlen(saved_argv[i]));
9a0e6896
LP
1572 }
1573 }
5b6319dc
LP
1574}
1575
f1566e63 1576char *lookup_uid(uid_t uid) {
ef2f1067 1577 long bufsize;
a05f97b3
LP
1578 char *name;
1579 _cleanup_free_ char *buf = NULL;
ef2f1067 1580 struct passwd pwbuf, *pw = NULL;
ef2f1067
LP
1581
1582 /* Shortcut things to avoid NSS lookups */
1583 if (uid == 0)
1584 return strdup("root");
1585
7c5f152a
LP
1586 bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
1587 if (bufsize <= 0)
ef2f1067
LP
1588 bufsize = 4096;
1589
7c5f152a
LP
1590 buf = malloc(bufsize);
1591 if (!buf)
ef2f1067
LP
1592 return NULL;
1593
a05f97b3
LP
1594 if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
1595 return strdup(pw->pw_name);
ef2f1067 1596
de0671ee 1597 if (asprintf(&name, UID_FMT, uid) < 0)
ef2f1067
LP
1598 return NULL;
1599
1600 return name;
1601}
1602
7c5f152a
LP
1603char* getlogname_malloc(void) {
1604 uid_t uid;
1605 struct stat st;
1606
1607 if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
1608 uid = st.st_uid;
1609 else
1610 uid = getuid();
1611
1612 return lookup_uid(uid);
1613}
1614
1615char *getusername_malloc(void) {
1616 const char *e;
1617
1618 e = getenv("USER");
1619 if (e)
1620 return strdup(e);
1621
1622 return lookup_uid(getuid());
1623}
1624
d1678248 1625bool is_fs_type(const struct statfs *s, statfs_f_type_t magic_value) {
943aad8c 1626 assert(s);
d1678248
ILG
1627 assert_cc(sizeof(statfs_f_type_t) >= sizeof(s->f_type));
1628
1629 return F_TYPE_EQUAL(s->f_type, magic_value);
1630}
1631
1632int fd_check_fstype(int fd, statfs_f_type_t magic_value) {
1633 struct statfs s;
1634
1635 if (fstatfs(fd, &s) < 0)
1636 return -errno;
73020ab2 1637
d1678248
ILG
1638 return is_fs_type(&s, magic_value);
1639}
1640
1641int path_check_fstype(const char *path, statfs_f_type_t magic_value) {
1642 _cleanup_close_ int fd = -1;
1643
1644 fd = open(path, O_RDONLY);
1645 if (fd < 0)
1646 return -errno;
1647
1648 return fd_check_fstype(fd, magic_value);
1649}
1650
1651bool is_temporary_fs(const struct statfs *s) {
1652 return is_fs_type(s, TMPFS_MAGIC) ||
1653 is_fs_type(s, RAMFS_MAGIC);
943aad8c
ZJS
1654}
1655
c6878637 1656int fd_is_temporary_fs(int fd) {
979ef53a
DR
1657 struct statfs s;
1658
1659 if (fstatfs(fd, &s) < 0)
1660 return -errno;
1661
1662 return is_temporary_fs(&s);
1663}
1664
8c6db833
LP
1665int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
1666 assert(path);
1667
1668 /* Under the assumption that we are running privileged we
1669 * first change the access mode and only then hand out
1670 * ownership to avoid a window where access is too open. */
1671
fed1e721 1672 if (mode != MODE_INVALID)
8d53b453
LP
1673 if (chmod(path, mode) < 0)
1674 return -errno;
8c6db833 1675
fed1e721 1676 if (uid != UID_INVALID || gid != GID_INVALID)
8d53b453
LP
1677 if (chown(path, uid, gid) < 0)
1678 return -errno;
8c6db833
LP
1679
1680 return 0;
ef2f1067
LP
1681}
1682
f4b47811
LP
1683int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
1684 assert(fd >= 0);
1685
1686 /* Under the assumption that we are running privileged we
1687 * first change the access mode and only then hand out
1688 * ownership to avoid a window where access is too open. */
1689
fed1e721 1690 if (mode != MODE_INVALID)
9588bc32
LP
1691 if (fchmod(fd, mode) < 0)
1692 return -errno;
f4b47811 1693
fed1e721 1694 if (uid != UID_INVALID || gid != GID_INVALID)
9588bc32
LP
1695 if (fchown(fd, uid, gid) < 0)
1696 return -errno;
f4b47811
LP
1697
1698 return 0;
1699}
1700
9d9951a4
HH
1701int files_same(const char *filea, const char *fileb) {
1702 struct stat a, b;
b4f10a5e 1703
9d9951a4 1704 if (stat(filea, &a) < 0)
b4f10a5e
LP
1705 return -errno;
1706
9d9951a4 1707 if (stat(fileb, &b) < 0)
b4f10a5e
LP
1708 return -errno;
1709
9d9951a4
HH
1710 return a.st_dev == b.st_dev &&
1711 a.st_ino == b.st_ino;
1712}
1713
1714int running_in_chroot(void) {
1715 int ret;
1716
1717 ret = files_same("/proc/1/root", "/");
1718 if (ret < 0)
1719 return ret;
1720
1721 return ret == 0;
b4f10a5e
LP
1722}
1723
c38dfac9 1724int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
03e334a1 1725 _cleanup_close_ int fd;
c38dfac9 1726 int r;
f6144808
LP
1727
1728 assert(path);
1729
c38dfac9
KS
1730 if (parents)
1731 mkdir_parents(path, 0755);
73836c5c 1732
c38dfac9 1733 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode > 0 ? mode : 0644);
73836c5c 1734 if (fd < 0)
f6144808
LP
1735 return -errno;
1736
c38dfac9
KS
1737 if (mode > 0) {
1738 r = fchmod(fd, mode);
1739 if (r < 0)
1740 return -errno;
1741 }
1742
fed1e721 1743 if (uid != UID_INVALID || gid != GID_INVALID) {
c38dfac9
KS
1744 r = fchown(fd, uid, gid);
1745 if (r < 0)
1746 return -errno;
1747 }
1748
3a43da28 1749 if (stamp != USEC_INFINITY) {
c38dfac9
KS
1750 struct timespec ts[2];
1751
1752 timespec_store(&ts[0], stamp);
359efc59 1753 ts[1] = ts[0];
c38dfac9
KS
1754 r = futimens(fd, ts);
1755 } else
1756 r = futimens(fd, NULL);
1757 if (r < 0)
1758 return -errno;
1759
f6144808
LP
1760 return 0;
1761}
afea26ad 1762
c38dfac9 1763int touch(const char *path) {
fed1e721 1764 return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, 0);
c38dfac9
KS
1765}
1766
e1eaca26 1767static char *unquote(const char *s, const char* quotes) {
11ce3427
LP
1768 size_t l;
1769 assert(s);
1770
73836c5c
LP
1771 /* This is rather stupid, simply removes the heading and
1772 * trailing quotes if there is one. Doesn't care about
e1eaca26
LP
1773 * escaping or anything.
1774 *
1775 * DON'T USE THIS FOR NEW CODE ANYMORE!*/
73836c5c 1776
31ed59c5
LP
1777 l = strlen(s);
1778 if (l < 2)
11ce3427
LP
1779 return strdup(s);
1780
97c4a07d 1781 if (strchr(quotes, s[0]) && s[l-1] == s[0])
11ce3427
LP
1782 return strndup(s+1, l-2);
1783
1784 return strdup(s);
1785}
1786
919ce0b7 1787noreturn void freeze(void) {
720ce21d
LP
1788
1789 /* Make sure nobody waits for us on a socket anymore */
1790 close_all_fds(NULL, 0);
1791
c29597a1
LP
1792 sync();
1793
3c14d26c
LP
1794 for (;;)
1795 pause();
1796}
1797
00dc5d76
LP
1798bool null_or_empty(struct stat *st) {
1799 assert(st);
1800
1801 if (S_ISREG(st->st_mode) && st->st_size <= 0)
1802 return true;
1803
c8f26f42 1804 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
00dc5d76
LP
1805 return true;
1806
1807 return false;
1808}
1809
83096483
LP
1810int null_or_empty_path(const char *fn) {
1811 struct stat st;
1812
1813 assert(fn);
1814
1815 if (stat(fn, &st) < 0)
1816 return -errno;
1817
1818 return null_or_empty(&st);
1819}
1820
ed88bcfb
ZJS
1821int null_or_empty_fd(int fd) {
1822 struct stat st;
1823
1824 assert(fd >= 0);
1825
1826 if (fstat(fd, &st) < 0)
1827 return -errno;
1828
1829 return null_or_empty(&st);
1830}
1831
a247755d 1832DIR *xopendirat(int fd, const char *name, int flags) {
c4731d11
LP
1833 int nfd;
1834 DIR *d;
1835
dd94c17e
LP
1836 assert(!(flags & O_CREAT));
1837
1838 nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
73836c5c 1839 if (nfd < 0)
c4731d11
LP
1840 return NULL;
1841
73836c5c
LP
1842 d = fdopendir(nfd);
1843 if (!d) {
03e334a1 1844 safe_close(nfd);
c4731d11
LP
1845 return NULL;
1846 }
1847
1848 return d;
3b63d2d3
LP
1849}
1850
383182b5 1851static char *tag_to_udev_node(const char *tagvalue, const char *by) {
22f5f628 1852 _cleanup_free_ char *t = NULL, *u = NULL;
22f5f628 1853 size_t enc_len;
e23a0ce8 1854
e1eaca26 1855 u = unquote(tagvalue, QUOTES);
6db615c1 1856 if (!u)
383182b5 1857 return NULL;
e23a0ce8 1858
1d5989fd 1859 enc_len = strlen(u) * 4 + 1;
22f5f628 1860 t = new(char, enc_len);
6db615c1 1861 if (!t)
383182b5 1862 return NULL;
e23a0ce8 1863
8f6ce71f 1864 if (encode_devnode_name(u, t, enc_len) < 0)
22f5f628 1865 return NULL;
e23a0ce8 1866
6db615c1 1867 return strjoin("/dev/disk/by-", by, "/", t, NULL);
383182b5 1868}
e23a0ce8 1869
383182b5 1870char *fstab_node_to_udev_node(const char *p) {
faa368e3
LP
1871 assert(p);
1872
383182b5
DR
1873 if (startswith(p, "LABEL="))
1874 return tag_to_udev_node(p+6, "label");
e23a0ce8 1875
383182b5
DR
1876 if (startswith(p, "UUID="))
1877 return tag_to_udev_node(p+5, "uuid");
e23a0ce8 1878
84cc2abf
DR
1879 if (startswith(p, "PARTUUID="))
1880 return tag_to_udev_node(p+9, "partuuid");
1881
1882 if (startswith(p, "PARTLABEL="))
1883 return tag_to_udev_node(p+10, "partlabel");
1884
e23a0ce8
LP
1885 return strdup(p);
1886}
1887
87d2c1ff 1888bool dirent_is_file(const struct dirent *de) {
fb19a739
LP
1889 assert(de);
1890
a34bf9db 1891 if (hidden_file(de->d_name))
fb19a739
LP
1892 return false;
1893
1894 if (de->d_type != DT_REG &&
1895 de->d_type != DT_LNK &&
1896 de->d_type != DT_UNKNOWN)
1897 return false;
1898
1899 return true;
1900}
1901
87d2c1ff
LP
1902bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
1903 assert(de);
1904
a228a22f
LP
1905 if (de->d_type != DT_REG &&
1906 de->d_type != DT_LNK &&
1907 de->d_type != DT_UNKNOWN)
1908 return false;
1909
a34bf9db 1910 if (hidden_file_allow_backup(de->d_name))
87d2c1ff
LP
1911 return false;
1912
1913 return endswith(de->d_name, suffix);
1914}
1915
e801700e 1916static int do_execute(char **directories, usec_t timeout, char *argv[]) {
49681057 1917 _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
e801700e
ZJS
1918 _cleanup_set_free_free_ Set *seen = NULL;
1919 char **directory;
83cc030f 1920
49681057
ZJS
1921 /* We fork this all off from a child process so that we can
1922 * somewhat cleanly make use of SIGALRM to set a time limit */
83cc030f 1923
ce30c8dc
LP
1924 (void) reset_all_signal_handlers();
1925 (void) reset_signal_mask();
83cc030f 1926
49681057 1927 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
83cc030f 1928
49681057
ZJS
1929 pids = hashmap_new(NULL);
1930 if (!pids)
1931 return log_oom();
83cc030f 1932
e801700e
ZJS
1933 seen = set_new(&string_hash_ops);
1934 if (!seen)
1935 return log_oom();
83cc030f 1936
e801700e
ZJS
1937 STRV_FOREACH(directory, directories) {
1938 _cleanup_closedir_ DIR *d;
1939 struct dirent *de;
83cc030f 1940
e801700e
ZJS
1941 d = opendir(*directory);
1942 if (!d) {
1943 if (errno == ENOENT)
1944 continue;
83cc030f 1945
e801700e
ZJS
1946 return log_error_errno(errno, "Failed to open directory %s: %m", *directory);
1947 }
83cc030f 1948
e801700e
ZJS
1949 FOREACH_DIRENT(de, d, break) {
1950 _cleanup_free_ char *path = NULL;
1951 pid_t pid;
1952 int r;
1953
1954 if (!dirent_is_file(de))
1955 continue;
83cc030f 1956
e801700e
ZJS
1957 if (set_contains(seen, de->d_name)) {
1958 log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name);
1959 continue;
1960 }
1961
1962 r = set_put_strdup(seen, de->d_name);
1963 if (r < 0)
1964 return log_oom();
1965
1966 path = strjoin(*directory, "/", de->d_name, NULL);
1967 if (!path)
1968 return log_oom();
1969
1970 if (null_or_empty_path(path)) {
1971 log_debug("%s is empty (a mask).", path);
1972 continue;
7034e9db 1973 }
83cc030f 1974
e801700e
ZJS
1975 pid = fork();
1976 if (pid < 0) {
1977 log_error_errno(errno, "Failed to fork: %m");
1978 continue;
1979 } else if (pid == 0) {
1980 char *_argv[2];
83cc030f 1981
e801700e 1982 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
83cc030f 1983
e801700e
ZJS
1984 if (!argv) {
1985 _argv[0] = path;
1986 _argv[1] = NULL;
1987 argv = _argv;
1988 } else
1989 argv[0] = path;
1990
1991 execv(path, argv);
1992 return log_error_errno(errno, "Failed to execute %s: %m", path);
1993 }
1994
1995 log_debug("Spawned %s as " PID_FMT ".", path, pid);
83cc030f 1996
e801700e
ZJS
1997 r = hashmap_put(pids, UINT_TO_PTR(pid), path);
1998 if (r < 0)
1999 return log_oom();
2000 path = NULL;
2001 }
49681057 2002 }
83cc030f 2003
49681057
ZJS
2004 /* Abort execution of this process after the timout. We simply
2005 * rely on SIGALRM as default action terminating the process,
2006 * and turn on alarm(). */
83cc030f 2007
49681057
ZJS
2008 if (timeout != USEC_INFINITY)
2009 alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
83cc030f 2010
49681057
ZJS
2011 while (!hashmap_isempty(pids)) {
2012 _cleanup_free_ char *path = NULL;
2013 pid_t pid;
aa62a893 2014
49681057
ZJS
2015 pid = PTR_TO_UINT(hashmap_first_key(pids));
2016 assert(pid > 0);
83cc030f 2017
49681057
ZJS
2018 path = hashmap_remove(pids, UINT_TO_PTR(pid));
2019 assert(path);
aa62a893 2020
49681057
ZJS
2021 wait_for_terminate_and_warn(path, pid, true);
2022 }
aa62a893 2023
49681057
ZJS
2024 return 0;
2025}
aa62a893 2026
e801700e 2027void execute_directories(const char* const* directories, usec_t timeout, char *argv[]) {
49681057
ZJS
2028 pid_t executor_pid;
2029 int r;
e801700e
ZJS
2030 char *name;
2031 char **dirs = (char**) directories;
2032
2033 assert(!strv_isempty(dirs));
83cc030f 2034
e801700e
ZJS
2035 name = basename(dirs[0]);
2036 assert(!isempty(name));
aa62a893 2037
e801700e
ZJS
2038 /* Executes all binaries in the directories in parallel and waits
2039 * for them to finish. Optionally a timeout is applied. If a file
2040 * with the same name exists in more than one directory, the
2041 * earliest one wins. */
83cc030f 2042
49681057
ZJS
2043 executor_pid = fork();
2044 if (executor_pid < 0) {
2045 log_error_errno(errno, "Failed to fork: %m");
2046 return;
2047
2048 } else if (executor_pid == 0) {
e801700e 2049 r = do_execute(dirs, timeout, argv);
49681057 2050 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
aa62a893 2051 }
83cc030f 2052
e801700e 2053 wait_for_terminate_and_warn(name, executor_pid, true);
83cc030f
LP
2054}
2055
a88c8750
TG
2056bool plymouth_running(void) {
2057 return access("/run/plymouth/pid", F_OK) >= 0;
2058}
2059
1325aa42 2060int pipe_eof(int fd) {
b92bea5d
ZJS
2061 struct pollfd pollfd = {
2062 .fd = fd,
2063 .events = POLLIN|POLLHUP,
2064 };
1325aa42 2065
d37a91e8
LP
2066 int r;
2067
1325aa42
LP
2068 r = poll(&pollfd, 1, 0);
2069 if (r < 0)
2070 return -errno;
2071
2072 if (r == 0)
2073 return 0;
2074
2075 return pollfd.revents & POLLHUP;
2076}
2077
8f2d43a0 2078int fd_wait_for_event(int fd, int event, usec_t t) {
968d3d24 2079
b92bea5d
ZJS
2080 struct pollfd pollfd = {
2081 .fd = fd,
2082 .events = event,
2083 };
df50185b 2084
968d3d24
LP
2085 struct timespec ts;
2086 int r;
2087
3a43da28 2088 r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
df50185b
LP
2089 if (r < 0)
2090 return -errno;
2091
2092 if (r == 0)
2093 return 0;
2094
2095 return pollfd.revents;
2096}
2097
5a3ab509
LP
2098int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
2099 FILE *f;
2100 char *t;
ae6c3cc0 2101 int r, fd;
5a3ab509
LP
2102
2103 assert(path);
2104 assert(_f);
2105 assert(_temp_path);
2106
14bcf25c 2107 r = tempfn_xxxxxx(path, NULL, &t);
ae6c3cc0
LP
2108 if (r < 0)
2109 return r;
5a3ab509 2110
2d5bdf5b 2111 fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC);
5a3ab509
LP
2112 if (fd < 0) {
2113 free(t);
2114 return -errno;
2115 }
2116
2117 f = fdopen(fd, "we");
2118 if (!f) {
64ee7ab4 2119 unlink_noerrno(t);
5a3ab509 2120 free(t);
ac521356 2121 safe_close(fd);
5a3ab509
LP
2122 return -errno;
2123 }
2124
2125 *_f = f;
2126 *_temp_path = t;
2127
2128 return 0;
2129}
2130
424a19f8 2131int symlink_atomic(const char *from, const char *to) {
2e78fa79 2132 _cleanup_free_ char *t = NULL;
ae6c3cc0 2133 int r;
34ca941c
LP
2134
2135 assert(from);
2136 assert(to);
2137
14bcf25c 2138 r = tempfn_random(to, NULL, &t);
ae6c3cc0
LP
2139 if (r < 0)
2140 return r;
34ca941c 2141
424a19f8
LP
2142 if (symlink(from, t) < 0)
2143 return -errno;
34ca941c
LP
2144
2145 if (rename(t, to) < 0) {
2e78fa79
LP
2146 unlink_noerrno(t);
2147 return -errno;
34ca941c
LP
2148 }
2149
424a19f8 2150 return 0;
34ca941c
LP
2151}
2152
875e1014
ILG
2153int symlink_idempotent(const char *from, const char *to) {
2154 _cleanup_free_ char *p = NULL;
2155 int r;
2156
2157 assert(from);
2158 assert(to);
2159
2160 if (symlink(from, to) < 0) {
2161 if (errno != EEXIST)
2162 return -errno;
2163
2164 r = readlink_malloc(to, &p);
2165 if (r < 0)
2166 return r;
2167
2168 if (!streq(p, from))
2169 return -EINVAL;
2170 }
2171
2172 return 0;
2173}
2174
1554afae
LP
2175int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
2176 _cleanup_free_ char *t = NULL;
ae6c3cc0 2177 int r;
1554afae
LP
2178
2179 assert(path);
2180
14bcf25c 2181 r = tempfn_random(path, NULL, &t);
ae6c3cc0
LP
2182 if (r < 0)
2183 return r;
1554afae
LP
2184
2185 if (mknod(t, mode, dev) < 0)
2186 return -errno;
2187
2188 if (rename(t, path) < 0) {
2189 unlink_noerrno(t);
2190 return -errno;
2191 }
2192
2193 return 0;
2194}
2195
2196int mkfifo_atomic(const char *path, mode_t mode) {
2197 _cleanup_free_ char *t = NULL;
ae6c3cc0 2198 int r;
1554afae
LP
2199
2200 assert(path);
2201
14bcf25c 2202 r = tempfn_random(path, NULL, &t);
ae6c3cc0
LP
2203 if (r < 0)
2204 return r;
1554afae
LP
2205
2206 if (mkfifo(t, mode) < 0)
2207 return -errno;
2208
2209 if (rename(t, path) < 0) {
2210 unlink_noerrno(t);
2211 return -errno;
2212 }
2213
2214 return 0;
2215}
2216
4d6d6518
LP
2217bool display_is_local(const char *display) {
2218 assert(display);
2219
2220 return
2221 display[0] == ':' &&
2222 display[1] >= '0' &&
2223 display[1] <= '9';
2224}
2225
2226int socket_from_display(const char *display, char **path) {
2227 size_t k;
2228 char *f, *c;
2229
2230 assert(display);
2231 assert(path);
2232
2233 if (!display_is_local(display))
2234 return -EINVAL;
2235
2236 k = strspn(display+1, "0123456789");
2237
f8294e41 2238 f = new(char, strlen("/tmp/.X11-unix/X") + k + 1);
4d6d6518
LP
2239 if (!f)
2240 return -ENOMEM;
2241
2242 c = stpcpy(f, "/tmp/.X11-unix/X");
2243 memcpy(c, display+1, k);
2244 c[k] = 0;
2245
2246 *path = f;
2247
2248 return 0;
2249}
2250
d05c5031
LP
2251int get_user_creds(
2252 const char **username,
2253 uid_t *uid, gid_t *gid,
2254 const char **home,
2255 const char **shell) {
2256
1cccf435 2257 struct passwd *p;
ddd88763 2258 uid_t u;
1cccf435
MV
2259
2260 assert(username);
2261 assert(*username);
1cccf435
MV
2262
2263 /* We enforce some special rules for uid=0: in order to avoid
2264 * NSS lookups for root we hardcode its data. */
2265
2266 if (streq(*username, "root") || streq(*username, "0")) {
2267 *username = "root";
4b67834e
LP
2268
2269 if (uid)
2270 *uid = 0;
2271
2272 if (gid)
2273 *gid = 0;
2274
2275 if (home)
2276 *home = "/root";
d05c5031
LP
2277
2278 if (shell)
2279 *shell = "/bin/sh";
2280
1cccf435
MV
2281 return 0;
2282 }
2283
ddd88763 2284 if (parse_uid(*username, &u) >= 0) {
1cccf435 2285 errno = 0;
ddd88763 2286 p = getpwuid(u);
1cccf435
MV
2287
2288 /* If there are multiple users with the same id, make
2289 * sure to leave $USER to the configured value instead
2290 * of the first occurrence in the database. However if
2291 * the uid was configured by a numeric uid, then let's
2292 * pick the real username from /etc/passwd. */
2293 if (p)
2294 *username = p->pw_name;
2295 } else {
2296 errno = 0;
2297 p = getpwnam(*username);
2298 }
2299
2300 if (!p)
8333c77e 2301 return errno > 0 ? -errno : -ESRCH;
1cccf435 2302
4b67834e
LP
2303 if (uid)
2304 *uid = p->pw_uid;
2305
2306 if (gid)
2307 *gid = p->pw_gid;
2308
2309 if (home)
2310 *home = p->pw_dir;
2311
d05c5031
LP
2312 if (shell)
2313 *shell = p->pw_shell;
2314
4b67834e
LP
2315 return 0;
2316}
2317
59164be4
LP
2318char* uid_to_name(uid_t uid) {
2319 struct passwd *p;
2320 char *r;
2321
2322 if (uid == 0)
2323 return strdup("root");
2324
2325 p = getpwuid(uid);
2326 if (p)
2327 return strdup(p->pw_name);
2328
de0671ee 2329 if (asprintf(&r, UID_FMT, uid) < 0)
59164be4
LP
2330 return NULL;
2331
2332 return r;
2333}
2334
4468addc
LP
2335char* gid_to_name(gid_t gid) {
2336 struct group *p;
2337 char *r;
2338
2339 if (gid == 0)
2340 return strdup("root");
2341
2342 p = getgrgid(gid);
2343 if (p)
2344 return strdup(p->gr_name);
2345
de0671ee 2346 if (asprintf(&r, GID_FMT, gid) < 0)
4468addc
LP
2347 return NULL;
2348
2349 return r;
2350}
2351
4b67834e
LP
2352int get_group_creds(const char **groupname, gid_t *gid) {
2353 struct group *g;
2354 gid_t id;
2355
2356 assert(groupname);
2357
2358 /* We enforce some special rules for gid=0: in order to avoid
2359 * NSS lookups for root we hardcode its data. */
2360
2361 if (streq(*groupname, "root") || streq(*groupname, "0")) {
2362 *groupname = "root";
2363
2364 if (gid)
2365 *gid = 0;
2366
2367 return 0;
2368 }
2369
2370 if (parse_gid(*groupname, &id) >= 0) {
2371 errno = 0;
2372 g = getgrgid(id);
2373
2374 if (g)
2375 *groupname = g->gr_name;
2376 } else {
2377 errno = 0;
2378 g = getgrnam(*groupname);
2379 }
2380
2381 if (!g)
8333c77e 2382 return errno > 0 ? -errno : -ESRCH;
4b67834e
LP
2383
2384 if (gid)
2385 *gid = g->gr_gid;
2386
1cccf435
MV
2387 return 0;
2388}
2389
4468addc
LP
2390int in_gid(gid_t gid) {
2391 gid_t *gids;
43673799
LP
2392 int ngroups_max, r, i;
2393
43673799
LP
2394 if (getgid() == gid)
2395 return 1;
2396
2397 if (getegid() == gid)
2398 return 1;
2399
2400 ngroups_max = sysconf(_SC_NGROUPS_MAX);
2401 assert(ngroups_max > 0);
2402
2403 gids = alloca(sizeof(gid_t) * ngroups_max);
2404
2405 r = getgroups(ngroups_max, gids);
2406 if (r < 0)
2407 return -errno;
2408
2409 for (i = 0; i < r; i++)
2410 if (gids[i] == gid)
2411 return 1;
2412
2413 return 0;
2414}
2415
4468addc
LP
2416int in_group(const char *name) {
2417 int r;
2418 gid_t gid;
2419
2420 r = get_group_creds(&name, &gid);
2421 if (r < 0)
2422 return r;
2423
2424 return in_gid(gid);
2425}
2426
8092a428 2427int glob_exists(const char *path) {
7fd1b19b 2428 _cleanup_globfree_ glob_t g = {};
8d98da3f 2429 int k;
8092a428
LP
2430
2431 assert(path);
2432
8092a428
LP
2433 errno = 0;
2434 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
2435
2436 if (k == GLOB_NOMATCH)
8d98da3f 2437 return 0;
8092a428 2438 else if (k == GLOB_NOSPACE)
8d98da3f 2439 return -ENOMEM;
8092a428 2440 else if (k == 0)
8d98da3f 2441 return !strv_isempty(g.gl_pathv);
8092a428 2442 else
8d98da3f
ZJS
2443 return errno ? -errno : -EIO;
2444}
8092a428 2445
8d98da3f
ZJS
2446int glob_extend(char ***strv, const char *path) {
2447 _cleanup_globfree_ glob_t g = {};
2448 int k;
2449 char **p;
2450
2451 errno = 0;
a8ccacf5 2452 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
8d98da3f
ZJS
2453
2454 if (k == GLOB_NOMATCH)
2455 return -ENOENT;
2456 else if (k == GLOB_NOSPACE)
2457 return -ENOMEM;
2458 else if (k != 0 || strv_isempty(g.gl_pathv))
2459 return errno ? -errno : -EIO;
2460
2461 STRV_FOREACH(p, g.gl_pathv) {
2462 k = strv_extend(strv, *p);
2463 if (k < 0)
2464 break;
2465 }
2466
2467 return k;
8092a428
LP
2468}
2469
83096483
LP
2470int dirent_ensure_type(DIR *d, struct dirent *de) {
2471 struct stat st;
2472
2473 assert(d);
2474 assert(de);
2475
2476 if (de->d_type != DT_UNKNOWN)
2477 return 0;
2478
2479 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
2480 return -errno;
2481
2482 de->d_type =
2483 S_ISREG(st.st_mode) ? DT_REG :
2484 S_ISDIR(st.st_mode) ? DT_DIR :
2485 S_ISLNK(st.st_mode) ? DT_LNK :
2486 S_ISFIFO(st.st_mode) ? DT_FIFO :
2487 S_ISSOCK(st.st_mode) ? DT_SOCK :
2488 S_ISCHR(st.st_mode) ? DT_CHR :
2489 S_ISBLK(st.st_mode) ? DT_BLK :
2490 DT_UNKNOWN;
2491
2492 return 0;
2493}
2494
034a2a52 2495int get_files_in_directory(const char *path, char ***list) {
893fa014
ZJS
2496 _cleanup_closedir_ DIR *d = NULL;
2497 size_t bufsize = 0, n = 0;
2498 _cleanup_strv_free_ char **l = NULL;
034a2a52
LP
2499
2500 assert(path);
d60ef526
LP
2501
2502 /* Returns all files in a directory in *list, and the number
2503 * of files as return value. If list is NULL returns only the
893fa014 2504 * number. */
034a2a52
LP
2505
2506 d = opendir(path);
8ea913b2
LP
2507 if (!d)
2508 return -errno;
2509
034a2a52 2510 for (;;) {
7d5e9c0f 2511 struct dirent *de;
034a2a52 2512
3fd11280
FW
2513 errno = 0;
2514 de = readdir(d);
2515 if (!de && errno != 0)
2516 return -errno;
034a2a52
LP
2517 if (!de)
2518 break;
2519
2520 dirent_ensure_type(d, de);
2521
2522 if (!dirent_is_file(de))
2523 continue;
2524
d60ef526 2525 if (list) {
893fa014
ZJS
2526 /* one extra slot is needed for the terminating NULL */
2527 if (!GREEDY_REALLOC(l, bufsize, n + 2))
2528 return -ENOMEM;
034a2a52 2529
893fa014
ZJS
2530 l[n] = strdup(de->d_name);
2531 if (!l[n])
2532 return -ENOMEM;
034a2a52 2533
893fa014 2534 l[++n] = NULL;
d60ef526 2535 } else
893fa014 2536 n++;
034a2a52
LP
2537 }
2538
893fa014
ZJS
2539 if (list) {
2540 *list = l;
2541 l = NULL; /* avoid freeing */
2542 }
034a2a52 2543
893fa014 2544 return n;
034a2a52
LP
2545}
2546
b636465b 2547bool is_main_thread(void) {
ec202eae 2548 static thread_local int cached = 0;
b636465b
LP
2549
2550 if (_unlikely_(cached == 0))
2551 cached = getpid() == gettid() ? 1 : -1;
2552
2553 return cached > 0;
2554}
2555
94959f0f
LP
2556int block_get_whole_disk(dev_t d, dev_t *ret) {
2557 char *p, *s;
2558 int r;
2559 unsigned n, m;
2560
2561 assert(ret);
2562
2563 /* If it has a queue this is good enough for us */
2564 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
2565 return -ENOMEM;
2566
2567 r = access(p, F_OK);
2568 free(p);
2569
2570 if (r >= 0) {
2571 *ret = d;
2572 return 0;
2573 }
2574
2575 /* If it is a partition find the originating device */
2576 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
2577 return -ENOMEM;
2578
2579 r = access(p, F_OK);
2580 free(p);
2581
2582 if (r < 0)
2583 return -ENOENT;
2584
2585 /* Get parent dev_t */
2586 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
2587 return -ENOMEM;
2588
2589 r = read_one_line_file(p, &s);
2590 free(p);
2591
2592 if (r < 0)
2593 return r;
2594
2595 r = sscanf(s, "%u:%u", &m, &n);
2596 free(s);
2597
2598 if (r != 2)
2599 return -EINVAL;
2600
2601 /* Only return this if it is really good enough for us. */
2602 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
2603 return -ENOMEM;
2604
2605 r = access(p, F_OK);
2606 free(p);
2607
2608 if (r >= 0) {
2609 *ret = makedev(m, n);
2610 return 0;
2611 }
2612
2613 return -ENOENT;
2614}
2615
f41607a6
LP
2616static const char *const ioprio_class_table[] = {
2617 [IOPRIO_CLASS_NONE] = "none",
2618 [IOPRIO_CLASS_RT] = "realtime",
2619 [IOPRIO_CLASS_BE] = "best-effort",
2620 [IOPRIO_CLASS_IDLE] = "idle"
2621};
2622
f8b69d1d 2623DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
f41607a6
LP
2624
2625static const char *const sigchld_code_table[] = {
2626 [CLD_EXITED] = "exited",
2627 [CLD_KILLED] = "killed",
2628 [CLD_DUMPED] = "dumped",
2629 [CLD_TRAPPED] = "trapped",
2630 [CLD_STOPPED] = "stopped",
2631 [CLD_CONTINUED] = "continued",
2632};
2633
2634DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
2635
2636static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
2637 [LOG_FAC(LOG_KERN)] = "kern",
2638 [LOG_FAC(LOG_USER)] = "user",
2639 [LOG_FAC(LOG_MAIL)] = "mail",
2640 [LOG_FAC(LOG_DAEMON)] = "daemon",
2641 [LOG_FAC(LOG_AUTH)] = "auth",
2642 [LOG_FAC(LOG_SYSLOG)] = "syslog",
2643 [LOG_FAC(LOG_LPR)] = "lpr",
2644 [LOG_FAC(LOG_NEWS)] = "news",
2645 [LOG_FAC(LOG_UUCP)] = "uucp",
2646 [LOG_FAC(LOG_CRON)] = "cron",
2647 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
2648 [LOG_FAC(LOG_FTP)] = "ftp",
2649 [LOG_FAC(LOG_LOCAL0)] = "local0",
2650 [LOG_FAC(LOG_LOCAL1)] = "local1",
2651 [LOG_FAC(LOG_LOCAL2)] = "local2",
2652 [LOG_FAC(LOG_LOCAL3)] = "local3",
2653 [LOG_FAC(LOG_LOCAL4)] = "local4",
2654 [LOG_FAC(LOG_LOCAL5)] = "local5",
2655 [LOG_FAC(LOG_LOCAL6)] = "local6",
2656 [LOG_FAC(LOG_LOCAL7)] = "local7"
2657};
2658
f8b69d1d 2659DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
f41607a6 2660
adb8ec96
EV
2661bool log_facility_unshifted_is_valid(int facility) {
2662 return facility >= 0 && facility <= LOG_FAC(~0);
2663}
2664
f41607a6
LP
2665static const char *const log_level_table[] = {
2666 [LOG_EMERG] = "emerg",
2667 [LOG_ALERT] = "alert",
2668 [LOG_CRIT] = "crit",
2669 [LOG_ERR] = "err",
2670 [LOG_WARNING] = "warning",
2671 [LOG_NOTICE] = "notice",
2672 [LOG_INFO] = "info",
2673 [LOG_DEBUG] = "debug"
2674};
2675
f8b69d1d 2676DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
f41607a6 2677
adb8ec96
EV
2678bool log_level_is_valid(int level) {
2679 return level >= 0 && level <= LOG_DEBUG;
2680}
2681
f41607a6
LP
2682static const char* const sched_policy_table[] = {
2683 [SCHED_OTHER] = "other",
2684 [SCHED_BATCH] = "batch",
2685 [SCHED_IDLE] = "idle",
2686 [SCHED_FIFO] = "fifo",
2687 [SCHED_RR] = "rr"
2688};
2689
f8b69d1d 2690DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
f41607a6 2691
517d56b1 2692static const char* const rlimit_table[_RLIMIT_MAX] = {
f41607a6
LP
2693 [RLIMIT_CPU] = "LimitCPU",
2694 [RLIMIT_FSIZE] = "LimitFSIZE",
2695 [RLIMIT_DATA] = "LimitDATA",
2696 [RLIMIT_STACK] = "LimitSTACK",
2697 [RLIMIT_CORE] = "LimitCORE",
2698 [RLIMIT_RSS] = "LimitRSS",
2699 [RLIMIT_NOFILE] = "LimitNOFILE",
2700 [RLIMIT_AS] = "LimitAS",
2701 [RLIMIT_NPROC] = "LimitNPROC",
2702 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
2703 [RLIMIT_LOCKS] = "LimitLOCKS",
2704 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
2705 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
2706 [RLIMIT_NICE] = "LimitNICE",
2707 [RLIMIT_RTPRIO] = "LimitRTPRIO",
2708 [RLIMIT_RTTIME] = "LimitRTTIME"
2709};
2710
2711DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
2712
2713static const char* const ip_tos_table[] = {
2714 [IPTOS_LOWDELAY] = "low-delay",
2715 [IPTOS_THROUGHPUT] = "throughput",
2716 [IPTOS_RELIABILITY] = "reliability",
2717 [IPTOS_LOWCOST] = "low-cost",
2718};
2719
f8b69d1d 2720DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
f41607a6 2721
65457142
FC
2722bool kexec_loaded(void) {
2723 bool loaded = false;
2724 char *s;
2725
2726 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
2727 if (s[0] == '1')
2728 loaded = true;
2729 free(s);
2730 }
2731 return loaded;
2732}
fb9de93d 2733
87d2c1ff
LP
2734int prot_from_flags(int flags) {
2735
2736 switch (flags & O_ACCMODE) {
2737
2738 case O_RDONLY:
2739 return PROT_READ;
2740
2741 case O_WRONLY:
2742 return PROT_WRITE;
2743
2744 case O_RDWR:
2745 return PROT_READ|PROT_WRITE;
2746
2747 default:
2748 return -EINVAL;
2749 }
7c99e0c1 2750}
689b9a22 2751
59f448cf 2752char *format_bytes(char *buf, size_t l, uint64_t t) {
c0f99c21 2753 unsigned i;
babfc091
LP
2754
2755 static const struct {
2756 const char *suffix;
59f448cf 2757 uint64_t factor;
babfc091 2758 } table[] = {
59f448cf
LP
2759 { "E", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
2760 { "P", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
2761 { "T", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
2762 { "G", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
2763 { "M", UINT64_C(1024)*UINT64_C(1024) },
2764 { "K", UINT64_C(1024) },
babfc091
LP
2765 };
2766
59f448cf 2767 if (t == (uint64_t) -1)
f02ca522
LP
2768 return NULL;
2769
babfc091
LP
2770 for (i = 0; i < ELEMENTSOF(table); i++) {
2771
2772 if (t >= table[i].factor) {
2773 snprintf(buf, l,
59f448cf
LP
2774 "%" PRIu64 ".%" PRIu64 "%s",
2775 t / table[i].factor,
2776 ((t*UINT64_C(10)) / table[i].factor) % UINT64_C(10),
babfc091
LP
2777 table[i].suffix);
2778
2779 goto finish;
2780 }
2781 }
2782
59f448cf 2783 snprintf(buf, l, "%" PRIu64 "B", t);
babfc091
LP
2784
2785finish:
2786 buf[l-1] = 0;
2787 return buf;
2788
2789}
55d7bfc1
LP
2790
2791void* memdup(const void *p, size_t l) {
2792 void *r;
2793
2794 assert(p);
2795
2796 r = malloc(l);
2797 if (!r)
2798 return NULL;
2799
2800 memcpy(r, p, l);
2801 return r;
2802}
bb99a35a
LP
2803
2804int fd_inc_sndbuf(int fd, size_t n) {
2805 int r, value;
2806 socklen_t l = sizeof(value);
2807
2808 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
92d75ca4 2809 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
bb99a35a
LP
2810 return 0;
2811
92d75ca4
LP
2812 /* If we have the privileges we will ignore the kernel limit. */
2813
bb99a35a 2814 value = (int) n;
92d75ca4
LP
2815 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
2816 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
2817 return -errno;
bb99a35a
LP
2818
2819 return 1;
2820}
2821
2822int fd_inc_rcvbuf(int fd, size_t n) {
2823 int r, value;
2824 socklen_t l = sizeof(value);
2825
2826 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
92d75ca4 2827 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
bb99a35a
LP
2828 return 0;
2829
92d75ca4 2830 /* If we have the privileges we will ignore the kernel limit. */
bb99a35a 2831
92d75ca4
LP
2832 value = (int) n;
2833 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
2834 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
2835 return -errno;
bb99a35a
LP
2836 return 1;
2837}
6bb92a16 2838
9bdc770c 2839int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
6bb92a16 2840 bool stdout_is_tty, stderr_is_tty;
8a7c93d8
LP
2841 pid_t parent_pid, agent_pid;
2842 sigset_t ss, saved_ss;
6bb92a16
LP
2843 unsigned n, i;
2844 va_list ap;
2845 char **l;
2846
2847 assert(pid);
2848 assert(path);
2849
6bb92a16
LP
2850 /* Spawns a temporary TTY agent, making sure it goes away when
2851 * we go away */
2852
8a7c93d8
LP
2853 parent_pid = getpid();
2854
2855 /* First we temporarily block all signals, so that the new
2856 * child has them blocked initially. This way, we can be sure
2857 * that SIGTERMs are not lost we might send to the agent. */
2858 assert_se(sigfillset(&ss) >= 0);
2859 assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0);
2860
6bb92a16 2861 agent_pid = fork();
8a7c93d8
LP
2862 if (agent_pid < 0) {
2863 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
6bb92a16 2864 return -errno;
8a7c93d8 2865 }
6bb92a16
LP
2866
2867 if (agent_pid != 0) {
8a7c93d8 2868 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
6bb92a16
LP
2869 *pid = agent_pid;
2870 return 0;
2871 }
2872
2873 /* In the child:
2874 *
2875 * Make sure the agent goes away when the parent dies */
2876 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
2877 _exit(EXIT_FAILURE);
2878
8a7c93d8
LP
2879 /* Make sure we actually can kill the agent, if we need to, in
2880 * case somebody invoked us from a shell script that trapped
2881 * SIGTERM or so... */
ce30c8dc
LP
2882 (void) reset_all_signal_handlers();
2883 (void) reset_signal_mask();
8a7c93d8 2884
6bb92a16 2885 /* Check whether our parent died before we were able
8a7c93d8 2886 * to set the death signal and unblock the signals */
6bb92a16
LP
2887 if (getppid() != parent_pid)
2888 _exit(EXIT_SUCCESS);
2889
2890 /* Don't leak fds to the agent */
9bdc770c 2891 close_all_fds(except, n_except);
6bb92a16
LP
2892
2893 stdout_is_tty = isatty(STDOUT_FILENO);
2894 stderr_is_tty = isatty(STDERR_FILENO);
2895
2896 if (!stdout_is_tty || !stderr_is_tty) {
8a7c93d8
LP
2897 int fd;
2898
6bb92a16
LP
2899 /* Detach from stdout/stderr. and reopen
2900 * /dev/tty for them. This is important to
2901 * ensure that when systemctl is started via
2902 * popen() or a similar call that expects to
2903 * read EOF we actually do generate EOF and
2904 * not delay this indefinitely by because we
2905 * keep an unused copy of stdin around. */
2906 fd = open("/dev/tty", O_WRONLY);
2907 if (fd < 0) {
56f64d95 2908 log_error_errno(errno, "Failed to open /dev/tty: %m");
6bb92a16
LP
2909 _exit(EXIT_FAILURE);
2910 }
2911
2912 if (!stdout_is_tty)
2913 dup2(fd, STDOUT_FILENO);
2914
2915 if (!stderr_is_tty)
2916 dup2(fd, STDERR_FILENO);
2917
2918 if (fd > 2)
2919 close(fd);
2920 }
2921
2922 /* Count arguments */
2923 va_start(ap, path);
2924 for (n = 0; va_arg(ap, char*); n++)
2925 ;
2926 va_end(ap);
2927
2928 /* Allocate strv */
2929 l = alloca(sizeof(char *) * (n + 1));
2930
2931 /* Fill in arguments */
2932 va_start(ap, path);
2933 for (i = 0; i <= n; i++)
2934 l[i] = va_arg(ap, char*);
2935 va_end(ap);
2936
2937 execv(path, l);
2938 _exit(EXIT_FAILURE);
2939}
68faf98c
LP
2940
2941int setrlimit_closest(int resource, const struct rlimit *rlim) {
2942 struct rlimit highest, fixed;
2943
2944 assert(rlim);
2945
2946 if (setrlimit(resource, rlim) >= 0)
2947 return 0;
2948
2949 if (errno != EPERM)
2950 return -errno;
2951
2952 /* So we failed to set the desired setrlimit, then let's try
2953 * to get as close as we can */
2954 assert_se(getrlimit(resource, &highest) == 0);
2955
2956 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
2957 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
2958
2959 if (setrlimit(resource, &fixed) < 0)
2960 return -errno;
2961
2962 return 0;
2963}
3d9a4122 2964
3d7415f4
LP
2965bool http_etag_is_valid(const char *etag) {
2966 if (isempty(etag))
2967 return false;
2968
2969 if (!endswith(etag, "\""))
2970 return false;
2971
2972 if (!startswith(etag, "\"") && !startswith(etag, "W/\""))
2973 return false;
2974
2975 return true;
2976}
2977
a2e03378
LP
2978bool http_url_is_valid(const char *url) {
2979 const char *p;
49dbfa7b 2980
a2e03378
LP
2981 if (isempty(url))
2982 return false;
49dbfa7b 2983
a2e03378
LP
2984 p = startswith(url, "http://");
2985 if (!p)
2986 p = startswith(url, "https://");
2987 if (!p)
2988 return false;
49dbfa7b 2989
a2e03378
LP
2990 if (isempty(p))
2991 return false;
49dbfa7b 2992
a2e03378
LP
2993 return ascii_is_valid(p);
2994}
49dbfa7b 2995
a2e03378
LP
2996bool documentation_url_is_valid(const char *url) {
2997 const char *p;
2998
2999 if (isempty(url))
3000 return false;
3001
3002 if (http_url_is_valid(url))
49dbfa7b
LP
3003 return true;
3004
a2e03378
LP
3005 p = startswith(url, "file:/");
3006 if (!p)
3007 p = startswith(url, "info:");
3008 if (!p)
3009 p = startswith(url, "man:");
3010
3011 if (isempty(p))
3012 return false;
3013
3014 return ascii_is_valid(p);
49dbfa7b 3015}
9be346c9
HH
3016
3017bool in_initrd(void) {
73020ab2 3018 static int saved = -1;
825c6fe5 3019 struct statfs s;
8f33b5b8 3020
825c6fe5
LP
3021 if (saved >= 0)
3022 return saved;
3023
3024 /* We make two checks here:
3025 *
3026 * 1. the flag file /etc/initrd-release must exist
3027 * 2. the root file system must be a memory file system
3028 *
3029 * The second check is extra paranoia, since misdetecting an
3030 * initrd can have bad bad consequences due the initrd
3031 * emptying when transititioning to the main systemd.
3032 */
3033
3034 saved = access("/etc/initrd-release", F_OK) >= 0 &&
3035 statfs("/", &s) >= 0 &&
943aad8c 3036 is_temporary_fs(&s);
9be346c9 3037
8f33b5b8 3038 return saved;
9be346c9 3039}
069cfc85 3040
7c5f152a 3041int get_home_dir(char **_h) {
2cfbd749 3042 struct passwd *p;
7c5f152a 3043 const char *e;
2cfbd749 3044 char *h;
7c5f152a 3045 uid_t u;
7c5f152a
LP
3046
3047 assert(_h);
3048
3049 /* Take the user specified one */
9a00f57a
LP
3050 e = secure_getenv("HOME");
3051 if (e && path_is_absolute(e)) {
7c5f152a
LP
3052 h = strdup(e);
3053 if (!h)
3054 return -ENOMEM;
3055
3056 *_h = h;
3057 return 0;
3058 }
3059
3060 /* Hardcode home directory for root to avoid NSS */
3061 u = getuid();
3062 if (u == 0) {
3063 h = strdup("/root");
3064 if (!h)
3065 return -ENOMEM;
3066
3067 *_h = h;
3068 return 0;
3069 }
3070
3071 /* Check the database... */
3072 errno = 0;
3073 p = getpwuid(u);
3074 if (!p)
bcb161b0 3075 return errno > 0 ? -errno : -ESRCH;
7c5f152a
LP
3076
3077 if (!path_is_absolute(p->pw_dir))
3078 return -EINVAL;
3079
3080 h = strdup(p->pw_dir);
3081 if (!h)
3082 return -ENOMEM;
3083
3084 *_h = h;
3085 return 0;
3086}
3087
2cfbd749
LP
3088int get_shell(char **_s) {
3089 struct passwd *p;
3090 const char *e;
3091 char *s;
3092 uid_t u;
3093
3094 assert(_s);
3095
3096 /* Take the user specified one */
3097 e = getenv("SHELL");
3098 if (e) {
3099 s = strdup(e);
3100 if (!s)
3101 return -ENOMEM;
3102
3103 *_s = s;
3104 return 0;
3105 }
3106
3107 /* Hardcode home directory for root to avoid NSS */
3108 u = getuid();
3109 if (u == 0) {
3110 s = strdup("/bin/sh");
3111 if (!s)
3112 return -ENOMEM;
3113
3114 *_s = s;
3115 return 0;
3116 }
3117
3118 /* Check the database... */
3119 errno = 0;
3120 p = getpwuid(u);
3121 if (!p)
3122 return errno > 0 ? -errno : -ESRCH;
3123
3124 if (!path_is_absolute(p->pw_shell))
3125 return -EINVAL;
3126
3127 s = strdup(p->pw_shell);
3128 if (!s)
3129 return -ENOMEM;
3130
3131 *_s = s;
3132 return 0;
3133}
3134
ae6c3cc0 3135bool filename_is_valid(const char *p) {
0b507b17
LP
3136
3137 if (isempty(p))
3138 return false;
3139
3140 if (strchr(p, '/'))
3141 return false;
3142
3143 if (streq(p, "."))
3144 return false;
3145
3146 if (streq(p, ".."))
3147 return false;
3148
3149 if (strlen(p) > FILENAME_MAX)
3150 return false;
3151
3152 return true;
3153}
3154
3155bool string_is_safe(const char *p) {
3156 const char *t;
3157
6294aa76
LP
3158 if (!p)
3159 return false;
0b507b17
LP
3160
3161 for (t = p; *t; t++) {
01539d6e 3162 if (*t > 0 && *t < ' ')
0b507b17
LP
3163 return false;
3164
843f6bf4 3165 if (strchr("\\\"\'\x7f", *t))
0b507b17
LP
3166 return false;
3167 }
3168
3169 return true;
3170}
cfbc22ab 3171
e884315e
LP
3172bool path_is_safe(const char *p) {
3173
3174 if (isempty(p))
3175 return false;
3176
3177 if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
3178 return false;
3179
6442185a 3180 if (strlen(p)+1 > PATH_MAX)
e884315e
LP
3181 return false;
3182
3183 /* The following two checks are not really dangerous, but hey, they still are confusing */
3184 if (streq(p, ".") || startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
3185 return false;
3186
3187 if (strstr(p, "//"))
3188 return false;
3189
3190 return true;
3191}
3192
a9e12476
KS
3193/* hey glibc, APIs with callbacks without a user pointer are so useless */
3194void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
1c574591 3195 int (*compar) (const void *, const void *, void *), void *arg) {
a9e12476
KS
3196 size_t l, u, idx;
3197 const void *p;
3198 int comparison;
3199
3200 l = 0;
3201 u = nmemb;
3202 while (l < u) {
3203 idx = (l + u) / 2;
3204 p = (void *)(((const char *) base) + (idx * size));
3205 comparison = compar(key, p, arg);
3206 if (comparison < 0)
3207 u = idx;
3208 else if (comparison > 0)
3209 l = idx + 1;
3210 else
3211 return (void *)p;
3212 }
3213 return NULL;
3214}
09017585 3215
20f56fdd
DR
3216void init_gettext(void) {
3217 setlocale(LC_ALL, "");
3218 textdomain(GETTEXT_PACKAGE);
3219}
3220
09017585
MS
3221bool is_locale_utf8(void) {
3222 const char *set;
3223 static int cached_answer = -1;
3224
3225 if (cached_answer >= 0)
3226 goto out;
3227
3228 if (!setlocale(LC_ALL, "")) {
3229 cached_answer = true;
3230 goto out;
3231 }
3232
3233 set = nl_langinfo(CODESET);
3234 if (!set) {
3235 cached_answer = true;
3236 goto out;
3237 }
3238
f168c273 3239 if (streq(set, "UTF-8")) {
fee79e01
HH
3240 cached_answer = true;
3241 goto out;
3242 }
3243
6cf2f1d9
HH
3244 /* For LC_CTYPE=="C" return true, because CTYPE is effectly
3245 * unset and everything can do to UTF-8 nowadays. */
fee79e01
HH
3246 set = setlocale(LC_CTYPE, NULL);
3247 if (!set) {
3248 cached_answer = true;
3249 goto out;
3250 }
3251
6cf2f1d9
HH
3252 /* Check result, but ignore the result if C was set
3253 * explicitly. */
3254 cached_answer =
9797f89b 3255 STR_IN_SET(set, "C", "POSIX") &&
6cf2f1d9
HH
3256 !getenv("LC_ALL") &&
3257 !getenv("LC_CTYPE") &&
3258 !getenv("LANG");
fee79e01 3259
09017585 3260out:
6cf2f1d9 3261 return (bool) cached_answer;
09017585 3262}
c339d977
MS
3263
3264const char *draw_special_char(DrawSpecialChar ch) {
3265 static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
6b01f1d3 3266
c339d977 3267 /* UTF-8 */ {
6b01f1d3 3268 [DRAW_TREE_VERTICAL] = "\342\224\202 ", /* │ */
45a5ff0d
MS
3269 [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */
3270 [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */
55c0b89c 3271 [DRAW_TREE_SPACE] = " ", /* */
6b01f1d3
LP
3272 [DRAW_TRIANGULAR_BULLET] = "\342\200\243", /* ‣ */
3273 [DRAW_BLACK_CIRCLE] = "\342\227\217", /* ● */
3274 [DRAW_ARROW] = "\342\206\222", /* → */
13f8b8cb 3275 [DRAW_DASH] = "\342\200\223", /* – */
c339d977 3276 },
6b01f1d3 3277
c339d977 3278 /* ASCII fallback */ {
6b01f1d3 3279 [DRAW_TREE_VERTICAL] = "| ",
45a5ff0d
MS
3280 [DRAW_TREE_BRANCH] = "|-",
3281 [DRAW_TREE_RIGHT] = "`-",
55c0b89c 3282 [DRAW_TREE_SPACE] = " ",
6b01f1d3
LP
3283 [DRAW_TRIANGULAR_BULLET] = ">",
3284 [DRAW_BLACK_CIRCLE] = "*",
3285 [DRAW_ARROW] = "->",
13f8b8cb 3286 [DRAW_DASH] = "-",
c339d977
MS
3287 }
3288 };
3289
3290 return draw_table[!is_locale_utf8()][ch];
3291}
409bc9c3 3292
240dbaa4
LP
3293int on_ac_power(void) {
3294 bool found_offline = false, found_online = false;
3295 _cleanup_closedir_ DIR *d = NULL;
3296
3297 d = opendir("/sys/class/power_supply");
3298 if (!d)
6d890034 3299 return errno == ENOENT ? true : -errno;
240dbaa4
LP
3300
3301 for (;;) {
3302 struct dirent *de;
240dbaa4
LP
3303 _cleanup_close_ int fd = -1, device = -1;
3304 char contents[6];
3305 ssize_t n;
240dbaa4 3306
3fd11280
FW
3307 errno = 0;
3308 de = readdir(d);
3309 if (!de && errno != 0)
3310 return -errno;
240dbaa4
LP
3311
3312 if (!de)
3313 break;
3314
a34bf9db 3315 if (hidden_file(de->d_name))
240dbaa4
LP
3316 continue;
3317
3318 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
3319 if (device < 0) {
3320 if (errno == ENOENT || errno == ENOTDIR)
3321 continue;
3322
3323 return -errno;
3324 }
3325
3326 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
3327 if (fd < 0) {
3328 if (errno == ENOENT)
3329 continue;
3330
3331 return -errno;
3332 }
3333
3334 n = read(fd, contents, sizeof(contents));
3335 if (n < 0)
3336 return -errno;
3337
3338 if (n != 6 || memcmp(contents, "Mains\n", 6))
3339 continue;
3340
03e334a1 3341 safe_close(fd);
240dbaa4
LP
3342 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
3343 if (fd < 0) {
3344 if (errno == ENOENT)
3345 continue;
3346
3347 return -errno;
3348 }
3349
3350 n = read(fd, contents, sizeof(contents));
3351 if (n < 0)
3352 return -errno;
3353
3354 if (n != 2 || contents[1] != '\n')
3355 return -EIO;
3356
3357 if (contents[0] == '1') {
3358 found_online = true;
3359 break;
3360 } else if (contents[0] == '0')
3361 found_offline = true;
3362 else
3363 return -EIO;
3364 }
3365
3366 return found_online || !found_offline;
3367}
fabe5c0e 3368
4cf7ea55 3369static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
fabe5c0e
LP
3370 char **i;
3371
3372 assert(path);
3373 assert(mode);
3374 assert(_f);
3375
7d8da2c9 3376 if (!path_strv_resolve_uniq(search, root))
fabe5c0e
LP
3377 return -ENOMEM;
3378
3379 STRV_FOREACH(i, search) {
3380 _cleanup_free_ char *p = NULL;
3381 FILE *f;
3382
375eadd9
MM
3383 if (root)
3384 p = strjoin(root, *i, "/", path, NULL);
3385 else
3386 p = strjoin(*i, "/", path, NULL);
fabe5c0e
LP
3387 if (!p)
3388 return -ENOMEM;
3389
3390 f = fopen(p, mode);
3391 if (f) {
3392 *_f = f;
3393 return 0;
3394 }
3395
3396 if (errno != ENOENT)
3397 return -errno;
3398 }
3399
3400 return -ENOENT;
3401}
3402
4cf7ea55 3403int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
fabe5c0e
LP
3404 _cleanup_strv_free_ char **copy = NULL;
3405
3406 assert(path);
3407 assert(mode);
3408 assert(_f);
3409
3410 if (path_is_absolute(path)) {
3411 FILE *f;
3412
3413 f = fopen(path, mode);
3414 if (f) {
3415 *_f = f;
3416 return 0;
3417 }
3418
3419 return -errno;
3420 }
3421
3422 copy = strv_copy((char**) search);
3423 if (!copy)
3424 return -ENOMEM;
3425
4cf7ea55 3426 return search_and_fopen_internal(path, mode, root, copy, _f);
fabe5c0e
LP
3427}
3428
4cf7ea55 3429int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
fabe5c0e
LP
3430 _cleanup_strv_free_ char **s = NULL;
3431
3432 if (path_is_absolute(path)) {
3433 FILE *f;
3434
3435 f = fopen(path, mode);
3436 if (f) {
3437 *_f = f;
3438 return 0;
3439 }
3440
3441 return -errno;
3442 }
3443
3444 s = strv_split_nulstr(search);
3445 if (!s)
3446 return -ENOMEM;
3447
4cf7ea55 3448 return search_and_fopen_internal(path, mode, root, s, _f);
fabe5c0e 3449}
c17ec25e 3450
ca2d3784
ZJS
3451void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
3452 size_t a, newalloc;
392d5b37
LP
3453 void *q;
3454
98088803 3455 assert(p);
e93c33d4
SL
3456 assert(allocated);
3457
392d5b37
LP
3458 if (*allocated >= need)
3459 return *p;
3460
ca2d3784
ZJS
3461 newalloc = MAX(need * 2, 64u / size);
3462 a = newalloc * size;
98088803
LP
3463
3464 /* check for overflows */
ca2d3784 3465 if (a < size * need)
98088803
LP
3466 return NULL;
3467
392d5b37
LP
3468 q = realloc(*p, a);
3469 if (!q)
3470 return NULL;
3471
3472 *p = q;
ca2d3784 3473 *allocated = newalloc;
392d5b37
LP
3474 return q;
3475}
aa96c6cb 3476
ca2d3784 3477void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
98088803 3478 size_t prev;
4545a231
DH
3479 uint8_t *q;
3480
98088803
LP
3481 assert(p);
3482 assert(allocated);
3483
3484 prev = *allocated;
3485
ca2d3784 3486 q = greedy_realloc(p, allocated, need, size);
4545a231
DH
3487 if (!q)
3488 return NULL;
3489
3490 if (*allocated > prev)
ca2d3784 3491 memzero(q + prev * size, (*allocated - prev) * size);
4545a231
DH
3492
3493 return q;
3494}
3495
aa96c6cb
LP
3496bool id128_is_valid(const char *s) {
3497 size_t i, l;
3498
3499 l = strlen(s);
3500 if (l == 32) {
3501
3502 /* Simple formatted 128bit hex string */
3503
3504 for (i = 0; i < l; i++) {
3505 char c = s[i];
3506
3507 if (!(c >= '0' && c <= '9') &&
3508 !(c >= 'a' && c <= 'z') &&
3509 !(c >= 'A' && c <= 'Z'))
3510 return false;
3511 }
3512
3513 } else if (l == 36) {
3514
3515 /* Formatted UUID */
3516
3517 for (i = 0; i < l; i++) {
3518 char c = s[i];
3519
3520 if ((i == 8 || i == 13 || i == 18 || i == 23)) {
3521 if (c != '-')
3522 return false;
3523 } else {
3524 if (!(c >= '0' && c <= '9') &&
3525 !(c >= 'a' && c <= 'z') &&
3526 !(c >= 'A' && c <= 'Z'))
3527 return false;
3528 }
3529 }
3530
3531 } else
3532 return false;
3533
3534 return true;
3535}
7085053a 3536
74df0fca 3537int shall_restore_state(void) {
1a299299 3538 _cleanup_free_ char *value = NULL;
74df0fca 3539 int r;
295edddf 3540
1a299299 3541 r = get_proc_cmdline_key("systemd.restore_state=", &value);
74df0fca
LP
3542 if (r < 0)
3543 return r;
1a299299
LP
3544 if (r == 0)
3545 return true;
295edddf 3546
1a299299 3547 return parse_boolean(value) != 0;
74df0fca
LP
3548}
3549
3550int proc_cmdline(char **ret) {
b5884878 3551 assert(ret);
295edddf 3552
75f86906 3553 if (detect_container() > 0)
b5884878
LP
3554 return get_process_cmdline(1, 0, false, ret);
3555 else
3556 return read_one_line_file("/proc/cmdline", ret);
295edddf 3557}
bc9fd78c 3558
059cb385 3559int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
141a79f4 3560 _cleanup_free_ char *line = NULL;
f32d2db1 3561 const char *p;
141a79f4
ZJS
3562 int r;
3563
059cb385
LP
3564 assert(parse_item);
3565
141a79f4
ZJS
3566 r = proc_cmdline(&line);
3567 if (r < 0)
b5884878 3568 return r;
141a79f4 3569
f32d2db1
LP
3570 p = line;
3571 for (;;) {
3572 _cleanup_free_ char *word = NULL;
3573 char *value = NULL;
141a79f4 3574
12ba2c44 3575 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
f32d2db1
LP
3576 if (r < 0)
3577 return r;
3578 if (r == 0)
3579 break;
141a79f4 3580
059cb385
LP
3581 /* Filter out arguments that are intended only for the
3582 * initrd */
3583 if (!in_initrd() && startswith(word, "rd."))
3584 continue;
3585
3586 value = strchr(word, '=');
3587 if (value)
3588 *(value++) = 0;
3589
3590 r = parse_item(word, value);
3591 if (r < 0)
141a79f4 3592 return r;
141a79f4
ZJS
3593 }
3594
3595 return 0;
3596}
3597
1a299299
LP
3598int get_proc_cmdline_key(const char *key, char **value) {
3599 _cleanup_free_ char *line = NULL, *ret = NULL;
3600 bool found = false;
3601 const char *p;
3602 int r;
3603
3604 assert(key);
3605
3606 r = proc_cmdline(&line);
3607 if (r < 0)
3608 return r;
3609
3610 p = line;
3611 for (;;) {
3612 _cleanup_free_ char *word = NULL;
3613 const char *e;
3614
12ba2c44 3615 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
1a299299
LP
3616 if (r < 0)
3617 return r;
3618 if (r == 0)
3619 break;
3620
3621 /* Filter out arguments that are intended only for the
3622 * initrd */
3623 if (!in_initrd() && startswith(word, "rd."))
3624 continue;
3625
3626 if (value) {
3627 e = startswith(word, key);
3628 if (!e)
3629 continue;
3630
3631 r = free_and_strdup(&ret, e);
3632 if (r < 0)
3633 return r;
3634
3635 found = true;
3636 } else {
3637 if (streq(word, key))
3638 found = true;
3639 }
3640 }
3641
3642 if (value) {
3643 *value = ret;
3644 ret = NULL;
3645 }
3646
3647 return found;
3648
3649}
3650
bc9fd78c
LP
3651int container_get_leader(const char *machine, pid_t *pid) {
3652 _cleanup_free_ char *s = NULL, *class = NULL;
3653 const char *p;
3654 pid_t leader;
3655 int r;
3656
3657 assert(machine);
3658 assert(pid);
3659
b9a8d250
LP
3660 if (!machine_name_is_valid(machine))
3661 return -EINVAL;
3662
63c372cb 3663 p = strjoina("/run/systemd/machines/", machine);
bc9fd78c
LP
3664 r = parse_env_file(p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
3665 if (r == -ENOENT)
3666 return -EHOSTDOWN;
3667 if (r < 0)
3668 return r;
3669 if (!s)
3670 return -EIO;
3671
3672 if (!streq_ptr(class, "container"))
3673 return -EIO;
3674
3675 r = parse_pid(s, &leader);
3676 if (r < 0)
3677 return r;
3678 if (leader <= 1)
3679 return -EIO;
3680
3681 *pid = leader;
3682 return 0;
3683}
3684
671c3419
RM
3685int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd) {
3686 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, netnsfd = -1, usernsfd = -1;
359a06aa 3687 int rfd = -1;
bc9fd78c
LP
3688
3689 assert(pid >= 0);
bc9fd78c 3690
878cd7e9
LP
3691 if (mntns_fd) {
3692 const char *mntns;
a4475f57 3693
878cd7e9
LP
3694 mntns = procfs_file_alloca(pid, "ns/mnt");
3695 mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
3696 if (mntnsfd < 0)
3697 return -errno;
3698 }
bc9fd78c 3699
878cd7e9
LP
3700 if (pidns_fd) {
3701 const char *pidns;
3702
3703 pidns = procfs_file_alloca(pid, "ns/pid");
3704 pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
3705 if (pidnsfd < 0)
3706 return -errno;
3707 }
3708
3709 if (netns_fd) {
3710 const char *netns;
3711
3712 netns = procfs_file_alloca(pid, "ns/net");
3713 netnsfd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
3714 if (netnsfd < 0)
3715 return -errno;
3716 }
3717
671c3419
RM
3718 if (userns_fd) {
3719 const char *userns;
3720
3721 userns = procfs_file_alloca(pid, "ns/user");
3722 usernsfd = open(userns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
3723 if (usernsfd < 0 && errno != ENOENT)
3724 return -errno;
3725 }
3726
878cd7e9
LP
3727 if (root_fd) {
3728 const char *root;
3729
3730 root = procfs_file_alloca(pid, "root");
3731 rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
3732 if (rfd < 0)
3733 return -errno;
3734 }
3735
3736 if (pidns_fd)
3737 *pidns_fd = pidnsfd;
bc9fd78c 3738
878cd7e9
LP
3739 if (mntns_fd)
3740 *mntns_fd = mntnsfd;
3741
3742 if (netns_fd)
3743 *netns_fd = netnsfd;
3744
671c3419
RM
3745 if (userns_fd)
3746 *userns_fd = usernsfd;
3747
878cd7e9
LP
3748 if (root_fd)
3749 *root_fd = rfd;
3750
671c3419 3751 pidnsfd = mntnsfd = netnsfd = usernsfd = -1;
bc9fd78c
LP
3752
3753 return 0;
3754}
3755
671c3419
RM
3756int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd) {
3757 if (userns_fd >= 0) {
3758 /* Can't setns to your own userns, since then you could
3759 * escalate from non-root to root in your own namespace, so
3760 * check if namespaces equal before attempting to enter. */
3761 _cleanup_free_ char *userns_fd_path = NULL;
3762 int r;
3763 if (asprintf(&userns_fd_path, "/proc/self/fd/%d", userns_fd) < 0)
3764 return -ENOMEM;
3765
3766 r = files_same(userns_fd_path, "/proc/self/ns/user");
3767 if (r < 0)
3768 return r;
3769 if (r)
3770 userns_fd = -1;
3771 }
bc9fd78c 3772
878cd7e9
LP
3773 if (pidns_fd >= 0)
3774 if (setns(pidns_fd, CLONE_NEWPID) < 0)
3775 return -errno;
a4475f57 3776
878cd7e9
LP
3777 if (mntns_fd >= 0)
3778 if (setns(mntns_fd, CLONE_NEWNS) < 0)
3779 return -errno;
bc9fd78c 3780
878cd7e9
LP
3781 if (netns_fd >= 0)
3782 if (setns(netns_fd, CLONE_NEWNET) < 0)
3783 return -errno;
bc9fd78c 3784
671c3419
RM
3785 if (userns_fd >= 0)
3786 if (setns(userns_fd, CLONE_NEWUSER) < 0)
3787 return -errno;
3788
878cd7e9
LP
3789 if (root_fd >= 0) {
3790 if (fchdir(root_fd) < 0)
3791 return -errno;
3792
3793 if (chroot(".") < 0)
3794 return -errno;
3795 }
bc9fd78c 3796
b4da6d6b 3797 return reset_uid_gid();
bc9fd78c 3798}
bf108e55 3799
eff05270
LP
3800int getpeercred(int fd, struct ucred *ucred) {
3801 socklen_t n = sizeof(struct ucred);
3802 struct ucred u;
3803 int r;
3804
3805 assert(fd >= 0);
3806 assert(ucred);
3807
3808 r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
3809 if (r < 0)
3810 return -errno;
3811
3812 if (n != sizeof(struct ucred))
3813 return -EIO;
3814
3815 /* Check if the data is actually useful and not suppressed due
3816 * to namespacing issues */
3817 if (u.pid <= 0)
3818 return -ENODATA;
fed1e721 3819 if (u.uid == UID_INVALID)
62028d9c 3820 return -ENODATA;
fed1e721 3821 if (u.gid == GID_INVALID)
62028d9c 3822 return -ENODATA;
eff05270
LP
3823
3824 *ucred = u;
3825 return 0;
3826}
3827
3828int getpeersec(int fd, char **ret) {
3829 socklen_t n = 64;
3830 char *s;
3831 int r;
3832
3833 assert(fd >= 0);
3834 assert(ret);
3835
3836 s = new0(char, n);
3837 if (!s)
3838 return -ENOMEM;
3839
3840 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
3841 if (r < 0) {
3842 free(s);
3843
3844 if (errno != ERANGE)
3845 return -errno;
3846
3847 s = new0(char, n);
3848 if (!s)
3849 return -ENOMEM;
3850
3851 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
3852 if (r < 0) {
3853 free(s);
3854 return -errno;
3855 }
3856 }
3857
ae98841e
LP
3858 if (isempty(s)) {
3859 free(s);
15411c0c 3860 return -EOPNOTSUPP;
ae98841e
LP
3861 }
3862
eff05270
LP
3863 *ret = s;
3864 return 0;
3865}
8e33886e 3866
0f010ef2 3867/* This is much like like mkostemp() but is subject to umask(). */
65b3903f 3868int mkostemp_safe(char *pattern, int flags) {
2d5bdf5b 3869 _cleanup_umask_ mode_t u;
0f010ef2 3870 int fd;
65b3903f 3871
d37a91e8 3872 assert(pattern);
65b3903f 3873
2d5bdf5b
LP
3874 u = umask(077);
3875
0f010ef2
ZJS
3876 fd = mkostemp(pattern, flags);
3877 if (fd < 0)
3878 return -errno;
65b3903f 3879
0f010ef2 3880 return fd;
65b3903f
ZJS
3881}
3882
8e33886e 3883int open_tmpfile(const char *path, int flags) {
8e33886e 3884 char *p;
a6afc4ae
LP
3885 int fd;
3886
3887 assert(path);
8e33886e
ZJS
3888
3889#ifdef O_TMPFILE
7736202c 3890 /* Try O_TMPFILE first, if it is supported */
a765f344 3891 fd = open(path, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
8e33886e
ZJS
3892 if (fd >= 0)
3893 return fd;
3894#endif
7736202c
LP
3895
3896 /* Fall back to unguessable name + unlinking */
63c372cb 3897 p = strjoina(path, "/systemd-tmp-XXXXXX");
8e33886e 3898
a6afc4ae 3899 fd = mkostemp_safe(p, flags);
8e33886e 3900 if (fd < 0)
65b3903f 3901 return fd;
8e33886e
ZJS
3902
3903 unlink(p);
3904 return fd;
3905}
fdb9161c
LP
3906
3907int fd_warn_permissions(const char *path, int fd) {
3908 struct stat st;
3909
3910 if (fstat(fd, &st) < 0)
3911 return -errno;
3912
3913 if (st.st_mode & 0111)
3914 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
3915
3916 if (st.st_mode & 0002)
3917 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
3918
3919 if (getpid() == 1 && (st.st_mode & 0044) != 0044)
3920 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);
3921
3922 return 0;
3923}
6afc95b7 3924
ac45f971 3925unsigned long personality_from_string(const char *p) {
6afc95b7
LP
3926
3927 /* Parse a personality specifier. We introduce our own
3928 * identifiers that indicate specific ABIs, rather than just
3929 * hints regarding the register size, since we want to keep
3930 * things open for multiple locally supported ABIs for the
3931 * same register size. We try to reuse the ABI identifiers
3932 * used by libseccomp. */
3933
3934#if defined(__x86_64__)
3935
3936 if (streq(p, "x86"))
3937 return PER_LINUX32;
3938
3939 if (streq(p, "x86-64"))
3940 return PER_LINUX;
3941
3942#elif defined(__i386__)
3943
3944 if (streq(p, "x86"))
3945 return PER_LINUX;
7517f51e
HB
3946
3947#elif defined(__s390x__)
3948
3949 if (streq(p, "s390"))
3950 return PER_LINUX32;
3951
3952 if (streq(p, "s390x"))
3953 return PER_LINUX;
3954
3955#elif defined(__s390__)
3956
3957 if (streq(p, "s390"))
3958 return PER_LINUX;
6afc95b7
LP
3959#endif
3960
050f7277 3961 return PERSONALITY_INVALID;
6afc95b7 3962}
ac45f971
LP
3963
3964const char* personality_to_string(unsigned long p) {
3965
3966#if defined(__x86_64__)
3967
3968 if (p == PER_LINUX32)
3969 return "x86";
3970
3971 if (p == PER_LINUX)
3972 return "x86-64";
3973
3974#elif defined(__i386__)
3975
3976 if (p == PER_LINUX)
3977 return "x86";
7517f51e
HB
3978
3979#elif defined(__s390x__)
3980
3981 if (p == PER_LINUX)
3982 return "s390x";
3983
3984 if (p == PER_LINUX32)
3985 return "s390";
3986
3987#elif defined(__s390__)
3988
3989 if (p == PER_LINUX)
3990 return "s390";
3991
ac45f971
LP
3992#endif
3993
3994 return NULL;
3995}
1c231f56
LP
3996
3997uint64_t physical_memory(void) {
3998 long mem;
3999
4000 /* We return this as uint64_t in case we are running as 32bit
4001 * process on a 64bit kernel with huge amounts of memory */
4002
4003 mem = sysconf(_SC_PHYS_PAGES);
4004 assert(mem > 0);
4005
4006 return (uint64_t) mem * (uint64_t) page_size();
4007}
6db615c1 4008
29bfbcd6
LP
4009void hexdump(FILE *f, const void *p, size_t s) {
4010 const uint8_t *b = p;
4011 unsigned n = 0;
4012
4013 assert(s == 0 || b);
4014
4015 while (s > 0) {
4016 size_t i;
4017
4018 fprintf(f, "%04x ", n);
4019
4020 for (i = 0; i < 16; i++) {
4021
4022 if (i >= s)
4023 fputs(" ", f);
4024 else
4025 fprintf(f, "%02x ", b[i]);
4026
4027 if (i == 7)
4028 fputc(' ', f);
4029 }
4030
4031 fputc(' ', f);
4032
4033 for (i = 0; i < 16; i++) {
4034
4035 if (i >= s)
4036 fputc(' ', f);
4037 else
4038 fputc(isprint(b[i]) ? (char) b[i] : '.', f);
4039 }
4040
4041 fputc('\n', f);
4042
4043 if (s < 16)
4044 break;
4045
4046 n += 16;
4047 b += 16;
4048 s -= 16;
4049 }
4050}
c5220a94 4051
966bff26 4052int update_reboot_param_file(const char *param) {
c5220a94
MO
4053 int r = 0;
4054
4055 if (param) {
4c1fc3e4 4056 r = write_string_file(REBOOT_PARAM_FILE, param, WRITE_STRING_FILE_CREATE);
c5220a94 4057 if (r < 0)
e53fc357 4058 return log_error_errno(r, "Failed to write reboot param to "REBOOT_PARAM_FILE": %m");
c5220a94 4059 } else
e53fc357 4060 (void) unlink(REBOOT_PARAM_FILE);
c5220a94 4061
e53fc357 4062 return 0;
c5220a94 4063}
6d313367
LP
4064
4065int umount_recursive(const char *prefix, int flags) {
4066 bool again;
4067 int n = 0, r;
4068
4069 /* Try to umount everything recursively below a
4070 * directory. Also, take care of stacked mounts, and keep
4071 * unmounting them until they are gone. */
4072
4073 do {
4074 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
4075
4076 again = false;
4077 r = 0;
4078
4079 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
4080 if (!proc_self_mountinfo)
4081 return -errno;
4082
4083 for (;;) {
4084 _cleanup_free_ char *path = NULL, *p = NULL;
4085 int k;
4086
4087 k = fscanf(proc_self_mountinfo,
4088 "%*s " /* (1) mount id */
4089 "%*s " /* (2) parent id */
4090 "%*s " /* (3) major:minor */
4091 "%*s " /* (4) root */
4092 "%ms " /* (5) mount point */
4093 "%*s" /* (6) mount options */
4094 "%*[^-]" /* (7) optional fields */
4095 "- " /* (8) separator */
4096 "%*s " /* (9) file system type */
4097 "%*s" /* (10) mount source */
4098 "%*s" /* (11) mount options 2 */
4099 "%*[^\n]", /* some rubbish at the end */
4100 &path);
6d313367
LP
4101 if (k != 1) {
4102 if (k == EOF)
4103 break;
4104
4105 continue;
4106 }
4107
527b7a42
LP
4108 r = cunescape(path, UNESCAPE_RELAX, &p);
4109 if (r < 0)
4110 return r;
6d313367
LP
4111
4112 if (!path_startswith(p, prefix))
4113 continue;
4114
4115 if (umount2(p, flags) < 0) {
4116 r = -errno;
4117 continue;
4118 }
4119
4120 again = true;
4121 n++;
4122
4123 break;
4124 }
4125
4126 } while (again);
4127
4128 return r ? r : n;
4129}
d6797c92 4130
abe4aa14
TM
4131static int get_mount_flags(const char *path, unsigned long *flags) {
4132 struct statvfs buf;
4133
4134 if (statvfs(path, &buf) < 0)
4135 return -errno;
4136 *flags = buf.f_flag;
4137 return 0;
4138}
4139
d6797c92
LP
4140int bind_remount_recursive(const char *prefix, bool ro) {
4141 _cleanup_set_free_free_ Set *done = NULL;
4142 _cleanup_free_ char *cleaned = NULL;
4143 int r;
4144
4145 /* Recursively remount a directory (and all its submounts)
4146 * read-only or read-write. If the directory is already
4147 * mounted, we reuse the mount and simply mark it
4148 * MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write
4149 * operation). If it isn't we first make it one. Afterwards we
4150 * apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to all
4151 * submounts we can access, too. When mounts are stacked on
4152 * the same mount point we only care for each individual
4153 * "top-level" mount on each point, as we cannot
4154 * influence/access the underlying mounts anyway. We do not
4155 * have any effect on future submounts that might get
4156 * propagated, they migt be writable. This includes future
4157 * submounts that have been triggered via autofs. */
4158
4159 cleaned = strdup(prefix);
4160 if (!cleaned)
4161 return -ENOMEM;
4162
4163 path_kill_slashes(cleaned);
4164
d5099efc 4165 done = set_new(&string_hash_ops);
d6797c92
LP
4166 if (!done)
4167 return -ENOMEM;
4168
4169 for (;;) {
4170 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
4171 _cleanup_set_free_free_ Set *todo = NULL;
4172 bool top_autofs = false;
4173 char *x;
abe4aa14 4174 unsigned long orig_flags;
d6797c92 4175
d5099efc 4176 todo = set_new(&string_hash_ops);
d6797c92
LP
4177 if (!todo)
4178 return -ENOMEM;
4179
4180 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
4181 if (!proc_self_mountinfo)
4182 return -errno;
4183
4184 for (;;) {
4185 _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
4186 int k;
4187
4188 k = fscanf(proc_self_mountinfo,
4189 "%*s " /* (1) mount id */
4190 "%*s " /* (2) parent id */
4191 "%*s " /* (3) major:minor */
4192 "%*s " /* (4) root */
4193 "%ms " /* (5) mount point */
4194 "%*s" /* (6) mount options (superblock) */
4195 "%*[^-]" /* (7) optional fields */
4196 "- " /* (8) separator */
4197 "%ms " /* (9) file system type */
4198 "%*s" /* (10) mount source */
4199 "%*s" /* (11) mount options (bind mount) */
4200 "%*[^\n]", /* some rubbish at the end */
4201 &path,
4202 &type);
4203 if (k != 2) {
4204 if (k == EOF)
4205 break;
4206
4207 continue;
4208 }
4209
527b7a42
LP
4210 r = cunescape(path, UNESCAPE_RELAX, &p);
4211 if (r < 0)
4212 return r;
d6797c92
LP
4213
4214 /* Let's ignore autofs mounts. If they aren't
4215 * triggered yet, we want to avoid triggering
4216 * them, as we don't make any guarantees for
4217 * future submounts anyway. If they are
4218 * already triggered, then we will find
4219 * another entry for this. */
4220 if (streq(type, "autofs")) {
4221 top_autofs = top_autofs || path_equal(cleaned, p);
4222 continue;
4223 }
4224
4225 if (path_startswith(p, cleaned) &&
4226 !set_contains(done, p)) {
4227
4228 r = set_consume(todo, p);
4229 p = NULL;
4230
4231 if (r == -EEXIST)
4232 continue;
4233 if (r < 0)
4234 return r;
4235 }
4236 }
4237
4238 /* If we have no submounts to process anymore and if
4239 * the root is either already done, or an autofs, we
4240 * are done */
4241 if (set_isempty(todo) &&
4242 (top_autofs || set_contains(done, cleaned)))
4243 return 0;
4244
4245 if (!set_contains(done, cleaned) &&
4246 !set_contains(todo, cleaned)) {
4247 /* The prefix directory itself is not yet a
4248 * mount, make it one. */
4249 if (mount(cleaned, cleaned, NULL, MS_BIND|MS_REC, NULL) < 0)
4250 return -errno;
4251
a7e07206
LP
4252 orig_flags = 0;
4253 (void) get_mount_flags(cleaned, &orig_flags);
abe4aa14 4254 orig_flags &= ~MS_RDONLY;
a7e07206 4255
abe4aa14 4256 if (mount(NULL, prefix, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0)
d6797c92
LP
4257 return -errno;
4258
4259 x = strdup(cleaned);
4260 if (!x)
4261 return -ENOMEM;
4262
4263 r = set_consume(done, x);
4264 if (r < 0)
4265 return r;
4266 }
4267
4268 while ((x = set_steal_first(todo))) {
4269
f871aeed 4270 r = set_consume(done, x);
85d834ae 4271 if (r == -EEXIST || r == 0)
d6797c92 4272 continue;
f871aeed 4273 if (r < 0)
d6797c92
LP
4274 return r;
4275
a7e07206
LP
4276 /* Try to reuse the original flag set, but
4277 * don't care for errors, in case of
4278 * obstructed mounts */
4279 orig_flags = 0;
4280 (void) get_mount_flags(x, &orig_flags);
abe4aa14 4281 orig_flags &= ~MS_RDONLY;
a7e07206 4282
abe4aa14 4283 if (mount(NULL, x, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) {
f871aeed 4284
d6797c92
LP
4285 /* Deal with mount points that are
4286 * obstructed by a later mount */
4287
f871aeed 4288 if (errno != ENOENT)
d6797c92
LP
4289 return -errno;
4290 }
f871aeed 4291
d6797c92
LP
4292 }
4293 }
4294}
1b992147
LP
4295
4296int fflush_and_check(FILE *f) {
45c196a7 4297 assert(f);
1b992147
LP
4298
4299 errno = 0;
4300 fflush(f);
4301
4302 if (ferror(f))
4303 return errno ? -errno : -EIO;
4304
4305 return 0;
4306}
2e78fa79 4307
14bcf25c 4308int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
2e78fa79
LP
4309 const char *fn;
4310 char *t;
2e78fa79
LP
4311
4312 assert(p);
ae6c3cc0
LP
4313 assert(ret);
4314
c4e34a61
LP
4315 /*
4316 * Turns this:
4317 * /foo/bar/waldo
4318 *
4319 * Into this:
14bcf25c 4320 * /foo/bar/.#<extra>waldoXXXXXX
c4e34a61
LP
4321 */
4322
ae6c3cc0
LP
4323 fn = basename(p);
4324 if (!filename_is_valid(fn))
4325 return -EINVAL;
2e78fa79 4326
14bcf25c
LP
4327 if (extra == NULL)
4328 extra = "";
4329
4330 t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
2e78fa79 4331 if (!t)
ae6c3cc0 4332 return -ENOMEM;
2e78fa79 4333
14bcf25c 4334 strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn), "XXXXXX");
2e78fa79 4335
c4e34a61 4336 *ret = path_kill_slashes(t);
ae6c3cc0 4337 return 0;
2e78fa79
LP
4338}
4339
14bcf25c 4340int tempfn_random(const char *p, const char *extra, char **ret) {
2e78fa79
LP
4341 const char *fn;
4342 char *t, *x;
4343 uint64_t u;
2e78fa79
LP
4344 unsigned i;
4345
4346 assert(p);
ae6c3cc0
LP
4347 assert(ret);
4348
c4e34a61
LP
4349 /*
4350 * Turns this:
4351 * /foo/bar/waldo
4352 *
4353 * Into this:
14bcf25c 4354 * /foo/bar/.#<extra>waldobaa2a261115984a9
c4e34a61
LP
4355 */
4356
ae6c3cc0
LP
4357 fn = basename(p);
4358 if (!filename_is_valid(fn))
4359 return -EINVAL;
2e78fa79 4360
14bcf25c
LP
4361 if (!extra)
4362 extra = "";
4363
4364 t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1);
2e78fa79 4365 if (!t)
ae6c3cc0 4366 return -ENOMEM;
2e78fa79 4367
14bcf25c 4368 x = stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn);
2e78fa79
LP
4369
4370 u = random_u64();
4371 for (i = 0; i < 16; i++) {
4372 *(x++) = hexchar(u & 0xF);
4373 u >>= 4;
4374 }
4375
4376 *x = 0;
4377
c4e34a61
LP
4378 *ret = path_kill_slashes(t);
4379 return 0;
4380}
4381
14bcf25c 4382int tempfn_random_child(const char *p, const char *extra, char **ret) {
c4e34a61
LP
4383 char *t, *x;
4384 uint64_t u;
4385 unsigned i;
4386
4387 assert(p);
4388 assert(ret);
4389
4390 /* Turns this:
4391 * /foo/bar/waldo
4392 * Into this:
14bcf25c 4393 * /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
c4e34a61
LP
4394 */
4395
14bcf25c
LP
4396 if (!extra)
4397 extra = "";
4398
4399 t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1);
c4e34a61
LP
4400 if (!t)
4401 return -ENOMEM;
4402
14bcf25c 4403 x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra);
c4e34a61
LP
4404
4405 u = random_u64();
4406 for (i = 0; i < 16; i++) {
4407 *(x++) = hexchar(u & 0xF);
4408 u >>= 4;
4409 }
4410
4411 *x = 0;
4412
4413 *ret = path_kill_slashes(t);
ae6c3cc0 4414 return 0;
2e78fa79 4415}
fecc80c1 4416
45035609
LP
4417int take_password_lock(const char *root) {
4418
4419 struct flock flock = {
4420 .l_type = F_WRLCK,
4421 .l_whence = SEEK_SET,
4422 .l_start = 0,
4423 .l_len = 0,
4424 };
4425
4426 const char *path;
4427 int fd, r;
4428
4429 /* This is roughly the same as lckpwdf(), but not as awful. We
4430 * don't want to use alarm() and signals, hence we implement
4431 * our own trivial version of this.
4432 *
4433 * Note that shadow-utils also takes per-database locks in
4434 * addition to lckpwdf(). However, we don't given that they
4435 * are redundant as they they invoke lckpwdf() first and keep
4436 * it during everything they do. The per-database locks are
4437 * awfully racy, and thus we just won't do them. */
4438
4439 if (root)
63c372cb 4440 path = strjoina(root, "/etc/.pwd.lock");
45035609
LP
4441 else
4442 path = "/etc/.pwd.lock";
4443
4444 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
4445 if (fd < 0)
4446 return -errno;
4447
4448 r = fcntl(fd, F_SETLKW, &flock);
4449 if (r < 0) {
4450 safe_close(fd);
4451 return -errno;
4452 }
4453
4454 return fd;
4455}
5261ba90
TT
4456
4457int is_symlink(const char *path) {
4458 struct stat info;
4459
4460 if (lstat(path, &info) < 0)
4461 return -errno;
4462
be57e297
LP
4463 return !!S_ISLNK(info.st_mode);
4464}
5261ba90 4465
be57e297
LP
4466int is_dir(const char* path, bool follow) {
4467 struct stat st;
d1bddcec 4468 int r;
be57e297 4469
d1bddcec
LP
4470 if (follow)
4471 r = stat(path, &st);
4472 else
4473 r = lstat(path, &st);
4474 if (r < 0)
4475 return -errno;
be57e297
LP
4476
4477 return !!S_ISDIR(st.st_mode);
a0627f82 4478}
7629889c 4479
ce5b3ad4
SJ
4480int is_device_node(const char *path) {
4481 struct stat info;
4482
4483 if (lstat(path, &info) < 0)
4484 return -errno;
4485
4486 return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode));
4487}
4488
10f9c755 4489ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) {
df241a67 4490 char fn[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
10f9c755
LP
4491 _cleanup_close_ int fd = -1;
4492 ssize_t l;
4493
4494 /* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */
4495
df241a67 4496 fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
10f9c755
LP
4497 if (fd < 0)
4498 return -errno;
4499
df241a67
LP
4500 xsprintf(fn, "/proc/self/fd/%i", fd);
4501
4502 l = getxattr(fn, attribute, value, size);
10f9c755
LP
4503 if (l < 0)
4504 return -errno;
4505
4506 return l;
4507}
4508
4509static int parse_crtime(le64_t le, usec_t *usec) {
4a4d89b6 4510 uint64_t u;
10f9c755
LP
4511
4512 assert(usec);
4513
4514 u = le64toh(le);
4515 if (u == 0 || u == (uint64_t) -1)
4516 return -EIO;
4517
4518 *usec = (usec_t) u;
4519 return 0;
4520}
4521
4522int fd_getcrtime(int fd, usec_t *usec) {
4a4d89b6
LP
4523 le64_t le;
4524 ssize_t n;
4525
4526 assert(fd >= 0);
4527 assert(usec);
4528
4529 /* Until Linux gets a real concept of birthtime/creation time,
4530 * let's fake one with xattrs */
4531
4532 n = fgetxattr(fd, "user.crtime_usec", &le, sizeof(le));
4533 if (n < 0)
4534 return -errno;
4535 if (n != sizeof(le))
4536 return -EIO;
4537
10f9c755
LP
4538 return parse_crtime(le, usec);
4539}
4540
4541int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags) {
4542 le64_t le;
4543 ssize_t n;
4544
4545 n = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags);
4546 if (n < 0)
4547 return -errno;
4548 if (n != sizeof(le))
4a4d89b6
LP
4549 return -EIO;
4550
10f9c755 4551 return parse_crtime(le, usec);
4a4d89b6
LP
4552}
4553
4554int path_getcrtime(const char *p, usec_t *usec) {
4a4d89b6
LP
4555 le64_t le;
4556 ssize_t n;
4557
4558 assert(p);
4559 assert(usec);
4560
4561 n = getxattr(p, "user.crtime_usec", &le, sizeof(le));
4562 if (n < 0)
4563 return -errno;
4564 if (n != sizeof(le))
4565 return -EIO;
4566
10f9c755 4567 return parse_crtime(le, usec);
4a4d89b6
LP
4568}
4569
4570int fd_setcrtime(int fd, usec_t usec) {
4571 le64_t le;
4572
4573 assert(fd >= 0);
4574
d61b600d
LP
4575 if (usec <= 0)
4576 usec = now(CLOCK_REALTIME);
4577
4a4d89b6 4578 le = htole64((uint64_t) usec);
2c39ea52 4579 if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), 0) < 0)
4a4d89b6
LP
4580 return -errno;
4581
4582 return 0;
4583}
a354329f 4584
1ed8f8c1 4585int chattr_fd(int fd, unsigned value, unsigned mask) {
45030287 4586 unsigned old_attr, new_attr;
03091baa 4587 struct stat st;
11689d2a
LP
4588
4589 assert(fd >= 0);
4590
03091baa
LP
4591 if (fstat(fd, &st) < 0)
4592 return -errno;
4593
4594 /* Explicitly check whether this is a regular file or
4595 * directory. If it is anything else (such as a device node or
4596 * fifo), then the ioctl will not hit the file systems but
4597 * possibly drivers, where the ioctl might have different
4598 * effects. Notably, DRM is using the same ioctl() number. */
4599
4600 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
4601 return -ENOTTY;
4602
45030287
LP
4603 if (mask == 0)
4604 return 0;
4605
11689d2a
LP
4606 if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
4607 return -errno;
4608
1ed8f8c1 4609 new_attr = (old_attr & ~mask) | (value & mask);
11689d2a
LP
4610 if (new_attr == old_attr)
4611 return 0;
4612
4613 if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
4614 return -errno;
4615
1ed8f8c1 4616 return 1;
11689d2a
LP
4617}
4618
1ed8f8c1 4619int chattr_path(const char *p, unsigned value, unsigned mask) {
11689d2a
LP
4620 _cleanup_close_ int fd = -1;
4621
45030287
LP
4622 assert(p);
4623
4624 if (mask == 0)
4625 return 0;
4626
01b72568 4627 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
11689d2a
LP
4628 if (fd < 0)
4629 return -errno;
4630
1ed8f8c1 4631 return chattr_fd(fd, value, mask);
5b9fbd35
GB
4632}
4633
01b72568 4634int read_attr_fd(int fd, unsigned *ret) {
03091baa
LP
4635 struct stat st;
4636
01b72568
LP
4637 assert(fd >= 0);
4638
03091baa
LP
4639 if (fstat(fd, &st) < 0)
4640 return -errno;
4641
4642 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
4643 return -ENOTTY;
4644
01b72568
LP
4645 if (ioctl(fd, FS_IOC_GETFLAGS, ret) < 0)
4646 return -errno;
4647
4648 return 0;
4649}
4650
4651int read_attr_path(const char *p, unsigned *ret) {
4652 _cleanup_close_ int fd = -1;
4653
4654 assert(p);
4655 assert(ret);
4656
4657 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
4658 if (fd < 0)
4659 return -errno;
4660
4661 return read_attr_fd(fd, ret);
4662}
30535c16 4663
ff6a7460
LP
4664static size_t nul_length(const uint8_t *p, size_t sz) {
4665 size_t n = 0;
4666
4667 while (sz > 0) {
4668 if (*p != 0)
4669 break;
4670
4671 n++;
4672 p++;
4673 sz--;
4674 }
4675
4676 return n;
4677}
4678
4679ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
4680 const uint8_t *q, *w, *e;
4681 ssize_t l;
4682
4683 q = w = p;
4684 e = q + sz;
4685 while (q < e) {
4686 size_t n;
4687
4688 n = nul_length(q, e - q);
4689
4690 /* If there are more than the specified run length of
4691 * NUL bytes, or if this is the beginning or the end
4692 * of the buffer, then seek instead of write */
4693 if ((n > run_length) ||
4694 (n > 0 && q == p) ||
4695 (n > 0 && q + n >= e)) {
4696 if (q > w) {
4697 l = write(fd, w, q - w);
4698 if (l < 0)
4699 return -errno;
4700 if (l != q -w)
4701 return -EIO;
4702 }
4703
4704 if (lseek(fd, n, SEEK_CUR) == (off_t) -1)
4705 return -errno;
4706
4707 q += n;
4708 w = q;
4709 } else if (n > 0)
4710 q += n;
4711 else
4712 q ++;
4713 }
4714
4715 if (q > w) {
4716 l = write(fd, w, q - w);
4717 if (l < 0)
4718 return -errno;
4719 if (l != q - w)
4720 return -EIO;
4721 }
4722
4723 return q - (const uint8_t*) p;
4724}
3576d631
LP
4725
4726void sigkill_wait(pid_t *pid) {
4727 if (!pid)
4728 return;
4729 if (*pid <= 1)
4730 return;
4731
4732 if (kill(*pid, SIGKILL) > 0)
4733 (void) wait_for_terminate(*pid, NULL);
4734}
3d7415f4
LP
4735
4736int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
4737 int a = 0, b = 0, c = 0;
4738 int k;
4739
4740 assert(p);
4741 assert(*p);
4742 assert(priority);
4743
4744 if ((*p)[0] != '<')
4745 return 0;
4746
4747 if (!strchr(*p, '>'))
4748 return 0;
4749
4750 if ((*p)[2] == '>') {
4751 c = undecchar((*p)[1]);
4752 k = 3;
4753 } else if ((*p)[3] == '>') {
4754 b = undecchar((*p)[1]);
4755 c = undecchar((*p)[2]);
4756 k = 4;
4757 } else if ((*p)[4] == '>') {
4758 a = undecchar((*p)[1]);
4759 b = undecchar((*p)[2]);
4760 c = undecchar((*p)[3]);
4761 k = 5;
4762 } else
4763 return 0;
4764
4765 if (a < 0 || b < 0 || c < 0 ||
4766 (!with_facility && (a || b || c > 7)))
4767 return 0;
4768
4769 if (with_facility)
4770 *priority = a*100 + b*10 + c;
4771 else
4772 *priority = (*priority & LOG_FACMASK) | c;
4773
4774 *p += k;
4775 return 1;
4776}
9cad100e
BB
4777
4778ssize_t string_table_lookup(const char * const *table, size_t len, const char *key) {
4779 size_t i;
4780
4781 if (!key)
4782 return -1;
4783
4784 for (i = 0; i < len; ++i)
4785 if (streq_ptr(table[i], key))
8c721f2b 4786 return (ssize_t) i;
9cad100e
BB
4787
4788 return -1;
4789}
1c8da044 4790
f85ef957
AC
4791int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
4792 struct stat buf;
4793 int ret;
4794
4795 ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
4796 if (ret >= 0)
4797 return 0;
4798
715d7599
RM
4799 /* renameat2() exists since Linux 3.15, btrfs added support for it later.
4800 * If it is not implemented, fallback to another method. */
4801 if (!IN_SET(errno, EINVAL, ENOSYS))
f85ef957
AC
4802 return -errno;
4803
4804 /* The link()/unlink() fallback does not work on directories. But
4805 * renameat() without RENAME_NOREPLACE gives the same semantics on
4806 * directories, except when newpath is an *empty* directory. This is
4807 * good enough. */
4808 ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW);
4809 if (ret >= 0 && S_ISDIR(buf.st_mode)) {
4810 ret = renameat(olddirfd, oldpath, newdirfd, newpath);
4811 return ret >= 0 ? 0 : -errno;
4812 }
4813
4814 /* If it is not a directory, use the link()/unlink() fallback. */
4815 ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0);
4816 if (ret < 0)
4817 return -errno;
4818
4819 ret = unlinkat(olddirfd, oldpath, 0);
4820 if (ret < 0) {
4821 /* backup errno before the following unlinkat() alters it */
4822 ret = errno;
4823 (void) unlinkat(newdirfd, newpath, 0);
4824 errno = ret;
4825 return -errno;
4826 }
4827
4828 return 0;
4829}
019c7fba 4830
2ff7b0a5
LP
4831int parse_mode(const char *s, mode_t *ret) {
4832 char *x;
4833 long l;
4834
4835 assert(s);
4836 assert(ret);
4837
4838 errno = 0;
4839 l = strtol(s, &x, 8);
4840 if (errno != 0)
4841 return -errno;
4842
4843 if (!x || x == s || *x)
4844 return -EINVAL;
4845 if (l < 0 || l > 07777)
4846 return -ERANGE;
4847
4848 *ret = (mode_t) l;
4849 return 0;
4850}
6458ec20
LP
4851
4852int mount_move_root(const char *path) {
4853 assert(path);
4854
4855 if (chdir(path) < 0)
4856 return -errno;
4857
4858 if (mount(path, "/", NULL, MS_MOVE, NULL) < 0)
4859 return -errno;
4860
4861 if (chroot(".") < 0)
4862 return -errno;
4863
4864 if (chdir("/") < 0)
4865 return -errno;
4866
4867 return 0;
4868}
b4da6d6b
LP
4869
4870int reset_uid_gid(void) {
4871
4872 if (setgroups(0, NULL) < 0)
4873 return -errno;
4874
4875 if (setresgid(0, 0, 0) < 0)
4876 return -errno;
4877
4878 if (setresuid(0, 0, 0) < 0)
4879 return -errno;
4880
4881 return 0;
4882}
7b9c9ab8
WC
4883
4884int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink) {
4885 char *v;
4886 size_t l;
4887 ssize_t n;
4888
4889 assert(path);
4890 assert(name);
4891 assert(value);
4892
4893 for (l = 100; ; l = (size_t) n + 1) {
4894 v = new0(char, l);
4895 if (!v)
4896 return -ENOMEM;
4897
4898 if (allow_symlink)
4899 n = lgetxattr(path, name, v, l);
4900 else
4901 n = getxattr(path, name, v, l);
4902
4903 if (n >= 0 && (size_t) n < l) {
4904 *value = v;
4905 return n;
4906 }
4907
4908 free(v);
4909
4910 if (n < 0 && errno != ERANGE)
4911 return -errno;
4912
4913 if (allow_symlink)
4914 n = lgetxattr(path, name, NULL, 0);
4915 else
4916 n = getxattr(path, name, NULL, 0);
4917 if (n < 0)
4918 return -errno;
4919 }
4920}
4921
4922int fgetxattr_malloc(int fd, const char *name, char **value) {
4923 char *v;
4924 size_t l;
4925 ssize_t n;
4926
4927 assert(fd >= 0);
4928 assert(name);
4929 assert(value);
4930
4931 for (l = 100; ; l = (size_t) n + 1) {
4932 v = new0(char, l);
4933 if (!v)
4934 return -ENOMEM;
4935
4936 n = fgetxattr(fd, name, v, l);
4937
4938 if (n >= 0 && (size_t) n < l) {
4939 *value = v;
4940 return n;
4941 }
4942
4943 free(v);
4944
4945 if (n < 0 && errno != ERANGE)
4946 return -errno;
4947
4948 n = fgetxattr(fd, name, NULL, 0);
4949 if (n < 0)
4950 return -errno;
4951 }
4952}
d9603714 4953
3ee897d6 4954int send_one_fd(int transport_fd, int fd, int flags) {
d9603714
DH
4955 union {
4956 struct cmsghdr cmsghdr;
4957 uint8_t buf[CMSG_SPACE(sizeof(int))];
4958 } control = {};
4959 struct msghdr mh = {
4960 .msg_control = &control,
4961 .msg_controllen = sizeof(control),
4962 };
4963 struct cmsghdr *cmsg;
d9603714
DH
4964
4965 assert(transport_fd >= 0);
4966 assert(fd >= 0);
4967
4968 cmsg = CMSG_FIRSTHDR(&mh);
4969 cmsg->cmsg_level = SOL_SOCKET;
4970 cmsg->cmsg_type = SCM_RIGHTS;
4971 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
4972 memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
4973
4974 mh.msg_controllen = CMSG_SPACE(sizeof(int));
3ee897d6 4975 if (sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags) < 0)
d9603714
DH
4976 return -errno;
4977
4978 return 0;
4979}
4980
3ee897d6 4981int receive_one_fd(int transport_fd, int flags) {
d9603714
DH
4982 union {
4983 struct cmsghdr cmsghdr;
4984 uint8_t buf[CMSG_SPACE(sizeof(int))];
4985 } control = {};
4986 struct msghdr mh = {
4987 .msg_control = &control,
4988 .msg_controllen = sizeof(control),
4989 };
3ee897d6 4990 struct cmsghdr *cmsg, *found = NULL;
d9603714
DH
4991
4992 assert(transport_fd >= 0);
4993
4994 /*
3ee897d6
LP
4995 * Receive a single FD via @transport_fd. We don't care for
4996 * the transport-type. We retrieve a single FD at most, so for
4997 * packet-based transports, the caller must ensure to send
4998 * only a single FD per packet. This is best used in
4999 * combination with send_one_fd().
d9603714
DH
5000 */
5001
3ee897d6 5002 if (recvmsg(transport_fd, &mh, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC | flags) < 0)
d9603714
DH
5003 return -errno;
5004
3ee897d6
LP
5005 CMSG_FOREACH(cmsg, &mh) {
5006 if (cmsg->cmsg_level == SOL_SOCKET &&
5007 cmsg->cmsg_type == SCM_RIGHTS &&
5008 cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
5009 assert(!found);
5010 found = cmsg;
5011 break;
5012 }
5013 }
5014
5015 if (!found) {
d9603714
DH
5016 cmsg_close_all(&mh);
5017 return -EIO;
5018 }
5019
3ee897d6 5020 return *(int*) CMSG_DATA(found);
d9603714 5021}
189d5bac
LP
5022
5023void nop_signal_handler(int sig) {
5024 /* nothing here */
5025}
3f6fd1ba
LP
5026
5027int version(void) {
5028 puts(PACKAGE_STRING "\n"
5029 SYSTEMD_FEATURES);
5030 return 0;
5031}
8dd4c05b
LP
5032
5033bool fdname_is_valid(const char *s) {
5034 const char *p;
5035
0a3bb96e 5036 /* Validates a name for $LISTEN_FDNAMES. We basically allow
8dd4c05b
LP
5037 * everything ASCII that's not a control character. Also, as
5038 * special exception the ":" character is not allowed, as we
0a3bb96e 5039 * use that as field separator in $LISTEN_FDNAMES.
8dd4c05b 5040 *
0a3bb96e
LP
5041 * Note that the empty string is explicitly allowed
5042 * here. However, we limit the length of the names to 255
5043 * characters. */
8dd4c05b
LP
5044
5045 if (!s)
5046 return false;
5047
5048 for (p = s; *p; p++) {
5049 if (*p < ' ')
5050 return false;
5051 if (*p >= 127)
5052 return false;
5053 if (*p == ':')
5054 return false;
5055 }
5056
5057 return p - s < 256;
5058}
257b0719
EV
5059
5060bool oom_score_adjust_is_valid(int oa) {
5061 return oa >= OOM_SCORE_ADJ_MIN && oa <= OOM_SCORE_ADJ_MAX;
5062}