]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/util.c
NEWS: start collecting items for v220
[thirdparty/systemd.git] / src / shared / 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
60918275
LP
22#include <string.h>
23#include <unistd.h>
24#include <errno.h>
85261803 25#include <stdlib.h>
034c6ed7 26#include <signal.h>
20f56fdd 27#include <libintl.h>
034c6ed7 28#include <stdio.h>
1dccbe19
LP
29#include <syslog.h>
30#include <sched.h>
31#include <sys/resource.h>
ef886c6a 32#include <linux/sched.h>
a9f5d454
LP
33#include <sys/types.h>
34#include <sys/stat.h>
3a0ecb08 35#include <fcntl.h>
a0d40ac5 36#include <dirent.h>
601f6a1e 37#include <sys/ioctl.h>
80876c20 38#include <stdarg.h>
0a6f50c0 39#include <poll.h>
3177a7fa 40#include <ctype.h>
5b6319dc 41#include <sys/prctl.h>
ef2f1067
LP
42#include <sys/utsname.h>
43#include <pwd.h>
4fd5948e 44#include <netinet/ip.h>
2e78aa99 45#include <sys/wait.h>
7948c4df 46#include <sys/time.h>
8092a428 47#include <glob.h>
4b67834e 48#include <grp.h>
87d2c1ff 49#include <sys/mman.h>
825c6fe5 50#include <sys/vfs.h>
6d313367 51#include <sys/mount.h>
825c6fe5 52#include <linux/magic.h>
0b507b17 53#include <limits.h>
09017585
MS
54#include <langinfo.h>
55#include <locale.h>
6afc95b7 56#include <sys/personality.h>
4a4d89b6 57#include <sys/xattr.h>
abe4aa14 58#include <sys/statvfs.h>
30535c16 59#include <sys/file.h>
11689d2a 60#include <linux/fs.h>
eef46c37
LP
61
62/* When we include libgen.h because we need dirname() we immediately
63 * undefine basename() since libgen.h defines it as a macro to the XDG
64 * version which is really broken. */
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
20f56fdd 72#include "config.h"
60918275
LP
73#include "macro.h"
74#include "util.h"
1dccbe19
LP
75#include "ioprio.h"
76#include "missing.h"
a9f5d454 77#include "log.h"
65d2ebdc 78#include "strv.h"
c38dfac9 79#include "mkdir.h"
9eb977db 80#include "path-util.h"
d06dacd0 81#include "exit-status.h"
83cc030f 82#include "hashmap.h"
4d1a6904 83#include "env-util.h"
a5c32cff 84#include "fileio.h"
8f6ce71f 85#include "device-nodes.h"
f405e86d
SL
86#include "utf8.h"
87#include "gunicode.h"
295edddf 88#include "virt.h"
477def80 89#include "def.h"
4a4d89b6 90#include "sparse-endian.h"
6482f626 91#include "formats-util.h"
0b452006 92#include "process-util.h"
3df3e884 93#include "random-util.h"
288a74cc 94#include "terminal-util.h"
958b66ea 95#include "hostname-util.h"
56cf987f 96
012d7b42
ZJS
97/* Put this test here for a lack of better place */
98assert_cc(EAGAIN == EWOULDBLOCK);
99
9a0e6896
LP
100int saved_argc = 0;
101char **saved_argv = NULL;
9086e840 102
37f85e66 103size_t page_size(void) {
ec202eae 104 static thread_local size_t pgsz = 0;
37f85e66 105 long r;
106
87d2c1ff 107 if (_likely_(pgsz > 0))
37f85e66 108 return pgsz;
109
e67f47e5
LP
110 r = sysconf(_SC_PAGESIZE);
111 assert(r > 0);
37f85e66 112
113 pgsz = (size_t) r;
37f85e66 114 return pgsz;
115}
116
e05797fb
LP
117bool streq_ptr(const char *a, const char *b) {
118
119 /* Like streq(), but tries to make sense of NULL pointers */
120
121 if (a && b)
122 return streq(a, b);
123
124 if (!a && !b)
125 return true;
126
127 return false;
128}
129
8c7c140f 130char* endswith(const char *s, const char *postfix) {
60918275
LP
131 size_t sl, pl;
132
133 assert(s);
134 assert(postfix);
135
136 sl = strlen(s);
137 pl = strlen(postfix);
138
d4d0d4db 139 if (pl == 0)
8c7c140f 140 return (char*) s + sl;
d4d0d4db 141
60918275 142 if (sl < pl)
8c7c140f
LP
143 return NULL;
144
145 if (memcmp(s + sl - pl, postfix, pl) != 0)
146 return NULL;
60918275 147
8c7c140f 148 return (char*) s + sl - pl;
60918275
LP
149}
150
d3226d77
ZJS
151char* endswith_no_case(const char *s, const char *postfix) {
152 size_t sl, pl;
153
154 assert(s);
155 assert(postfix);
156
157 sl = strlen(s);
158 pl = strlen(postfix);
159
160 if (pl == 0)
161 return (char*) s + sl;
162
163 if (sl < pl)
164 return NULL;
165
166 if (strcasecmp(s + sl - pl, postfix) != 0)
167 return NULL;
168
169 return (char*) s + sl - pl;
170}
171
5cb36f41 172char* first_word(const char *s, const char *word) {
79d6d816 173 size_t sl, wl;
5cb36f41 174 const char *p;
79d6d816
LP
175
176 assert(s);
177 assert(word);
178
5cb36f41
LP
179 /* Checks if the string starts with the specified word, either
180 * followed by NUL or by whitespace. Returns a pointer to the
181 * NUL or the first character after the whitespace. */
182
79d6d816
LP
183 sl = strlen(s);
184 wl = strlen(word);
185
186 if (sl < wl)
5cb36f41 187 return NULL;
79d6d816 188
d4d0d4db 189 if (wl == 0)
5cb36f41 190 return (char*) s;
d4d0d4db 191
79d6d816 192 if (memcmp(s, word, wl) != 0)
5cb36f41
LP
193 return NULL;
194
195 p = s + wl;
196 if (*p == 0)
197 return (char*) p;
198
199 if (!strchr(WHITESPACE, *p))
200 return NULL;
79d6d816 201
5cb36f41
LP
202 p += strspn(p, WHITESPACE);
203 return (char*) p;
79d6d816
LP
204}
205
0b452006 206size_t cescape_char(char c, char *buf) {
c593bb36
JF
207 char * buf_old = buf;
208
209 switch (c) {
210
211 case '\a':
212 *(buf++) = '\\';
213 *(buf++) = 'a';
214 break;
215 case '\b':
216 *(buf++) = '\\';
217 *(buf++) = 'b';
218 break;
219 case '\f':
220 *(buf++) = '\\';
221 *(buf++) = 'f';
222 break;
223 case '\n':
224 *(buf++) = '\\';
225 *(buf++) = 'n';
226 break;
227 case '\r':
228 *(buf++) = '\\';
229 *(buf++) = 'r';
230 break;
231 case '\t':
232 *(buf++) = '\\';
233 *(buf++) = 't';
234 break;
235 case '\v':
236 *(buf++) = '\\';
237 *(buf++) = 'v';
238 break;
239 case '\\':
240 *(buf++) = '\\';
241 *(buf++) = '\\';
242 break;
243 case '"':
244 *(buf++) = '\\';
245 *(buf++) = '"';
246 break;
247 case '\'':
248 *(buf++) = '\\';
249 *(buf++) = '\'';
250 break;
251
252 default:
253 /* For special chars we prefer octal over
254 * hexadecimal encoding, simply because glib's
255 * g_strescape() does the same */
256 if ((c < ' ') || (c >= 127)) {
257 *(buf++) = '\\';
258 *(buf++) = octchar((unsigned char) c >> 6);
259 *(buf++) = octchar((unsigned char) c >> 3);
260 *(buf++) = octchar((unsigned char) c);
261 } else
262 *(buf++) = c;
263 break;
264 }
265
266 return buf - buf_old;
267}
268
42f4e3c4 269int close_nointr(int fd) {
b0ee8068 270 assert(fd >= 0);
a9f85faf
LP
271
272 if (close(fd) >= 0)
273 return 0;
274
275 /*
276 * Just ignore EINTR; a retry loop is the wrong thing to do on
277 * Linux.
278 *
279 * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
280 * https://bugzilla.gnome.org/show_bug.cgi?id=682819
281 * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
282 * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
283 */
284 if (errno == EINTR)
d96ea504 285 return 0;
a9f85faf
LP
286
287 return -errno;
60918275 288}
85261803 289
03e334a1
LP
290int safe_close(int fd) {
291
292 /*
293 * Like close_nointr() but cannot fail. Guarantees errno is
294 * unchanged. Is a NOP with negative fds passed, and returns
295 * -1, so that it can be used in this syntax:
296 *
297 * fd = safe_close(fd);
298 */
85f136b5 299
03e334a1
LP
300 if (fd >= 0) {
301 PROTECT_ERRNO;
d96ea504
LP
302
303 /* The kernel might return pretty much any error code
304 * via close(), but the fd will be closed anyway. The
305 * only condition we want to check for here is whether
306 * the fd was invalid at all... */
307
308 assert_se(close_nointr(fd) != -EBADF);
03e334a1 309 }
85f136b5 310
03e334a1 311 return -1;
85f136b5
LP
312}
313
5b6319dc
LP
314void close_many(const int fds[], unsigned n_fd) {
315 unsigned i;
316
2c93b4ef
LP
317 assert(fds || n_fd <= 0);
318
5b6319dc 319 for (i = 0; i < n_fd; i++)
03e334a1 320 safe_close(fds[i]);
5b6319dc
LP
321}
322
4b73a0c0
LP
323int unlink_noerrno(const char *path) {
324 PROTECT_ERRNO;
325 int r;
326
327 r = unlink(path);
328 if (r < 0)
329 return -errno;
330
331 return 0;
332}
333
85261803
LP
334int parse_boolean(const char *v) {
335 assert(v);
336
0f625d0b 337 if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on"))
85261803 338 return 1;
0f625d0b 339 else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off"))
85261803
LP
340 return 0;
341
342 return -EINVAL;
343}
344
3ba686c1 345int parse_pid(const char *s, pid_t* ret_pid) {
0b172489 346 unsigned long ul = 0;
3ba686c1
LP
347 pid_t pid;
348 int r;
349
350 assert(s);
351 assert(ret_pid);
352
e67f47e5
LP
353 r = safe_atolu(s, &ul);
354 if (r < 0)
3ba686c1
LP
355 return r;
356
357 pid = (pid_t) ul;
358
359 if ((unsigned long) pid != ul)
360 return -ERANGE;
361
362 if (pid <= 0)
363 return -ERANGE;
364
365 *ret_pid = pid;
366 return 0;
367}
368
034a2a52
LP
369int parse_uid(const char *s, uid_t* ret_uid) {
370 unsigned long ul = 0;
371 uid_t uid;
372 int r;
373
374 assert(s);
034a2a52 375
e67f47e5
LP
376 r = safe_atolu(s, &ul);
377 if (r < 0)
034a2a52
LP
378 return r;
379
380 uid = (uid_t) ul;
381
382 if ((unsigned long) uid != ul)
383 return -ERANGE;
384
fed1e721 385 /* Some libc APIs use UID_INVALID as special placeholder */
306a55c8 386 if (uid == (uid_t) 0xFFFFFFFF)
f841a154 387 return -ENXIO;
306a55c8 388
6afeb1cf 389 /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
306a55c8 390 if (uid == (uid_t) 0xFFFF)
f841a154 391 return -ENXIO;
306a55c8 392
8b0849e9
LP
393 if (ret_uid)
394 *ret_uid = uid;
395
034a2a52
LP
396 return 0;
397}
398
85261803
LP
399int safe_atou(const char *s, unsigned *ret_u) {
400 char *x = NULL;
034c6ed7 401 unsigned long l;
85261803
LP
402
403 assert(s);
404 assert(ret_u);
405
406 errno = 0;
407 l = strtoul(s, &x, 0);
408
f3910003 409 if (!x || x == s || *x || errno)
48deb058 410 return errno > 0 ? -errno : -EINVAL;
85261803 411
034c6ed7 412 if ((unsigned long) (unsigned) l != l)
85261803
LP
413 return -ERANGE;
414
415 *ret_u = (unsigned) l;
416 return 0;
417}
418
419int safe_atoi(const char *s, int *ret_i) {
420 char *x = NULL;
034c6ed7 421 long l;
85261803
LP
422
423 assert(s);
424 assert(ret_i);
425
426 errno = 0;
427 l = strtol(s, &x, 0);
428
f3910003 429 if (!x || x == s || *x || errno)
48deb058 430 return errno > 0 ? -errno : -EINVAL;
85261803 431
034c6ed7 432 if ((long) (int) l != l)
85261803
LP
433 return -ERANGE;
434
034c6ed7
LP
435 *ret_i = (int) l;
436 return 0;
437}
438
b914e211
LP
439int safe_atou8(const char *s, uint8_t *ret) {
440 char *x = NULL;
441 unsigned long l;
442
443 assert(s);
444 assert(ret);
445
446 errno = 0;
447 l = strtoul(s, &x, 0);
448
449 if (!x || x == s || *x || errno)
450 return errno > 0 ? -errno : -EINVAL;
451
452 if ((unsigned long) (uint8_t) l != l)
453 return -ERANGE;
454
455 *ret = (uint8_t) l;
456 return 0;
457}
458
781fa938
LP
459int safe_atou16(const char *s, uint16_t *ret) {
460 char *x = NULL;
461 unsigned long l;
462
463 assert(s);
464 assert(ret);
465
466 errno = 0;
467 l = strtoul(s, &x, 0);
468
469 if (!x || x == s || *x || errno)
470 return errno > 0 ? -errno : -EINVAL;
471
472 if ((unsigned long) (uint16_t) l != l)
473 return -ERANGE;
474
475 *ret = (uint16_t) l;
476 return 0;
477}
478
479int safe_atoi16(const char *s, int16_t *ret) {
480 char *x = NULL;
481 long l;
482
483 assert(s);
484 assert(ret);
485
486 errno = 0;
487 l = strtol(s, &x, 0);
488
489 if (!x || x == s || *x || errno)
490 return errno > 0 ? -errno : -EINVAL;
491
492 if ((long) (int16_t) l != l)
493 return -ERANGE;
494
495 *ret = (int16_t) l;
496 return 0;
497}
498
034c6ed7
LP
499int safe_atollu(const char *s, long long unsigned *ret_llu) {
500 char *x = NULL;
501 unsigned long long l;
502
503 assert(s);
504 assert(ret_llu);
505
506 errno = 0;
507 l = strtoull(s, &x, 0);
508
f3910003 509 if (!x || x == s || *x || errno)
034c6ed7
LP
510 return errno ? -errno : -EINVAL;
511
512 *ret_llu = l;
513 return 0;
514}
515
516int safe_atolli(const char *s, long long int *ret_lli) {
517 char *x = NULL;
518 long long l;
519
520 assert(s);
521 assert(ret_lli);
522
523 errno = 0;
524 l = strtoll(s, &x, 0);
525
f3910003 526 if (!x || x == s || *x || errno)
034c6ed7
LP
527 return errno ? -errno : -EINVAL;
528
529 *ret_lli = l;
85261803
LP
530 return 0;
531}
a41e8209 532
f7900e25
TA
533int safe_atod(const char *s, double *ret_d) {
534 char *x = NULL;
32b2634e 535 double d = 0;
0193ad26 536 locale_t loc;
f7900e25
TA
537
538 assert(s);
539 assert(ret_d);
540
0193ad26
CR
541 loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
542 if (loc == (locale_t) 0)
543 return -errno;
f7900e25 544
0193ad26
CR
545 errno = 0;
546 d = strtod_l(s, &x, loc);
547
548 if (!x || x == s || *x || errno) {
549 freelocale(loc);
f7900e25 550 return errno ? -errno : -EINVAL;
0193ad26 551 }
f7900e25 552
0193ad26 553 freelocale(loc);
f7900e25
TA
554 *ret_d = (double) d;
555 return 0;
556}
557
bf85c24d
SP
558static size_t strcspn_escaped(const char *s, const char *reject) {
559 bool escaped = false;
ba774317 560 int n;
bf85c24d
SP
561
562 for (n=0; s[n]; n++) {
563 if (escaped)
564 escaped = false;
565 else if (s[n] == '\\')
566 escaped = true;
567 else if (strchr(reject, s[n]))
a2a5291b 568 break;
bf85c24d 569 }
ba774317 570
a2a5291b
ZJS
571 /* if s ends in \, return index of previous char */
572 return n - escaped;
bf85c24d
SP
573}
574
a41e8209 575/* Split a string into words. */
a2a5291b
ZJS
576const char* split(const char **state, size_t *l, const char *separator, bool quoted) {
577 const char *current;
a41e8209 578
a2a5291b 579 current = *state;
a41e8209 580
a2a5291b
ZJS
581 if (!*current) {
582 assert(**state == '\0');
a41e8209 583 return NULL;
a2a5291b 584 }
a41e8209 585
65d2ebdc 586 current += strspn(current, separator);
a2a5291b
ZJS
587 if (!*current) {
588 *state = current;
70f75a52 589 return NULL;
a2a5291b 590 }
70f75a52 591
bf85c24d 592 if (quoted && strchr("\'\"", *current)) {
a2a5291b
ZJS
593 char quotechars[2] = {*current, '\0'};
594
595 *l = strcspn_escaped(current + 1, quotechars);
470dca63 596 if (current[*l + 1] == '\0' || current[*l + 1] != quotechars[0] ||
a2a5291b 597 (current[*l + 2] && !strchr(separator, current[*l + 2]))) {
cc13b327 598 /* right quote missing or garbage at the end */
a2a5291b
ZJS
599 *state = current;
600 return NULL;
601 }
a2a5291b 602 *state = current++ + *l + 2;
bf85c24d
SP
603 } else if (quoted) {
604 *l = strcspn_escaped(current, separator);
ba774317
ZJS
605 if (current[*l] && !strchr(separator, current[*l])) {
606 /* unfinished escape */
607 *state = current;
608 return NULL;
609 }
a2a5291b 610 *state = current + *l;
034c6ed7 611 } else {
bf85c24d 612 *l = strcspn(current, separator);
a2a5291b 613 *state = current + *l;
034c6ed7
LP
614 }
615
a2a5291b 616 return current;
034c6ed7
LP
617}
618
34ca941c
LP
619int fchmod_umask(int fd, mode_t m) {
620 mode_t u;
621 int r;
622
623 u = umask(0777);
624 r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
625 umask(u);
626
627 return r;
628}
629
7072ced8
LP
630char *truncate_nl(char *s) {
631 assert(s);
632
633 s[strcspn(s, NEWLINE)] = 0;
634 return s;
635}
636
fab56fc5
LP
637char *strnappend(const char *s, const char *suffix, size_t b) {
638 size_t a;
44d8db9e
LP
639 char *r;
640
fab56fc5
LP
641 if (!s && !suffix)
642 return strdup("");
643
644 if (!s)
645 return strndup(suffix, b);
646
647 if (!suffix)
648 return strdup(s);
649
44d8db9e
LP
650 assert(s);
651 assert(suffix);
652
653 a = strlen(s);
aa408e77 654 if (b > ((size_t) -1) - a)
040f18ea 655 return NULL;
44d8db9e 656
040f18ea
LP
657 r = new(char, a+b+1);
658 if (!r)
44d8db9e
LP
659 return NULL;
660
661 memcpy(r, s, a);
662 memcpy(r+a, suffix, b);
663 r[a+b] = 0;
664
665 return r;
666}
87f0e418 667
fab56fc5
LP
668char *strappend(const char *s, const char *suffix) {
669 return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
670}
671
849958d1 672int readlinkat_malloc(int fd, const char *p, char **ret) {
87f0e418 673 size_t l = 100;
2d2ebd6b 674 int r;
87f0e418
LP
675
676 assert(p);
2d2ebd6b 677 assert(ret);
87f0e418
LP
678
679 for (;;) {
680 char *c;
681 ssize_t n;
682
2d2ebd6b
LP
683 c = new(char, l);
684 if (!c)
87f0e418
LP
685 return -ENOMEM;
686
849958d1 687 n = readlinkat(fd, p, c, l-1);
2d2ebd6b
LP
688 if (n < 0) {
689 r = -errno;
87f0e418 690 free(c);
2d2ebd6b 691 return r;
87f0e418
LP
692 }
693
694 if ((size_t) n < l-1) {
695 c[n] = 0;
2d2ebd6b 696 *ret = c;
87f0e418
LP
697 return 0;
698 }
699
700 free(c);
701 l *= 2;
702 }
703}
704
849958d1
LP
705int readlink_malloc(const char *p, char **ret) {
706 return readlinkat_malloc(AT_FDCWD, p, ret);
707}
708
9a67bcf2
TG
709int readlink_value(const char *p, char **ret) {
710 _cleanup_free_ char *link = NULL;
711 char *value;
712 int r;
713
714 r = readlink_malloc(p, &link);
715 if (r < 0)
716 return r;
717
718 value = basename(link);
719 if (!value)
720 return -ENOENT;
721
722 value = strdup(value);
723 if (!value)
724 return -ENOMEM;
725
726 *ret = value;
727
728 return 0;
729}
730
2c7108c4 731int readlink_and_make_absolute(const char *p, char **r) {
1058cbf2
ZJS
732 _cleanup_free_ char *target = NULL;
733 char *k;
2c7108c4
LP
734 int j;
735
736 assert(p);
737 assert(r);
738
1058cbf2
ZJS
739 j = readlink_malloc(p, &target);
740 if (j < 0)
2c7108c4
LP
741 return j;
742
743 k = file_in_same_dir(p, target);
2c7108c4
LP
744 if (!k)
745 return -ENOMEM;
746
747 *r = k;
748 return 0;
749}
750
83096483
LP
751int readlink_and_canonicalize(const char *p, char **r) {
752 char *t, *s;
753 int j;
754
755 assert(p);
756 assert(r);
757
758 j = readlink_and_make_absolute(p, &t);
759 if (j < 0)
760 return j;
761
762 s = canonicalize_file_name(t);
763 if (s) {
764 free(t);
765 *r = s;
766 } else
767 *r = t;
768
769 path_kill_slashes(*r);
770
771 return 0;
772}
773
2a987ee8 774int reset_all_signal_handlers(void) {
24a5d6b0 775 int sig, r = 0;
2a987ee8
LP
776
777 for (sig = 1; sig < _NSIG; sig++) {
b92bea5d
ZJS
778 struct sigaction sa = {
779 .sa_handler = SIG_DFL,
780 .sa_flags = SA_RESTART,
781 };
2a987ee8 782
24a5d6b0 783 /* These two cannot be caught... */
2a987ee8
LP
784 if (sig == SIGKILL || sig == SIGSTOP)
785 continue;
786
2a987ee8
LP
787 /* On Linux the first two RT signals are reserved by
788 * glibc, and sigaction() will return EINVAL for them. */
789 if ((sigaction(sig, &sa, NULL) < 0))
24a5d6b0
LP
790 if (errno != EINVAL && r == 0)
791 r = -errno;
2a987ee8
LP
792 }
793
24a5d6b0 794 return r;
2a987ee8 795}
4a72ff34 796
1dedb74a
LP
797int reset_signal_mask(void) {
798 sigset_t ss;
799
800 if (sigemptyset(&ss) < 0)
801 return -errno;
802
803 if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0)
804 return -errno;
805
806 return 0;
807}
808
4a72ff34 809char *strstrip(char *s) {
57a8eca8 810 char *e;
4a72ff34
LP
811
812 /* Drops trailing whitespace. Modifies the string in
813 * place. Returns pointer to first non-space character */
814
815 s += strspn(s, WHITESPACE);
816
57a8eca8
LP
817 for (e = strchr(s, 0); e > s; e --)
818 if (!strchr(WHITESPACE, e[-1]))
819 break;
4a72ff34 820
57a8eca8 821 *e = 0;
4a72ff34
LP
822
823 return s;
4a72ff34
LP
824}
825
ee9b5e01
LP
826char *delete_chars(char *s, const char *bad) {
827 char *f, *t;
828
829 /* Drops all whitespace, regardless where in the string */
830
831 for (f = s, t = s; *f; f++) {
832 if (strchr(bad, *f))
833 continue;
834
835 *(t++) = *f;
836 }
837
838 *t = 0;
839
840 return s;
841}
842
4a72ff34 843char *file_in_same_dir(const char *path, const char *filename) {
ebd93cb6 844 char *e, *ret;
4a72ff34
LP
845 size_t k;
846
847 assert(path);
848 assert(filename);
849
850 /* This removes the last component of path and appends
851 * filename, unless the latter is absolute anyway or the
852 * former isn't */
853
854 if (path_is_absolute(filename))
855 return strdup(filename);
856
ebd93cb6
LP
857 e = strrchr(path, '/');
858 if (!e)
4a72ff34
LP
859 return strdup(filename);
860
861 k = strlen(filename);
ebd93cb6
LP
862 ret = new(char, (e + 1 - path) + k + 1);
863 if (!ret)
4a72ff34
LP
864 return NULL;
865
ebd93cb6
LP
866 memcpy(mempcpy(ret, path, e + 1 - path), filename, k + 1);
867 return ret;
4a72ff34 868}
fb624d04 869
c32dd69b
LP
870int rmdir_parents(const char *path, const char *stop) {
871 size_t l;
872 int r = 0;
873
874 assert(path);
875 assert(stop);
876
877 l = strlen(path);
878
879 /* Skip trailing slashes */
880 while (l > 0 && path[l-1] == '/')
881 l--;
882
883 while (l > 0) {
884 char *t;
885
886 /* Skip last component */
887 while (l > 0 && path[l-1] != '/')
888 l--;
889
890 /* Skip trailing slashes */
891 while (l > 0 && path[l-1] == '/')
892 l--;
893
894 if (l <= 0)
895 break;
896
897 if (!(t = strndup(path, l)))
898 return -ENOMEM;
899
900 if (path_startswith(stop, t)) {
901 free(t);
902 return 0;
903 }
904
905 r = rmdir(t);
906 free(t);
907
908 if (r < 0)
909 if (errno != ENOENT)
910 return -errno;
911 }
912
913 return 0;
914}
915
fb624d04
LP
916char hexchar(int x) {
917 static const char table[16] = "0123456789abcdef";
918
919 return table[x & 15];
920}
4fe88d28
LP
921
922int unhexchar(char c) {
923
924 if (c >= '0' && c <= '9')
925 return c - '0';
926
927 if (c >= 'a' && c <= 'f')
ea430986 928 return c - 'a' + 10;
4fe88d28
LP
929
930 if (c >= 'A' && c <= 'F')
ea430986 931 return c - 'A' + 10;
4fe88d28 932
7e8185ef 933 return -EINVAL;
4fe88d28
LP
934}
935
66e35261
LP
936char *hexmem(const void *p, size_t l) {
937 char *r, *z;
938 const uint8_t *x;
939
940 z = r = malloc(l * 2 + 1);
941 if (!r)
942 return NULL;
943
944 for (x = p; x < (const uint8_t*) p + l; x++) {
945 *(z++) = hexchar(*x >> 4);
946 *(z++) = hexchar(*x & 15);
947 }
948
949 *z = 0;
950 return r;
951}
952
2181a7f5
LP
953void *unhexmem(const char *p, size_t l) {
954 uint8_t *r, *z;
955 const char *x;
956
957 assert(p);
958
959 z = r = malloc((l + 1) / 2 + 1);
960 if (!r)
961 return NULL;
962
963 for (x = p; x < p + l; x += 2) {
964 int a, b;
965
966 a = unhexchar(x[0]);
967 if (x+1 < p + l)
968 b = unhexchar(x[1]);
969 else
970 b = 0;
971
972 *(z++) = (uint8_t) a << 4 | (uint8_t) b;
973 }
974
975 *z = 0;
976 return r;
977}
978
4fe88d28
LP
979char octchar(int x) {
980 return '0' + (x & 7);
981}
982
983int unoctchar(char c) {
984
985 if (c >= '0' && c <= '7')
986 return c - '0';
987
7e8185ef 988 return -EINVAL;
4fe88d28
LP
989}
990
5af98f82
LP
991char decchar(int x) {
992 return '0' + (x % 10);
993}
994
995int undecchar(char c) {
996
997 if (c >= '0' && c <= '9')
998 return c - '0';
999
7e8185ef 1000 return -EINVAL;
5af98f82
LP
1001}
1002
4fe88d28
LP
1003char *cescape(const char *s) {
1004 char *r, *t;
1005 const char *f;
1006
1007 assert(s);
1008
96406c1a 1009 /* Does C style string escaping. May be reversed with
019c7fba 1010 * cunescape(). */
4fe88d28 1011
f8e2fb7b
LP
1012 r = new(char, strlen(s)*4 + 1);
1013 if (!r)
4fe88d28
LP
1014 return NULL;
1015
1016 for (f = s, t = r; *f; f++)
c593bb36 1017 t += cescape_char(*f, t);
4fe88d28
LP
1018
1019 *t = 0;
1020
1021 return r;
1022}
1023
f3ee6297 1024static int cunescape_one(const char *p, size_t length, char *ret, uint32_t *ret_unicode) {
4034a06d
LP
1025 int r = 1;
1026
1027 assert(p);
1028 assert(*p);
1029 assert(ret);
1030
f3ee6297
LP
1031 /* Unescapes C style. Returns the unescaped character in ret,
1032 * unless we encountered a \u sequence in which case the full
1033 * unicode character is returned in ret_unicode, instead. */
1034
4034a06d
LP
1035 if (length != (size_t) -1 && length < 1)
1036 return -EINVAL;
1037
1038 switch (p[0]) {
1039
1040 case 'a':
1041 *ret = '\a';
1042 break;
1043 case 'b':
1044 *ret = '\b';
1045 break;
1046 case 'f':
1047 *ret = '\f';
1048 break;
1049 case 'n':
1050 *ret = '\n';
1051 break;
1052 case 'r':
1053 *ret = '\r';
1054 break;
1055 case 't':
1056 *ret = '\t';
1057 break;
1058 case 'v':
1059 *ret = '\v';
1060 break;
1061 case '\\':
1062 *ret = '\\';
1063 break;
1064 case '"':
1065 *ret = '"';
1066 break;
1067 case '\'':
1068 *ret = '\'';
1069 break;
1070
1071 case 's':
1072 /* This is an extension of the XDG syntax files */
1073 *ret = ' ';
1074 break;
1075
1076 case 'x': {
1077 /* hexadecimal encoding */
1078 int a, b;
1079
1080 if (length != (size_t) -1 && length < 3)
1081 return -EINVAL;
1082
1083 a = unhexchar(p[1]);
1084 if (a < 0)
1085 return -EINVAL;
1086
1087 b = unhexchar(p[2]);
1088 if (b < 0)
1089 return -EINVAL;
1090
f3ee6297 1091 /* Don't allow NUL bytes */
4034a06d
LP
1092 if (a == 0 && b == 0)
1093 return -EINVAL;
1094
f3ee6297 1095 *ret = (char) ((a << 4U) | b);
4034a06d
LP
1096 r = 3;
1097 break;
1098 }
1099
f3ee6297
LP
1100 case 'u': {
1101 /* C++11 style 16bit unicode */
1102
1103 int a[4];
1104 unsigned i;
1105 uint32_t c;
1106
1107 if (length != (size_t) -1 && length < 5)
1108 return -EINVAL;
1109
1110 for (i = 0; i < 4; i++) {
1111 a[i] = unhexchar(p[1 + i]);
1112 if (a[i] < 0)
1113 return a[i];
1114 }
1115
1116 c = ((uint32_t) a[0] << 12U) | ((uint32_t) a[1] << 8U) | ((uint32_t) a[2] << 4U) | (uint32_t) a[3];
1117
1118 /* Don't allow 0 chars */
1119 if (c == 0)
1120 return -EINVAL;
1121
1122 if (c < 128)
1123 *ret = c;
1124 else {
1125 if (!ret_unicode)
1126 return -EINVAL;
1127
1128 *ret = 0;
1129 *ret_unicode = c;
1130 }
1131
1132 r = 5;
1133 break;
1134 }
1135
1136 case 'U': {
1137 /* C++11 style 32bit unicode */
1138
1139 int a[8];
1140 unsigned i;
1141 uint32_t c;
1142
1143 if (length != (size_t) -1 && length < 9)
1144 return -EINVAL;
1145
1146 for (i = 0; i < 8; i++) {
1147 a[i] = unhexchar(p[1 + i]);
1148 if (a[i] < 0)
1149 return a[i];
1150 }
1151
1152 c = ((uint32_t) a[0] << 28U) | ((uint32_t) a[1] << 24U) | ((uint32_t) a[2] << 20U) | ((uint32_t) a[3] << 16U) |
1153 ((uint32_t) a[4] << 12U) | ((uint32_t) a[5] << 8U) | ((uint32_t) a[6] << 4U) | (uint32_t) a[7];
1154
1155 /* Don't allow 0 chars */
1156 if (c == 0)
1157 return -EINVAL;
1158
1159 /* Don't allow invalid code points */
1160 if (!unichar_is_valid(c))
1161 return -EINVAL;
1162
1163 if (c < 128)
1164 *ret = c;
1165 else {
1166 if (!ret_unicode)
1167 return -EINVAL;
1168
1169 *ret = 0;
1170 *ret_unicode = c;
1171 }
1172
1173 r = 9;
1174 break;
1175 }
1176
4034a06d
LP
1177 case '0':
1178 case '1':
1179 case '2':
1180 case '3':
1181 case '4':
1182 case '5':
1183 case '6':
1184 case '7': {
1185 /* octal encoding */
f3ee6297
LP
1186 int a, b, c;
1187 uint32_t m;
4034a06d
LP
1188
1189 if (length != (size_t) -1 && length < 4)
1190 return -EINVAL;
1191
1192 a = unoctchar(p[0]);
1193 if (a < 0)
1194 return -EINVAL;
1195
1196 b = unoctchar(p[1]);
1197 if (b < 0)
1198 return -EINVAL;
1199
1200 c = unoctchar(p[2]);
1201 if (c < 0)
1202 return -EINVAL;
1203
1204 /* don't allow NUL bytes */
1205 if (a == 0 && b == 0 && c == 0)
1206 return -EINVAL;
1207
1208 /* Don't allow bytes above 255 */
f3ee6297 1209 m = ((uint32_t) a << 6U) | ((uint32_t) b << 3U) | (uint32_t) c;
4034a06d
LP
1210 if (m > 255)
1211 return -EINVAL;
1212
f3ee6297 1213 *ret = m;
4034a06d
LP
1214 r = 3;
1215 break;
1216 }
1217
1218 default:
1219 return -EINVAL;
1220 }
1221
1222 return r;
1223}
1224
527b7a42 1225int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret) {
4fe88d28
LP
1226 char *r, *t;
1227 const char *f;
5b4c61cd 1228 size_t pl;
4fe88d28
LP
1229
1230 assert(s);
527b7a42 1231 assert(ret);
4fe88d28 1232
5b4c61cd
LP
1233 /* Undoes C style string escaping, and optionally prefixes it. */
1234
1235 pl = prefix ? strlen(prefix) : 0;
4fe88d28 1236
5b4c61cd 1237 r = new(char, pl+length+1);
7f110ff9 1238 if (!r)
527b7a42 1239 return -ENOMEM;
4fe88d28 1240
5b4c61cd
LP
1241 if (prefix)
1242 memcpy(r, prefix, pl);
1243
1244 for (f = s, t = r + pl; f < s + length; f++) {
4034a06d 1245 size_t remaining;
f3ee6297
LP
1246 uint32_t u;
1247 char c;
4034a06d
LP
1248 int k;
1249
1250 remaining = s + length - f;
7f769619 1251 assert(remaining > 0);
4fe88d28 1252
527b7a42
LP
1253 if (*f != '\\') {
1254 /* A literal literal, copy verbatim */
4fe88d28
LP
1255 *(t++) = *f;
1256 continue;
1257 }
1258
527b7a42
LP
1259 if (remaining == 1) {
1260 if (flags & UNESCAPE_RELAX) {
1261 /* A trailing backslash, copy verbatim */
1262 *(t++) = *f;
1263 continue;
1264 }
1265
cd977dca 1266 free(r);
527b7a42
LP
1267 return -EINVAL;
1268 }
1269
f3ee6297 1270 k = cunescape_one(f + 1, remaining - 1, &c, &u);
4034a06d 1271 if (k < 0) {
527b7a42
LP
1272 if (flags & UNESCAPE_RELAX) {
1273 /* Invalid escape code, let's take it literal then */
1274 *(t++) = '\\';
1275 continue;
1276 }
1277
cd977dca 1278 free(r);
527b7a42 1279 return k;
4fe88d28 1280 }
4034a06d 1281
f3ee6297
LP
1282 if (c != 0)
1283 /* Non-Unicode? Let's encode this directly */
1284 *(t++) = c;
1285 else
1286 /* Unicode? Then let's encode this in UTF-8 */
1287 t += utf8_encode_unichar(t, u);
1288
4034a06d 1289 f += k;
4fe88d28
LP
1290 }
1291
4fe88d28 1292 *t = 0;
4fe88d28 1293
527b7a42
LP
1294 *ret = r;
1295 return t - r;
5b4c61cd
LP
1296}
1297
527b7a42
LP
1298int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret) {
1299 return cunescape_length_with_prefix(s, length, NULL, flags, ret);
1300}
5b4c61cd 1301
527b7a42
LP
1302int cunescape(const char *s, UnescapeFlags flags, char **ret) {
1303 return cunescape_length(s, strlen(s), flags, ret);
6febfd0d 1304}
4fe88d28
LP
1305
1306char *xescape(const char *s, const char *bad) {
1307 char *r, *t;
1308 const char *f;
1309
1310 /* Escapes all chars in bad, in addition to \ and all special
1311 * chars, in \xFF style escaping. May be reversed with
019c7fba 1312 * cunescape(). */
4fe88d28 1313
08ace05b
LP
1314 r = new(char, strlen(s) * 4 + 1);
1315 if (!r)
4fe88d28
LP
1316 return NULL;
1317
1318 for (f = s, t = r; *f; f++) {
1319
b866264a
LP
1320 if ((*f < ' ') || (*f >= 127) ||
1321 (*f == '\\') || strchr(bad, *f)) {
4fe88d28
LP
1322 *(t++) = '\\';
1323 *(t++) = 'x';
1324 *(t++) = hexchar(*f >> 4);
1325 *(t++) = hexchar(*f);
1326 } else
1327 *(t++) = *f;
1328 }
1329
1330 *t = 0;
1331
1332 return r;
1333}
1334
67d51650 1335char *ascii_strlower(char *t) {
4fe88d28
LP
1336 char *p;
1337
67d51650 1338 assert(t);
4fe88d28 1339
67d51650 1340 for (p = t; *p; p++)
4fe88d28
LP
1341 if (*p >= 'A' && *p <= 'Z')
1342 *p = *p - 'A' + 'a';
1343
67d51650 1344 return t;
4fe88d28 1345}
1dccbe19 1346
a34bf9db 1347_pure_ static bool hidden_file_allow_backup(const char *filename) {
c85dc17b
LP
1348 assert(filename);
1349
1350 return
1351 filename[0] == '.' ||
6c78be3c 1352 streq(filename, "lost+found") ||
e472d476
LP
1353 streq(filename, "aquota.user") ||
1354 streq(filename, "aquota.group") ||
c85dc17b
LP
1355 endswith(filename, ".rpmnew") ||
1356 endswith(filename, ".rpmsave") ||
1357 endswith(filename, ".rpmorig") ||
1358 endswith(filename, ".dpkg-old") ||
1359 endswith(filename, ".dpkg-new") ||
0cdfd26e 1360 endswith(filename, ".dpkg-tmp") ||
c7088e49
MP
1361 endswith(filename, ".dpkg-dist") ||
1362 endswith(filename, ".dpkg-bak") ||
1363 endswith(filename, ".dpkg-backup") ||
1364 endswith(filename, ".dpkg-remove") ||
c85dc17b
LP
1365 endswith(filename, ".swp");
1366}
1367
a34bf9db 1368bool hidden_file(const char *filename) {
a228a22f
LP
1369 assert(filename);
1370
1371 if (endswith(filename, "~"))
93f1a063 1372 return true;
a228a22f 1373
a34bf9db 1374 return hidden_file_allow_backup(filename);
a228a22f
LP
1375}
1376
3a0ecb08 1377int fd_nonblock(int fd, bool nonblock) {
be8f4e9e 1378 int flags, nflags;
3a0ecb08
LP
1379
1380 assert(fd >= 0);
1381
be8f4e9e
LP
1382 flags = fcntl(fd, F_GETFL, 0);
1383 if (flags < 0)
3a0ecb08
LP
1384 return -errno;
1385
1386 if (nonblock)
be8f4e9e 1387 nflags = flags | O_NONBLOCK;
3a0ecb08 1388 else
be8f4e9e
LP
1389 nflags = flags & ~O_NONBLOCK;
1390
1391 if (nflags == flags)
1392 return 0;
3a0ecb08 1393
34b42c96 1394 if (fcntl(fd, F_SETFL, nflags) < 0)
3a0ecb08
LP
1395 return -errno;
1396
1397 return 0;
1398}
1399
1400int fd_cloexec(int fd, bool cloexec) {
be8f4e9e 1401 int flags, nflags;
3a0ecb08
LP
1402
1403 assert(fd >= 0);
1404
be8f4e9e
LP
1405 flags = fcntl(fd, F_GETFD, 0);
1406 if (flags < 0)
3a0ecb08
LP
1407 return -errno;
1408
1409 if (cloexec)
be8f4e9e 1410 nflags = flags | FD_CLOEXEC;
3a0ecb08 1411 else
be8f4e9e
LP
1412 nflags = flags & ~FD_CLOEXEC;
1413
1414 if (nflags == flags)
1415 return 0;
3a0ecb08 1416
34b42c96 1417 if (fcntl(fd, F_SETFD, nflags) < 0)
3a0ecb08
LP
1418 return -errno;
1419
1420 return 0;
1421}
1422
44a6b1b6 1423_pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
b19be9eb
LP
1424 unsigned i;
1425
1426 assert(n_fdset == 0 || fdset);
1427
1428 for (i = 0; i < n_fdset; i++)
1429 if (fdset[i] == fd)
1430 return true;
1431
1432 return false;
1433}
1434
a0d40ac5 1435int close_all_fds(const int except[], unsigned n_except) {
e1d75803 1436 _cleanup_closedir_ DIR *d = NULL;
a0d40ac5
LP
1437 struct dirent *de;
1438 int r = 0;
1439
b19be9eb
LP
1440 assert(n_except == 0 || except);
1441
1442 d = opendir("/proc/self/fd");
1443 if (!d) {
1444 int fd;
1445 struct rlimit rl;
1446
1447 /* When /proc isn't available (for example in chroots)
1448 * the fallback is brute forcing through the fd
1449 * table */
1450
1451 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
1452 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
1453
1454 if (fd_in_set(fd, except, n_except))
1455 continue;
1456
1457 if (close_nointr(fd) < 0)
1458 if (errno != EBADF && r == 0)
1459 r = -errno;
1460 }
1461
1462 return r;
1463 }
a0d40ac5
LP
1464
1465 while ((de = readdir(d))) {
a7610064 1466 int fd = -1;
a0d40ac5 1467
a34bf9db 1468 if (hidden_file(de->d_name))
a0d40ac5
LP
1469 continue;
1470
720ce21d
LP
1471 if (safe_atoi(de->d_name, &fd) < 0)
1472 /* Let's better ignore this, just in case */
1473 continue;
a0d40ac5
LP
1474
1475 if (fd < 3)
1476 continue;
1477
1478 if (fd == dirfd(d))
1479 continue;
1480
b19be9eb
LP
1481 if (fd_in_set(fd, except, n_except))
1482 continue;
a0d40ac5 1483
720ce21d 1484 if (close_nointr(fd) < 0) {
2f357920 1485 /* Valgrind has its own FD and doesn't want to have it closed */
720ce21d
LP
1486 if (errno != EBADF && r == 0)
1487 r = -errno;
2f357920 1488 }
a0d40ac5
LP
1489 }
1490
a0d40ac5
LP
1491 return r;
1492}
1493
db12775d
LP
1494bool chars_intersect(const char *a, const char *b) {
1495 const char *p;
1496
1497 /* Returns true if any of the chars in a are in b. */
1498 for (p = a; *p; p++)
1499 if (strchr(b, *p))
1500 return true;
1501
1502 return false;
1503}
1504
42856c10 1505bool fstype_is_network(const char *fstype) {
a05f97b3 1506 static const char table[] =
ba89821c 1507 "afs\0"
a05f97b3
LP
1508 "cifs\0"
1509 "smbfs\0"
da92ca5e 1510 "sshfs\0"
a05f97b3 1511 "ncpfs\0"
dac70dc7 1512 "ncp\0"
a05f97b3
LP
1513 "nfs\0"
1514 "nfs4\0"
1515 "gfs\0"
67608cad
LP
1516 "gfs2\0"
1517 "glusterfs\0";
1518
1519 const char *x;
1520
1521 x = startswith(fstype, "fuse.");
1522 if (x)
1523 fstype = x;
42856c10 1524
a05f97b3 1525 return nulstr_contains(table, fstype);
42856c10
LP
1526}
1527
80876c20 1528int flush_fd(int fd) {
b92bea5d
ZJS
1529 struct pollfd pollfd = {
1530 .fd = fd,
1531 .events = POLLIN,
1532 };
80876c20
LP
1533
1534 for (;;) {
20c03b7b 1535 char buf[LINE_MAX];
80876c20
LP
1536 ssize_t l;
1537 int r;
1538
e62d8c39
ZJS
1539 r = poll(&pollfd, 1, 0);
1540 if (r < 0) {
80876c20
LP
1541 if (errno == EINTR)
1542 continue;
1543
1544 return -errno;
80876c20 1545
e62d8c39 1546 } else if (r == 0)
80876c20
LP
1547 return 0;
1548
e62d8c39
ZJS
1549 l = read(fd, buf, sizeof(buf));
1550 if (l < 0) {
80876c20
LP
1551
1552 if (errno == EINTR)
1553 continue;
1554
1555 if (errno == EAGAIN)
1556 return 0;
1557
1558 return -errno;
e62d8c39 1559 } else if (l == 0)
80876c20
LP
1560 return 0;
1561 }
1562}
1563
9a34ec5f
LP
1564int sigaction_many(const struct sigaction *sa, ...) {
1565 va_list ap;
1566 int r = 0, sig;
1567
1568 va_start(ap, sa);
1569 while ((sig = va_arg(ap, int)) > 0)
1570 if (sigaction(sig, sa, NULL) < 0)
1571 r = -errno;
1572 va_end(ap);
1573
1574 return r;
1575}
1576
1577int ignore_signals(int sig, ...) {
b92bea5d
ZJS
1578 struct sigaction sa = {
1579 .sa_handler = SIG_IGN,
1580 .sa_flags = SA_RESTART,
1581 };
9a34ec5f
LP
1582 va_list ap;
1583 int r = 0;
a337c6fc 1584
9a34ec5f
LP
1585 if (sigaction(sig, &sa, NULL) < 0)
1586 r = -errno;
1587
1588 va_start(ap, sig);
1589 while ((sig = va_arg(ap, int)) > 0)
1590 if (sigaction(sig, &sa, NULL) < 0)
1591 r = -errno;
1592 va_end(ap);
1593
1594 return r;
1595}
1596
1597int default_signals(int sig, ...) {
b92bea5d
ZJS
1598 struct sigaction sa = {
1599 .sa_handler = SIG_DFL,
1600 .sa_flags = SA_RESTART,
1601 };
9a34ec5f
LP
1602 va_list ap;
1603 int r = 0;
1604
9a34ec5f
LP
1605 if (sigaction(sig, &sa, NULL) < 0)
1606 r = -errno;
1607
1608 va_start(ap, sig);
1609 while ((sig = va_arg(ap, int)) > 0)
1610 if (sigaction(sig, &sa, NULL) < 0)
1611 r = -errno;
1612 va_end(ap);
1613
1614 return r;
a337c6fc
LP
1615}
1616
3d94f76c 1617void safe_close_pair(int p[]) {
8d567588
LP
1618 assert(p);
1619
3d94f76c
LP
1620 if (p[0] == p[1]) {
1621 /* Special case pairs which use the same fd in both
1622 * directions... */
1623 p[0] = p[1] = safe_close(p[0]);
1624 return;
8d567588
LP
1625 }
1626
3d94f76c
LP
1627 p[0] = safe_close(p[0]);
1628 p[1] = safe_close(p[1]);
8d567588
LP
1629}
1630
eb22ac37 1631ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
7d5dd5e0 1632 uint8_t *p = buf;
8d567588
LP
1633 ssize_t n = 0;
1634
1635 assert(fd >= 0);
1636 assert(buf);
1637
8d567588
LP
1638 while (nbytes > 0) {
1639 ssize_t k;
1640
7d5dd5e0 1641 k = read(fd, p, nbytes);
6ce830fa
LP
1642 if (k < 0) {
1643 if (errno == EINTR)
1644 continue;
8d567588 1645
6ce830fa 1646 if (errno == EAGAIN && do_poll) {
8d567588 1647
6ce830fa
LP
1648 /* We knowingly ignore any return value here,
1649 * and expect that any error/EOF is reported
1650 * via read() */
8d567588 1651
6ce830fa
LP
1652 fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
1653 continue;
1654 }
1655
1656 return n > 0 ? n : -errno;
7d5dd5e0 1657 }
8d567588 1658
6ce830fa
LP
1659 if (k == 0)
1660 return n;
8d567588
LP
1661
1662 p += k;
1663 nbytes -= k;
1664 n += k;
1665 }
1666
1667 return n;
1668}
1669
a6dcc7e5
ZJS
1670int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
1671 ssize_t n;
1672
1673 n = loop_read(fd, buf, nbytes, do_poll);
1674 if (n < 0)
1675 return n;
1676 if ((size_t) n != nbytes)
1677 return -EIO;
1678 return 0;
1679}
1680
553acb7b 1681int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
7d5dd5e0 1682 const uint8_t *p = buf;
eb22ac37
LP
1683
1684 assert(fd >= 0);
1685 assert(buf);
1686
553acb7b
ZJS
1687 errno = 0;
1688
8c7e28a1 1689 do {
eb22ac37
LP
1690 ssize_t k;
1691
fe652127 1692 k = write(fd, p, nbytes);
6ce830fa
LP
1693 if (k < 0) {
1694 if (errno == EINTR)
1695 continue;
eb22ac37 1696
6ce830fa
LP
1697 if (errno == EAGAIN && do_poll) {
1698 /* We knowingly ignore any return value here,
1699 * and expect that any error/EOF is reported
1700 * via write() */
eb22ac37 1701
6ce830fa
LP
1702 fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
1703 continue;
1704 }
eb22ac37 1705
6ce830fa 1706 return -errno;
7d5dd5e0 1707 }
eb22ac37 1708
8c7e28a1 1709 if (nbytes > 0 && k == 0) /* Can't really happen */
6ce830fa 1710 return -EIO;
eb22ac37
LP
1711
1712 p += k;
1713 nbytes -= k;
8c7e28a1 1714 } while (nbytes > 0);
eb22ac37 1715
553acb7b 1716 return 0;
eb22ac37
LP
1717}
1718
5556b5fe
LP
1719int parse_size(const char *t, off_t base, off_t *size) {
1720
55ede093 1721 /* Soo, sometimes we want to parse IEC binary suffixes, and
5556b5fe
LP
1722 * sometimes SI decimal suffixes. This function can parse
1723 * both. Which one is the right way depends on the
1724 * context. Wikipedia suggests that SI is customary for
30a5b782 1725 * hardware metrics and network speeds, while IEC is
5556b5fe
LP
1726 * customary for most data sizes used by software and volatile
1727 * (RAM) memory. Hence be careful which one you pick!
1728 *
1729 * In either case we use just K, M, G as suffix, and not Ki,
1730 * Mi, Gi or so (as IEC would suggest). That's because that's
1731 * frickin' ugly. But this means you really need to make sure
1732 * to document which base you are parsing when you use this
1733 * call. */
1734
1735 struct table {
ab1f0633 1736 const char *suffix;
b32ff512 1737 unsigned long long factor;
5556b5fe
LP
1738 };
1739
1740 static const struct table iec[] = {
32895bb3 1741 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
840292be
ZJS
1742 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
1743 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
1744 { "G", 1024ULL*1024ULL*1024ULL },
1745 { "M", 1024ULL*1024ULL },
1746 { "K", 1024ULL },
1747 { "B", 1 },
ab1f0633
LP
1748 { "", 1 },
1749 };
1750
5556b5fe 1751 static const struct table si[] = {
5556b5fe 1752 { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
840292be
ZJS
1753 { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
1754 { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
1755 { "G", 1000ULL*1000ULL*1000ULL },
1756 { "M", 1000ULL*1000ULL },
1757 { "K", 1000ULL },
1758 { "B", 1 },
5556b5fe
LP
1759 { "", 1 },
1760 };
1761
1762 const struct table *table;
ab1f0633 1763 const char *p;
b32ff512 1764 unsigned long long r = 0;
840292be 1765 unsigned n_entries, start_pos = 0;
ab1f0633
LP
1766
1767 assert(t);
5556b5fe
LP
1768 assert(base == 1000 || base == 1024);
1769 assert(size);
1770
1771 if (base == 1000) {
1772 table = si;
1773 n_entries = ELEMENTSOF(si);
1774 } else {
1775 table = iec;
1776 n_entries = ELEMENTSOF(iec);
1777 }
ab1f0633
LP
1778
1779 p = t;
1780 do {
1781 long long l;
9480794b
ZJS
1782 unsigned long long l2;
1783 double frac = 0;
ab1f0633
LP
1784 char *e;
1785 unsigned i;
1786
1787 errno = 0;
1788 l = strtoll(p, &e, 10);
1789
8333c77e 1790 if (errno > 0)
ab1f0633
LP
1791 return -errno;
1792
1793 if (l < 0)
1794 return -ERANGE;
1795
1796 if (e == p)
1797 return -EINVAL;
1798
9480794b
ZJS
1799 if (*e == '.') {
1800 e++;
1801 if (*e >= '0' && *e <= '9') {
1802 char *e2;
1803
1804 /* strotoull itself would accept space/+/- */
1805 l2 = strtoull(e, &e2, 10);
1806
1807 if (errno == ERANGE)
1808 return -errno;
1809
1810 /* Ignore failure. E.g. 10.M is valid */
1811 frac = l2;
1812 for (; e < e2; e++)
1813 frac /= 10;
1814 }
1815 }
1816
ab1f0633
LP
1817 e += strspn(e, WHITESPACE);
1818
840292be 1819 for (i = start_pos; i < n_entries; i++)
ab1f0633 1820 if (startswith(e, table[i].suffix)) {
b32ff512 1821 unsigned long long tmp;
9480794b 1822 if ((unsigned long long) l + (frac > 0) > ULLONG_MAX / table[i].factor)
b32ff512 1823 return -ERANGE;
9480794b 1824 tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
b32ff512
ZJS
1825 if (tmp > ULLONG_MAX - r)
1826 return -ERANGE;
1827
1828 r += tmp;
1829 if ((unsigned long long) (off_t) r != r)
1830 return -ERANGE;
1831
ab1f0633 1832 p = e + strlen(table[i].suffix);
840292be
ZJS
1833
1834 start_pos = i + 1;
ab1f0633
LP
1835 break;
1836 }
1837
5556b5fe 1838 if (i >= n_entries)
ab1f0633
LP
1839 return -EINVAL;
1840
b32ff512 1841 } while (*p);
ab1f0633 1842
5556b5fe 1843 *size = r;
ab1f0633
LP
1844
1845 return 0;
1846}
1847
8407a5d0
LP
1848bool is_device_path(const char *path) {
1849
1850 /* Returns true on paths that refer to a device, either in
1851 * sysfs or in /dev */
1852
1853 return
1854 path_startswith(path, "/dev/") ||
1855 path_startswith(path, "/sys/");
1856}
1857
01f78473 1858int dir_is_empty(const char *path) {
a05f97b3 1859 _cleanup_closedir_ DIR *d;
01f78473 1860
a05f97b3
LP
1861 d = opendir(path);
1862 if (!d)
01f78473
LP
1863 return -errno;
1864
1865 for (;;) {
7d5e9c0f 1866 struct dirent *de;
01f78473 1867
3fd11280
FW
1868 errno = 0;
1869 de = readdir(d);
1870 if (!de && errno != 0)
1871 return -errno;
01f78473 1872
a05f97b3
LP
1873 if (!de)
1874 return 1;
01f78473 1875
a34bf9db 1876 if (!hidden_file(de->d_name))
a05f97b3
LP
1877 return 0;
1878 }
01f78473
LP
1879}
1880
844ec79b
ZJS
1881char* dirname_malloc(const char *path) {
1882 char *d, *dir, *dir2;
1883
1884 d = strdup(path);
1885 if (!d)
1886 return NULL;
1887 dir = dirname(d);
1888 assert(dir);
1889
1890 if (dir != d) {
1891 dir2 = strdup(dir);
1892 free(d);
1893 return dir2;
1894 }
1895
1896 return dir;
1897}
1898
5b6319dc
LP
1899void rename_process(const char name[8]) {
1900 assert(name);
1901
5d6b1584
LP
1902 /* This is a like a poor man's setproctitle(). It changes the
1903 * comm field, argv[0], and also the glibc's internally used
1904 * name of the process. For the first one a limit of 16 chars
1905 * applies, to the second one usually one of 10 (i.e. length
1906 * of "/sbin/init"), to the third one one of 7 (i.e. length of
1907 * "systemd"). If you pass a longer string it will be
1908 * truncated */
5b6319dc 1909
5d6b1584 1910 prctl(PR_SET_NAME, name);
5b6319dc
LP
1911
1912 if (program_invocation_name)
1913 strncpy(program_invocation_name, name, strlen(program_invocation_name));
9a0e6896
LP
1914
1915 if (saved_argc > 0) {
1916 int i;
1917
1918 if (saved_argv[0])
1919 strncpy(saved_argv[0], name, strlen(saved_argv[0]));
1920
1921 for (i = 1; i < saved_argc; i++) {
1922 if (!saved_argv[i])
1923 break;
1924
29804cc1 1925 memzero(saved_argv[i], strlen(saved_argv[i]));
9a0e6896
LP
1926 }
1927 }
5b6319dc
LP
1928}
1929
7d793605
LP
1930void sigset_add_many(sigset_t *ss, ...) {
1931 va_list ap;
1932 int sig;
1933
1934 assert(ss);
1935
1936 va_start(ap, ss);
1937 while ((sig = va_arg(ap, int)) > 0)
1938 assert_se(sigaddset(ss, sig) == 0);
1939 va_end(ap);
1940}
1941
856a5a7d
LP
1942int sigprocmask_many(int how, ...) {
1943 va_list ap;
1944 sigset_t ss;
1945 int sig;
1946
1947 assert_se(sigemptyset(&ss) == 0);
1948
1949 va_start(ap, how);
1950 while ((sig = va_arg(ap, int)) > 0)
1951 assert_se(sigaddset(&ss, sig) == 0);
1952 va_end(ap);
1953
1954 if (sigprocmask(how, &ss, NULL) < 0)
1955 return -errno;
1956
1957 return 0;
1958}
f1566e63 1959char *lookup_uid(uid_t uid) {
ef2f1067 1960 long bufsize;
a05f97b3
LP
1961 char *name;
1962 _cleanup_free_ char *buf = NULL;
ef2f1067 1963 struct passwd pwbuf, *pw = NULL;
ef2f1067
LP
1964
1965 /* Shortcut things to avoid NSS lookups */
1966 if (uid == 0)
1967 return strdup("root");
1968
7c5f152a
LP
1969 bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
1970 if (bufsize <= 0)
ef2f1067
LP
1971 bufsize = 4096;
1972
7c5f152a
LP
1973 buf = malloc(bufsize);
1974 if (!buf)
ef2f1067
LP
1975 return NULL;
1976
a05f97b3
LP
1977 if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
1978 return strdup(pw->pw_name);
ef2f1067 1979
de0671ee 1980 if (asprintf(&name, UID_FMT, uid) < 0)
ef2f1067
LP
1981 return NULL;
1982
1983 return name;
1984}
1985
7c5f152a
LP
1986char* getlogname_malloc(void) {
1987 uid_t uid;
1988 struct stat st;
1989
1990 if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
1991 uid = st.st_uid;
1992 else
1993 uid = getuid();
1994
1995 return lookup_uid(uid);
1996}
1997
1998char *getusername_malloc(void) {
1999 const char *e;
2000
2001 e = getenv("USER");
2002 if (e)
2003 return strdup(e);
2004
2005 return lookup_uid(getuid());
2006}
2007
c6878637 2008bool is_temporary_fs(const struct statfs *s) {
943aad8c 2009 assert(s);
73020ab2
SL
2010
2011 return F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) ||
2012 F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC);
943aad8c
ZJS
2013}
2014
c6878637 2015int fd_is_temporary_fs(int fd) {
979ef53a
DR
2016 struct statfs s;
2017
2018 if (fstatfs(fd, &s) < 0)
2019 return -errno;
2020
2021 return is_temporary_fs(&s);
2022}
2023
8c6db833
LP
2024int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
2025 assert(path);
2026
2027 /* Under the assumption that we are running privileged we
2028 * first change the access mode and only then hand out
2029 * ownership to avoid a window where access is too open. */
2030
fed1e721 2031 if (mode != MODE_INVALID)
8d53b453
LP
2032 if (chmod(path, mode) < 0)
2033 return -errno;
8c6db833 2034
fed1e721 2035 if (uid != UID_INVALID || gid != GID_INVALID)
8d53b453
LP
2036 if (chown(path, uid, gid) < 0)
2037 return -errno;
8c6db833
LP
2038
2039 return 0;
ef2f1067
LP
2040}
2041
f4b47811
LP
2042int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
2043 assert(fd >= 0);
2044
2045 /* Under the assumption that we are running privileged we
2046 * first change the access mode and only then hand out
2047 * ownership to avoid a window where access is too open. */
2048
fed1e721 2049 if (mode != MODE_INVALID)
9588bc32
LP
2050 if (fchmod(fd, mode) < 0)
2051 return -errno;
f4b47811 2052
fed1e721 2053 if (uid != UID_INVALID || gid != GID_INVALID)
9588bc32
LP
2054 if (fchown(fd, uid, gid) < 0)
2055 return -errno;
f4b47811
LP
2056
2057 return 0;
2058}
2059
82c121a4
LP
2060cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
2061 cpu_set_t *r;
2062 unsigned n = 1024;
2063
2064 /* Allocates the cpuset in the right size */
2065
2066 for (;;) {
2067 if (!(r = CPU_ALLOC(n)))
2068 return NULL;
2069
2070 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
2071 CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
2072
2073 if (ncpus)
2074 *ncpus = n;
2075
2076 return r;
2077 }
2078
2079 CPU_FREE(r);
2080
2081 if (errno != EINVAL)
2082 return NULL;
2083
2084 n *= 2;
2085 }
2086}
2087
9d9951a4
HH
2088int files_same(const char *filea, const char *fileb) {
2089 struct stat a, b;
b4f10a5e 2090
9d9951a4 2091 if (stat(filea, &a) < 0)
b4f10a5e
LP
2092 return -errno;
2093
9d9951a4 2094 if (stat(fileb, &b) < 0)
b4f10a5e
LP
2095 return -errno;
2096
9d9951a4
HH
2097 return a.st_dev == b.st_dev &&
2098 a.st_ino == b.st_ino;
2099}
2100
2101int running_in_chroot(void) {
2102 int ret;
2103
2104 ret = files_same("/proc/1/root", "/");
2105 if (ret < 0)
2106 return ret;
2107
2108 return ret == 0;
b4f10a5e
LP
2109}
2110
f405e86d 2111static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
72f59706 2112 size_t x;
8fe914ec
LP
2113 char *r;
2114
2115 assert(s);
2116 assert(percent <= 100);
72f59706 2117 assert(new_length >= 3);
8fe914ec 2118
72f59706
LP
2119 if (old_length <= 3 || old_length <= new_length)
2120 return strndup(s, old_length);
8fe914ec 2121
72f59706
LP
2122 r = new0(char, new_length+1);
2123 if (!r)
a6f0104a 2124 return NULL;
8fe914ec 2125
72f59706 2126 x = (new_length * percent) / 100;
8fe914ec 2127
72f59706
LP
2128 if (x > new_length - 3)
2129 x = new_length - 3;
8fe914ec
LP
2130
2131 memcpy(r, s, x);
2132 r[x] = '.';
2133 r[x+1] = '.';
2134 r[x+2] = '.';
2135 memcpy(r + x + 3,
72f59706
LP
2136 s + old_length - (new_length - x - 3),
2137 new_length - x - 3);
8fe914ec
LP
2138
2139 return r;
2140}
2141
f405e86d
SL
2142char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
2143 size_t x;
2144 char *e;
2145 const char *i, *j;
2146 unsigned k, len, len2;
2147
2148 assert(s);
2149 assert(percent <= 100);
2150 assert(new_length >= 3);
2151
2152 /* if no multibyte characters use ascii_ellipsize_mem for speed */
2153 if (ascii_is_valid(s))
2154 return ascii_ellipsize_mem(s, old_length, new_length, percent);
2155
2156 if (old_length <= 3 || old_length <= new_length)
2157 return strndup(s, old_length);
2158
2159 x = (new_length * percent) / 100;
2160
2161 if (x > new_length - 3)
2162 x = new_length - 3;
2163
2164 k = 0;
2165 for (i = s; k < x && i < s + old_length; i = utf8_next_char(i)) {
2166 int c;
2167
2168 c = utf8_encoded_to_unichar(i);
2169 if (c < 0)
2170 return NULL;
2171 k += unichar_iswide(c) ? 2 : 1;
2172 }
2173
2174 if (k > x) /* last character was wide and went over quota */
2175 x ++;
2176
2177 for (j = s + old_length; k < new_length && j > i; ) {
2178 int c;
2179
2180 j = utf8_prev_char(j);
2181 c = utf8_encoded_to_unichar(j);
2182 if (c < 0)
2183 return NULL;
2184 k += unichar_iswide(c) ? 2 : 1;
2185 }
2186 assert(i <= j);
2187
2188 /* we don't actually need to ellipsize */
2189 if (i == j)
2190 return memdup(s, old_length + 1);
2191
2192 /* make space for ellipsis */
2193 j = utf8_next_char(j);
2194
2195 len = i - s;
2196 len2 = s + old_length - j;
2197 e = new(char, len + 3 + len2 + 1);
2198 if (!e)
2199 return NULL;
2200
2201 /*
2202 printf("old_length=%zu new_length=%zu x=%zu len=%u len2=%u k=%u\n",
2203 old_length, new_length, x, len, len2, k);
2204 */
2205
2206 memcpy(e, s, len);
2207 e[len] = 0xe2; /* tri-dot ellipsis: … */
2208 e[len + 1] = 0x80;
2209 e[len + 2] = 0xa6;
2210
2211 memcpy(e + len + 3, j, len2 + 1);
2212
2213 return e;
2214}
2215
72f59706
LP
2216char *ellipsize(const char *s, size_t length, unsigned percent) {
2217 return ellipsize_mem(s, strlen(s), length, percent);
2218}
2219
c38dfac9 2220int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
03e334a1 2221 _cleanup_close_ int fd;
c38dfac9 2222 int r;
f6144808
LP
2223
2224 assert(path);
2225
c38dfac9
KS
2226 if (parents)
2227 mkdir_parents(path, 0755);
73836c5c 2228
c38dfac9 2229 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode > 0 ? mode : 0644);
73836c5c 2230 if (fd < 0)
f6144808
LP
2231 return -errno;
2232
c38dfac9
KS
2233 if (mode > 0) {
2234 r = fchmod(fd, mode);
2235 if (r < 0)
2236 return -errno;
2237 }
2238
fed1e721 2239 if (uid != UID_INVALID || gid != GID_INVALID) {
c38dfac9
KS
2240 r = fchown(fd, uid, gid);
2241 if (r < 0)
2242 return -errno;
2243 }
2244
3a43da28 2245 if (stamp != USEC_INFINITY) {
c38dfac9
KS
2246 struct timespec ts[2];
2247
2248 timespec_store(&ts[0], stamp);
359efc59 2249 ts[1] = ts[0];
c38dfac9
KS
2250 r = futimens(fd, ts);
2251 } else
2252 r = futimens(fd, NULL);
2253 if (r < 0)
2254 return -errno;
2255
f6144808
LP
2256 return 0;
2257}
afea26ad 2258
c38dfac9 2259int touch(const char *path) {
fed1e721 2260 return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, 0);
c38dfac9
KS
2261}
2262
e1eaca26 2263static char *unquote(const char *s, const char* quotes) {
11ce3427
LP
2264 size_t l;
2265 assert(s);
2266
73836c5c
LP
2267 /* This is rather stupid, simply removes the heading and
2268 * trailing quotes if there is one. Doesn't care about
e1eaca26
LP
2269 * escaping or anything.
2270 *
2271 * DON'T USE THIS FOR NEW CODE ANYMORE!*/
73836c5c 2272
31ed59c5
LP
2273 l = strlen(s);
2274 if (l < 2)
11ce3427
LP
2275 return strdup(s);
2276
97c4a07d 2277 if (strchr(quotes, s[0]) && s[l-1] == s[0])
11ce3427
LP
2278 return strndup(s+1, l-2);
2279
2280 return strdup(s);
2281}
2282
919ce0b7 2283noreturn void freeze(void) {
720ce21d
LP
2284
2285 /* Make sure nobody waits for us on a socket anymore */
2286 close_all_fds(NULL, 0);
2287
c29597a1
LP
2288 sync();
2289
3c14d26c
LP
2290 for (;;)
2291 pause();
2292}
2293
00dc5d76
LP
2294bool null_or_empty(struct stat *st) {
2295 assert(st);
2296
2297 if (S_ISREG(st->st_mode) && st->st_size <= 0)
2298 return true;
2299
c8f26f42 2300 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
00dc5d76
LP
2301 return true;
2302
2303 return false;
2304}
2305
83096483
LP
2306int null_or_empty_path(const char *fn) {
2307 struct stat st;
2308
2309 assert(fn);
2310
2311 if (stat(fn, &st) < 0)
2312 return -errno;
2313
2314 return null_or_empty(&st);
2315}
2316
ed88bcfb
ZJS
2317int null_or_empty_fd(int fd) {
2318 struct stat st;
2319
2320 assert(fd >= 0);
2321
2322 if (fstat(fd, &st) < 0)
2323 return -errno;
2324
2325 return null_or_empty(&st);
2326}
2327
a247755d 2328DIR *xopendirat(int fd, const char *name, int flags) {
c4731d11
LP
2329 int nfd;
2330 DIR *d;
2331
dd94c17e
LP
2332 assert(!(flags & O_CREAT));
2333
2334 nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
73836c5c 2335 if (nfd < 0)
c4731d11
LP
2336 return NULL;
2337
73836c5c
LP
2338 d = fdopendir(nfd);
2339 if (!d) {
03e334a1 2340 safe_close(nfd);
c4731d11
LP
2341 return NULL;
2342 }
2343
2344 return d;
3b63d2d3
LP
2345}
2346
8a0867d6
LP
2347int signal_from_string_try_harder(const char *s) {
2348 int signo;
2349 assert(s);
2350
73836c5c
LP
2351 signo = signal_from_string(s);
2352 if (signo <= 0)
8a0867d6
LP
2353 if (startswith(s, "SIG"))
2354 return signal_from_string(s+3);
2355
2356 return signo;
2357}
2358
383182b5 2359static char *tag_to_udev_node(const char *tagvalue, const char *by) {
22f5f628 2360 _cleanup_free_ char *t = NULL, *u = NULL;
22f5f628 2361 size_t enc_len;
e23a0ce8 2362
e1eaca26 2363 u = unquote(tagvalue, QUOTES);
6db615c1 2364 if (!u)
383182b5 2365 return NULL;
e23a0ce8 2366
1d5989fd 2367 enc_len = strlen(u) * 4 + 1;
22f5f628 2368 t = new(char, enc_len);
6db615c1 2369 if (!t)
383182b5 2370 return NULL;
e23a0ce8 2371
8f6ce71f 2372 if (encode_devnode_name(u, t, enc_len) < 0)
22f5f628 2373 return NULL;
e23a0ce8 2374
6db615c1 2375 return strjoin("/dev/disk/by-", by, "/", t, NULL);
383182b5 2376}
e23a0ce8 2377
383182b5 2378char *fstab_node_to_udev_node(const char *p) {
faa368e3
LP
2379 assert(p);
2380
383182b5
DR
2381 if (startswith(p, "LABEL="))
2382 return tag_to_udev_node(p+6, "label");
e23a0ce8 2383
383182b5
DR
2384 if (startswith(p, "UUID="))
2385 return tag_to_udev_node(p+5, "uuid");
e23a0ce8 2386
84cc2abf
DR
2387 if (startswith(p, "PARTUUID="))
2388 return tag_to_udev_node(p+9, "partuuid");
2389
2390 if (startswith(p, "PARTLABEL="))
2391 return tag_to_udev_node(p+10, "partlabel");
2392
e23a0ce8
LP
2393 return strdup(p);
2394}
2395
87d2c1ff 2396bool dirent_is_file(const struct dirent *de) {
fb19a739
LP
2397 assert(de);
2398
a34bf9db 2399 if (hidden_file(de->d_name))
fb19a739
LP
2400 return false;
2401
2402 if (de->d_type != DT_REG &&
2403 de->d_type != DT_LNK &&
2404 de->d_type != DT_UNKNOWN)
2405 return false;
2406
2407 return true;
2408}
2409
87d2c1ff
LP
2410bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
2411 assert(de);
2412
a228a22f
LP
2413 if (de->d_type != DT_REG &&
2414 de->d_type != DT_LNK &&
2415 de->d_type != DT_UNKNOWN)
2416 return false;
2417
a34bf9db 2418 if (hidden_file_allow_backup(de->d_name))
87d2c1ff
LP
2419 return false;
2420
2421 return endswith(de->d_name, suffix);
2422}
2423
e801700e 2424static int do_execute(char **directories, usec_t timeout, char *argv[]) {
49681057 2425 _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
e801700e
ZJS
2426 _cleanup_set_free_free_ Set *seen = NULL;
2427 char **directory;
83cc030f 2428
49681057
ZJS
2429 /* We fork this all off from a child process so that we can
2430 * somewhat cleanly make use of SIGALRM to set a time limit */
83cc030f 2431
49681057
ZJS
2432 reset_all_signal_handlers();
2433 reset_signal_mask();
83cc030f 2434
49681057 2435 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
83cc030f 2436
49681057
ZJS
2437 pids = hashmap_new(NULL);
2438 if (!pids)
2439 return log_oom();
83cc030f 2440
e801700e
ZJS
2441 seen = set_new(&string_hash_ops);
2442 if (!seen)
2443 return log_oom();
83cc030f 2444
e801700e
ZJS
2445 STRV_FOREACH(directory, directories) {
2446 _cleanup_closedir_ DIR *d;
2447 struct dirent *de;
83cc030f 2448
e801700e
ZJS
2449 d = opendir(*directory);
2450 if (!d) {
2451 if (errno == ENOENT)
2452 continue;
83cc030f 2453
e801700e
ZJS
2454 return log_error_errno(errno, "Failed to open directory %s: %m", *directory);
2455 }
83cc030f 2456
e801700e
ZJS
2457 FOREACH_DIRENT(de, d, break) {
2458 _cleanup_free_ char *path = NULL;
2459 pid_t pid;
2460 int r;
2461
2462 if (!dirent_is_file(de))
2463 continue;
83cc030f 2464
e801700e
ZJS
2465 if (set_contains(seen, de->d_name)) {
2466 log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name);
2467 continue;
2468 }
2469
2470 r = set_put_strdup(seen, de->d_name);
2471 if (r < 0)
2472 return log_oom();
2473
2474 path = strjoin(*directory, "/", de->d_name, NULL);
2475 if (!path)
2476 return log_oom();
2477
2478 if (null_or_empty_path(path)) {
2479 log_debug("%s is empty (a mask).", path);
2480 continue;
7034e9db 2481 }
83cc030f 2482
e801700e
ZJS
2483 pid = fork();
2484 if (pid < 0) {
2485 log_error_errno(errno, "Failed to fork: %m");
2486 continue;
2487 } else if (pid == 0) {
2488 char *_argv[2];
83cc030f 2489
e801700e 2490 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
83cc030f 2491
e801700e
ZJS
2492 if (!argv) {
2493 _argv[0] = path;
2494 _argv[1] = NULL;
2495 argv = _argv;
2496 } else
2497 argv[0] = path;
2498
2499 execv(path, argv);
2500 return log_error_errno(errno, "Failed to execute %s: %m", path);
2501 }
2502
2503 log_debug("Spawned %s as " PID_FMT ".", path, pid);
83cc030f 2504
e801700e
ZJS
2505 r = hashmap_put(pids, UINT_TO_PTR(pid), path);
2506 if (r < 0)
2507 return log_oom();
2508 path = NULL;
2509 }
49681057 2510 }
83cc030f 2511
49681057
ZJS
2512 /* Abort execution of this process after the timout. We simply
2513 * rely on SIGALRM as default action terminating the process,
2514 * and turn on alarm(). */
83cc030f 2515
49681057
ZJS
2516 if (timeout != USEC_INFINITY)
2517 alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
83cc030f 2518
49681057
ZJS
2519 while (!hashmap_isempty(pids)) {
2520 _cleanup_free_ char *path = NULL;
2521 pid_t pid;
aa62a893 2522
49681057
ZJS
2523 pid = PTR_TO_UINT(hashmap_first_key(pids));
2524 assert(pid > 0);
83cc030f 2525
49681057
ZJS
2526 path = hashmap_remove(pids, UINT_TO_PTR(pid));
2527 assert(path);
aa62a893 2528
49681057
ZJS
2529 wait_for_terminate_and_warn(path, pid, true);
2530 }
aa62a893 2531
49681057
ZJS
2532 return 0;
2533}
aa62a893 2534
e801700e 2535void execute_directories(const char* const* directories, usec_t timeout, char *argv[]) {
49681057
ZJS
2536 pid_t executor_pid;
2537 int r;
e801700e
ZJS
2538 char *name;
2539 char **dirs = (char**) directories;
2540
2541 assert(!strv_isempty(dirs));
83cc030f 2542
e801700e
ZJS
2543 name = basename(dirs[0]);
2544 assert(!isempty(name));
aa62a893 2545
e801700e
ZJS
2546 /* Executes all binaries in the directories in parallel and waits
2547 * for them to finish. Optionally a timeout is applied. If a file
2548 * with the same name exists in more than one directory, the
2549 * earliest one wins. */
83cc030f 2550
49681057
ZJS
2551 executor_pid = fork();
2552 if (executor_pid < 0) {
2553 log_error_errno(errno, "Failed to fork: %m");
2554 return;
2555
2556 } else if (executor_pid == 0) {
e801700e 2557 r = do_execute(dirs, timeout, argv);
49681057 2558 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
aa62a893 2559 }
83cc030f 2560
e801700e 2561 wait_for_terminate_and_warn(name, executor_pid, true);
83cc030f
LP
2562}
2563
05feefe0
LP
2564bool nulstr_contains(const char*nulstr, const char *needle) {
2565 const char *i;
2566
2567 if (!nulstr)
2568 return false;
2569
2570 NULSTR_FOREACH(i, nulstr)
2571 if (streq(i, needle))
2572 return true;
2573
2574 return false;
2575}
2576
a88c8750
TG
2577bool plymouth_running(void) {
2578 return access("/run/plymouth/pid", F_OK) >= 0;
2579}
2580
9beb3f4d
LP
2581char* strshorten(char *s, size_t l) {
2582 assert(s);
2583
2584 if (l < strlen(s))
2585 s[l] = 0;
2586
2587 return s;
2588}
2589
7f0d207d
LP
2590bool machine_name_is_valid(const char *s) {
2591
2592 if (!hostname_is_valid(s))
2593 return false;
2594
2595 /* Machine names should be useful hostnames, but also be
2596 * useful in unit names, hence we enforce a stricter length
2597 * limitation. */
2598
2599 if (strlen(s) > 64)
2600 return false;
2601
2602 return true;
2603}
2604
1325aa42 2605int pipe_eof(int fd) {
b92bea5d
ZJS
2606 struct pollfd pollfd = {
2607 .fd = fd,
2608 .events = POLLIN|POLLHUP,
2609 };
1325aa42 2610
d37a91e8
LP
2611 int r;
2612
1325aa42
LP
2613 r = poll(&pollfd, 1, 0);
2614 if (r < 0)
2615 return -errno;
2616
2617 if (r == 0)
2618 return 0;
2619
2620 return pollfd.revents & POLLHUP;
2621}
2622
8f2d43a0 2623int fd_wait_for_event(int fd, int event, usec_t t) {
968d3d24 2624
b92bea5d
ZJS
2625 struct pollfd pollfd = {
2626 .fd = fd,
2627 .events = event,
2628 };
df50185b 2629
968d3d24
LP
2630 struct timespec ts;
2631 int r;
2632
3a43da28 2633 r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
df50185b
LP
2634 if (r < 0)
2635 return -errno;
2636
2637 if (r == 0)
2638 return 0;
2639
2640 return pollfd.revents;
2641}
2642
5a3ab509
LP
2643int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
2644 FILE *f;
2645 char *t;
ae6c3cc0 2646 int r, fd;
5a3ab509
LP
2647
2648 assert(path);
2649 assert(_f);
2650 assert(_temp_path);
2651
ae6c3cc0
LP
2652 r = tempfn_xxxxxx(path, &t);
2653 if (r < 0)
2654 return r;
5a3ab509 2655
2d5bdf5b 2656 fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC);
5a3ab509
LP
2657 if (fd < 0) {
2658 free(t);
2659 return -errno;
2660 }
2661
2662 f = fdopen(fd, "we");
2663 if (!f) {
2664 unlink(t);
2665 free(t);
2666 return -errno;
2667 }
2668
2669 *_f = f;
2670 *_temp_path = t;
2671
2672 return 0;
2673}
2674
424a19f8 2675int symlink_atomic(const char *from, const char *to) {
2e78fa79 2676 _cleanup_free_ char *t = NULL;
ae6c3cc0 2677 int r;
34ca941c
LP
2678
2679 assert(from);
2680 assert(to);
2681
ae6c3cc0
LP
2682 r = tempfn_random(to, &t);
2683 if (r < 0)
2684 return r;
34ca941c 2685
424a19f8
LP
2686 if (symlink(from, t) < 0)
2687 return -errno;
34ca941c
LP
2688
2689 if (rename(t, to) < 0) {
2e78fa79
LP
2690 unlink_noerrno(t);
2691 return -errno;
34ca941c
LP
2692 }
2693
424a19f8 2694 return 0;
34ca941c
LP
2695}
2696
875e1014
ILG
2697int symlink_idempotent(const char *from, const char *to) {
2698 _cleanup_free_ char *p = NULL;
2699 int r;
2700
2701 assert(from);
2702 assert(to);
2703
2704 if (symlink(from, to) < 0) {
2705 if (errno != EEXIST)
2706 return -errno;
2707
2708 r = readlink_malloc(to, &p);
2709 if (r < 0)
2710 return r;
2711
2712 if (!streq(p, from))
2713 return -EINVAL;
2714 }
2715
2716 return 0;
2717}
2718
1554afae
LP
2719int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
2720 _cleanup_free_ char *t = NULL;
ae6c3cc0 2721 int r;
1554afae
LP
2722
2723 assert(path);
2724
ae6c3cc0
LP
2725 r = tempfn_random(path, &t);
2726 if (r < 0)
2727 return r;
1554afae
LP
2728
2729 if (mknod(t, mode, dev) < 0)
2730 return -errno;
2731
2732 if (rename(t, path) < 0) {
2733 unlink_noerrno(t);
2734 return -errno;
2735 }
2736
2737 return 0;
2738}
2739
2740int mkfifo_atomic(const char *path, mode_t mode) {
2741 _cleanup_free_ char *t = NULL;
ae6c3cc0 2742 int r;
1554afae
LP
2743
2744 assert(path);
2745
ae6c3cc0
LP
2746 r = tempfn_random(path, &t);
2747 if (r < 0)
2748 return r;
1554afae
LP
2749
2750 if (mkfifo(t, mode) < 0)
2751 return -errno;
2752
2753 if (rename(t, path) < 0) {
2754 unlink_noerrno(t);
2755 return -errno;
2756 }
2757
2758 return 0;
2759}
2760
4d6d6518
LP
2761bool display_is_local(const char *display) {
2762 assert(display);
2763
2764 return
2765 display[0] == ':' &&
2766 display[1] >= '0' &&
2767 display[1] <= '9';
2768}
2769
2770int socket_from_display(const char *display, char **path) {
2771 size_t k;
2772 char *f, *c;
2773
2774 assert(display);
2775 assert(path);
2776
2777 if (!display_is_local(display))
2778 return -EINVAL;
2779
2780 k = strspn(display+1, "0123456789");
2781
f8294e41 2782 f = new(char, strlen("/tmp/.X11-unix/X") + k + 1);
4d6d6518
LP
2783 if (!f)
2784 return -ENOMEM;
2785
2786 c = stpcpy(f, "/tmp/.X11-unix/X");
2787 memcpy(c, display+1, k);
2788 c[k] = 0;
2789
2790 *path = f;
2791
2792 return 0;
2793}
2794
d05c5031
LP
2795int get_user_creds(
2796 const char **username,
2797 uid_t *uid, gid_t *gid,
2798 const char **home,
2799 const char **shell) {
2800
1cccf435 2801 struct passwd *p;
ddd88763 2802 uid_t u;
1cccf435
MV
2803
2804 assert(username);
2805 assert(*username);
1cccf435
MV
2806
2807 /* We enforce some special rules for uid=0: in order to avoid
2808 * NSS lookups for root we hardcode its data. */
2809
2810 if (streq(*username, "root") || streq(*username, "0")) {
2811 *username = "root";
4b67834e
LP
2812
2813 if (uid)
2814 *uid = 0;
2815
2816 if (gid)
2817 *gid = 0;
2818
2819 if (home)
2820 *home = "/root";
d05c5031
LP
2821
2822 if (shell)
2823 *shell = "/bin/sh";
2824
1cccf435
MV
2825 return 0;
2826 }
2827
ddd88763 2828 if (parse_uid(*username, &u) >= 0) {
1cccf435 2829 errno = 0;
ddd88763 2830 p = getpwuid(u);
1cccf435
MV
2831
2832 /* If there are multiple users with the same id, make
2833 * sure to leave $USER to the configured value instead
2834 * of the first occurrence in the database. However if
2835 * the uid was configured by a numeric uid, then let's
2836 * pick the real username from /etc/passwd. */
2837 if (p)
2838 *username = p->pw_name;
2839 } else {
2840 errno = 0;
2841 p = getpwnam(*username);
2842 }
2843
2844 if (!p)
8333c77e 2845 return errno > 0 ? -errno : -ESRCH;
1cccf435 2846
4b67834e
LP
2847 if (uid)
2848 *uid = p->pw_uid;
2849
2850 if (gid)
2851 *gid = p->pw_gid;
2852
2853 if (home)
2854 *home = p->pw_dir;
2855
d05c5031
LP
2856 if (shell)
2857 *shell = p->pw_shell;
2858
4b67834e
LP
2859 return 0;
2860}
2861
59164be4
LP
2862char* uid_to_name(uid_t uid) {
2863 struct passwd *p;
2864 char *r;
2865
2866 if (uid == 0)
2867 return strdup("root");
2868
2869 p = getpwuid(uid);
2870 if (p)
2871 return strdup(p->pw_name);
2872
de0671ee 2873 if (asprintf(&r, UID_FMT, uid) < 0)
59164be4
LP
2874 return NULL;
2875
2876 return r;
2877}
2878
4468addc
LP
2879char* gid_to_name(gid_t gid) {
2880 struct group *p;
2881 char *r;
2882
2883 if (gid == 0)
2884 return strdup("root");
2885
2886 p = getgrgid(gid);
2887 if (p)
2888 return strdup(p->gr_name);
2889
de0671ee 2890 if (asprintf(&r, GID_FMT, gid) < 0)
4468addc
LP
2891 return NULL;
2892
2893 return r;
2894}
2895
4b67834e
LP
2896int get_group_creds(const char **groupname, gid_t *gid) {
2897 struct group *g;
2898 gid_t id;
2899
2900 assert(groupname);
2901
2902 /* We enforce some special rules for gid=0: in order to avoid
2903 * NSS lookups for root we hardcode its data. */
2904
2905 if (streq(*groupname, "root") || streq(*groupname, "0")) {
2906 *groupname = "root";
2907
2908 if (gid)
2909 *gid = 0;
2910
2911 return 0;
2912 }
2913
2914 if (parse_gid(*groupname, &id) >= 0) {
2915 errno = 0;
2916 g = getgrgid(id);
2917
2918 if (g)
2919 *groupname = g->gr_name;
2920 } else {
2921 errno = 0;
2922 g = getgrnam(*groupname);
2923 }
2924
2925 if (!g)
8333c77e 2926 return errno > 0 ? -errno : -ESRCH;
4b67834e
LP
2927
2928 if (gid)
2929 *gid = g->gr_gid;
2930
1cccf435
MV
2931 return 0;
2932}
2933
4468addc
LP
2934int in_gid(gid_t gid) {
2935 gid_t *gids;
43673799
LP
2936 int ngroups_max, r, i;
2937
43673799
LP
2938 if (getgid() == gid)
2939 return 1;
2940
2941 if (getegid() == gid)
2942 return 1;
2943
2944 ngroups_max = sysconf(_SC_NGROUPS_MAX);
2945 assert(ngroups_max > 0);
2946
2947 gids = alloca(sizeof(gid_t) * ngroups_max);
2948
2949 r = getgroups(ngroups_max, gids);
2950 if (r < 0)
2951 return -errno;
2952
2953 for (i = 0; i < r; i++)
2954 if (gids[i] == gid)
2955 return 1;
2956
2957 return 0;
2958}
2959
4468addc
LP
2960int in_group(const char *name) {
2961 int r;
2962 gid_t gid;
2963
2964 r = get_group_creds(&name, &gid);
2965 if (r < 0)
2966 return r;
2967
2968 return in_gid(gid);
2969}
2970
8092a428 2971int glob_exists(const char *path) {
7fd1b19b 2972 _cleanup_globfree_ glob_t g = {};
8d98da3f 2973 int k;
8092a428
LP
2974
2975 assert(path);
2976
8092a428
LP
2977 errno = 0;
2978 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
2979
2980 if (k == GLOB_NOMATCH)
8d98da3f 2981 return 0;
8092a428 2982 else if (k == GLOB_NOSPACE)
8d98da3f 2983 return -ENOMEM;
8092a428 2984 else if (k == 0)
8d98da3f 2985 return !strv_isempty(g.gl_pathv);
8092a428 2986 else
8d98da3f
ZJS
2987 return errno ? -errno : -EIO;
2988}
8092a428 2989
8d98da3f
ZJS
2990int glob_extend(char ***strv, const char *path) {
2991 _cleanup_globfree_ glob_t g = {};
2992 int k;
2993 char **p;
2994
2995 errno = 0;
a8ccacf5 2996 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
8d98da3f
ZJS
2997
2998 if (k == GLOB_NOMATCH)
2999 return -ENOENT;
3000 else if (k == GLOB_NOSPACE)
3001 return -ENOMEM;
3002 else if (k != 0 || strv_isempty(g.gl_pathv))
3003 return errno ? -errno : -EIO;
3004
3005 STRV_FOREACH(p, g.gl_pathv) {
3006 k = strv_extend(strv, *p);
3007 if (k < 0)
3008 break;
3009 }
3010
3011 return k;
8092a428
LP
3012}
3013
83096483
LP
3014int dirent_ensure_type(DIR *d, struct dirent *de) {
3015 struct stat st;
3016
3017 assert(d);
3018 assert(de);
3019
3020 if (de->d_type != DT_UNKNOWN)
3021 return 0;
3022
3023 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
3024 return -errno;
3025
3026 de->d_type =
3027 S_ISREG(st.st_mode) ? DT_REG :
3028 S_ISDIR(st.st_mode) ? DT_DIR :
3029 S_ISLNK(st.st_mode) ? DT_LNK :
3030 S_ISFIFO(st.st_mode) ? DT_FIFO :
3031 S_ISSOCK(st.st_mode) ? DT_SOCK :
3032 S_ISCHR(st.st_mode) ? DT_CHR :
3033 S_ISBLK(st.st_mode) ? DT_BLK :
3034 DT_UNKNOWN;
3035
3036 return 0;
3037}
3038
034a2a52 3039int get_files_in_directory(const char *path, char ***list) {
893fa014
ZJS
3040 _cleanup_closedir_ DIR *d = NULL;
3041 size_t bufsize = 0, n = 0;
3042 _cleanup_strv_free_ char **l = NULL;
034a2a52
LP
3043
3044 assert(path);
d60ef526
LP
3045
3046 /* Returns all files in a directory in *list, and the number
3047 * of files as return value. If list is NULL returns only the
893fa014 3048 * number. */
034a2a52
LP
3049
3050 d = opendir(path);
8ea913b2
LP
3051 if (!d)
3052 return -errno;
3053
034a2a52 3054 for (;;) {
7d5e9c0f 3055 struct dirent *de;
034a2a52 3056
3fd11280
FW
3057 errno = 0;
3058 de = readdir(d);
3059 if (!de && errno != 0)
3060 return -errno;
034a2a52
LP
3061 if (!de)
3062 break;
3063
3064 dirent_ensure_type(d, de);
3065
3066 if (!dirent_is_file(de))
3067 continue;
3068
d60ef526 3069 if (list) {
893fa014
ZJS
3070 /* one extra slot is needed for the terminating NULL */
3071 if (!GREEDY_REALLOC(l, bufsize, n + 2))
3072 return -ENOMEM;
034a2a52 3073
893fa014
ZJS
3074 l[n] = strdup(de->d_name);
3075 if (!l[n])
3076 return -ENOMEM;
034a2a52 3077
893fa014 3078 l[++n] = NULL;
d60ef526 3079 } else
893fa014 3080 n++;
034a2a52
LP
3081 }
3082
893fa014
ZJS
3083 if (list) {
3084 *list = l;
3085 l = NULL; /* avoid freeing */
3086 }
034a2a52 3087
893fa014 3088 return n;
034a2a52
LP
3089}
3090
b7def684 3091char *strjoin(const char *x, ...) {
911a4828
LP
3092 va_list ap;
3093 size_t l;
3094 char *r, *p;
3095
3096 va_start(ap, x);
3097
3098 if (x) {
3099 l = strlen(x);
3100
3101 for (;;) {
3102 const char *t;
040f18ea 3103 size_t n;
911a4828
LP
3104
3105 t = va_arg(ap, const char *);
3106 if (!t)
3107 break;
3108
040f18ea 3109 n = strlen(t);
e98055de
LN
3110 if (n > ((size_t) -1) - l) {
3111 va_end(ap);
040f18ea 3112 return NULL;
e98055de 3113 }
040f18ea
LP
3114
3115 l += n;
911a4828
LP
3116 }
3117 } else
3118 l = 0;
3119
3120 va_end(ap);
3121
3122 r = new(char, l+1);
3123 if (!r)
3124 return NULL;
3125
3126 if (x) {
3127 p = stpcpy(r, x);
3128
3129 va_start(ap, x);
3130
3131 for (;;) {
3132 const char *t;
3133
3134 t = va_arg(ap, const char *);
3135 if (!t)
3136 break;
3137
3138 p = stpcpy(p, t);
3139 }
8ea913b2
LP
3140
3141 va_end(ap);
911a4828
LP
3142 } else
3143 r[0] = 0;
3144
3145 return r;
3146}
3147
b636465b 3148bool is_main_thread(void) {
ec202eae 3149 static thread_local int cached = 0;
b636465b
LP
3150
3151 if (_unlikely_(cached == 0))
3152 cached = getpid() == gettid() ? 1 : -1;
3153
3154 return cached > 0;
3155}
3156
94959f0f
LP
3157int block_get_whole_disk(dev_t d, dev_t *ret) {
3158 char *p, *s;
3159 int r;
3160 unsigned n, m;
3161
3162 assert(ret);
3163
3164 /* If it has a queue this is good enough for us */
3165 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
3166 return -ENOMEM;
3167
3168 r = access(p, F_OK);
3169 free(p);
3170
3171 if (r >= 0) {
3172 *ret = d;
3173 return 0;
3174 }
3175
3176 /* If it is a partition find the originating device */
3177 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
3178 return -ENOMEM;
3179
3180 r = access(p, F_OK);
3181 free(p);
3182
3183 if (r < 0)
3184 return -ENOENT;
3185
3186 /* Get parent dev_t */
3187 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
3188 return -ENOMEM;
3189
3190 r = read_one_line_file(p, &s);
3191 free(p);
3192
3193 if (r < 0)
3194 return r;
3195
3196 r = sscanf(s, "%u:%u", &m, &n);
3197 free(s);
3198
3199 if (r != 2)
3200 return -EINVAL;
3201
3202 /* Only return this if it is really good enough for us. */
3203 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
3204 return -ENOMEM;
3205
3206 r = access(p, F_OK);
3207 free(p);
3208
3209 if (r >= 0) {
3210 *ret = makedev(m, n);
3211 return 0;
3212 }
3213
3214 return -ENOENT;
3215}
3216
f41607a6
LP
3217static const char *const ioprio_class_table[] = {
3218 [IOPRIO_CLASS_NONE] = "none",
3219 [IOPRIO_CLASS_RT] = "realtime",
3220 [IOPRIO_CLASS_BE] = "best-effort",
3221 [IOPRIO_CLASS_IDLE] = "idle"
3222};
3223
f8b69d1d 3224DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
f41607a6
LP
3225
3226static const char *const sigchld_code_table[] = {
3227 [CLD_EXITED] = "exited",
3228 [CLD_KILLED] = "killed",
3229 [CLD_DUMPED] = "dumped",
3230 [CLD_TRAPPED] = "trapped",
3231 [CLD_STOPPED] = "stopped",
3232 [CLD_CONTINUED] = "continued",
3233};
3234
3235DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
3236
3237static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
3238 [LOG_FAC(LOG_KERN)] = "kern",
3239 [LOG_FAC(LOG_USER)] = "user",
3240 [LOG_FAC(LOG_MAIL)] = "mail",
3241 [LOG_FAC(LOG_DAEMON)] = "daemon",
3242 [LOG_FAC(LOG_AUTH)] = "auth",
3243 [LOG_FAC(LOG_SYSLOG)] = "syslog",
3244 [LOG_FAC(LOG_LPR)] = "lpr",
3245 [LOG_FAC(LOG_NEWS)] = "news",
3246 [LOG_FAC(LOG_UUCP)] = "uucp",
3247 [LOG_FAC(LOG_CRON)] = "cron",
3248 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
3249 [LOG_FAC(LOG_FTP)] = "ftp",
3250 [LOG_FAC(LOG_LOCAL0)] = "local0",
3251 [LOG_FAC(LOG_LOCAL1)] = "local1",
3252 [LOG_FAC(LOG_LOCAL2)] = "local2",
3253 [LOG_FAC(LOG_LOCAL3)] = "local3",
3254 [LOG_FAC(LOG_LOCAL4)] = "local4",
3255 [LOG_FAC(LOG_LOCAL5)] = "local5",
3256 [LOG_FAC(LOG_LOCAL6)] = "local6",
3257 [LOG_FAC(LOG_LOCAL7)] = "local7"
3258};
3259
f8b69d1d 3260DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
f41607a6
LP
3261
3262static const char *const log_level_table[] = {
3263 [LOG_EMERG] = "emerg",
3264 [LOG_ALERT] = "alert",
3265 [LOG_CRIT] = "crit",
3266 [LOG_ERR] = "err",
3267 [LOG_WARNING] = "warning",
3268 [LOG_NOTICE] = "notice",
3269 [LOG_INFO] = "info",
3270 [LOG_DEBUG] = "debug"
3271};
3272
f8b69d1d 3273DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
f41607a6
LP
3274
3275static const char* const sched_policy_table[] = {
3276 [SCHED_OTHER] = "other",
3277 [SCHED_BATCH] = "batch",
3278 [SCHED_IDLE] = "idle",
3279 [SCHED_FIFO] = "fifo",
3280 [SCHED_RR] = "rr"
3281};
3282
f8b69d1d 3283DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
f41607a6 3284
517d56b1 3285static const char* const rlimit_table[_RLIMIT_MAX] = {
f41607a6
LP
3286 [RLIMIT_CPU] = "LimitCPU",
3287 [RLIMIT_FSIZE] = "LimitFSIZE",
3288 [RLIMIT_DATA] = "LimitDATA",
3289 [RLIMIT_STACK] = "LimitSTACK",
3290 [RLIMIT_CORE] = "LimitCORE",
3291 [RLIMIT_RSS] = "LimitRSS",
3292 [RLIMIT_NOFILE] = "LimitNOFILE",
3293 [RLIMIT_AS] = "LimitAS",
3294 [RLIMIT_NPROC] = "LimitNPROC",
3295 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
3296 [RLIMIT_LOCKS] = "LimitLOCKS",
3297 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
3298 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
3299 [RLIMIT_NICE] = "LimitNICE",
3300 [RLIMIT_RTPRIO] = "LimitRTPRIO",
3301 [RLIMIT_RTTIME] = "LimitRTTIME"
3302};
3303
3304DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
3305
3306static const char* const ip_tos_table[] = {
3307 [IPTOS_LOWDELAY] = "low-delay",
3308 [IPTOS_THROUGHPUT] = "throughput",
3309 [IPTOS_RELIABILITY] = "reliability",
3310 [IPTOS_LOWCOST] = "low-cost",
3311};
3312
f8b69d1d 3313DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
f41607a6 3314
4e240ab0 3315static const char *const __signal_table[] = {
f41607a6
LP
3316 [SIGHUP] = "HUP",
3317 [SIGINT] = "INT",
3318 [SIGQUIT] = "QUIT",
3319 [SIGILL] = "ILL",
3320 [SIGTRAP] = "TRAP",
3321 [SIGABRT] = "ABRT",
3322 [SIGBUS] = "BUS",
3323 [SIGFPE] = "FPE",
3324 [SIGKILL] = "KILL",
3325 [SIGUSR1] = "USR1",
3326 [SIGSEGV] = "SEGV",
3327 [SIGUSR2] = "USR2",
3328 [SIGPIPE] = "PIPE",
3329 [SIGALRM] = "ALRM",
3330 [SIGTERM] = "TERM",
3331#ifdef SIGSTKFLT
3332 [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
3333#endif
3334 [SIGCHLD] = "CHLD",
3335 [SIGCONT] = "CONT",
3336 [SIGSTOP] = "STOP",
3337 [SIGTSTP] = "TSTP",
3338 [SIGTTIN] = "TTIN",
3339 [SIGTTOU] = "TTOU",
3340 [SIGURG] = "URG",
3341 [SIGXCPU] = "XCPU",
3342 [SIGXFSZ] = "XFSZ",
3343 [SIGVTALRM] = "VTALRM",
3344 [SIGPROF] = "PROF",
3345 [SIGWINCH] = "WINCH",
3346 [SIGIO] = "IO",
3347 [SIGPWR] = "PWR",
3348 [SIGSYS] = "SYS"
3349};
3350
4e240ab0
MS
3351DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
3352
3353const char *signal_to_string(int signo) {
ec202eae 3354 static thread_local char buf[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1];
4e240ab0
MS
3355 const char *name;
3356
3357 name = __signal_to_string(signo);
3358 if (name)
3359 return name;
3360
3361 if (signo >= SIGRTMIN && signo <= SIGRTMAX)
fa70beaa 3362 snprintf(buf, sizeof(buf), "RTMIN+%d", signo - SIGRTMIN);
4e240ab0 3363 else
fa70beaa
LP
3364 snprintf(buf, sizeof(buf), "%d", signo);
3365
4e240ab0
MS
3366 return buf;
3367}
3368
3369int signal_from_string(const char *s) {
3370 int signo;
3371 int offset = 0;
3372 unsigned u;
3373
040f18ea 3374 signo = __signal_from_string(s);
4e240ab0
MS
3375 if (signo > 0)
3376 return signo;
3377
3378 if (startswith(s, "RTMIN+")) {
3379 s += 6;
3380 offset = SIGRTMIN;
3381 }
3382 if (safe_atou(s, &u) >= 0) {
3383 signo = (int) u + offset;
3384 if (signo > 0 && signo < _NSIG)
3385 return signo;
3386 }
7e8185ef 3387 return -EINVAL;
4e240ab0 3388}
65457142
FC
3389
3390bool kexec_loaded(void) {
3391 bool loaded = false;
3392 char *s;
3393
3394 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
3395 if (s[0] == '1')
3396 loaded = true;
3397 free(s);
3398 }
3399 return loaded;
3400}
fb9de93d 3401
87d2c1ff
LP
3402int prot_from_flags(int flags) {
3403
3404 switch (flags & O_ACCMODE) {
3405
3406 case O_RDONLY:
3407 return PROT_READ;
3408
3409 case O_WRONLY:
3410 return PROT_WRITE;
3411
3412 case O_RDWR:
3413 return PROT_READ|PROT_WRITE;
3414
3415 default:
3416 return -EINVAL;
3417 }
7c99e0c1 3418}
689b9a22 3419
babfc091 3420char *format_bytes(char *buf, size_t l, off_t t) {
c0f99c21 3421 unsigned i;
babfc091
LP
3422
3423 static const struct {
3424 const char *suffix;
3425 off_t factor;
3426 } table[] = {
32895bb3
LP
3427 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
3428 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
babfc091
LP
3429 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
3430 { "G", 1024ULL*1024ULL*1024ULL },
3431 { "M", 1024ULL*1024ULL },
3432 { "K", 1024ULL },
3433 };
3434
f02ca522
LP
3435 if (t == (off_t) -1)
3436 return NULL;
3437
babfc091
LP
3438 for (i = 0; i < ELEMENTSOF(table); i++) {
3439
3440 if (t >= table[i].factor) {
3441 snprintf(buf, l,
3442 "%llu.%llu%s",
3443 (unsigned long long) (t / table[i].factor),
3444 (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
3445 table[i].suffix);
3446
3447 goto finish;
3448 }
3449 }
3450
3451 snprintf(buf, l, "%lluB", (unsigned long long) t);
3452
3453finish:
3454 buf[l-1] = 0;
3455 return buf;
3456
3457}
55d7bfc1
LP
3458
3459void* memdup(const void *p, size_t l) {
3460 void *r;
3461
3462 assert(p);
3463
3464 r = malloc(l);
3465 if (!r)
3466 return NULL;
3467
3468 memcpy(r, p, l);
3469 return r;
3470}
bb99a35a
LP
3471
3472int fd_inc_sndbuf(int fd, size_t n) {
3473 int r, value;
3474 socklen_t l = sizeof(value);
3475
3476 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
92d75ca4 3477 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
bb99a35a
LP
3478 return 0;
3479
92d75ca4
LP
3480 /* If we have the privileges we will ignore the kernel limit. */
3481
bb99a35a 3482 value = (int) n;
92d75ca4
LP
3483 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
3484 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
3485 return -errno;
bb99a35a
LP
3486
3487 return 1;
3488}
3489
3490int fd_inc_rcvbuf(int fd, size_t n) {
3491 int r, value;
3492 socklen_t l = sizeof(value);
3493
3494 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
92d75ca4 3495 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
bb99a35a
LP
3496 return 0;
3497
92d75ca4 3498 /* If we have the privileges we will ignore the kernel limit. */
bb99a35a 3499
92d75ca4
LP
3500 value = (int) n;
3501 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
3502 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
3503 return -errno;
bb99a35a
LP
3504 return 1;
3505}
6bb92a16 3506
9bdc770c 3507int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
6bb92a16 3508 bool stdout_is_tty, stderr_is_tty;
8a7c93d8
LP
3509 pid_t parent_pid, agent_pid;
3510 sigset_t ss, saved_ss;
6bb92a16
LP
3511 unsigned n, i;
3512 va_list ap;
3513 char **l;
3514
3515 assert(pid);
3516 assert(path);
3517
6bb92a16
LP
3518 /* Spawns a temporary TTY agent, making sure it goes away when
3519 * we go away */
3520
8a7c93d8
LP
3521 parent_pid = getpid();
3522
3523 /* First we temporarily block all signals, so that the new
3524 * child has them blocked initially. This way, we can be sure
3525 * that SIGTERMs are not lost we might send to the agent. */
3526 assert_se(sigfillset(&ss) >= 0);
3527 assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0);
3528
6bb92a16 3529 agent_pid = fork();
8a7c93d8
LP
3530 if (agent_pid < 0) {
3531 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
6bb92a16 3532 return -errno;
8a7c93d8 3533 }
6bb92a16
LP
3534
3535 if (agent_pid != 0) {
8a7c93d8 3536 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
6bb92a16
LP
3537 *pid = agent_pid;
3538 return 0;
3539 }
3540
3541 /* In the child:
3542 *
3543 * Make sure the agent goes away when the parent dies */
3544 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
3545 _exit(EXIT_FAILURE);
3546
8a7c93d8
LP
3547 /* Make sure we actually can kill the agent, if we need to, in
3548 * case somebody invoked us from a shell script that trapped
3549 * SIGTERM or so... */
3550 reset_all_signal_handlers();
3551 reset_signal_mask();
3552
6bb92a16 3553 /* Check whether our parent died before we were able
8a7c93d8 3554 * to set the death signal and unblock the signals */
6bb92a16
LP
3555 if (getppid() != parent_pid)
3556 _exit(EXIT_SUCCESS);
3557
3558 /* Don't leak fds to the agent */
9bdc770c 3559 close_all_fds(except, n_except);
6bb92a16
LP
3560
3561 stdout_is_tty = isatty(STDOUT_FILENO);
3562 stderr_is_tty = isatty(STDERR_FILENO);
3563
3564 if (!stdout_is_tty || !stderr_is_tty) {
8a7c93d8
LP
3565 int fd;
3566
6bb92a16
LP
3567 /* Detach from stdout/stderr. and reopen
3568 * /dev/tty for them. This is important to
3569 * ensure that when systemctl is started via
3570 * popen() or a similar call that expects to
3571 * read EOF we actually do generate EOF and
3572 * not delay this indefinitely by because we
3573 * keep an unused copy of stdin around. */
3574 fd = open("/dev/tty", O_WRONLY);
3575 if (fd < 0) {
56f64d95 3576 log_error_errno(errno, "Failed to open /dev/tty: %m");
6bb92a16
LP
3577 _exit(EXIT_FAILURE);
3578 }
3579
3580 if (!stdout_is_tty)
3581 dup2(fd, STDOUT_FILENO);
3582
3583 if (!stderr_is_tty)
3584 dup2(fd, STDERR_FILENO);
3585
3586 if (fd > 2)
3587 close(fd);
3588 }
3589
3590 /* Count arguments */
3591 va_start(ap, path);
3592 for (n = 0; va_arg(ap, char*); n++)
3593 ;
3594 va_end(ap);
3595
3596 /* Allocate strv */
3597 l = alloca(sizeof(char *) * (n + 1));
3598
3599 /* Fill in arguments */
3600 va_start(ap, path);
3601 for (i = 0; i <= n; i++)
3602 l[i] = va_arg(ap, char*);
3603 va_end(ap);
3604
3605 execv(path, l);
3606 _exit(EXIT_FAILURE);
3607}
68faf98c
LP
3608
3609int setrlimit_closest(int resource, const struct rlimit *rlim) {
3610 struct rlimit highest, fixed;
3611
3612 assert(rlim);
3613
3614 if (setrlimit(resource, rlim) >= 0)
3615 return 0;
3616
3617 if (errno != EPERM)
3618 return -errno;
3619
3620 /* So we failed to set the desired setrlimit, then let's try
3621 * to get as close as we can */
3622 assert_se(getrlimit(resource, &highest) == 0);
3623
3624 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
3625 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
3626
3627 if (setrlimit(resource, &fixed) < 0)
3628 return -errno;
3629
3630 return 0;
3631}
3d9a4122 3632
3d7415f4
LP
3633bool http_etag_is_valid(const char *etag) {
3634 if (isempty(etag))
3635 return false;
3636
3637 if (!endswith(etag, "\""))
3638 return false;
3639
3640 if (!startswith(etag, "\"") && !startswith(etag, "W/\""))
3641 return false;
3642
3643 return true;
3644}
3645
a2e03378
LP
3646bool http_url_is_valid(const char *url) {
3647 const char *p;
49dbfa7b 3648
a2e03378
LP
3649 if (isempty(url))
3650 return false;
49dbfa7b 3651
a2e03378
LP
3652 p = startswith(url, "http://");
3653 if (!p)
3654 p = startswith(url, "https://");
3655 if (!p)
3656 return false;
49dbfa7b 3657
a2e03378
LP
3658 if (isempty(p))
3659 return false;
49dbfa7b 3660
a2e03378
LP
3661 return ascii_is_valid(p);
3662}
49dbfa7b 3663
a2e03378
LP
3664bool documentation_url_is_valid(const char *url) {
3665 const char *p;
3666
3667 if (isempty(url))
3668 return false;
3669
3670 if (http_url_is_valid(url))
49dbfa7b
LP
3671 return true;
3672
a2e03378
LP
3673 p = startswith(url, "file:/");
3674 if (!p)
3675 p = startswith(url, "info:");
3676 if (!p)
3677 p = startswith(url, "man:");
3678
3679 if (isempty(p))
3680 return false;
3681
3682 return ascii_is_valid(p);
49dbfa7b 3683}
9be346c9
HH
3684
3685bool in_initrd(void) {
73020ab2 3686 static int saved = -1;
825c6fe5 3687 struct statfs s;
8f33b5b8 3688
825c6fe5
LP
3689 if (saved >= 0)
3690 return saved;
3691
3692 /* We make two checks here:
3693 *
3694 * 1. the flag file /etc/initrd-release must exist
3695 * 2. the root file system must be a memory file system
3696 *
3697 * The second check is extra paranoia, since misdetecting an
3698 * initrd can have bad bad consequences due the initrd
3699 * emptying when transititioning to the main systemd.
3700 */
3701
3702 saved = access("/etc/initrd-release", F_OK) >= 0 &&
3703 statfs("/", &s) >= 0 &&
943aad8c 3704 is_temporary_fs(&s);
9be346c9 3705
8f33b5b8 3706 return saved;
9be346c9 3707}
069cfc85 3708
7c5f152a 3709int get_home_dir(char **_h) {
2cfbd749 3710 struct passwd *p;
7c5f152a 3711 const char *e;
2cfbd749 3712 char *h;
7c5f152a 3713 uid_t u;
7c5f152a
LP
3714
3715 assert(_h);
3716
3717 /* Take the user specified one */
9a00f57a
LP
3718 e = secure_getenv("HOME");
3719 if (e && path_is_absolute(e)) {
7c5f152a
LP
3720 h = strdup(e);
3721 if (!h)
3722 return -ENOMEM;
3723
3724 *_h = h;
3725 return 0;
3726 }
3727
3728 /* Hardcode home directory for root to avoid NSS */
3729 u = getuid();
3730 if (u == 0) {
3731 h = strdup("/root");
3732 if (!h)
3733 return -ENOMEM;
3734
3735 *_h = h;
3736 return 0;
3737 }
3738
3739 /* Check the database... */
3740 errno = 0;
3741 p = getpwuid(u);
3742 if (!p)
bcb161b0 3743 return errno > 0 ? -errno : -ESRCH;
7c5f152a
LP
3744
3745 if (!path_is_absolute(p->pw_dir))
3746 return -EINVAL;
3747
3748 h = strdup(p->pw_dir);
3749 if (!h)
3750 return -ENOMEM;
3751
3752 *_h = h;
3753 return 0;
3754}
3755
2cfbd749
LP
3756int get_shell(char **_s) {
3757 struct passwd *p;
3758 const char *e;
3759 char *s;
3760 uid_t u;
3761
3762 assert(_s);
3763
3764 /* Take the user specified one */
3765 e = getenv("SHELL");
3766 if (e) {
3767 s = strdup(e);
3768 if (!s)
3769 return -ENOMEM;
3770
3771 *_s = s;
3772 return 0;
3773 }
3774
3775 /* Hardcode home directory for root to avoid NSS */
3776 u = getuid();
3777 if (u == 0) {
3778 s = strdup("/bin/sh");
3779 if (!s)
3780 return -ENOMEM;
3781
3782 *_s = s;
3783 return 0;
3784 }
3785
3786 /* Check the database... */
3787 errno = 0;
3788 p = getpwuid(u);
3789 if (!p)
3790 return errno > 0 ? -errno : -ESRCH;
3791
3792 if (!path_is_absolute(p->pw_shell))
3793 return -EINVAL;
3794
3795 s = strdup(p->pw_shell);
3796 if (!s)
3797 return -ENOMEM;
3798
3799 *_s = s;
3800 return 0;
3801}
3802
ae6c3cc0 3803bool filename_is_valid(const char *p) {
0b507b17
LP
3804
3805 if (isempty(p))
3806 return false;
3807
3808 if (strchr(p, '/'))
3809 return false;
3810
3811 if (streq(p, "."))
3812 return false;
3813
3814 if (streq(p, ".."))
3815 return false;
3816
3817 if (strlen(p) > FILENAME_MAX)
3818 return false;
3819
3820 return true;
3821}
3822
3823bool string_is_safe(const char *p) {
3824 const char *t;
3825
6294aa76
LP
3826 if (!p)
3827 return false;
0b507b17
LP
3828
3829 for (t = p; *t; t++) {
01539d6e 3830 if (*t > 0 && *t < ' ')
0b507b17
LP
3831 return false;
3832
6294aa76 3833 if (strchr("\\\"\'\0x7f", *t))
0b507b17
LP
3834 return false;
3835 }
3836
3837 return true;
3838}
cfbc22ab 3839
ac4c8d6d 3840/**
6294aa76
LP
3841 * Check if a string contains control characters. If 'ok' is non-NULL
3842 * it may be a string containing additional CCs to be considered OK.
ac4c8d6d 3843 */
6294aa76 3844bool string_has_cc(const char *p, const char *ok) {
4d1a6904
LP
3845 const char *t;
3846
3847 assert(p);
3848
3a8a9163 3849 for (t = p; *t; t++) {
6294aa76 3850 if (ok && strchr(ok, *t))
1cb1767a 3851 continue;
6294aa76
LP
3852
3853 if (*t > 0 && *t < ' ')
4d1a6904
LP
3854 return true;
3855
3a8a9163
LP
3856 if (*t == 127)
3857 return true;
3858 }
3859
4d1a6904
LP
3860 return false;
3861}
3862
e884315e
LP
3863bool path_is_safe(const char *p) {
3864
3865 if (isempty(p))
3866 return false;
3867
3868 if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
3869 return false;
3870
6442185a 3871 if (strlen(p)+1 > PATH_MAX)
e884315e
LP
3872 return false;
3873
3874 /* The following two checks are not really dangerous, but hey, they still are confusing */
3875 if (streq(p, ".") || startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
3876 return false;
3877
3878 if (strstr(p, "//"))
3879 return false;
3880
3881 return true;
3882}
3883
a9e12476
KS
3884/* hey glibc, APIs with callbacks without a user pointer are so useless */
3885void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
1c574591 3886 int (*compar) (const void *, const void *, void *), void *arg) {
a9e12476
KS
3887 size_t l, u, idx;
3888 const void *p;
3889 int comparison;
3890
3891 l = 0;
3892 u = nmemb;
3893 while (l < u) {
3894 idx = (l + u) / 2;
3895 p = (void *)(((const char *) base) + (idx * size));
3896 comparison = compar(key, p, arg);
3897 if (comparison < 0)
3898 u = idx;
3899 else if (comparison > 0)
3900 l = idx + 1;
3901 else
3902 return (void *)p;
3903 }
3904 return NULL;
3905}
09017585 3906
20f56fdd
DR
3907void init_gettext(void) {
3908 setlocale(LC_ALL, "");
3909 textdomain(GETTEXT_PACKAGE);
3910}
3911
09017585
MS
3912bool is_locale_utf8(void) {
3913 const char *set;
3914 static int cached_answer = -1;
3915
3916 if (cached_answer >= 0)
3917 goto out;
3918
3919 if (!setlocale(LC_ALL, "")) {
3920 cached_answer = true;
3921 goto out;
3922 }
3923
3924 set = nl_langinfo(CODESET);
3925 if (!set) {
3926 cached_answer = true;
3927 goto out;
3928 }
3929
f168c273 3930 if (streq(set, "UTF-8")) {
fee79e01
HH
3931 cached_answer = true;
3932 goto out;
3933 }
3934
6cf2f1d9
HH
3935 /* For LC_CTYPE=="C" return true, because CTYPE is effectly
3936 * unset and everything can do to UTF-8 nowadays. */
fee79e01
HH
3937 set = setlocale(LC_CTYPE, NULL);
3938 if (!set) {
3939 cached_answer = true;
3940 goto out;
3941 }
3942
6cf2f1d9
HH
3943 /* Check result, but ignore the result if C was set
3944 * explicitly. */
3945 cached_answer =
3946 streq(set, "C") &&
3947 !getenv("LC_ALL") &&
3948 !getenv("LC_CTYPE") &&
3949 !getenv("LANG");
fee79e01 3950
09017585 3951out:
6cf2f1d9 3952 return (bool) cached_answer;
09017585 3953}
c339d977
MS
3954
3955const char *draw_special_char(DrawSpecialChar ch) {
3956 static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
6b01f1d3 3957
c339d977 3958 /* UTF-8 */ {
6b01f1d3 3959 [DRAW_TREE_VERTICAL] = "\342\224\202 ", /* │ */
45a5ff0d
MS
3960 [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */
3961 [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */
55c0b89c 3962 [DRAW_TREE_SPACE] = " ", /* */
6b01f1d3
LP
3963 [DRAW_TRIANGULAR_BULLET] = "\342\200\243", /* ‣ */
3964 [DRAW_BLACK_CIRCLE] = "\342\227\217", /* ● */
3965 [DRAW_ARROW] = "\342\206\222", /* → */
13f8b8cb 3966 [DRAW_DASH] = "\342\200\223", /* – */
c339d977 3967 },
6b01f1d3 3968
c339d977 3969 /* ASCII fallback */ {
6b01f1d3 3970 [DRAW_TREE_VERTICAL] = "| ",
45a5ff0d
MS
3971 [DRAW_TREE_BRANCH] = "|-",
3972 [DRAW_TREE_RIGHT] = "`-",
55c0b89c 3973 [DRAW_TREE_SPACE] = " ",
6b01f1d3
LP
3974 [DRAW_TRIANGULAR_BULLET] = ">",
3975 [DRAW_BLACK_CIRCLE] = "*",
3976 [DRAW_ARROW] = "->",
13f8b8cb 3977 [DRAW_DASH] = "-",
c339d977
MS
3978 }
3979 };
3980
3981 return draw_table[!is_locale_utf8()][ch];
3982}
409bc9c3
LP
3983
3984char *strreplace(const char *text, const char *old_string, const char *new_string) {
3985 const char *f;
3986 char *t, *r;
3987 size_t l, old_len, new_len;
3988
3989 assert(text);
3990 assert(old_string);
3991 assert(new_string);
3992
3993 old_len = strlen(old_string);
3994 new_len = strlen(new_string);
3995
3996 l = strlen(text);
3997 r = new(char, l+1);
3998 if (!r)
3999 return NULL;
4000
4001 f = text;
4002 t = r;
4003 while (*f) {
4004 char *a;
4005 size_t d, nl;
4006
4007 if (!startswith(f, old_string)) {
4008 *(t++) = *(f++);
4009 continue;
4010 }
4011
4012 d = t - r;
4013 nl = l - old_len + new_len;
4014 a = realloc(r, nl + 1);
4015 if (!a)
4016 goto oom;
4017
4018 l = nl;
4019 r = a;
4020 t = r + d;
4021
4022 t = stpcpy(t, new_string);
4023 f += old_len;
4024 }
4025
4026 *t = 0;
4027 return r;
4028
4029oom:
4030 free(r);
4031 return NULL;
4032}
e8bc0ea2
LP
4033
4034char *strip_tab_ansi(char **ibuf, size_t *_isz) {
660ddc72 4035 const char *i, *begin = NULL;
e8bc0ea2
LP
4036 enum {
4037 STATE_OTHER,
4038 STATE_ESCAPE,
4039 STATE_BRACKET
4040 } state = STATE_OTHER;
4041 char *obuf = NULL;
4042 size_t osz = 0, isz;
4043 FILE *f;
4044
4045 assert(ibuf);
4046 assert(*ibuf);
4047
4048 /* Strips ANSI color and replaces TABs by 8 spaces */
4049
4050 isz = _isz ? *_isz : strlen(*ibuf);
4051
4052 f = open_memstream(&obuf, &osz);
4053 if (!f)
4054 return NULL;
4055
4056 for (i = *ibuf; i < *ibuf + isz + 1; i++) {
4057
4058 switch (state) {
4059
4060 case STATE_OTHER:
4061 if (i >= *ibuf + isz) /* EOT */
4062 break;
4063 else if (*i == '\x1B')
4064 state = STATE_ESCAPE;
4065 else if (*i == '\t')
4066 fputs(" ", f);
4067 else
4068 fputc(*i, f);
4069 break;
4070
4071 case STATE_ESCAPE:
4072 if (i >= *ibuf + isz) { /* EOT */
4073 fputc('\x1B', f);
4074 break;
4075 } else if (*i == '[') {
4076 state = STATE_BRACKET;
4077 begin = i + 1;
4078 } else {
4079 fputc('\x1B', f);
4080 fputc(*i, f);
4081 state = STATE_OTHER;
4082 }
4083
4084 break;
4085
4086 case STATE_BRACKET:
4087
4088 if (i >= *ibuf + isz || /* EOT */
4089 (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
4090 fputc('\x1B', f);
4091 fputc('[', f);
4092 state = STATE_OTHER;
4093 i = begin-1;
4094 } else if (*i == 'm')
4095 state = STATE_OTHER;
4096 break;
4097 }
4098 }
4099
4100 if (ferror(f)) {
4101 fclose(f);
4102 free(obuf);
4103 return NULL;
4104 }
4105
4106 fclose(f);
4107
4108 free(*ibuf);
4109 *ibuf = obuf;
4110
4111 if (_isz)
4112 *_isz = osz;
4113
4114 return obuf;
4115}
240dbaa4
LP
4116
4117int on_ac_power(void) {
4118 bool found_offline = false, found_online = false;
4119 _cleanup_closedir_ DIR *d = NULL;
4120
4121 d = opendir("/sys/class/power_supply");
4122 if (!d)
6d890034 4123 return errno == ENOENT ? true : -errno;
240dbaa4
LP
4124
4125 for (;;) {
4126 struct dirent *de;
240dbaa4
LP
4127 _cleanup_close_ int fd = -1, device = -1;
4128 char contents[6];
4129 ssize_t n;
240dbaa4 4130
3fd11280
FW
4131 errno = 0;
4132 de = readdir(d);
4133 if (!de && errno != 0)
4134 return -errno;
240dbaa4
LP
4135
4136 if (!de)
4137 break;
4138
a34bf9db 4139 if (hidden_file(de->d_name))
240dbaa4
LP
4140 continue;
4141
4142 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
4143 if (device < 0) {
4144 if (errno == ENOENT || errno == ENOTDIR)
4145 continue;
4146
4147 return -errno;
4148 }
4149
4150 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
4151 if (fd < 0) {
4152 if (errno == ENOENT)
4153 continue;
4154
4155 return -errno;
4156 }
4157
4158 n = read(fd, contents, sizeof(contents));
4159 if (n < 0)
4160 return -errno;
4161
4162 if (n != 6 || memcmp(contents, "Mains\n", 6))
4163 continue;
4164
03e334a1 4165 safe_close(fd);
240dbaa4
LP
4166 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
4167 if (fd < 0) {
4168 if (errno == ENOENT)
4169 continue;
4170
4171 return -errno;
4172 }
4173
4174 n = read(fd, contents, sizeof(contents));
4175 if (n < 0)
4176 return -errno;
4177
4178 if (n != 2 || contents[1] != '\n')
4179 return -EIO;
4180
4181 if (contents[0] == '1') {
4182 found_online = true;
4183 break;
4184 } else if (contents[0] == '0')
4185 found_offline = true;
4186 else
4187 return -EIO;
4188 }
4189
4190 return found_online || !found_offline;
4191}
fabe5c0e 4192
4cf7ea55 4193static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
fabe5c0e
LP
4194 char **i;
4195
4196 assert(path);
4197 assert(mode);
4198 assert(_f);
4199
7d8da2c9 4200 if (!path_strv_resolve_uniq(search, root))
fabe5c0e
LP
4201 return -ENOMEM;
4202
4203 STRV_FOREACH(i, search) {
4204 _cleanup_free_ char *p = NULL;
4205 FILE *f;
4206
375eadd9
MM
4207 if (root)
4208 p = strjoin(root, *i, "/", path, NULL);
4209 else
4210 p = strjoin(*i, "/", path, NULL);
fabe5c0e
LP
4211 if (!p)
4212 return -ENOMEM;
4213
4214 f = fopen(p, mode);
4215 if (f) {
4216 *_f = f;
4217 return 0;
4218 }
4219
4220 if (errno != ENOENT)
4221 return -errno;
4222 }
4223
4224 return -ENOENT;
4225}
4226
4cf7ea55 4227int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
fabe5c0e
LP
4228 _cleanup_strv_free_ char **copy = NULL;
4229
4230 assert(path);
4231 assert(mode);
4232 assert(_f);
4233
4234 if (path_is_absolute(path)) {
4235 FILE *f;
4236
4237 f = fopen(path, mode);
4238 if (f) {
4239 *_f = f;
4240 return 0;
4241 }
4242
4243 return -errno;
4244 }
4245
4246 copy = strv_copy((char**) search);
4247 if (!copy)
4248 return -ENOMEM;
4249
4cf7ea55 4250 return search_and_fopen_internal(path, mode, root, copy, _f);
fabe5c0e
LP
4251}
4252
4cf7ea55 4253int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
fabe5c0e
LP
4254 _cleanup_strv_free_ char **s = NULL;
4255
4256 if (path_is_absolute(path)) {
4257 FILE *f;
4258
4259 f = fopen(path, mode);
4260 if (f) {
4261 *_f = f;
4262 return 0;
4263 }
4264
4265 return -errno;
4266 }
4267
4268 s = strv_split_nulstr(search);
4269 if (!s)
4270 return -ENOMEM;
4271
4cf7ea55 4272 return search_and_fopen_internal(path, mode, root, s, _f);
fabe5c0e 4273}
c17ec25e 4274
66e35261
LP
4275char *strextend(char **x, ...) {
4276 va_list ap;
4277 size_t f, l;
4278 char *r, *p;
4279
4280 assert(x);
4281
4282 l = f = *x ? strlen(*x) : 0;
4283
4284 va_start(ap, x);
4285 for (;;) {
4286 const char *t;
4287 size_t n;
4288
4289 t = va_arg(ap, const char *);
4290 if (!t)
4291 break;
4292
4293 n = strlen(t);
4294 if (n > ((size_t) -1) - l) {
4295 va_end(ap);
4296 return NULL;
4297 }
4298
4299 l += n;
4300 }
4301 va_end(ap);
4302
4303 r = realloc(*x, l+1);
4304 if (!r)
4305 return NULL;
4306
4307 p = r + f;
4308
4309 va_start(ap, x);
4310 for (;;) {
4311 const char *t;
4312
4313 t = va_arg(ap, const char *);
4314 if (!t)
4315 break;
4316
4317 p = stpcpy(p, t);
4318 }
4319 va_end(ap);
4320
4321 *p = 0;
4322 *x = r;
4323
4324 return r + l;
4325}
9a17484d
LP
4326
4327char *strrep(const char *s, unsigned n) {
4328 size_t l;
4329 char *r, *p;
4330 unsigned i;
4331
4332 assert(s);
4333
4334 l = strlen(s);
4335 p = r = malloc(l * n + 1);
4336 if (!r)
4337 return NULL;
4338
4339 for (i = 0; i < n; i++)
4340 p = stpcpy(p, s);
4341
4342 *p = 0;
4343 return r;
4344}
392d5b37 4345
ca2d3784
ZJS
4346void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
4347 size_t a, newalloc;
392d5b37
LP
4348 void *q;
4349
98088803 4350 assert(p);
e93c33d4
SL
4351 assert(allocated);
4352
392d5b37
LP
4353 if (*allocated >= need)
4354 return *p;
4355
ca2d3784
ZJS
4356 newalloc = MAX(need * 2, 64u / size);
4357 a = newalloc * size;
98088803
LP
4358
4359 /* check for overflows */
ca2d3784 4360 if (a < size * need)
98088803
LP
4361 return NULL;
4362
392d5b37
LP
4363 q = realloc(*p, a);
4364 if (!q)
4365 return NULL;
4366
4367 *p = q;
ca2d3784 4368 *allocated = newalloc;
392d5b37
LP
4369 return q;
4370}
aa96c6cb 4371
ca2d3784 4372void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
98088803 4373 size_t prev;
4545a231
DH
4374 uint8_t *q;
4375
98088803
LP
4376 assert(p);
4377 assert(allocated);
4378
4379 prev = *allocated;
4380
ca2d3784 4381 q = greedy_realloc(p, allocated, need, size);
4545a231
DH
4382 if (!q)
4383 return NULL;
4384
4385 if (*allocated > prev)
ca2d3784 4386 memzero(q + prev * size, (*allocated - prev) * size);
4545a231
DH
4387
4388 return q;
4389}
4390
aa96c6cb
LP
4391bool id128_is_valid(const char *s) {
4392 size_t i, l;
4393
4394 l = strlen(s);
4395 if (l == 32) {
4396
4397 /* Simple formatted 128bit hex string */
4398
4399 for (i = 0; i < l; i++) {
4400 char c = s[i];
4401
4402 if (!(c >= '0' && c <= '9') &&
4403 !(c >= 'a' && c <= 'z') &&
4404 !(c >= 'A' && c <= 'Z'))
4405 return false;
4406 }
4407
4408 } else if (l == 36) {
4409
4410 /* Formatted UUID */
4411
4412 for (i = 0; i < l; i++) {
4413 char c = s[i];
4414
4415 if ((i == 8 || i == 13 || i == 18 || i == 23)) {
4416 if (c != '-')
4417 return false;
4418 } else {
4419 if (!(c >= '0' && c <= '9') &&
4420 !(c >= 'a' && c <= 'z') &&
4421 !(c >= 'A' && c <= 'Z'))
4422 return false;
4423 }
4424 }
4425
4426 } else
4427 return false;
4428
4429 return true;
4430}
7085053a 4431
d4ac85c6
LP
4432int split_pair(const char *s, const char *sep, char **l, char **r) {
4433 char *x, *a, *b;
4434
4435 assert(s);
4436 assert(sep);
4437 assert(l);
4438 assert(r);
4439
4440 if (isempty(sep))
4441 return -EINVAL;
4442
4443 x = strstr(s, sep);
4444 if (!x)
4445 return -EINVAL;
4446
4447 a = strndup(s, x - s);
4448 if (!a)
4449 return -ENOMEM;
4450
4451 b = strdup(x + strlen(sep));
4452 if (!b) {
4453 free(a);
4454 return -ENOMEM;
4455 }
4456
4457 *l = a;
4458 *r = b;
4459
4460 return 0;
4461}
295edddf 4462
74df0fca 4463int shall_restore_state(void) {
1a299299 4464 _cleanup_free_ char *value = NULL;
74df0fca 4465 int r;
295edddf 4466
1a299299 4467 r = get_proc_cmdline_key("systemd.restore_state=", &value);
74df0fca
LP
4468 if (r < 0)
4469 return r;
1a299299
LP
4470 if (r == 0)
4471 return true;
295edddf 4472
1a299299 4473 return parse_boolean(value) != 0;
74df0fca
LP
4474}
4475
4476int proc_cmdline(char **ret) {
b5884878 4477 assert(ret);
295edddf 4478
b5884878
LP
4479 if (detect_container(NULL) > 0)
4480 return get_process_cmdline(1, 0, false, ret);
4481 else
4482 return read_one_line_file("/proc/cmdline", ret);
295edddf 4483}
bc9fd78c 4484
059cb385 4485int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
141a79f4 4486 _cleanup_free_ char *line = NULL;
f32d2db1 4487 const char *p;
141a79f4
ZJS
4488 int r;
4489
059cb385
LP
4490 assert(parse_item);
4491
141a79f4
ZJS
4492 r = proc_cmdline(&line);
4493 if (r < 0)
b5884878 4494 return r;
141a79f4 4495
f32d2db1
LP
4496 p = line;
4497 for (;;) {
4498 _cleanup_free_ char *word = NULL;
4499 char *value = NULL;
141a79f4 4500
4034a06d 4501 r = unquote_first_word(&p, &word, UNQUOTE_RELAX);
f32d2db1
LP
4502 if (r < 0)
4503 return r;
4504 if (r == 0)
4505 break;
141a79f4 4506
059cb385
LP
4507 /* Filter out arguments that are intended only for the
4508 * initrd */
4509 if (!in_initrd() && startswith(word, "rd."))
4510 continue;
4511
4512 value = strchr(word, '=');
4513 if (value)
4514 *(value++) = 0;
4515
4516 r = parse_item(word, value);
4517 if (r < 0)
141a79f4 4518 return r;
141a79f4
ZJS
4519 }
4520
4521 return 0;
4522}
4523
1a299299
LP
4524int get_proc_cmdline_key(const char *key, char **value) {
4525 _cleanup_free_ char *line = NULL, *ret = NULL;
4526 bool found = false;
4527 const char *p;
4528 int r;
4529
4530 assert(key);
4531
4532 r = proc_cmdline(&line);
4533 if (r < 0)
4534 return r;
4535
4536 p = line;
4537 for (;;) {
4538 _cleanup_free_ char *word = NULL;
4539 const char *e;
4540
4034a06d 4541 r = unquote_first_word(&p, &word, UNQUOTE_RELAX);
1a299299
LP
4542 if (r < 0)
4543 return r;
4544 if (r == 0)
4545 break;
4546
4547 /* Filter out arguments that are intended only for the
4548 * initrd */
4549 if (!in_initrd() && startswith(word, "rd."))
4550 continue;
4551
4552 if (value) {
4553 e = startswith(word, key);
4554 if (!e)
4555 continue;
4556
4557 r = free_and_strdup(&ret, e);
4558 if (r < 0)
4559 return r;
4560
4561 found = true;
4562 } else {
4563 if (streq(word, key))
4564 found = true;
4565 }
4566 }
4567
4568 if (value) {
4569 *value = ret;
4570 ret = NULL;
4571 }
4572
4573 return found;
4574
4575}
4576
bc9fd78c
LP
4577int container_get_leader(const char *machine, pid_t *pid) {
4578 _cleanup_free_ char *s = NULL, *class = NULL;
4579 const char *p;
4580 pid_t leader;
4581 int r;
4582
4583 assert(machine);
4584 assert(pid);
4585
63c372cb 4586 p = strjoina("/run/systemd/machines/", machine);
bc9fd78c
LP
4587 r = parse_env_file(p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
4588 if (r == -ENOENT)
4589 return -EHOSTDOWN;
4590 if (r < 0)
4591 return r;
4592 if (!s)
4593 return -EIO;
4594
4595 if (!streq_ptr(class, "container"))
4596 return -EIO;
4597
4598 r = parse_pid(s, &leader);
4599 if (r < 0)
4600 return r;
4601 if (leader <= 1)
4602 return -EIO;
4603
4604 *pid = leader;
4605 return 0;
4606}
4607
878cd7e9
LP
4608int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *root_fd) {
4609 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, netnsfd = -1;
359a06aa 4610 int rfd = -1;
bc9fd78c
LP
4611
4612 assert(pid >= 0);
bc9fd78c 4613
878cd7e9
LP
4614 if (mntns_fd) {
4615 const char *mntns;
a4475f57 4616
878cd7e9
LP
4617 mntns = procfs_file_alloca(pid, "ns/mnt");
4618 mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
4619 if (mntnsfd < 0)
4620 return -errno;
4621 }
bc9fd78c 4622
878cd7e9
LP
4623 if (pidns_fd) {
4624 const char *pidns;
4625
4626 pidns = procfs_file_alloca(pid, "ns/pid");
4627 pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
4628 if (pidnsfd < 0)
4629 return -errno;
4630 }
4631
4632 if (netns_fd) {
4633 const char *netns;
4634
4635 netns = procfs_file_alloca(pid, "ns/net");
4636 netnsfd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
4637 if (netnsfd < 0)
4638 return -errno;
4639 }
4640
4641 if (root_fd) {
4642 const char *root;
4643
4644 root = procfs_file_alloca(pid, "root");
4645 rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
4646 if (rfd < 0)
4647 return -errno;
4648 }
4649
4650 if (pidns_fd)
4651 *pidns_fd = pidnsfd;
bc9fd78c 4652
878cd7e9
LP
4653 if (mntns_fd)
4654 *mntns_fd = mntnsfd;
4655
4656 if (netns_fd)
4657 *netns_fd = netnsfd;
4658
4659 if (root_fd)
4660 *root_fd = rfd;
4661
4662 pidnsfd = mntnsfd = netnsfd = -1;
bc9fd78c
LP
4663
4664 return 0;
4665}
4666
878cd7e9 4667int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int root_fd) {
bc9fd78c 4668
878cd7e9
LP
4669 if (pidns_fd >= 0)
4670 if (setns(pidns_fd, CLONE_NEWPID) < 0)
4671 return -errno;
a4475f57 4672
878cd7e9
LP
4673 if (mntns_fd >= 0)
4674 if (setns(mntns_fd, CLONE_NEWNS) < 0)
4675 return -errno;
bc9fd78c 4676
878cd7e9
LP
4677 if (netns_fd >= 0)
4678 if (setns(netns_fd, CLONE_NEWNET) < 0)
4679 return -errno;
bc9fd78c 4680
878cd7e9
LP
4681 if (root_fd >= 0) {
4682 if (fchdir(root_fd) < 0)
4683 return -errno;
4684
4685 if (chroot(".") < 0)
4686 return -errno;
4687 }
bc9fd78c 4688
b4da6d6b 4689 return reset_uid_gid();
bc9fd78c 4690}
bf108e55 4691
eff05270
LP
4692int getpeercred(int fd, struct ucred *ucred) {
4693 socklen_t n = sizeof(struct ucred);
4694 struct ucred u;
4695 int r;
4696
4697 assert(fd >= 0);
4698 assert(ucred);
4699
4700 r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
4701 if (r < 0)
4702 return -errno;
4703
4704 if (n != sizeof(struct ucred))
4705 return -EIO;
4706
4707 /* Check if the data is actually useful and not suppressed due
4708 * to namespacing issues */
4709 if (u.pid <= 0)
4710 return -ENODATA;
fed1e721 4711 if (u.uid == UID_INVALID)
62028d9c 4712 return -ENODATA;
fed1e721 4713 if (u.gid == GID_INVALID)
62028d9c 4714 return -ENODATA;
eff05270
LP
4715
4716 *ucred = u;
4717 return 0;
4718}
4719
4720int getpeersec(int fd, char **ret) {
4721 socklen_t n = 64;
4722 char *s;
4723 int r;
4724
4725 assert(fd >= 0);
4726 assert(ret);
4727
4728 s = new0(char, n);
4729 if (!s)
4730 return -ENOMEM;
4731
4732 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
4733 if (r < 0) {
4734 free(s);
4735
4736 if (errno != ERANGE)
4737 return -errno;
4738
4739 s = new0(char, n);
4740 if (!s)
4741 return -ENOMEM;
4742
4743 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
4744 if (r < 0) {
4745 free(s);
4746 return -errno;
4747 }
4748 }
4749
ae98841e
LP
4750 if (isempty(s)) {
4751 free(s);
15411c0c 4752 return -EOPNOTSUPP;
ae98841e
LP
4753 }
4754
eff05270
LP
4755 *ret = s;
4756 return 0;
4757}
8e33886e 4758
0f010ef2 4759/* This is much like like mkostemp() but is subject to umask(). */
65b3903f 4760int mkostemp_safe(char *pattern, int flags) {
2d5bdf5b 4761 _cleanup_umask_ mode_t u;
0f010ef2 4762 int fd;
65b3903f 4763
d37a91e8 4764 assert(pattern);
65b3903f 4765
2d5bdf5b
LP
4766 u = umask(077);
4767
0f010ef2
ZJS
4768 fd = mkostemp(pattern, flags);
4769 if (fd < 0)
4770 return -errno;
65b3903f 4771
0f010ef2 4772 return fd;
65b3903f
ZJS
4773}
4774
8e33886e 4775int open_tmpfile(const char *path, int flags) {
8e33886e 4776 char *p;
a6afc4ae
LP
4777 int fd;
4778
4779 assert(path);
8e33886e
ZJS
4780
4781#ifdef O_TMPFILE
7736202c 4782 /* Try O_TMPFILE first, if it is supported */
a765f344 4783 fd = open(path, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
8e33886e
ZJS
4784 if (fd >= 0)
4785 return fd;
4786#endif
7736202c
LP
4787
4788 /* Fall back to unguessable name + unlinking */
63c372cb 4789 p = strjoina(path, "/systemd-tmp-XXXXXX");
8e33886e 4790
a6afc4ae 4791 fd = mkostemp_safe(p, flags);
8e33886e 4792 if (fd < 0)
65b3903f 4793 return fd;
8e33886e
ZJS
4794
4795 unlink(p);
4796 return fd;
4797}
fdb9161c
LP
4798
4799int fd_warn_permissions(const char *path, int fd) {
4800 struct stat st;
4801
4802 if (fstat(fd, &st) < 0)
4803 return -errno;
4804
4805 if (st.st_mode & 0111)
4806 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
4807
4808 if (st.st_mode & 0002)
4809 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
4810
4811 if (getpid() == 1 && (st.st_mode & 0044) != 0044)
4812 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);
4813
4814 return 0;
4815}
6afc95b7 4816
ac45f971 4817unsigned long personality_from_string(const char *p) {
6afc95b7
LP
4818
4819 /* Parse a personality specifier. We introduce our own
4820 * identifiers that indicate specific ABIs, rather than just
4821 * hints regarding the register size, since we want to keep
4822 * things open for multiple locally supported ABIs for the
4823 * same register size. We try to reuse the ABI identifiers
4824 * used by libseccomp. */
4825
4826#if defined(__x86_64__)
4827
4828 if (streq(p, "x86"))
4829 return PER_LINUX32;
4830
4831 if (streq(p, "x86-64"))
4832 return PER_LINUX;
4833
4834#elif defined(__i386__)
4835
4836 if (streq(p, "x86"))
4837 return PER_LINUX;
4838#endif
4839
4840 /* personality(7) documents that 0xffffffffUL is used for
4841 * querying the current personality, hence let's use that here
4842 * as error indicator. */
4843 return 0xffffffffUL;
4844}
ac45f971
LP
4845
4846const char* personality_to_string(unsigned long p) {
4847
4848#if defined(__x86_64__)
4849
4850 if (p == PER_LINUX32)
4851 return "x86";
4852
4853 if (p == PER_LINUX)
4854 return "x86-64";
4855
4856#elif defined(__i386__)
4857
4858 if (p == PER_LINUX)
4859 return "x86";
4860#endif
4861
4862 return NULL;
4863}
1c231f56
LP
4864
4865uint64_t physical_memory(void) {
4866 long mem;
4867
4868 /* We return this as uint64_t in case we are running as 32bit
4869 * process on a 64bit kernel with huge amounts of memory */
4870
4871 mem = sysconf(_SC_PHYS_PAGES);
4872 assert(mem > 0);
4873
4874 return (uint64_t) mem * (uint64_t) page_size();
4875}
6db615c1 4876
29bfbcd6
LP
4877void hexdump(FILE *f, const void *p, size_t s) {
4878 const uint8_t *b = p;
4879 unsigned n = 0;
4880
4881 assert(s == 0 || b);
4882
4883 while (s > 0) {
4884 size_t i;
4885
4886 fprintf(f, "%04x ", n);
4887
4888 for (i = 0; i < 16; i++) {
4889
4890 if (i >= s)
4891 fputs(" ", f);
4892 else
4893 fprintf(f, "%02x ", b[i]);
4894
4895 if (i == 7)
4896 fputc(' ', f);
4897 }
4898
4899 fputc(' ', f);
4900
4901 for (i = 0; i < 16; i++) {
4902
4903 if (i >= s)
4904 fputc(' ', f);
4905 else
4906 fputc(isprint(b[i]) ? (char) b[i] : '.', f);
4907 }
4908
4909 fputc('\n', f);
4910
4911 if (s < 16)
4912 break;
4913
4914 n += 16;
4915 b += 16;
4916 s -= 16;
4917 }
4918}
c5220a94 4919
966bff26 4920int update_reboot_param_file(const char *param) {
c5220a94
MO
4921 int r = 0;
4922
4923 if (param) {
4924
4925 r = write_string_file(REBOOT_PARAM_FILE, param);
4926 if (r < 0)
4927 log_error("Failed to write reboot param to "
4928 REBOOT_PARAM_FILE": %s", strerror(-r));
4929 } else
4930 unlink(REBOOT_PARAM_FILE);
4931
4932 return r;
4933}
6d313367
LP
4934
4935int umount_recursive(const char *prefix, int flags) {
4936 bool again;
4937 int n = 0, r;
4938
4939 /* Try to umount everything recursively below a
4940 * directory. Also, take care of stacked mounts, and keep
4941 * unmounting them until they are gone. */
4942
4943 do {
4944 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
4945
4946 again = false;
4947 r = 0;
4948
4949 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
4950 if (!proc_self_mountinfo)
4951 return -errno;
4952
4953 for (;;) {
4954 _cleanup_free_ char *path = NULL, *p = NULL;
4955 int k;
4956
4957 k = fscanf(proc_self_mountinfo,
4958 "%*s " /* (1) mount id */
4959 "%*s " /* (2) parent id */
4960 "%*s " /* (3) major:minor */
4961 "%*s " /* (4) root */
4962 "%ms " /* (5) mount point */
4963 "%*s" /* (6) mount options */
4964 "%*[^-]" /* (7) optional fields */
4965 "- " /* (8) separator */
4966 "%*s " /* (9) file system type */
4967 "%*s" /* (10) mount source */
4968 "%*s" /* (11) mount options 2 */
4969 "%*[^\n]", /* some rubbish at the end */
4970 &path);
6d313367
LP
4971 if (k != 1) {
4972 if (k == EOF)
4973 break;
4974
4975 continue;
4976 }
4977
527b7a42
LP
4978 r = cunescape(path, UNESCAPE_RELAX, &p);
4979 if (r < 0)
4980 return r;
6d313367
LP
4981
4982 if (!path_startswith(p, prefix))
4983 continue;
4984
4985 if (umount2(p, flags) < 0) {
4986 r = -errno;
4987 continue;
4988 }
4989
4990 again = true;
4991 n++;
4992
4993 break;
4994 }
4995
4996 } while (again);
4997
4998 return r ? r : n;
4999}
d6797c92 5000
abe4aa14
TM
5001static int get_mount_flags(const char *path, unsigned long *flags) {
5002 struct statvfs buf;
5003
5004 if (statvfs(path, &buf) < 0)
5005 return -errno;
5006 *flags = buf.f_flag;
5007 return 0;
5008}
5009
d6797c92
LP
5010int bind_remount_recursive(const char *prefix, bool ro) {
5011 _cleanup_set_free_free_ Set *done = NULL;
5012 _cleanup_free_ char *cleaned = NULL;
5013 int r;
5014
5015 /* Recursively remount a directory (and all its submounts)
5016 * read-only or read-write. If the directory is already
5017 * mounted, we reuse the mount and simply mark it
5018 * MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write
5019 * operation). If it isn't we first make it one. Afterwards we
5020 * apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to all
5021 * submounts we can access, too. When mounts are stacked on
5022 * the same mount point we only care for each individual
5023 * "top-level" mount on each point, as we cannot
5024 * influence/access the underlying mounts anyway. We do not
5025 * have any effect on future submounts that might get
5026 * propagated, they migt be writable. This includes future
5027 * submounts that have been triggered via autofs. */
5028
5029 cleaned = strdup(prefix);
5030 if (!cleaned)
5031 return -ENOMEM;
5032
5033 path_kill_slashes(cleaned);
5034
d5099efc 5035 done = set_new(&string_hash_ops);
d6797c92
LP
5036 if (!done)
5037 return -ENOMEM;
5038
5039 for (;;) {
5040 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
5041 _cleanup_set_free_free_ Set *todo = NULL;
5042 bool top_autofs = false;
5043 char *x;
abe4aa14 5044 unsigned long orig_flags;
d6797c92 5045
d5099efc 5046 todo = set_new(&string_hash_ops);
d6797c92
LP
5047 if (!todo)
5048 return -ENOMEM;
5049
5050 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
5051 if (!proc_self_mountinfo)
5052 return -errno;
5053
5054 for (;;) {
5055 _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
5056 int k;
5057
5058 k = fscanf(proc_self_mountinfo,
5059 "%*s " /* (1) mount id */
5060 "%*s " /* (2) parent id */
5061 "%*s " /* (3) major:minor */
5062 "%*s " /* (4) root */
5063 "%ms " /* (5) mount point */
5064 "%*s" /* (6) mount options (superblock) */
5065 "%*[^-]" /* (7) optional fields */
5066 "- " /* (8) separator */
5067 "%ms " /* (9) file system type */
5068 "%*s" /* (10) mount source */
5069 "%*s" /* (11) mount options (bind mount) */
5070 "%*[^\n]", /* some rubbish at the end */
5071 &path,
5072 &type);
5073 if (k != 2) {
5074 if (k == EOF)
5075 break;
5076
5077 continue;
5078 }
5079
527b7a42
LP
5080 r = cunescape(path, UNESCAPE_RELAX, &p);
5081 if (r < 0)
5082 return r;
d6797c92
LP
5083
5084 /* Let's ignore autofs mounts. If they aren't
5085 * triggered yet, we want to avoid triggering
5086 * them, as we don't make any guarantees for
5087 * future submounts anyway. If they are
5088 * already triggered, then we will find
5089 * another entry for this. */
5090 if (streq(type, "autofs")) {
5091 top_autofs = top_autofs || path_equal(cleaned, p);
5092 continue;
5093 }
5094
5095 if (path_startswith(p, cleaned) &&
5096 !set_contains(done, p)) {
5097
5098 r = set_consume(todo, p);
5099 p = NULL;
5100
5101 if (r == -EEXIST)
5102 continue;
5103 if (r < 0)
5104 return r;
5105 }
5106 }
5107
5108 /* If we have no submounts to process anymore and if
5109 * the root is either already done, or an autofs, we
5110 * are done */
5111 if (set_isempty(todo) &&
5112 (top_autofs || set_contains(done, cleaned)))
5113 return 0;
5114
5115 if (!set_contains(done, cleaned) &&
5116 !set_contains(todo, cleaned)) {
5117 /* The prefix directory itself is not yet a
5118 * mount, make it one. */
5119 if (mount(cleaned, cleaned, NULL, MS_BIND|MS_REC, NULL) < 0)
5120 return -errno;
5121
a7e07206
LP
5122 orig_flags = 0;
5123 (void) get_mount_flags(cleaned, &orig_flags);
abe4aa14 5124 orig_flags &= ~MS_RDONLY;
a7e07206 5125
abe4aa14 5126 if (mount(NULL, prefix, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0)
d6797c92
LP
5127 return -errno;
5128
5129 x = strdup(cleaned);
5130 if (!x)
5131 return -ENOMEM;
5132
5133 r = set_consume(done, x);
5134 if (r < 0)
5135 return r;
5136 }
5137
5138 while ((x = set_steal_first(todo))) {
5139
5140 r = set_consume(done, x);
5141 if (r == -EEXIST)
5142 continue;
5143 if (r < 0)
5144 return r;
5145
a7e07206
LP
5146 /* Try to reuse the original flag set, but
5147 * don't care for errors, in case of
5148 * obstructed mounts */
5149 orig_flags = 0;
5150 (void) get_mount_flags(x, &orig_flags);
abe4aa14 5151 orig_flags &= ~MS_RDONLY;
a7e07206 5152
abe4aa14 5153 if (mount(NULL, x, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) {
d6797c92
LP
5154
5155 /* Deal with mount points that are
5156 * obstructed by a later mount */
5157
5158 if (errno != ENOENT)
5159 return -errno;
5160 }
5161
5162 }
5163 }
5164}
1b992147
LP
5165
5166int fflush_and_check(FILE *f) {
45c196a7 5167 assert(f);
1b992147
LP
5168
5169 errno = 0;
5170 fflush(f);
5171
5172 if (ferror(f))
5173 return errno ? -errno : -EIO;
5174
5175 return 0;
5176}
2e78fa79 5177
ae6c3cc0 5178int tempfn_xxxxxx(const char *p, char **ret) {
2e78fa79
LP
5179 const char *fn;
5180 char *t;
2e78fa79
LP
5181
5182 assert(p);
ae6c3cc0
LP
5183 assert(ret);
5184
c4e34a61
LP
5185 /*
5186 * Turns this:
5187 * /foo/bar/waldo
5188 *
5189 * Into this:
8eebf6ad 5190 * /foo/bar/.#waldoXXXXXX
c4e34a61
LP
5191 */
5192
ae6c3cc0
LP
5193 fn = basename(p);
5194 if (!filename_is_valid(fn))
5195 return -EINVAL;
2e78fa79 5196
8eebf6ad 5197 t = new(char, strlen(p) + 2 + 6 + 1);
2e78fa79 5198 if (!t)
ae6c3cc0 5199 return -ENOMEM;
2e78fa79 5200
8eebf6ad 5201 strcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), fn), "XXXXXX");
2e78fa79 5202
c4e34a61 5203 *ret = path_kill_slashes(t);
ae6c3cc0 5204 return 0;
2e78fa79
LP
5205}
5206
ae6c3cc0 5207int tempfn_random(const char *p, char **ret) {
2e78fa79
LP
5208 const char *fn;
5209 char *t, *x;
5210 uint64_t u;
2e78fa79
LP
5211 unsigned i;
5212
5213 assert(p);
ae6c3cc0
LP
5214 assert(ret);
5215
c4e34a61
LP
5216 /*
5217 * Turns this:
5218 * /foo/bar/waldo
5219 *
5220 * Into this:
8eebf6ad 5221 * /foo/bar/.#waldobaa2a261115984a9
c4e34a61
LP
5222 */
5223
ae6c3cc0
LP
5224 fn = basename(p);
5225 if (!filename_is_valid(fn))
5226 return -EINVAL;
2e78fa79 5227
8eebf6ad 5228 t = new(char, strlen(p) + 2 + 16 + 1);
2e78fa79 5229 if (!t)
ae6c3cc0 5230 return -ENOMEM;
2e78fa79 5231
8eebf6ad 5232 x = stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), fn);
2e78fa79
LP
5233
5234 u = random_u64();
5235 for (i = 0; i < 16; i++) {
5236 *(x++) = hexchar(u & 0xF);
5237 u >>= 4;
5238 }
5239
5240 *x = 0;
5241
c4e34a61
LP
5242 *ret = path_kill_slashes(t);
5243 return 0;
5244}
5245
5246int tempfn_random_child(const char *p, char **ret) {
5247 char *t, *x;
5248 uint64_t u;
5249 unsigned i;
5250
5251 assert(p);
5252 assert(ret);
5253
5254 /* Turns this:
5255 * /foo/bar/waldo
5256 * Into this:
8eebf6ad 5257 * /foo/bar/waldo/.#3c2b6219aa75d7d0
c4e34a61
LP
5258 */
5259
8eebf6ad 5260 t = new(char, strlen(p) + 3 + 16 + 1);
c4e34a61
LP
5261 if (!t)
5262 return -ENOMEM;
5263
8eebf6ad 5264 x = stpcpy(stpcpy(t, p), "/.#");
c4e34a61
LP
5265
5266 u = random_u64();
5267 for (i = 0; i < 16; i++) {
5268 *(x++) = hexchar(u & 0xF);
5269 u >>= 4;
5270 }
5271
5272 *x = 0;
5273
5274 *ret = path_kill_slashes(t);
ae6c3cc0 5275 return 0;
2e78fa79 5276}
fecc80c1 5277
45035609
LP
5278int take_password_lock(const char *root) {
5279
5280 struct flock flock = {
5281 .l_type = F_WRLCK,
5282 .l_whence = SEEK_SET,
5283 .l_start = 0,
5284 .l_len = 0,
5285 };
5286
5287 const char *path;
5288 int fd, r;
5289
5290 /* This is roughly the same as lckpwdf(), but not as awful. We
5291 * don't want to use alarm() and signals, hence we implement
5292 * our own trivial version of this.
5293 *
5294 * Note that shadow-utils also takes per-database locks in
5295 * addition to lckpwdf(). However, we don't given that they
5296 * are redundant as they they invoke lckpwdf() first and keep
5297 * it during everything they do. The per-database locks are
5298 * awfully racy, and thus we just won't do them. */
5299
5300 if (root)
63c372cb 5301 path = strjoina(root, "/etc/.pwd.lock");
45035609
LP
5302 else
5303 path = "/etc/.pwd.lock";
5304
5305 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
5306 if (fd < 0)
5307 return -errno;
5308
5309 r = fcntl(fd, F_SETLKW, &flock);
5310 if (r < 0) {
5311 safe_close(fd);
5312 return -errno;
5313 }
5314
5315 return fd;
5316}
5261ba90
TT
5317
5318int is_symlink(const char *path) {
5319 struct stat info;
5320
5321 if (lstat(path, &info) < 0)
5322 return -errno;
5323
be57e297
LP
5324 return !!S_ISLNK(info.st_mode);
5325}
5261ba90 5326
be57e297
LP
5327int is_dir(const char* path, bool follow) {
5328 struct stat st;
d1bddcec 5329 int r;
be57e297 5330
d1bddcec
LP
5331 if (follow)
5332 r = stat(path, &st);
5333 else
5334 r = lstat(path, &st);
5335 if (r < 0)
5336 return -errno;
be57e297
LP
5337
5338 return !!S_ISDIR(st.st_mode);
a0627f82 5339}
7629889c 5340
ce5b3ad4
SJ
5341int is_device_node(const char *path) {
5342 struct stat info;
5343
5344 if (lstat(path, &info) < 0)
5345 return -errno;
5346
5347 return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode));
5348}
5349
4034a06d 5350int unquote_first_word(const char **p, char **ret, UnquoteFlags flags) {
7629889c
LP
5351 _cleanup_free_ char *s = NULL;
5352 size_t allocated = 0, sz = 0;
4034a06d 5353 int r;
7629889c
LP
5354
5355 enum {
5356 START,
5357 VALUE,
5358 VALUE_ESCAPE,
5359 SINGLE_QUOTE,
5360 SINGLE_QUOTE_ESCAPE,
5361 DOUBLE_QUOTE,
5362 DOUBLE_QUOTE_ESCAPE,
5363 SPACE,
5364 } state = START;
5365
5366 assert(p);
5367 assert(*p);
5368 assert(ret);
5369
5370 /* Parses the first word of a string, and returns it in
5371 * *ret. Removes all quotes in the process. When parsing fails
5372 * (because of an uneven number of quotes or similar), leaves
5373 * the pointer *p at the first invalid character. */
5374
5375 for (;;) {
5376 char c = **p;
5377
5378 switch (state) {
5379
5380 case START:
5381 if (c == 0)
5382 goto finish;
5383 else if (strchr(WHITESPACE, c))
5384 break;
5385
5386 state = VALUE;
5387 /* fallthrough */
5388
5389 case VALUE:
5390 if (c == 0)
5391 goto finish;
5392 else if (c == '\'')
5393 state = SINGLE_QUOTE;
5394 else if (c == '\\')
5395 state = VALUE_ESCAPE;
5396 else if (c == '\"')
5397 state = DOUBLE_QUOTE;
5398 else if (strchr(WHITESPACE, c))
5399 state = SPACE;
5400 else {
5401 if (!GREEDY_REALLOC(s, allocated, sz+2))
5402 return -ENOMEM;
5403
5404 s[sz++] = c;
5405 }
5406
5407 break;
5408
5409 case VALUE_ESCAPE:
f32d2db1 5410 if (c == 0) {
4034a06d 5411 if (flags & UNQUOTE_RELAX)
f32d2db1 5412 goto finish;
7629889c 5413 return -EINVAL;
f32d2db1 5414 }
7629889c 5415
8ebac1f9 5416 if (!GREEDY_REALLOC(s, allocated, sz+7))
7629889c
LP
5417 return -ENOMEM;
5418
4034a06d 5419 if (flags & UNQUOTE_CUNESCAPE) {
f3ee6297
LP
5420 uint32_t u;
5421
5422 r = cunescape_one(*p, (size_t) -1, &c, &u);
4034a06d
LP
5423 if (r < 0)
5424 return -EINVAL;
5425
5426 (*p) += r - 1;
4034a06d 5427
f3ee6297
LP
5428 if (c != 0)
5429 s[sz++] = c; /* normal explicit char */
5430 else
8ebac1f9 5431 sz += utf8_encode_unichar(s + sz, u); /* unicode chars we'll encode as utf8 */
f3ee6297
LP
5432 } else
5433 s[sz++] = c;
7629889c 5434
f3ee6297 5435 state = VALUE;
7629889c
LP
5436 break;
5437
5438 case SINGLE_QUOTE:
f32d2db1 5439 if (c == 0) {
4034a06d 5440 if (flags & UNQUOTE_RELAX)
f32d2db1 5441 goto finish;
7629889c 5442 return -EINVAL;
f32d2db1 5443 } else if (c == '\'')
7629889c
LP
5444 state = VALUE;
5445 else if (c == '\\')
5446 state = SINGLE_QUOTE_ESCAPE;
5447 else {
5448 if (!GREEDY_REALLOC(s, allocated, sz+2))
5449 return -ENOMEM;
5450
5451 s[sz++] = c;
5452 }
5453
5454 break;
5455
5456 case SINGLE_QUOTE_ESCAPE:
f32d2db1 5457 if (c == 0) {
4034a06d 5458 if (flags & UNQUOTE_RELAX)
f32d2db1 5459 goto finish;
7629889c 5460 return -EINVAL;
f32d2db1 5461 }
7629889c 5462
8ebac1f9 5463 if (!GREEDY_REALLOC(s, allocated, sz+7))
7629889c
LP
5464 return -ENOMEM;
5465
4034a06d 5466 if (flags & UNQUOTE_CUNESCAPE) {
f3ee6297
LP
5467 uint32_t u;
5468
5469 r = cunescape_one(*p, (size_t) -1, &c, &u);
4034a06d
LP
5470 if (r < 0)
5471 return -EINVAL;
5472
5473 (*p) += r - 1;
4034a06d 5474
f3ee6297
LP
5475 if (c != 0)
5476 s[sz++] = c;
5477 else
8ebac1f9 5478 sz += utf8_encode_unichar(s + sz, u);
f3ee6297
LP
5479 } else
5480 s[sz++] = c;
5481
7629889c
LP
5482 state = SINGLE_QUOTE;
5483 break;
5484
5485 case DOUBLE_QUOTE:
5486 if (c == 0)
5487 return -EINVAL;
5488 else if (c == '\"')
5489 state = VALUE;
5490 else if (c == '\\')
5491 state = DOUBLE_QUOTE_ESCAPE;
5492 else {
5493 if (!GREEDY_REALLOC(s, allocated, sz+2))
5494 return -ENOMEM;
5495
5496 s[sz++] = c;
5497 }
5498
5499 break;
5500
5501 case DOUBLE_QUOTE_ESCAPE:
f32d2db1 5502 if (c == 0) {
4034a06d 5503 if (flags & UNQUOTE_RELAX)
f32d2db1 5504 goto finish;
7629889c 5505 return -EINVAL;
f32d2db1 5506 }
7629889c 5507
8ebac1f9 5508 if (!GREEDY_REALLOC(s, allocated, sz+7))
7629889c
LP
5509 return -ENOMEM;
5510
4034a06d 5511 if (flags & UNQUOTE_CUNESCAPE) {
f3ee6297
LP
5512 uint32_t u;
5513
5514 r = cunescape_one(*p, (size_t) -1, &c, &u);
4034a06d
LP
5515 if (r < 0)
5516 return -EINVAL;
5517
5518 (*p) += r - 1;
4034a06d 5519
f3ee6297
LP
5520 if (c != 0)
5521 s[sz++] = c;
5522 else
8ebac1f9 5523 sz += utf8_encode_unichar(s + sz, u);
f3ee6297
LP
5524 } else
5525 s[sz++] = c;
5526
7629889c
LP
5527 state = DOUBLE_QUOTE;
5528 break;
5529
5530 case SPACE:
5531 if (c == 0)
5532 goto finish;
5533 if (!strchr(WHITESPACE, c))
5534 goto finish;
5535
5536 break;
5537 }
5538
5539 (*p) ++;
5540 }
5541
5542finish:
5543 if (!s) {
5544 *ret = NULL;
5545 return 0;
5546 }
5547
5548 s[sz] = 0;
5549 *ret = s;
5550 s = NULL;
5551
5552 return 1;
5553}
5554
4034a06d 5555int unquote_many_words(const char **p, UnquoteFlags flags, ...) {
7629889c
LP
5556 va_list ap;
5557 char **l;
5558 int n = 0, i, c, r;
5559
5560 /* Parses a number of words from a string, stripping any
5561 * quotes if necessary. */
5562
5563 assert(p);
5564
5565 /* Count how many words are expected */
4034a06d 5566 va_start(ap, flags);
7629889c
LP
5567 for (;;) {
5568 if (!va_arg(ap, char **))
5569 break;
5570 n++;
5571 }
5572 va_end(ap);
5573
5574 if (n <= 0)
5575 return 0;
5576
5577 /* Read all words into a temporary array */
5578 l = newa0(char*, n);
5579 for (c = 0; c < n; c++) {
5580
4034a06d 5581 r = unquote_first_word(p, &l[c], flags);
7629889c
LP
5582 if (r < 0) {
5583 int j;
5584
081e009b 5585 for (j = 0; j < c; j++)
7629889c 5586 free(l[j]);
081e009b
LN
5587
5588 return r;
7629889c
LP
5589 }
5590
5591 if (r == 0)
5592 break;
5593 }
5594
5595 /* If we managed to parse all words, return them in the passed
5596 * in parameters */
4034a06d 5597 va_start(ap, flags);
7629889c
LP
5598 for (i = 0; i < n; i++) {
5599 char **v;
5600
5601 v = va_arg(ap, char **);
5602 assert(v);
5603
5604 *v = l[i];
5605 }
5606 va_end(ap);
5607
5608 return c;
5609}
2928b0a8
LP
5610
5611int free_and_strdup(char **p, const char *s) {
5612 char *t;
5613
5614 assert(p);
5615
5616 /* Replaces a string pointer with an strdup()ed new string,
5617 * possibly freeing the old one. */
5618
4b64536e
LP
5619 if (streq_ptr(*p, s))
5620 return 0;
5621
2928b0a8
LP
5622 if (s) {
5623 t = strdup(s);
5624 if (!t)
5625 return -ENOMEM;
5626 } else
5627 t = NULL;
5628
5629 free(*p);
5630 *p = t;
5631
4b64536e 5632 return 1;
2928b0a8 5633}
605f81a8 5634
ee451d76
LP
5635int ptsname_malloc(int fd, char **ret) {
5636 size_t l = 100;
5637
9d8c4979
LP
5638 assert(fd >= 0);
5639 assert(ret);
5640
ee451d76
LP
5641 for (;;) {
5642 char *c;
5643
5644 c = new(char, l);
5645 if (!c)
5646 return -ENOMEM;
5647
5648 if (ptsname_r(fd, c, l) == 0) {
5649 *ret = c;
5650 return 0;
5651 }
5652 if (errno != ERANGE) {
5653 free(c);
5654 return -errno;
5655 }
5656
5657 free(c);
5658 l *= 2;
5659 }
5660}
5f8cc96a
LP
5661
5662int openpt_in_namespace(pid_t pid, int flags) {
5663 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, rootfd = -1;
5664 _cleanup_close_pair_ int pair[2] = { -1, -1 };
5665 union {
5666 struct cmsghdr cmsghdr;
5667 uint8_t buf[CMSG_SPACE(sizeof(int))];
5668 } control = {};
5669 struct msghdr mh = {
5670 .msg_control = &control,
5671 .msg_controllen = sizeof(control),
5672 };
5673 struct cmsghdr *cmsg;
5674 siginfo_t si;
5675 pid_t child;
5676 int r;
5677
5678 assert(pid > 0);
5679
5680 r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &rootfd);
5681 if (r < 0)
5682 return r;
5683
5684 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
5685 return -errno;
5686
5687 child = fork();
5688 if (child < 0)
5689 return -errno;
5690
5691 if (child == 0) {
5692 int master;
5693
5694 pair[0] = safe_close(pair[0]);
5695
5696 r = namespace_enter(pidnsfd, mntnsfd, -1, rootfd);
5697 if (r < 0)
5698 _exit(EXIT_FAILURE);
5699
5700 master = posix_openpt(flags);
5701 if (master < 0)
5702 _exit(EXIT_FAILURE);
5703
5704 cmsg = CMSG_FIRSTHDR(&mh);
5705 cmsg->cmsg_level = SOL_SOCKET;
5706 cmsg->cmsg_type = SCM_RIGHTS;
5707 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
5708 memcpy(CMSG_DATA(cmsg), &master, sizeof(int));
5709
5710 mh.msg_controllen = cmsg->cmsg_len;
5711
5712 if (sendmsg(pair[1], &mh, MSG_NOSIGNAL) < 0)
5713 _exit(EXIT_FAILURE);
5714
5715 _exit(EXIT_SUCCESS);
5716 }
5717
5718 pair[1] = safe_close(pair[1]);
5719
5720 r = wait_for_terminate(child, &si);
5721 if (r < 0)
5722 return r;
5723 if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
5724 return -EIO;
5725
5726 if (recvmsg(pair[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
5727 return -errno;
5728
5729 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg))
5730 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
5731 int *fds;
5732 unsigned n_fds;
5733
5734 fds = (int*) CMSG_DATA(cmsg);
5735 n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
5736
5737 if (n_fds != 1) {
5738 close_many(fds, n_fds);
5739 return -EIO;
5740 }
5741
5742 return fds[0];
5743 }
5744
5745 return -EIO;
5746}
4a4d89b6 5747
10f9c755
LP
5748ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) {
5749 _cleanup_close_ int fd = -1;
5750 ssize_t l;
5751
5752 /* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */
5753
5754 fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOATIME|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
5755 if (fd < 0)
5756 return -errno;
5757
5758 l = fgetxattr(fd, attribute, value, size);
5759 if (l < 0)
5760 return -errno;
5761
5762 return l;
5763}
5764
5765static int parse_crtime(le64_t le, usec_t *usec) {
4a4d89b6 5766 uint64_t u;
10f9c755
LP
5767
5768 assert(usec);
5769
5770 u = le64toh(le);
5771 if (u == 0 || u == (uint64_t) -1)
5772 return -EIO;
5773
5774 *usec = (usec_t) u;
5775 return 0;
5776}
5777
5778int fd_getcrtime(int fd, usec_t *usec) {
4a4d89b6
LP
5779 le64_t le;
5780 ssize_t n;
5781
5782 assert(fd >= 0);
5783 assert(usec);
5784
5785 /* Until Linux gets a real concept of birthtime/creation time,
5786 * let's fake one with xattrs */
5787
5788 n = fgetxattr(fd, "user.crtime_usec", &le, sizeof(le));
5789 if (n < 0)
5790 return -errno;
5791 if (n != sizeof(le))
5792 return -EIO;
5793
10f9c755
LP
5794 return parse_crtime(le, usec);
5795}
5796
5797int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags) {
5798 le64_t le;
5799 ssize_t n;
5800
5801 n = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags);
5802 if (n < 0)
5803 return -errno;
5804 if (n != sizeof(le))
4a4d89b6
LP
5805 return -EIO;
5806
10f9c755 5807 return parse_crtime(le, usec);
4a4d89b6
LP
5808}
5809
5810int path_getcrtime(const char *p, usec_t *usec) {
4a4d89b6
LP
5811 le64_t le;
5812 ssize_t n;
5813
5814 assert(p);
5815 assert(usec);
5816
5817 n = getxattr(p, "user.crtime_usec", &le, sizeof(le));
5818 if (n < 0)
5819 return -errno;
5820 if (n != sizeof(le))
5821 return -EIO;
5822
10f9c755 5823 return parse_crtime(le, usec);
4a4d89b6
LP
5824}
5825
5826int fd_setcrtime(int fd, usec_t usec) {
5827 le64_t le;
5828
5829 assert(fd >= 0);
5830
d61b600d
LP
5831 if (usec <= 0)
5832 usec = now(CLOCK_REALTIME);
5833
4a4d89b6 5834 le = htole64((uint64_t) usec);
2c39ea52 5835 if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), 0) < 0)
4a4d89b6
LP
5836 return -errno;
5837
5838 return 0;
5839}
a354329f
LP
5840
5841int same_fd(int a, int b) {
5842 struct stat sta, stb;
f7ad54a3
LP
5843 pid_t pid;
5844 int r, fa, fb;
a354329f
LP
5845
5846 assert(a >= 0);
5847 assert(b >= 0);
5848
f7ad54a3
LP
5849 /* Compares two file descriptors. Note that semantics are
5850 * quite different depending on whether we have kcmp() or we
5851 * don't. If we have kcmp() this will only return true for
5852 * dup()ed file descriptors, but not otherwise. If we don't
5853 * have kcmp() this will also return true for two fds of the same
5854 * file, created by separate open() calls. Since we use this
5855 * call mostly for filtering out duplicates in the fd store
5856 * this difference hopefully doesn't matter too much. */
5857
a354329f
LP
5858 if (a == b)
5859 return true;
5860
f7ad54a3
LP
5861 /* Try to use kcmp() if we have it. */
5862 pid = getpid();
5863 r = kcmp(pid, pid, KCMP_FILE, a, b);
5864 if (r == 0)
5865 return true;
5866 if (r > 0)
5867 return false;
5868 if (errno != ENOSYS)
5869 return -errno;
5870
5871 /* We don't have kcmp(), use fstat() instead. */
a354329f
LP
5872 if (fstat(a, &sta) < 0)
5873 return -errno;
5874
5875 if (fstat(b, &stb) < 0)
5876 return -errno;
5877
5878 if ((sta.st_mode & S_IFMT) != (stb.st_mode & S_IFMT))
5879 return false;
5880
f7ad54a3
LP
5881 /* We consider all device fds different, since two device fds
5882 * might refer to quite different device contexts even though
5883 * they share the same inode and backing dev_t. */
a354329f 5884
f7ad54a3
LP
5885 if (S_ISCHR(sta.st_mode) || S_ISBLK(sta.st_mode))
5886 return false;
5887
5888 if (sta.st_dev != stb.st_dev || sta.st_ino != stb.st_ino)
5889 return false;
5890
5891 /* The fds refer to the same inode on disk, let's also check
5892 * if they have the same fd flags. This is useful to
5893 * distuingish the read and write side of a pipe created with
5894 * pipe(). */
5895 fa = fcntl(a, F_GETFL);
5896 if (fa < 0)
5897 return -errno;
5898
5899 fb = fcntl(b, F_GETFL);
5900 if (fb < 0)
5901 return -errno;
5902
5903 return fa == fb;
a354329f 5904}
11689d2a 5905
1ed8f8c1 5906int chattr_fd(int fd, unsigned value, unsigned mask) {
45030287 5907 unsigned old_attr, new_attr;
03091baa 5908 struct stat st;
11689d2a
LP
5909
5910 assert(fd >= 0);
5911
03091baa
LP
5912 if (fstat(fd, &st) < 0)
5913 return -errno;
5914
5915 /* Explicitly check whether this is a regular file or
5916 * directory. If it is anything else (such as a device node or
5917 * fifo), then the ioctl will not hit the file systems but
5918 * possibly drivers, where the ioctl might have different
5919 * effects. Notably, DRM is using the same ioctl() number. */
5920
5921 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
5922 return -ENOTTY;
5923
45030287
LP
5924 if (mask == 0)
5925 return 0;
5926
11689d2a
LP
5927 if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
5928 return -errno;
5929
1ed8f8c1 5930 new_attr = (old_attr & ~mask) | (value & mask);
11689d2a
LP
5931 if (new_attr == old_attr)
5932 return 0;
5933
5934 if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
5935 return -errno;
5936
1ed8f8c1 5937 return 1;
11689d2a
LP
5938}
5939
1ed8f8c1 5940int chattr_path(const char *p, unsigned value, unsigned mask) {
11689d2a
LP
5941 _cleanup_close_ int fd = -1;
5942
45030287
LP
5943 assert(p);
5944
5945 if (mask == 0)
5946 return 0;
5947
01b72568 5948 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
11689d2a
LP
5949 if (fd < 0)
5950 return -errno;
5951
1ed8f8c1 5952 return chattr_fd(fd, value, mask);
5b9fbd35
GB
5953}
5954
01b72568 5955int read_attr_fd(int fd, unsigned *ret) {
03091baa
LP
5956 struct stat st;
5957
01b72568
LP
5958 assert(fd >= 0);
5959
03091baa
LP
5960 if (fstat(fd, &st) < 0)
5961 return -errno;
5962
5963 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
5964 return -ENOTTY;
5965
01b72568
LP
5966 if (ioctl(fd, FS_IOC_GETFLAGS, ret) < 0)
5967 return -errno;
5968
5969 return 0;
5970}
5971
5972int read_attr_path(const char *p, unsigned *ret) {
5973 _cleanup_close_ int fd = -1;
5974
5975 assert(p);
5976 assert(ret);
5977
5978 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
5979 if (fd < 0)
5980 return -errno;
5981
5982 return read_attr_fd(fd, ret);
5983}
30535c16 5984
ff6a7460
LP
5985static size_t nul_length(const uint8_t *p, size_t sz) {
5986 size_t n = 0;
5987
5988 while (sz > 0) {
5989 if (*p != 0)
5990 break;
5991
5992 n++;
5993 p++;
5994 sz--;
5995 }
5996
5997 return n;
5998}
5999
6000ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
6001 const uint8_t *q, *w, *e;
6002 ssize_t l;
6003
6004 q = w = p;
6005 e = q + sz;
6006 while (q < e) {
6007 size_t n;
6008
6009 n = nul_length(q, e - q);
6010
6011 /* If there are more than the specified run length of
6012 * NUL bytes, or if this is the beginning or the end
6013 * of the buffer, then seek instead of write */
6014 if ((n > run_length) ||
6015 (n > 0 && q == p) ||
6016 (n > 0 && q + n >= e)) {
6017 if (q > w) {
6018 l = write(fd, w, q - w);
6019 if (l < 0)
6020 return -errno;
6021 if (l != q -w)
6022 return -EIO;
6023 }
6024
6025 if (lseek(fd, n, SEEK_CUR) == (off_t) -1)
6026 return -errno;
6027
6028 q += n;
6029 w = q;
6030 } else if (n > 0)
6031 q += n;
6032 else
6033 q ++;
6034 }
6035
6036 if (q > w) {
6037 l = write(fd, w, q - w);
6038 if (l < 0)
6039 return -errno;
6040 if (l != q - w)
6041 return -EIO;
6042 }
6043
6044 return q - (const uint8_t*) p;
6045}
3576d631
LP
6046
6047void sigkill_wait(pid_t *pid) {
6048 if (!pid)
6049 return;
6050 if (*pid <= 1)
6051 return;
6052
6053 if (kill(*pid, SIGKILL) > 0)
6054 (void) wait_for_terminate(*pid, NULL);
6055}
3d7415f4
LP
6056
6057int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
6058 int a = 0, b = 0, c = 0;
6059 int k;
6060
6061 assert(p);
6062 assert(*p);
6063 assert(priority);
6064
6065 if ((*p)[0] != '<')
6066 return 0;
6067
6068 if (!strchr(*p, '>'))
6069 return 0;
6070
6071 if ((*p)[2] == '>') {
6072 c = undecchar((*p)[1]);
6073 k = 3;
6074 } else if ((*p)[3] == '>') {
6075 b = undecchar((*p)[1]);
6076 c = undecchar((*p)[2]);
6077 k = 4;
6078 } else if ((*p)[4] == '>') {
6079 a = undecchar((*p)[1]);
6080 b = undecchar((*p)[2]);
6081 c = undecchar((*p)[3]);
6082 k = 5;
6083 } else
6084 return 0;
6085
6086 if (a < 0 || b < 0 || c < 0 ||
6087 (!with_facility && (a || b || c > 7)))
6088 return 0;
6089
6090 if (with_facility)
6091 *priority = a*100 + b*10 + c;
6092 else
6093 *priority = (*priority & LOG_FACMASK) | c;
6094
6095 *p += k;
6096 return 1;
6097}
9cad100e
BB
6098
6099ssize_t string_table_lookup(const char * const *table, size_t len, const char *key) {
6100 size_t i;
6101
6102 if (!key)
6103 return -1;
6104
6105 for (i = 0; i < len; ++i)
6106 if (streq_ptr(table[i], key))
6107 return (ssize_t)i;
6108
6109 return -1;
6110}
1c8da044
LP
6111
6112void cmsg_close_all(struct msghdr *mh) {
6113 struct cmsghdr *cmsg;
6114
6115 assert(mh);
6116
6117 for (cmsg = CMSG_FIRSTHDR(mh); cmsg; cmsg = CMSG_NXTHDR(mh, cmsg))
6118 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
6119 close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int));
6120}
f85ef957
AC
6121
6122int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
6123 struct stat buf;
6124 int ret;
6125
6126 ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
6127 if (ret >= 0)
6128 return 0;
6129
6130 /* Even though renameat2() exists since Linux 3.15, btrfs added
6131 * support for it later. If it is not implemented, fallback to another
6132 * method. */
6133 if (errno != EINVAL)
6134 return -errno;
6135
6136 /* The link()/unlink() fallback does not work on directories. But
6137 * renameat() without RENAME_NOREPLACE gives the same semantics on
6138 * directories, except when newpath is an *empty* directory. This is
6139 * good enough. */
6140 ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW);
6141 if (ret >= 0 && S_ISDIR(buf.st_mode)) {
6142 ret = renameat(olddirfd, oldpath, newdirfd, newpath);
6143 return ret >= 0 ? 0 : -errno;
6144 }
6145
6146 /* If it is not a directory, use the link()/unlink() fallback. */
6147 ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0);
6148 if (ret < 0)
6149 return -errno;
6150
6151 ret = unlinkat(olddirfd, oldpath, 0);
6152 if (ret < 0) {
6153 /* backup errno before the following unlinkat() alters it */
6154 ret = errno;
6155 (void) unlinkat(newdirfd, newpath, 0);
6156 errno = ret;
6157 return -errno;
6158 }
6159
6160 return 0;
6161}
019c7fba
LP
6162
6163char *shell_maybe_quote(const char *s) {
6164 const char *p;
6165 char *r, *t;
6166
6167 assert(s);
6168
6169 /* Encloses a string in double quotes if necessary to make it
6170 * OK as shell string. */
6171
6172 for (p = s; *p; p++)
6173 if (*p <= ' ' ||
6174 *p >= 127 ||
6175 strchr(SHELL_NEED_QUOTES, *p))
6176 break;
6177
6178 if (!*p)
6179 return strdup(s);
6180
6181 r = new(char, 1+strlen(s)*2+1+1);
6182 if (!r)
6183 return NULL;
6184
6185 t = r;
6186 *(t++) = '"';
6187 t = mempcpy(t, s, p - s);
6188
6189 for (; *p; p++) {
6190
6191 if (strchr(SHELL_NEED_ESCAPE, *p))
6192 *(t++) = '\\';
6193
6194 *(t++) = *p;
6195 }
6196
6197 *(t++)= '"';
6198 *t = 0;
6199
6200 return r;
6201}
2ff7b0a5
LP
6202
6203int parse_mode(const char *s, mode_t *ret) {
6204 char *x;
6205 long l;
6206
6207 assert(s);
6208 assert(ret);
6209
6210 errno = 0;
6211 l = strtol(s, &x, 8);
6212 if (errno != 0)
6213 return -errno;
6214
6215 if (!x || x == s || *x)
6216 return -EINVAL;
6217 if (l < 0 || l > 07777)
6218 return -ERANGE;
6219
6220 *ret = (mode_t) l;
6221 return 0;
6222}
6458ec20
LP
6223
6224int mount_move_root(const char *path) {
6225 assert(path);
6226
6227 if (chdir(path) < 0)
6228 return -errno;
6229
6230 if (mount(path, "/", NULL, MS_MOVE, NULL) < 0)
6231 return -errno;
6232
6233 if (chroot(".") < 0)
6234 return -errno;
6235
6236 if (chdir("/") < 0)
6237 return -errno;
6238
6239 return 0;
6240}
b4da6d6b
LP
6241
6242int reset_uid_gid(void) {
6243
6244 if (setgroups(0, NULL) < 0)
6245 return -errno;
6246
6247 if (setresgid(0, 0, 0) < 0)
6248 return -errno;
6249
6250 if (setresuid(0, 0, 0) < 0)
6251 return -errno;
6252
6253 return 0;
6254}