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