]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/util.c
efivars: itialize variable
[thirdparty/systemd.git] / src / shared / util.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
60918275 2
a7334b09
LP
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
a7334b09
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
a7334b09 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
60918275
LP
22#include <string.h>
23#include <unistd.h>
24#include <errno.h>
85261803 25#include <stdlib.h>
034c6ed7 26#include <signal.h>
20f56fdd
DR
27#include <libintl.h>
28#include <locale.h>
034c6ed7 29#include <stdio.h>
1dccbe19
LP
30#include <syslog.h>
31#include <sched.h>
32#include <sys/resource.h>
ef886c6a 33#include <linux/sched.h>
a9f5d454
LP
34#include <sys/types.h>
35#include <sys/stat.h>
3a0ecb08 36#include <fcntl.h>
a0d40ac5 37#include <dirent.h>
601f6a1e
LP
38#include <sys/ioctl.h>
39#include <linux/vt.h>
40#include <linux/tiocl.h>
80876c20
LP
41#include <termios.h>
42#include <stdarg.h>
0a6f50c0 43#include <poll.h>
3177a7fa 44#include <ctype.h>
5b6319dc 45#include <sys/prctl.h>
ef2f1067
LP
46#include <sys/utsname.h>
47#include <pwd.h>
4fd5948e 48#include <netinet/ip.h>
3fe5e5d4 49#include <linux/kd.h>
2e78aa99 50#include <sys/wait.h>
7948c4df 51#include <sys/time.h>
8092a428 52#include <glob.h>
4b67834e 53#include <grp.h>
87d2c1ff 54#include <sys/mman.h>
825c6fe5 55#include <sys/vfs.h>
6d313367 56#include <sys/mount.h>
825c6fe5 57#include <linux/magic.h>
0b507b17 58#include <limits.h>
09017585
MS
59#include <langinfo.h>
60#include <locale.h>
6afc95b7 61#include <sys/personality.h>
4a4d89b6 62#include <sys/xattr.h>
abe4aa14 63#include <sys/statvfs.h>
30535c16 64#include <sys/file.h>
11689d2a 65#include <linux/fs.h>
eef46c37
LP
66
67/* When we include libgen.h because we need dirname() we immediately
68 * undefine basename() since libgen.h defines it as a macro to the XDG
69 * version which is really broken. */
70#include <libgen.h>
2b6bf07d 71#undef basename
60918275 72
9bf3b535
LP
73#ifdef HAVE_SYS_AUXV_H
74#include <sys/auxv.h>
75#endif
76
20f56fdd 77#include "config.h"
60918275
LP
78#include "macro.h"
79#include "util.h"
1dccbe19
LP
80#include "ioprio.h"
81#include "missing.h"
a9f5d454 82#include "log.h"
65d2ebdc 83#include "strv.h"
c38dfac9 84#include "mkdir.h"
9eb977db 85#include "path-util.h"
d06dacd0 86#include "exit-status.h"
83cc030f 87#include "hashmap.h"
4d1a6904 88#include "env-util.h"
a5c32cff 89#include "fileio.h"
8f6ce71f 90#include "device-nodes.h"
f405e86d
SL
91#include "utf8.h"
92#include "gunicode.h"
295edddf 93#include "virt.h"
477def80 94#include "def.h"
4a4d89b6 95#include "sparse-endian.h"
56cf987f 96
9a0e6896
LP
97int saved_argc = 0;
98char **saved_argv = NULL;
9086e840 99
28917d7d 100static volatile unsigned cached_columns = 0;
ed757c0c 101static volatile unsigned cached_lines = 0;
9a0e6896 102
37f85e66 103size_t page_size(void) {
ec202eae 104 static thread_local size_t pgsz = 0;
37f85e66 105 long r;
106
87d2c1ff 107 if (_likely_(pgsz > 0))
37f85e66 108 return pgsz;
109
e67f47e5
LP
110 r = sysconf(_SC_PAGESIZE);
111 assert(r > 0);
37f85e66 112
113 pgsz = (size_t) r;
37f85e66 114 return pgsz;
115}
116
e05797fb
LP
117bool streq_ptr(const char *a, const char *b) {
118
119 /* Like streq(), but tries to make sense of NULL pointers */
120
121 if (a && b)
122 return streq(a, b);
123
124 if (!a && !b)
125 return true;
126
127 return false;
128}
129
8c7c140f 130char* endswith(const char *s, const char *postfix) {
60918275
LP
131 size_t sl, pl;
132
133 assert(s);
134 assert(postfix);
135
136 sl = strlen(s);
137 pl = strlen(postfix);
138
d4d0d4db 139 if (pl == 0)
8c7c140f 140 return (char*) s + sl;
d4d0d4db 141
60918275 142 if (sl < pl)
8c7c140f
LP
143 return NULL;
144
145 if (memcmp(s + sl - pl, postfix, pl) != 0)
146 return NULL;
60918275 147
8c7c140f 148 return (char*) s + sl - pl;
60918275
LP
149}
150
5cb36f41 151char* first_word(const char *s, const char *word) {
79d6d816 152 size_t sl, wl;
5cb36f41 153 const char *p;
79d6d816
LP
154
155 assert(s);
156 assert(word);
157
5cb36f41
LP
158 /* Checks if the string starts with the specified word, either
159 * followed by NUL or by whitespace. Returns a pointer to the
160 * NUL or the first character after the whitespace. */
161
79d6d816
LP
162 sl = strlen(s);
163 wl = strlen(word);
164
165 if (sl < wl)
5cb36f41 166 return NULL;
79d6d816 167
d4d0d4db 168 if (wl == 0)
5cb36f41 169 return (char*) s;
d4d0d4db 170
79d6d816 171 if (memcmp(s, word, wl) != 0)
5cb36f41
LP
172 return NULL;
173
174 p = s + wl;
175 if (*p == 0)
176 return (char*) p;
177
178 if (!strchr(WHITESPACE, *p))
179 return NULL;
79d6d816 180
5cb36f41
LP
181 p += strspn(p, WHITESPACE);
182 return (char*) p;
79d6d816
LP
183}
184
c593bb36
JF
185static size_t cescape_char(char c, char *buf) {
186 char * buf_old = buf;
187
188 switch (c) {
189
190 case '\a':
191 *(buf++) = '\\';
192 *(buf++) = 'a';
193 break;
194 case '\b':
195 *(buf++) = '\\';
196 *(buf++) = 'b';
197 break;
198 case '\f':
199 *(buf++) = '\\';
200 *(buf++) = 'f';
201 break;
202 case '\n':
203 *(buf++) = '\\';
204 *(buf++) = 'n';
205 break;
206 case '\r':
207 *(buf++) = '\\';
208 *(buf++) = 'r';
209 break;
210 case '\t':
211 *(buf++) = '\\';
212 *(buf++) = 't';
213 break;
214 case '\v':
215 *(buf++) = '\\';
216 *(buf++) = 'v';
217 break;
218 case '\\':
219 *(buf++) = '\\';
220 *(buf++) = '\\';
221 break;
222 case '"':
223 *(buf++) = '\\';
224 *(buf++) = '"';
225 break;
226 case '\'':
227 *(buf++) = '\\';
228 *(buf++) = '\'';
229 break;
230
231 default:
232 /* For special chars we prefer octal over
233 * hexadecimal encoding, simply because glib's
234 * g_strescape() does the same */
235 if ((c < ' ') || (c >= 127)) {
236 *(buf++) = '\\';
237 *(buf++) = octchar((unsigned char) c >> 6);
238 *(buf++) = octchar((unsigned char) c >> 3);
239 *(buf++) = octchar((unsigned char) c);
240 } else
241 *(buf++) = c;
242 break;
243 }
244
245 return buf - buf_old;
246}
247
42f4e3c4 248int close_nointr(int fd) {
b0ee8068 249 assert(fd >= 0);
a9f85faf
LP
250
251 if (close(fd) >= 0)
252 return 0;
253
254 /*
255 * Just ignore EINTR; a retry loop is the wrong thing to do on
256 * Linux.
257 *
258 * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
259 * https://bugzilla.gnome.org/show_bug.cgi?id=682819
260 * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
261 * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
262 */
263 if (errno == EINTR)
d96ea504 264 return 0;
a9f85faf
LP
265
266 return -errno;
60918275 267}
85261803 268
03e334a1
LP
269int safe_close(int fd) {
270
271 /*
272 * Like close_nointr() but cannot fail. Guarantees errno is
273 * unchanged. Is a NOP with negative fds passed, and returns
274 * -1, so that it can be used in this syntax:
275 *
276 * fd = safe_close(fd);
277 */
85f136b5 278
03e334a1
LP
279 if (fd >= 0) {
280 PROTECT_ERRNO;
d96ea504
LP
281
282 /* The kernel might return pretty much any error code
283 * via close(), but the fd will be closed anyway. The
284 * only condition we want to check for here is whether
285 * the fd was invalid at all... */
286
287 assert_se(close_nointr(fd) != -EBADF);
03e334a1 288 }
85f136b5 289
03e334a1 290 return -1;
85f136b5
LP
291}
292
5b6319dc
LP
293void close_many(const int fds[], unsigned n_fd) {
294 unsigned i;
295
2c93b4ef
LP
296 assert(fds || n_fd <= 0);
297
5b6319dc 298 for (i = 0; i < n_fd; i++)
03e334a1 299 safe_close(fds[i]);
5b6319dc
LP
300}
301
4b73a0c0
LP
302int unlink_noerrno(const char *path) {
303 PROTECT_ERRNO;
304 int r;
305
306 r = unlink(path);
307 if (r < 0)
308 return -errno;
309
310 return 0;
311}
312
85261803
LP
313int parse_boolean(const char *v) {
314 assert(v);
315
0f625d0b 316 if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on"))
85261803 317 return 1;
0f625d0b 318 else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off"))
85261803
LP
319 return 0;
320
321 return -EINVAL;
322}
323
3ba686c1 324int parse_pid(const char *s, pid_t* ret_pid) {
0b172489 325 unsigned long ul = 0;
3ba686c1
LP
326 pid_t pid;
327 int r;
328
329 assert(s);
330 assert(ret_pid);
331
e67f47e5
LP
332 r = safe_atolu(s, &ul);
333 if (r < 0)
3ba686c1
LP
334 return r;
335
336 pid = (pid_t) ul;
337
338 if ((unsigned long) pid != ul)
339 return -ERANGE;
340
341 if (pid <= 0)
342 return -ERANGE;
343
344 *ret_pid = pid;
345 return 0;
346}
347
034a2a52
LP
348int parse_uid(const char *s, uid_t* ret_uid) {
349 unsigned long ul = 0;
350 uid_t uid;
351 int r;
352
353 assert(s);
354 assert(ret_uid);
355
e67f47e5
LP
356 r = safe_atolu(s, &ul);
357 if (r < 0)
034a2a52
LP
358 return r;
359
360 uid = (uid_t) ul;
361
362 if ((unsigned long) uid != ul)
363 return -ERANGE;
364
fed1e721 365 /* Some libc APIs use UID_INVALID as special placeholder */
306a55c8 366 if (uid == (uid_t) 0xFFFFFFFF)
f841a154 367 return -ENXIO;
306a55c8 368
6afeb1cf 369 /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
306a55c8 370 if (uid == (uid_t) 0xFFFF)
f841a154 371 return -ENXIO;
306a55c8 372
034a2a52
LP
373 *ret_uid = uid;
374 return 0;
375}
376
85261803
LP
377int safe_atou(const char *s, unsigned *ret_u) {
378 char *x = NULL;
034c6ed7 379 unsigned long l;
85261803
LP
380
381 assert(s);
382 assert(ret_u);
383
384 errno = 0;
385 l = strtoul(s, &x, 0);
386
f3910003 387 if (!x || x == s || *x || errno)
48deb058 388 return errno > 0 ? -errno : -EINVAL;
85261803 389
034c6ed7 390 if ((unsigned long) (unsigned) l != l)
85261803
LP
391 return -ERANGE;
392
393 *ret_u = (unsigned) l;
394 return 0;
395}
396
397int safe_atoi(const char *s, int *ret_i) {
398 char *x = NULL;
034c6ed7 399 long l;
85261803
LP
400
401 assert(s);
402 assert(ret_i);
403
404 errno = 0;
405 l = strtol(s, &x, 0);
406
f3910003 407 if (!x || x == s || *x || errno)
48deb058 408 return errno > 0 ? -errno : -EINVAL;
85261803 409
034c6ed7 410 if ((long) (int) l != l)
85261803
LP
411 return -ERANGE;
412
034c6ed7
LP
413 *ret_i = (int) l;
414 return 0;
415}
416
b914e211
LP
417int safe_atou8(const char *s, uint8_t *ret) {
418 char *x = NULL;
419 unsigned long l;
420
421 assert(s);
422 assert(ret);
423
424 errno = 0;
425 l = strtoul(s, &x, 0);
426
427 if (!x || x == s || *x || errno)
428 return errno > 0 ? -errno : -EINVAL;
429
430 if ((unsigned long) (uint8_t) l != l)
431 return -ERANGE;
432
433 *ret = (uint8_t) l;
434 return 0;
435}
436
781fa938
LP
437int safe_atou16(const char *s, uint16_t *ret) {
438 char *x = NULL;
439 unsigned long l;
440
441 assert(s);
442 assert(ret);
443
444 errno = 0;
445 l = strtoul(s, &x, 0);
446
447 if (!x || x == s || *x || errno)
448 return errno > 0 ? -errno : -EINVAL;
449
450 if ((unsigned long) (uint16_t) l != l)
451 return -ERANGE;
452
453 *ret = (uint16_t) l;
454 return 0;
455}
456
457int safe_atoi16(const char *s, int16_t *ret) {
458 char *x = NULL;
459 long l;
460
461 assert(s);
462 assert(ret);
463
464 errno = 0;
465 l = strtol(s, &x, 0);
466
467 if (!x || x == s || *x || errno)
468 return errno > 0 ? -errno : -EINVAL;
469
470 if ((long) (int16_t) l != l)
471 return -ERANGE;
472
473 *ret = (int16_t) l;
474 return 0;
475}
476
034c6ed7
LP
477int safe_atollu(const char *s, long long unsigned *ret_llu) {
478 char *x = NULL;
479 unsigned long long l;
480
481 assert(s);
482 assert(ret_llu);
483
484 errno = 0;
485 l = strtoull(s, &x, 0);
486
f3910003 487 if (!x || x == s || *x || errno)
034c6ed7
LP
488 return errno ? -errno : -EINVAL;
489
490 *ret_llu = l;
491 return 0;
492}
493
494int safe_atolli(const char *s, long long int *ret_lli) {
495 char *x = NULL;
496 long long l;
497
498 assert(s);
499 assert(ret_lli);
500
501 errno = 0;
502 l = strtoll(s, &x, 0);
503
f3910003 504 if (!x || x == s || *x || errno)
034c6ed7
LP
505 return errno ? -errno : -EINVAL;
506
507 *ret_lli = l;
85261803
LP
508 return 0;
509}
a41e8209 510
f7900e25
TA
511int safe_atod(const char *s, double *ret_d) {
512 char *x = NULL;
32b2634e 513 double d = 0;
0193ad26 514 locale_t loc;
f7900e25
TA
515
516 assert(s);
517 assert(ret_d);
518
0193ad26
CR
519 loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
520 if (loc == (locale_t) 0)
521 return -errno;
f7900e25 522
0193ad26
CR
523 errno = 0;
524 d = strtod_l(s, &x, loc);
525
526 if (!x || x == s || *x || errno) {
527 freelocale(loc);
f7900e25 528 return errno ? -errno : -EINVAL;
0193ad26 529 }
f7900e25 530
0193ad26 531 freelocale(loc);
f7900e25
TA
532 *ret_d = (double) d;
533 return 0;
534}
535
bf85c24d
SP
536static size_t strcspn_escaped(const char *s, const char *reject) {
537 bool escaped = false;
ba774317 538 int n;
bf85c24d
SP
539
540 for (n=0; s[n]; n++) {
541 if (escaped)
542 escaped = false;
543 else if (s[n] == '\\')
544 escaped = true;
545 else if (strchr(reject, s[n]))
a2a5291b 546 break;
bf85c24d 547 }
ba774317 548
a2a5291b
ZJS
549 /* if s ends in \, return index of previous char */
550 return n - escaped;
bf85c24d
SP
551}
552
a41e8209 553/* Split a string into words. */
a2a5291b
ZJS
554const char* split(const char **state, size_t *l, const char *separator, bool quoted) {
555 const char *current;
a41e8209 556
a2a5291b 557 current = *state;
a41e8209 558
a2a5291b
ZJS
559 if (!*current) {
560 assert(**state == '\0');
a41e8209 561 return NULL;
a2a5291b 562 }
a41e8209 563
65d2ebdc 564 current += strspn(current, separator);
a2a5291b
ZJS
565 if (!*current) {
566 *state = current;
70f75a52 567 return NULL;
a2a5291b 568 }
70f75a52 569
bf85c24d 570 if (quoted && strchr("\'\"", *current)) {
a2a5291b
ZJS
571 char quotechars[2] = {*current, '\0'};
572
573 *l = strcspn_escaped(current + 1, quotechars);
574 if (current[*l + 1] == '\0' ||
575 (current[*l + 2] && !strchr(separator, current[*l + 2]))) {
cc13b327 576 /* right quote missing or garbage at the end */
a2a5291b
ZJS
577 *state = current;
578 return NULL;
579 }
580 assert(current[*l + 1] == quotechars[0]);
581 *state = current++ + *l + 2;
bf85c24d
SP
582 } else if (quoted) {
583 *l = strcspn_escaped(current, separator);
ba774317
ZJS
584 if (current[*l] && !strchr(separator, current[*l])) {
585 /* unfinished escape */
586 *state = current;
587 return NULL;
588 }
a2a5291b 589 *state = current + *l;
034c6ed7 590 } else {
bf85c24d 591 *l = strcspn(current, separator);
a2a5291b 592 *state = current + *l;
034c6ed7
LP
593 }
594
a2a5291b 595 return current;
034c6ed7
LP
596}
597
034c6ed7
LP
598int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
599 int r;
b4696bce 600 _cleanup_free_ char *line = NULL;
bb00e604 601 long unsigned ppid;
49aa47c7 602 const char *p;
034c6ed7 603
49aa47c7 604 assert(pid >= 0);
034c6ed7
LP
605 assert(_ppid);
606
49aa47c7
LP
607 if (pid == 0) {
608 *_ppid = getppid();
609 return 0;
610 }
034c6ed7 611
49aa47c7 612 p = procfs_file_alloca(pid, "stat");
b4696bce
SP
613 r = read_one_line_file(p, &line);
614 if (r < 0)
034c6ed7 615 return r;
034c6ed7 616
034c6ed7
LP
617 /* Let's skip the pid and comm fields. The latter is enclosed
618 * in () but does not escape any () in its value, so let's
619 * skip over it manually */
620
2fbe635a
LP
621 p = strrchr(line, ')');
622 if (!p)
034c6ed7
LP
623 return -EIO;
624
625 p++;
626
627 if (sscanf(p, " "
628 "%*c " /* state */
bb00e604 629 "%lu ", /* ppid */
034c6ed7
LP
630 &ppid) != 1)
631 return -EIO;
632
bb00e604 633 if ((long unsigned) (pid_t) ppid != ppid)
034c6ed7
LP
634 return -ERANGE;
635
636 *_ppid = (pid_t) ppid;
637
638 return 0;
639}
640
34ca941c
LP
641int fchmod_umask(int fd, mode_t m) {
642 mode_t u;
643 int r;
644
645 u = umask(0777);
646 r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
647 umask(u);
648
649 return r;
650}
651
7072ced8
LP
652char *truncate_nl(char *s) {
653 assert(s);
654
655 s[strcspn(s, NEWLINE)] = 0;
656 return s;
657}
658
93b5eaec 659int get_process_state(pid_t pid) {
e10c9985
YS
660 const char *p;
661 char state;
662 int r;
663 _cleanup_free_ char *line = NULL;
664
665 assert(pid >= 0);
666
667 p = procfs_file_alloca(pid, "stat");
668 r = read_one_line_file(p, &line);
669 if (r < 0)
670 return r;
671
672 p = strrchr(line, ')');
673 if (!p)
674 return -EIO;
675
676 p++;
677
678 if (sscanf(p, " %c", &state) != 1)
679 return -EIO;
680
681 return (unsigned char) state;
682}
683
87d2c1ff 684int get_process_comm(pid_t pid, char **name) {
49aa47c7 685 const char *p;
5b12334d 686 int r;
7072ced8 687
7072ced8 688 assert(name);
49aa47c7 689 assert(pid >= 0);
7072ced8 690
b68fa010 691 p = procfs_file_alloca(pid, "comm");
7072ced8 692
5b12334d
LP
693 r = read_one_line_file(p, name);
694 if (r == -ENOENT)
695 return -ESRCH;
696
697 return r;
7072ced8
LP
698}
699
87d2c1ff 700int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
49aa47c7 701 _cleanup_fclose_ FILE *f = NULL;
9bdbc2e2 702 char *r = NULL, *k;
49aa47c7 703 const char *p;
c59760ee 704 int c;
c59760ee 705
c59760ee 706 assert(line);
49aa47c7 707 assert(pid >= 0);
c59760ee 708
b68fa010 709 p = procfs_file_alloca(pid, "cmdline");
c59760ee 710
49aa47c7 711 f = fopen(p, "re");
c59760ee
LP
712 if (!f)
713 return -errno;
49aa47c7 714
9bdbc2e2 715 if (max_length == 0) {
49aa47c7
LP
716 size_t len = 0, allocated = 0;
717
9bdbc2e2 718 while ((c = getc(f)) != EOF) {
49aa47c7
LP
719
720 if (!GREEDY_REALLOC(r, allocated, len+2)) {
9bdbc2e2 721 free(r);
9bdbc2e2
LN
722 return -ENOMEM;
723 }
49aa47c7
LP
724
725 r[len++] = isprint(c) ? c : ' ';
9bdbc2e2 726 }
49aa47c7
LP
727
728 if (len > 0)
729 r[len-1] = 0;
730
9bdbc2e2
LN
731 } else {
732 bool space = false;
733 size_t left;
49aa47c7 734
9bdbc2e2 735 r = new(char, max_length);
49aa47c7 736 if (!r)
9bdbc2e2 737 return -ENOMEM;
c59760ee 738
9bdbc2e2
LN
739 k = r;
740 left = max_length;
741 while ((c = getc(f)) != EOF) {
c59760ee 742
9bdbc2e2
LN
743 if (isprint(c)) {
744 if (space) {
745 if (left <= 4)
746 break;
747
748 *(k++) = ' ';
749 left--;
750 space = false;
751 }
c59760ee 752
c59760ee
LP
753 if (left <= 4)
754 break;
755
9bdbc2e2 756 *(k++) = (char) c;
057fbb58 757 left--;
9bdbc2e2
LN
758 } else
759 space = true;
760 }
c59760ee 761
9bdbc2e2
LN
762 if (left <= 4) {
763 size_t n = MIN(left-1, 3U);
764 memcpy(k, "...", n);
765 k[n] = 0;
766 } else
767 *k = 0;
c59760ee
LP
768 }
769
35d2e7ec 770 /* Kernel threads have no argv[] */
0c2576ef 771 if (isempty(r)) {
b47d419c 772 _cleanup_free_ char *t = NULL;
35d2e7ec
LP
773 int h;
774
775 free(r);
776
87d2c1ff
LP
777 if (!comm_fallback)
778 return -ENOENT;
779
780 h = get_process_comm(pid, &t);
781 if (h < 0)
35d2e7ec
LP
782 return h;
783
b7def684 784 r = strjoin("[", t, "]", NULL);
87d2c1ff 785 if (!r)
35d2e7ec
LP
786 return -ENOMEM;
787 }
fa776d8e 788
c59760ee
LP
789 *line = r;
790 return 0;
791}
792
1e5678d0 793int is_kernel_thread(pid_t pid) {
49aa47c7 794 const char *p;
1e5678d0
LP
795 size_t count;
796 char c;
797 bool eof;
798 FILE *f;
799
800 if (pid == 0)
801 return 0;
802
49aa47c7 803 assert(pid > 0);
1e5678d0 804
49aa47c7
LP
805 p = procfs_file_alloca(pid, "cmdline");
806 f = fopen(p, "re");
1e5678d0
LP
807 if (!f)
808 return -errno;
809
810 count = fread(&c, 1, 1, f);
811 eof = feof(f);
812 fclose(f);
813
814 /* Kernel threads have an empty cmdline */
815
816 if (count <= 0)
817 return eof ? 1 : -errno;
818
819 return 0;
820}
821
3a832116
SL
822int get_process_capeff(pid_t pid, char **capeff) {
823 const char *p;
3a832116
SL
824
825 assert(capeff);
826 assert(pid >= 0);
827
b68fa010 828 p = procfs_file_alloca(pid, "status");
3a832116 829
69ab8088 830 return get_status_field(p, "\nCapEff:", capeff);
3a832116 831}
49aa47c7 832
ad450c3e
JF
833static int get_process_link_contents(const char *proc_file, char **name) {
834 int r;
835
836 assert(proc_file);
837 assert(name);
838
839 r = readlink_malloc(proc_file, name);
840 if (r < 0)
841 return r == -ENOENT ? -ESRCH : r;
842
843 return 0;
844}
845
87d2c1ff 846int get_process_exe(pid_t pid, char **name) {
49aa47c7 847 const char *p;
e79f68d1
ZJS
848 char *d;
849 int r;
87d2c1ff 850
49aa47c7 851 assert(pid >= 0);
87d2c1ff 852
b68fa010 853 p = procfs_file_alloca(pid, "exe");
ad450c3e 854 r = get_process_link_contents(p, name);
e79f68d1 855 if (r < 0)
ad450c3e 856 return r;
e79f68d1
ZJS
857
858 d = endswith(*name, " (deleted)");
859 if (d)
860 *d = '\0';
861
862 return 0;
87d2c1ff
LP
863}
864
901c3d0d 865static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
f74e605f 866 _cleanup_fclose_ FILE *f = NULL;
9db11a99 867 char line[LINE_MAX];
49aa47c7 868 const char *p;
7e4ab3c5 869
f74e605f 870 assert(field);
7e4ab3c5
LP
871 assert(uid);
872
873 if (pid == 0)
874 return getuid();
875
49aa47c7
LP
876 p = procfs_file_alloca(pid, "status");
877 f = fopen(p, "re");
7e4ab3c5
LP
878 if (!f)
879 return -errno;
880
9db11a99 881 FOREACH_LINE(line, f, return -errno) {
f74e605f 882 char *l;
7e4ab3c5
LP
883
884 l = strstrip(line);
885
901c3d0d
LP
886 if (startswith(l, field)) {
887 l += strlen(field);
7e4ab3c5
LP
888 l += strspn(l, WHITESPACE);
889
890 l[strcspn(l, WHITESPACE)] = 0;
891
f74e605f 892 return parse_uid(l, uid);
7e4ab3c5
LP
893 }
894 }
895
f74e605f 896 return -EIO;
7e4ab3c5
LP
897}
898
901c3d0d
LP
899int get_process_uid(pid_t pid, uid_t *uid) {
900 return get_process_id(pid, "Uid:", uid);
901}
902
903int get_process_gid(pid_t pid, gid_t *gid) {
49aa47c7 904 assert_cc(sizeof(uid_t) == sizeof(gid_t));
901c3d0d
LP
905 return get_process_id(pid, "Gid:", gid);
906}
907
ad450c3e
JF
908int get_process_cwd(pid_t pid, char **cwd) {
909 const char *p;
910
911 assert(pid >= 0);
912
913 p = procfs_file_alloca(pid, "cwd");
914
915 return get_process_link_contents(p, cwd);
916}
917
918int get_process_root(pid_t pid, char **root) {
919 const char *p;
920
921 assert(pid >= 0);
922
923 p = procfs_file_alloca(pid, "root");
924
925 return get_process_link_contents(p, root);
926}
927
e706d931 928int get_process_environ(pid_t pid, char **env) {
c593bb36
JF
929 _cleanup_fclose_ FILE *f = NULL;
930 _cleanup_free_ char *outcome = NULL;
931 int c;
932 const char *p;
933 size_t allocated = 0, sz = 0;
934
935 assert(pid >= 0);
e706d931 936 assert(env);
c593bb36
JF
937
938 p = procfs_file_alloca(pid, "environ");
939
940 f = fopen(p, "re");
941 if (!f)
942 return -errno;
943
944 while ((c = fgetc(f)) != EOF) {
945 if (!GREEDY_REALLOC(outcome, allocated, sz + 5))
946 return -ENOMEM;
947
948 if (c == '\0')
949 outcome[sz++] = '\n';
950 else
951 sz += cescape_char(c, outcome + sz);
952 }
953
954 outcome[sz] = '\0';
e706d931 955 *env = outcome;
c593bb36
JF
956 outcome = NULL;
957
958 return 0;
959}
960
fab56fc5
LP
961char *strnappend(const char *s, const char *suffix, size_t b) {
962 size_t a;
44d8db9e
LP
963 char *r;
964
fab56fc5
LP
965 if (!s && !suffix)
966 return strdup("");
967
968 if (!s)
969 return strndup(suffix, b);
970
971 if (!suffix)
972 return strdup(s);
973
44d8db9e
LP
974 assert(s);
975 assert(suffix);
976
977 a = strlen(s);
aa408e77 978 if (b > ((size_t) -1) - a)
040f18ea 979 return NULL;
44d8db9e 980
040f18ea
LP
981 r = new(char, a+b+1);
982 if (!r)
44d8db9e
LP
983 return NULL;
984
985 memcpy(r, s, a);
986 memcpy(r+a, suffix, b);
987 r[a+b] = 0;
988
989 return r;
990}
87f0e418 991
fab56fc5
LP
992char *strappend(const char *s, const char *suffix) {
993 return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
994}
995
849958d1 996int readlinkat_malloc(int fd, const char *p, char **ret) {
87f0e418 997 size_t l = 100;
2d2ebd6b 998 int r;
87f0e418
LP
999
1000 assert(p);
2d2ebd6b 1001 assert(ret);
87f0e418
LP
1002
1003 for (;;) {
1004 char *c;
1005 ssize_t n;
1006
2d2ebd6b
LP
1007 c = new(char, l);
1008 if (!c)
87f0e418
LP
1009 return -ENOMEM;
1010
849958d1 1011 n = readlinkat(fd, p, c, l-1);
2d2ebd6b
LP
1012 if (n < 0) {
1013 r = -errno;
87f0e418 1014 free(c);
2d2ebd6b 1015 return r;
87f0e418
LP
1016 }
1017
1018 if ((size_t) n < l-1) {
1019 c[n] = 0;
2d2ebd6b 1020 *ret = c;
87f0e418
LP
1021 return 0;
1022 }
1023
1024 free(c);
1025 l *= 2;
1026 }
1027}
1028
849958d1
LP
1029int readlink_malloc(const char *p, char **ret) {
1030 return readlinkat_malloc(AT_FDCWD, p, ret);
1031}
1032
9a67bcf2
TG
1033int readlink_value(const char *p, char **ret) {
1034 _cleanup_free_ char *link = NULL;
1035 char *value;
1036 int r;
1037
1038 r = readlink_malloc(p, &link);
1039 if (r < 0)
1040 return r;
1041
1042 value = basename(link);
1043 if (!value)
1044 return -ENOENT;
1045
1046 value = strdup(value);
1047 if (!value)
1048 return -ENOMEM;
1049
1050 *ret = value;
1051
1052 return 0;
1053}
1054
2c7108c4 1055int readlink_and_make_absolute(const char *p, char **r) {
1058cbf2
ZJS
1056 _cleanup_free_ char *target = NULL;
1057 char *k;
2c7108c4
LP
1058 int j;
1059
1060 assert(p);
1061 assert(r);
1062
1058cbf2
ZJS
1063 j = readlink_malloc(p, &target);
1064 if (j < 0)
2c7108c4
LP
1065 return j;
1066
1067 k = file_in_same_dir(p, target);
2c7108c4
LP
1068 if (!k)
1069 return -ENOMEM;
1070
1071 *r = k;
1072 return 0;
1073}
1074
83096483
LP
1075int readlink_and_canonicalize(const char *p, char **r) {
1076 char *t, *s;
1077 int j;
1078
1079 assert(p);
1080 assert(r);
1081
1082 j = readlink_and_make_absolute(p, &t);
1083 if (j < 0)
1084 return j;
1085
1086 s = canonicalize_file_name(t);
1087 if (s) {
1088 free(t);
1089 *r = s;
1090 } else
1091 *r = t;
1092
1093 path_kill_slashes(*r);
1094
1095 return 0;
1096}
1097
2a987ee8 1098int reset_all_signal_handlers(void) {
24a5d6b0 1099 int sig, r = 0;
2a987ee8
LP
1100
1101 for (sig = 1; sig < _NSIG; sig++) {
b92bea5d
ZJS
1102 struct sigaction sa = {
1103 .sa_handler = SIG_DFL,
1104 .sa_flags = SA_RESTART,
1105 };
2a987ee8 1106
24a5d6b0 1107 /* These two cannot be caught... */
2a987ee8
LP
1108 if (sig == SIGKILL || sig == SIGSTOP)
1109 continue;
1110
2a987ee8
LP
1111 /* On Linux the first two RT signals are reserved by
1112 * glibc, and sigaction() will return EINVAL for them. */
1113 if ((sigaction(sig, &sa, NULL) < 0))
24a5d6b0
LP
1114 if (errno != EINVAL && r == 0)
1115 r = -errno;
2a987ee8
LP
1116 }
1117
24a5d6b0 1118 return r;
2a987ee8 1119}
4a72ff34 1120
1dedb74a
LP
1121int reset_signal_mask(void) {
1122 sigset_t ss;
1123
1124 if (sigemptyset(&ss) < 0)
1125 return -errno;
1126
1127 if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0)
1128 return -errno;
1129
1130 return 0;
1131}
1132
4a72ff34 1133char *strstrip(char *s) {
57a8eca8 1134 char *e;
4a72ff34
LP
1135
1136 /* Drops trailing whitespace. Modifies the string in
1137 * place. Returns pointer to first non-space character */
1138
1139 s += strspn(s, WHITESPACE);
1140
57a8eca8
LP
1141 for (e = strchr(s, 0); e > s; e --)
1142 if (!strchr(WHITESPACE, e[-1]))
1143 break;
4a72ff34 1144
57a8eca8 1145 *e = 0;
4a72ff34
LP
1146
1147 return s;
4a72ff34
LP
1148}
1149
ee9b5e01
LP
1150char *delete_chars(char *s, const char *bad) {
1151 char *f, *t;
1152
1153 /* Drops all whitespace, regardless where in the string */
1154
1155 for (f = s, t = s; *f; f++) {
1156 if (strchr(bad, *f))
1157 continue;
1158
1159 *(t++) = *f;
1160 }
1161
1162 *t = 0;
1163
1164 return s;
1165}
1166
4a72ff34 1167char *file_in_same_dir(const char *path, const char *filename) {
ebd93cb6 1168 char *e, *ret;
4a72ff34
LP
1169 size_t k;
1170
1171 assert(path);
1172 assert(filename);
1173
1174 /* This removes the last component of path and appends
1175 * filename, unless the latter is absolute anyway or the
1176 * former isn't */
1177
1178 if (path_is_absolute(filename))
1179 return strdup(filename);
1180
ebd93cb6
LP
1181 e = strrchr(path, '/');
1182 if (!e)
4a72ff34
LP
1183 return strdup(filename);
1184
1185 k = strlen(filename);
ebd93cb6
LP
1186 ret = new(char, (e + 1 - path) + k + 1);
1187 if (!ret)
4a72ff34
LP
1188 return NULL;
1189
ebd93cb6
LP
1190 memcpy(mempcpy(ret, path, e + 1 - path), filename, k + 1);
1191 return ret;
4a72ff34 1192}
fb624d04 1193
c32dd69b
LP
1194int rmdir_parents(const char *path, const char *stop) {
1195 size_t l;
1196 int r = 0;
1197
1198 assert(path);
1199 assert(stop);
1200
1201 l = strlen(path);
1202
1203 /* Skip trailing slashes */
1204 while (l > 0 && path[l-1] == '/')
1205 l--;
1206
1207 while (l > 0) {
1208 char *t;
1209
1210 /* Skip last component */
1211 while (l > 0 && path[l-1] != '/')
1212 l--;
1213
1214 /* Skip trailing slashes */
1215 while (l > 0 && path[l-1] == '/')
1216 l--;
1217
1218 if (l <= 0)
1219 break;
1220
1221 if (!(t = strndup(path, l)))
1222 return -ENOMEM;
1223
1224 if (path_startswith(stop, t)) {
1225 free(t);
1226 return 0;
1227 }
1228
1229 r = rmdir(t);
1230 free(t);
1231
1232 if (r < 0)
1233 if (errno != ENOENT)
1234 return -errno;
1235 }
1236
1237 return 0;
1238}
1239
fb624d04
LP
1240char hexchar(int x) {
1241 static const char table[16] = "0123456789abcdef";
1242
1243 return table[x & 15];
1244}
4fe88d28
LP
1245
1246int unhexchar(char c) {
1247
1248 if (c >= '0' && c <= '9')
1249 return c - '0';
1250
1251 if (c >= 'a' && c <= 'f')
ea430986 1252 return c - 'a' + 10;
4fe88d28
LP
1253
1254 if (c >= 'A' && c <= 'F')
ea430986 1255 return c - 'A' + 10;
4fe88d28 1256
7e8185ef 1257 return -EINVAL;
4fe88d28
LP
1258}
1259
66e35261
LP
1260char *hexmem(const void *p, size_t l) {
1261 char *r, *z;
1262 const uint8_t *x;
1263
1264 z = r = malloc(l * 2 + 1);
1265 if (!r)
1266 return NULL;
1267
1268 for (x = p; x < (const uint8_t*) p + l; x++) {
1269 *(z++) = hexchar(*x >> 4);
1270 *(z++) = hexchar(*x & 15);
1271 }
1272
1273 *z = 0;
1274 return r;
1275}
1276
2181a7f5
LP
1277void *unhexmem(const char *p, size_t l) {
1278 uint8_t *r, *z;
1279 const char *x;
1280
1281 assert(p);
1282
1283 z = r = malloc((l + 1) / 2 + 1);
1284 if (!r)
1285 return NULL;
1286
1287 for (x = p; x < p + l; x += 2) {
1288 int a, b;
1289
1290 a = unhexchar(x[0]);
1291 if (x+1 < p + l)
1292 b = unhexchar(x[1]);
1293 else
1294 b = 0;
1295
1296 *(z++) = (uint8_t) a << 4 | (uint8_t) b;
1297 }
1298
1299 *z = 0;
1300 return r;
1301}
1302
4fe88d28
LP
1303char octchar(int x) {
1304 return '0' + (x & 7);
1305}
1306
1307int unoctchar(char c) {
1308
1309 if (c >= '0' && c <= '7')
1310 return c - '0';
1311
7e8185ef 1312 return -EINVAL;
4fe88d28
LP
1313}
1314
5af98f82
LP
1315char decchar(int x) {
1316 return '0' + (x % 10);
1317}
1318
1319int undecchar(char c) {
1320
1321 if (c >= '0' && c <= '9')
1322 return c - '0';
1323
7e8185ef 1324 return -EINVAL;
5af98f82
LP
1325}
1326
4fe88d28
LP
1327char *cescape(const char *s) {
1328 char *r, *t;
1329 const char *f;
1330
1331 assert(s);
1332
1333 /* Does C style string escaping. */
1334
f8e2fb7b
LP
1335 r = new(char, strlen(s)*4 + 1);
1336 if (!r)
4fe88d28
LP
1337 return NULL;
1338
1339 for (f = s, t = r; *f; f++)
c593bb36 1340 t += cescape_char(*f, t);
4fe88d28
LP
1341
1342 *t = 0;
1343
1344 return r;
1345}
1346
5b4c61cd 1347char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix) {
4fe88d28
LP
1348 char *r, *t;
1349 const char *f;
5b4c61cd 1350 size_t pl;
4fe88d28
LP
1351
1352 assert(s);
1353
5b4c61cd
LP
1354 /* Undoes C style string escaping, and optionally prefixes it. */
1355
1356 pl = prefix ? strlen(prefix) : 0;
4fe88d28 1357
5b4c61cd 1358 r = new(char, pl+length+1);
7f110ff9 1359 if (!r)
1e2fd62d 1360 return NULL;
4fe88d28 1361
5b4c61cd
LP
1362 if (prefix)
1363 memcpy(r, prefix, pl);
1364
1365 for (f = s, t = r + pl; f < s + length; f++) {
7f769619
ZJS
1366 size_t remaining = s + length - f;
1367 assert(remaining > 0);
4fe88d28 1368
7f769619 1369 if (*f != '\\') { /* a literal literal */
4fe88d28
LP
1370 *(t++) = *f;
1371 continue;
1372 }
1373
7f769619
ZJS
1374 if (--remaining == 0) { /* copy trailing backslash verbatim */
1375 *(t++) = *f;
1376 break;
1377 }
1378
4fe88d28
LP
1379 f++;
1380
1381 switch (*f) {
1382
1383 case 'a':
1384 *(t++) = '\a';
1385 break;
1386 case 'b':
1387 *(t++) = '\b';
1388 break;
1389 case 'f':
1390 *(t++) = '\f';
1391 break;
1392 case 'n':
1393 *(t++) = '\n';
1394 break;
1395 case 'r':
1396 *(t++) = '\r';
1397 break;
1398 case 't':
1399 *(t++) = '\t';
1400 break;
1401 case 'v':
1402 *(t++) = '\v';
1403 break;
1404 case '\\':
1405 *(t++) = '\\';
1406 break;
1407 case '"':
1408 *(t++) = '"';
1409 break;
1410 case '\'':
1411 *(t++) = '\'';
1412 break;
1413
e167fb86
LP
1414 case 's':
1415 /* This is an extension of the XDG syntax files */
1416 *(t++) = ' ';
1417 break;
1418
4fe88d28
LP
1419 case 'x': {
1420 /* hexadecimal encoding */
7f769619 1421 int a = -1, b = -1;
4fe88d28 1422
7f769619
ZJS
1423 if (remaining >= 2) {
1424 a = unhexchar(f[1]);
1425 b = unhexchar(f[2]);
1426 }
7f110ff9 1427
e0a33e7b 1428 if (a < 0 || b < 0 || (a == 0 && b == 0)) {
4fe88d28
LP
1429 /* Invalid escape code, let's take it literal then */
1430 *(t++) = '\\';
1431 *(t++) = 'x';
1432 } else {
1433 *(t++) = (char) ((a << 4) | b);
1434 f += 2;
1435 }
1436
1437 break;
1438 }
1439
1440 case '0':
1441 case '1':
1442 case '2':
1443 case '3':
1444 case '4':
1445 case '5':
1446 case '6':
1447 case '7': {
1448 /* octal encoding */
7f769619 1449 int a = -1, b = -1, c = -1;
4fe88d28 1450
7f769619
ZJS
1451 if (remaining >= 3) {
1452 a = unoctchar(f[0]);
1453 b = unoctchar(f[1]);
1454 c = unoctchar(f[2]);
1455 }
7f110ff9 1456
e0a33e7b 1457 if (a < 0 || b < 0 || c < 0 || (a == 0 && b == 0 && c == 0)) {
4fe88d28
LP
1458 /* Invalid escape code, let's take it literal then */
1459 *(t++) = '\\';
1460 *(t++) = f[0];
1461 } else {
1462 *(t++) = (char) ((a << 6) | (b << 3) | c);
1463 f += 2;
1464 }
1465
1466 break;
1467 }
1468
4fe88d28
LP
1469 default:
1470 /* Invalid escape code, let's take it literal then */
1471 *(t++) = '\\';
f3d4cc01 1472 *(t++) = *f;
4fe88d28
LP
1473 break;
1474 }
1475 }
1476
4fe88d28
LP
1477 *t = 0;
1478 return r;
1479}
1480
5b4c61cd
LP
1481char *cunescape_length(const char *s, size_t length) {
1482 return cunescape_length_with_prefix(s, length, NULL);
1483}
1484
6febfd0d 1485char *cunescape(const char *s) {
5b4c61cd
LP
1486 assert(s);
1487
6febfd0d
LP
1488 return cunescape_length(s, strlen(s));
1489}
4fe88d28
LP
1490
1491char *xescape(const char *s, const char *bad) {
1492 char *r, *t;
1493 const char *f;
1494
1495 /* Escapes all chars in bad, in addition to \ and all special
1496 * chars, in \xFF style escaping. May be reversed with
1497 * cunescape. */
1498
08ace05b
LP
1499 r = new(char, strlen(s) * 4 + 1);
1500 if (!r)
4fe88d28
LP
1501 return NULL;
1502
1503 for (f = s, t = r; *f; f++) {
1504
b866264a
LP
1505 if ((*f < ' ') || (*f >= 127) ||
1506 (*f == '\\') || strchr(bad, *f)) {
4fe88d28
LP
1507 *(t++) = '\\';
1508 *(t++) = 'x';
1509 *(t++) = hexchar(*f >> 4);
1510 *(t++) = hexchar(*f);
1511 } else
1512 *(t++) = *f;
1513 }
1514
1515 *t = 0;
1516
1517 return r;
1518}
1519
67d51650 1520char *ascii_strlower(char *t) {
4fe88d28
LP
1521 char *p;
1522
67d51650 1523 assert(t);
4fe88d28 1524
67d51650 1525 for (p = t; *p; p++)
4fe88d28
LP
1526 if (*p >= 'A' && *p <= 'Z')
1527 *p = *p - 'A' + 'a';
1528
67d51650 1529 return t;
4fe88d28 1530}
1dccbe19 1531
a34bf9db 1532_pure_ static bool hidden_file_allow_backup(const char *filename) {
c85dc17b
LP
1533 assert(filename);
1534
1535 return
1536 filename[0] == '.' ||
6c78be3c 1537 streq(filename, "lost+found") ||
e472d476
LP
1538 streq(filename, "aquota.user") ||
1539 streq(filename, "aquota.group") ||
c85dc17b
LP
1540 endswith(filename, ".rpmnew") ||
1541 endswith(filename, ".rpmsave") ||
1542 endswith(filename, ".rpmorig") ||
1543 endswith(filename, ".dpkg-old") ||
1544 endswith(filename, ".dpkg-new") ||
0cdfd26e 1545 endswith(filename, ".dpkg-tmp") ||
c7088e49
MP
1546 endswith(filename, ".dpkg-dist") ||
1547 endswith(filename, ".dpkg-bak") ||
1548 endswith(filename, ".dpkg-backup") ||
1549 endswith(filename, ".dpkg-remove") ||
c85dc17b
LP
1550 endswith(filename, ".swp");
1551}
1552
a34bf9db 1553bool hidden_file(const char *filename) {
a228a22f
LP
1554 assert(filename);
1555
1556 if (endswith(filename, "~"))
93f1a063 1557 return true;
a228a22f 1558
a34bf9db 1559 return hidden_file_allow_backup(filename);
a228a22f
LP
1560}
1561
3a0ecb08 1562int fd_nonblock(int fd, bool nonblock) {
be8f4e9e 1563 int flags, nflags;
3a0ecb08
LP
1564
1565 assert(fd >= 0);
1566
be8f4e9e
LP
1567 flags = fcntl(fd, F_GETFL, 0);
1568 if (flags < 0)
3a0ecb08
LP
1569 return -errno;
1570
1571 if (nonblock)
be8f4e9e 1572 nflags = flags | O_NONBLOCK;
3a0ecb08 1573 else
be8f4e9e
LP
1574 nflags = flags & ~O_NONBLOCK;
1575
1576 if (nflags == flags)
1577 return 0;
3a0ecb08 1578
34b42c96 1579 if (fcntl(fd, F_SETFL, nflags) < 0)
3a0ecb08
LP
1580 return -errno;
1581
1582 return 0;
1583}
1584
1585int fd_cloexec(int fd, bool cloexec) {
be8f4e9e 1586 int flags, nflags;
3a0ecb08
LP
1587
1588 assert(fd >= 0);
1589
be8f4e9e
LP
1590 flags = fcntl(fd, F_GETFD, 0);
1591 if (flags < 0)
3a0ecb08
LP
1592 return -errno;
1593
1594 if (cloexec)
be8f4e9e 1595 nflags = flags | FD_CLOEXEC;
3a0ecb08 1596 else
be8f4e9e
LP
1597 nflags = flags & ~FD_CLOEXEC;
1598
1599 if (nflags == flags)
1600 return 0;
3a0ecb08 1601
34b42c96 1602 if (fcntl(fd, F_SETFD, nflags) < 0)
3a0ecb08
LP
1603 return -errno;
1604
1605 return 0;
1606}
1607
44a6b1b6 1608_pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
b19be9eb
LP
1609 unsigned i;
1610
1611 assert(n_fdset == 0 || fdset);
1612
1613 for (i = 0; i < n_fdset; i++)
1614 if (fdset[i] == fd)
1615 return true;
1616
1617 return false;
1618}
1619
a0d40ac5 1620int close_all_fds(const int except[], unsigned n_except) {
e1d75803 1621 _cleanup_closedir_ DIR *d = NULL;
a0d40ac5
LP
1622 struct dirent *de;
1623 int r = 0;
1624
b19be9eb
LP
1625 assert(n_except == 0 || except);
1626
1627 d = opendir("/proc/self/fd");
1628 if (!d) {
1629 int fd;
1630 struct rlimit rl;
1631
1632 /* When /proc isn't available (for example in chroots)
1633 * the fallback is brute forcing through the fd
1634 * table */
1635
1636 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
1637 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
1638
1639 if (fd_in_set(fd, except, n_except))
1640 continue;
1641
1642 if (close_nointr(fd) < 0)
1643 if (errno != EBADF && r == 0)
1644 r = -errno;
1645 }
1646
1647 return r;
1648 }
a0d40ac5
LP
1649
1650 while ((de = readdir(d))) {
a7610064 1651 int fd = -1;
a0d40ac5 1652
a34bf9db 1653 if (hidden_file(de->d_name))
a0d40ac5
LP
1654 continue;
1655
720ce21d
LP
1656 if (safe_atoi(de->d_name, &fd) < 0)
1657 /* Let's better ignore this, just in case */
1658 continue;
a0d40ac5
LP
1659
1660 if (fd < 3)
1661 continue;
1662
1663 if (fd == dirfd(d))
1664 continue;
1665
b19be9eb
LP
1666 if (fd_in_set(fd, except, n_except))
1667 continue;
a0d40ac5 1668
720ce21d 1669 if (close_nointr(fd) < 0) {
2f357920 1670 /* Valgrind has its own FD and doesn't want to have it closed */
720ce21d
LP
1671 if (errno != EBADF && r == 0)
1672 r = -errno;
2f357920 1673 }
a0d40ac5
LP
1674 }
1675
a0d40ac5
LP
1676 return r;
1677}
1678
db12775d
LP
1679bool chars_intersect(const char *a, const char *b) {
1680 const char *p;
1681
1682 /* Returns true if any of the chars in a are in b. */
1683 for (p = a; *p; p++)
1684 if (strchr(b, *p))
1685 return true;
1686
1687 return false;
1688}
1689
42856c10 1690bool fstype_is_network(const char *fstype) {
a05f97b3 1691 static const char table[] =
ba89821c 1692 "afs\0"
a05f97b3
LP
1693 "cifs\0"
1694 "smbfs\0"
da92ca5e 1695 "sshfs\0"
a05f97b3 1696 "ncpfs\0"
dac70dc7 1697 "ncp\0"
a05f97b3
LP
1698 "nfs\0"
1699 "nfs4\0"
1700 "gfs\0"
67608cad
LP
1701 "gfs2\0"
1702 "glusterfs\0";
1703
1704 const char *x;
1705
1706 x = startswith(fstype, "fuse.");
1707 if (x)
1708 fstype = x;
42856c10 1709
a05f97b3 1710 return nulstr_contains(table, fstype);
42856c10
LP
1711}
1712
601f6a1e 1713int chvt(int vt) {
a05f97b3 1714 _cleanup_close_ int fd;
601f6a1e 1715
a05f97b3
LP
1716 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
1717 if (fd < 0)
601f6a1e
LP
1718 return -errno;
1719
1720 if (vt < 0) {
1721 int tiocl[2] = {
1722 TIOCL_GETKMSGREDIRECT,
1723 0
1724 };
1725
a05f97b3
LP
1726 if (ioctl(fd, TIOCLINUX, tiocl) < 0)
1727 return -errno;
601f6a1e
LP
1728
1729 vt = tiocl[0] <= 0 ? 1 : tiocl[0];
1730 }
1731
1732 if (ioctl(fd, VT_ACTIVATE, vt) < 0)
a05f97b3 1733 return -errno;
601f6a1e 1734
a05f97b3 1735 return 0;
601f6a1e
LP
1736}
1737
8f2d43a0 1738int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
80876c20 1739 struct termios old_termios, new_termios;
e0a33e7b 1740 char c, line[LINE_MAX];
80876c20
LP
1741
1742 assert(f);
1743 assert(ret);
1744
1745 if (tcgetattr(fileno(f), &old_termios) >= 0) {
1746 new_termios = old_termios;
1747
1748 new_termios.c_lflag &= ~ICANON;
1749 new_termios.c_cc[VMIN] = 1;
1750 new_termios.c_cc[VTIME] = 0;
1751
1752 if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
1753 size_t k;
1754
3a43da28 1755 if (t != USEC_INFINITY) {
8f2d43a0
LP
1756 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) {
1757 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
1758 return -ETIMEDOUT;
1759 }
1760 }
1761
80876c20
LP
1762 k = fread(&c, 1, 1, f);
1763
1764 tcsetattr(fileno(f), TCSADRAIN, &old_termios);
1765
1766 if (k <= 0)
1767 return -EIO;
1768
1769 if (need_nl)
1770 *need_nl = c != '\n';
1771
1772 *ret = c;
1773 return 0;
1774 }
1775 }
1776
3a43da28 1777 if (t != USEC_INFINITY) {
8f2d43a0
LP
1778 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0)
1779 return -ETIMEDOUT;
e0a33e7b 1780 }
8f2d43a0 1781
3a8a9163 1782 errno = 0;
8f2d43a0 1783 if (!fgets(line, sizeof(line), f))
3a8a9163 1784 return errno ? -errno : -EIO;
80876c20
LP
1785
1786 truncate_nl(line);
1787
1788 if (strlen(line) != 1)
1789 return -EBADMSG;
1790
1791 if (need_nl)
1792 *need_nl = false;
1793
1794 *ret = line[0];
1795 return 0;
1796}
1797
418b9be5 1798int ask_char(char *ret, const char *replies, const char *text, ...) {
e0a33e7b 1799 int r;
1b39d4b9 1800
80876c20
LP
1801 assert(ret);
1802 assert(replies);
1803 assert(text);
1804
1805 for (;;) {
1806 va_list ap;
1807 char c;
80876c20
LP
1808 bool need_nl = true;
1809
8481248b 1810 if (on_tty())
c1072ea0 1811 fputs(ANSI_HIGHLIGHT_ON, stdout);
b1b2dc0c 1812
80876c20
LP
1813 va_start(ap, text);
1814 vprintf(text, ap);
1815 va_end(ap);
1816
8481248b 1817 if (on_tty())
c1072ea0 1818 fputs(ANSI_HIGHLIGHT_OFF, stdout);
b1b2dc0c 1819
80876c20
LP
1820 fflush(stdout);
1821
3a43da28 1822 r = read_one_char(stdin, &c, USEC_INFINITY, &need_nl);
8f2d43a0 1823 if (r < 0) {
80876c20
LP
1824
1825 if (r == -EBADMSG) {
1826 puts("Bad input, please try again.");
1827 continue;
1828 }
1829
1830 putchar('\n');
1831 return r;
1832 }
1833
1834 if (need_nl)
1835 putchar('\n');
1836
1837 if (strchr(replies, c)) {
1838 *ret = c;
1839 return 0;
1840 }
1841
1842 puts("Read unexpected character, please try again.");
1843 }
1844}
1845
418b9be5
LP
1846int ask_string(char **ret, const char *text, ...) {
1847 assert(ret);
1848 assert(text);
1849
1850 for (;;) {
1851 char line[LINE_MAX];
1852 va_list ap;
1853
1854 if (on_tty())
1855 fputs(ANSI_HIGHLIGHT_ON, stdout);
1856
1857 va_start(ap, text);
1858 vprintf(text, ap);
1859 va_end(ap);
1860
1861 if (on_tty())
1862 fputs(ANSI_HIGHLIGHT_OFF, stdout);
1863
1864 fflush(stdout);
1865
1866 errno = 0;
1867 if (!fgets(line, sizeof(line), stdin))
1868 return errno ? -errno : -EIO;
1869
1870 if (!endswith(line, "\n"))
1871 putchar('\n');
1872 else {
1873 char *s;
1874
1875 if (isempty(line))
1876 continue;
1877
1878 truncate_nl(line);
1879 s = strdup(line);
1880 if (!s)
1881 return -ENOMEM;
1882
1883 *ret = s;
1884 return 0;
1885 }
1886 }
1887}
1888
512947d4 1889int reset_terminal_fd(int fd, bool switch_to_text) {
80876c20
LP
1890 struct termios termios;
1891 int r = 0;
3fe5e5d4
LP
1892
1893 /* Set terminal to some sane defaults */
80876c20
LP
1894
1895 assert(fd >= 0);
1896
eed1d0e3
LP
1897 /* We leave locked terminal attributes untouched, so that
1898 * Plymouth may set whatever it wants to set, and we don't
1899 * interfere with that. */
3fe5e5d4
LP
1900
1901 /* Disable exclusive mode, just in case */
1902 ioctl(fd, TIOCNXCL);
1903
5c0100a5 1904 /* Switch to text mode */
512947d4
MS
1905 if (switch_to_text)
1906 ioctl(fd, KDSETMODE, KD_TEXT);
5c0100a5 1907
3fe5e5d4 1908 /* Enable console unicode mode */
df465b3f 1909 ioctl(fd, KDSKBMODE, K_UNICODE);
80876c20
LP
1910
1911 if (tcgetattr(fd, &termios) < 0) {
1912 r = -errno;
1913 goto finish;
1914 }
1915
aaf694ca
LP
1916 /* We only reset the stuff that matters to the software. How
1917 * hardware is set up we don't touch assuming that somebody
1918 * else will do that for us */
1919
1920 termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
80876c20
LP
1921 termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
1922 termios.c_oflag |= ONLCR;
1923 termios.c_cflag |= CREAD;
1924 termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
1925
1926 termios.c_cc[VINTR] = 03; /* ^C */
1927 termios.c_cc[VQUIT] = 034; /* ^\ */
1928 termios.c_cc[VERASE] = 0177;
1929 termios.c_cc[VKILL] = 025; /* ^X */
1930 termios.c_cc[VEOF] = 04; /* ^D */
1931 termios.c_cc[VSTART] = 021; /* ^Q */
1932 termios.c_cc[VSTOP] = 023; /* ^S */
1933 termios.c_cc[VSUSP] = 032; /* ^Z */
1934 termios.c_cc[VLNEXT] = 026; /* ^V */
1935 termios.c_cc[VWERASE] = 027; /* ^W */
1936 termios.c_cc[VREPRINT] = 022; /* ^R */
aaf694ca
LP
1937 termios.c_cc[VEOL] = 0;
1938 termios.c_cc[VEOL2] = 0;
80876c20
LP
1939
1940 termios.c_cc[VTIME] = 0;
1941 termios.c_cc[VMIN] = 1;
1942
1943 if (tcsetattr(fd, TCSANOW, &termios) < 0)
1944 r = -errno;
1945
1946finish:
1947 /* Just in case, flush all crap out */
1948 tcflush(fd, TCIOFLUSH);
1949
1950 return r;
1951}
1952
6ea832a2 1953int reset_terminal(const char *name) {
03e334a1 1954 _cleanup_close_ int fd = -1;
6ea832a2
LP
1955
1956 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
1957 if (fd < 0)
1958 return fd;
1959
03e334a1 1960 return reset_terminal_fd(fd, true);
6ea832a2
LP
1961}
1962
80876c20
LP
1963int open_terminal(const char *name, int mode) {
1964 int fd, r;
f73f76ac 1965 unsigned c = 0;
80876c20 1966
f73f76ac
LP
1967 /*
1968 * If a TTY is in the process of being closed opening it might
1969 * cause EIO. This is horribly awful, but unlikely to be
1970 * changed in the kernel. Hence we work around this problem by
1971 * retrying a couple of times.
1972 *
1973 * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
1974 */
1975
dd94c17e
LP
1976 assert(!(mode & O_CREAT));
1977
f73f76ac 1978 for (;;) {
dd94c17e 1979 fd = open(name, mode, 0);
af6da548 1980 if (fd >= 0)
f73f76ac
LP
1981 break;
1982
1983 if (errno != EIO)
1984 return -errno;
1985
af6da548 1986 /* Max 1s in total */
f73f76ac
LP
1987 if (c >= 20)
1988 return -errno;
1989
1990 usleep(50 * USEC_PER_MSEC);
1991 c++;
1992 }
1993
af6da548
LP
1994 r = isatty(fd);
1995 if (r < 0) {
03e334a1 1996 safe_close(fd);
80876c20
LP
1997 return -errno;
1998 }
1999
2000 if (!r) {
03e334a1 2001 safe_close(fd);
80876c20
LP
2002 return -ENOTTY;
2003 }
2004
2005 return fd;
2006}
2007
2008int flush_fd(int fd) {
b92bea5d
ZJS
2009 struct pollfd pollfd = {
2010 .fd = fd,
2011 .events = POLLIN,
2012 };
80876c20
LP
2013
2014 for (;;) {
20c03b7b 2015 char buf[LINE_MAX];
80876c20
LP
2016 ssize_t l;
2017 int r;
2018
e62d8c39
ZJS
2019 r = poll(&pollfd, 1, 0);
2020 if (r < 0) {
80876c20
LP
2021 if (errno == EINTR)
2022 continue;
2023
2024 return -errno;
80876c20 2025
e62d8c39 2026 } else if (r == 0)
80876c20
LP
2027 return 0;
2028
e62d8c39
ZJS
2029 l = read(fd, buf, sizeof(buf));
2030 if (l < 0) {
80876c20
LP
2031
2032 if (errno == EINTR)
2033 continue;
2034
2035 if (errno == EAGAIN)
2036 return 0;
2037
2038 return -errno;
e62d8c39 2039 } else if (l == 0)
80876c20
LP
2040 return 0;
2041 }
2042}
2043
af6da548
LP
2044int acquire_terminal(
2045 const char *name,
2046 bool fail,
2047 bool force,
2048 bool ignore_tiocstty_eperm,
2049 usec_t timeout) {
2050
4a0ff478 2051 int fd = -1, notify = -1, r = 0, wd = -1;
af6da548 2052 usec_t ts = 0;
80876c20
LP
2053
2054 assert(name);
2055
2056 /* We use inotify to be notified when the tty is closed. We
2057 * create the watch before checking if we can actually acquire
2058 * it, so that we don't lose any event.
2059 *
2060 * Note: strictly speaking this actually watches for the
2061 * device being closed, it does *not* really watch whether a
2062 * tty loses its controlling process. However, unless some
2063 * rogue process uses TIOCNOTTY on /dev/tty *after* closing
2064 * its tty otherwise this will not become a problem. As long
2065 * as the administrator makes sure not configure any service
2066 * on the same tty as an untrusted user this should not be a
2067 * problem. (Which he probably should not do anyway.) */
2068
3a43da28 2069 if (timeout != USEC_INFINITY)
af6da548
LP
2070 ts = now(CLOCK_MONOTONIC);
2071
80876c20 2072 if (!fail && !force) {
3a43da28 2073 notify = inotify_init1(IN_CLOEXEC | (timeout != USEC_INFINITY ? IN_NONBLOCK : 0));
af6da548 2074 if (notify < 0) {
80876c20
LP
2075 r = -errno;
2076 goto fail;
2077 }
2078
af6da548
LP
2079 wd = inotify_add_watch(notify, name, IN_CLOSE);
2080 if (wd < 0) {
80876c20
LP
2081 r = -errno;
2082 goto fail;
2083 }
2084 }
2085
2086 for (;;) {
b92bea5d
ZJS
2087 struct sigaction sa_old, sa_new = {
2088 .sa_handler = SIG_IGN,
2089 .sa_flags = SA_RESTART,
2090 };
2091
af6da548
LP
2092 if (notify >= 0) {
2093 r = flush_fd(notify);
2094 if (r < 0)
e3d1855b 2095 goto fail;
af6da548 2096 }
80876c20
LP
2097
2098 /* We pass here O_NOCTTY only so that we can check the return
2099 * value TIOCSCTTY and have a reliable way to figure out if we
2100 * successfully became the controlling process of the tty */
af6da548
LP
2101 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
2102 if (fd < 0)
6ea832a2 2103 return fd;
80876c20 2104
32c4bef8
LP
2105 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
2106 * if we already own the tty. */
32c4bef8
LP
2107 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
2108
80876c20 2109 /* First, try to get the tty */
32c4bef8
LP
2110 if (ioctl(fd, TIOCSCTTY, force) < 0)
2111 r = -errno;
2112
2113 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
21de3988
LP
2114
2115 /* Sometimes it makes sense to ignore TIOCSCTTY
2116 * returning EPERM, i.e. when very likely we already
2117 * are have this controlling terminal. */
32c4bef8 2118 if (r < 0 && r == -EPERM && ignore_tiocstty_eperm)
21de3988
LP
2119 r = 0;
2120
32c4bef8 2121 if (r < 0 && (force || fail || r != -EPERM)) {
80876c20
LP
2122 goto fail;
2123 }
2124
2125 if (r >= 0)
2126 break;
2127
2128 assert(!fail);
2129 assert(!force);
2130 assert(notify >= 0);
2131
2132 for (;;) {
0254e944 2133 union inotify_event_buffer buffer;
f601daa7 2134 struct inotify_event *e;
f7c1ad4f 2135 ssize_t l;
80876c20 2136
3a43da28 2137 if (timeout != USEC_INFINITY) {
af6da548
LP
2138 usec_t n;
2139
2140 n = now(CLOCK_MONOTONIC);
2141 if (ts + timeout < n) {
2142 r = -ETIMEDOUT;
2143 goto fail;
2144 }
2145
2146 r = fd_wait_for_event(fd, POLLIN, ts + timeout - n);
2147 if (r < 0)
2148 goto fail;
2149
2150 if (r == 0) {
2151 r = -ETIMEDOUT;
2152 goto fail;
2153 }
2154 }
2155
0254e944 2156 l = read(notify, &buffer, sizeof(buffer));
af6da548 2157 if (l < 0) {
af6da548 2158 if (errno == EINTR || errno == EAGAIN)
f601daa7
LP
2159 continue;
2160
2161 r = -errno;
2162 goto fail;
2163 }
2164
f7c1ad4f 2165 FOREACH_INOTIFY_EVENT(e, buffer, l) {
f601daa7 2166 if (e->wd != wd || !(e->mask & IN_CLOSE)) {
80876c20 2167 r = -EIO;
f601daa7
LP
2168 goto fail;
2169 }
80876c20
LP
2170 }
2171
2172 break;
2173 }
2174
2175 /* We close the tty fd here since if the old session
2176 * ended our handle will be dead. It's important that
2177 * we do this after sleeping, so that we don't enter
2178 * an endless loop. */
6f53e671 2179 fd = safe_close(fd);
80876c20
LP
2180 }
2181
03e334a1 2182 safe_close(notify);
80876c20 2183
512947d4
MS
2184 r = reset_terminal_fd(fd, true);
2185 if (r < 0)
da927ba9 2186 log_warning_errno(r, "Failed to reset terminal: %m");
80876c20
LP
2187
2188 return fd;
2189
2190fail:
03e334a1
LP
2191 safe_close(fd);
2192 safe_close(notify);
80876c20
LP
2193
2194 return r;
2195}
2196
2197int release_terminal(void) {
56d96fc0 2198 static const struct sigaction sa_new = {
b92bea5d
ZJS
2199 .sa_handler = SIG_IGN,
2200 .sa_flags = SA_RESTART,
2201 };
56d96fc0
LP
2202
2203 _cleanup_close_ int fd = -1;
2204 struct sigaction sa_old;
2205 int r = 0;
80876c20 2206
e62d8c39
ZJS
2207 fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC);
2208 if (fd < 0)
80876c20
LP
2209 return -errno;
2210
57cd2192
LP
2211 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
2212 * by our own TIOCNOTTY */
57cd2192
LP
2213 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
2214
80876c20
LP
2215 if (ioctl(fd, TIOCNOTTY) < 0)
2216 r = -errno;
2217
57cd2192
LP
2218 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
2219
80876c20
LP
2220 return r;
2221}
2222
9a34ec5f
LP
2223int sigaction_many(const struct sigaction *sa, ...) {
2224 va_list ap;
2225 int r = 0, sig;
2226
2227 va_start(ap, sa);
2228 while ((sig = va_arg(ap, int)) > 0)
2229 if (sigaction(sig, sa, NULL) < 0)
2230 r = -errno;
2231 va_end(ap);
2232
2233 return r;
2234}
2235
2236int ignore_signals(int sig, ...) {
b92bea5d
ZJS
2237 struct sigaction sa = {
2238 .sa_handler = SIG_IGN,
2239 .sa_flags = SA_RESTART,
2240 };
9a34ec5f
LP
2241 va_list ap;
2242 int r = 0;
a337c6fc 2243
9a34ec5f
LP
2244 if (sigaction(sig, &sa, NULL) < 0)
2245 r = -errno;
2246
2247 va_start(ap, sig);
2248 while ((sig = va_arg(ap, int)) > 0)
2249 if (sigaction(sig, &sa, NULL) < 0)
2250 r = -errno;
2251 va_end(ap);
2252
2253 return r;
2254}
2255
2256int default_signals(int sig, ...) {
b92bea5d
ZJS
2257 struct sigaction sa = {
2258 .sa_handler = SIG_DFL,
2259 .sa_flags = SA_RESTART,
2260 };
9a34ec5f
LP
2261 va_list ap;
2262 int r = 0;
2263
9a34ec5f
LP
2264 if (sigaction(sig, &sa, NULL) < 0)
2265 r = -errno;
2266
2267 va_start(ap, sig);
2268 while ((sig = va_arg(ap, int)) > 0)
2269 if (sigaction(sig, &sa, NULL) < 0)
2270 r = -errno;
2271 va_end(ap);
2272
2273 return r;
a337c6fc
LP
2274}
2275
3d94f76c 2276void safe_close_pair(int p[]) {
8d567588
LP
2277 assert(p);
2278
3d94f76c
LP
2279 if (p[0] == p[1]) {
2280 /* Special case pairs which use the same fd in both
2281 * directions... */
2282 p[0] = p[1] = safe_close(p[0]);
2283 return;
8d567588
LP
2284 }
2285
3d94f76c
LP
2286 p[0] = safe_close(p[0]);
2287 p[1] = safe_close(p[1]);
8d567588
LP
2288}
2289
eb22ac37 2290ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
7d5dd5e0 2291 uint8_t *p = buf;
8d567588
LP
2292 ssize_t n = 0;
2293
2294 assert(fd >= 0);
2295 assert(buf);
2296
8d567588
LP
2297 while (nbytes > 0) {
2298 ssize_t k;
2299
7d5dd5e0 2300 k = read(fd, p, nbytes);
6ce830fa
LP
2301 if (k < 0) {
2302 if (errno == EINTR)
2303 continue;
8d567588 2304
6ce830fa 2305 if (errno == EAGAIN && do_poll) {
8d567588 2306
6ce830fa
LP
2307 /* We knowingly ignore any return value here,
2308 * and expect that any error/EOF is reported
2309 * via read() */
8d567588 2310
6ce830fa
LP
2311 fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
2312 continue;
2313 }
2314
2315 return n > 0 ? n : -errno;
7d5dd5e0 2316 }
8d567588 2317
6ce830fa
LP
2318 if (k == 0)
2319 return n;
8d567588
LP
2320
2321 p += k;
2322 nbytes -= k;
2323 n += k;
2324 }
2325
2326 return n;
2327}
2328
553acb7b 2329int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
7d5dd5e0 2330 const uint8_t *p = buf;
eb22ac37
LP
2331
2332 assert(fd >= 0);
2333 assert(buf);
2334
553acb7b
ZJS
2335 errno = 0;
2336
eb22ac37
LP
2337 while (nbytes > 0) {
2338 ssize_t k;
2339
fe652127 2340 k = write(fd, p, nbytes);
6ce830fa
LP
2341 if (k < 0) {
2342 if (errno == EINTR)
2343 continue;
eb22ac37 2344
6ce830fa
LP
2345 if (errno == EAGAIN && do_poll) {
2346 /* We knowingly ignore any return value here,
2347 * and expect that any error/EOF is reported
2348 * via write() */
eb22ac37 2349
6ce830fa
LP
2350 fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
2351 continue;
2352 }
eb22ac37 2353
6ce830fa 2354 return -errno;
7d5dd5e0 2355 }
eb22ac37 2356
6ce830fa
LP
2357 if (k == 0) /* Can't really happen */
2358 return -EIO;
eb22ac37
LP
2359
2360 p += k;
2361 nbytes -= k;
eb22ac37
LP
2362 }
2363
553acb7b 2364 return 0;
eb22ac37
LP
2365}
2366
5556b5fe
LP
2367int parse_size(const char *t, off_t base, off_t *size) {
2368
2369 /* Soo, sometimes we want to parse IEC binary suffxies, and
2370 * sometimes SI decimal suffixes. This function can parse
2371 * both. Which one is the right way depends on the
2372 * context. Wikipedia suggests that SI is customary for
2373 * hardrware metrics and network speeds, while IEC is
2374 * customary for most data sizes used by software and volatile
2375 * (RAM) memory. Hence be careful which one you pick!
2376 *
2377 * In either case we use just K, M, G as suffix, and not Ki,
2378 * Mi, Gi or so (as IEC would suggest). That's because that's
2379 * frickin' ugly. But this means you really need to make sure
2380 * to document which base you are parsing when you use this
2381 * call. */
2382
2383 struct table {
ab1f0633 2384 const char *suffix;
b32ff512 2385 unsigned long long factor;
5556b5fe
LP
2386 };
2387
2388 static const struct table iec[] = {
32895bb3 2389 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
840292be
ZJS
2390 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2391 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
2392 { "G", 1024ULL*1024ULL*1024ULL },
2393 { "M", 1024ULL*1024ULL },
2394 { "K", 1024ULL },
2395 { "B", 1 },
ab1f0633
LP
2396 { "", 1 },
2397 };
2398
5556b5fe 2399 static const struct table si[] = {
5556b5fe 2400 { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
840292be
ZJS
2401 { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
2402 { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
2403 { "G", 1000ULL*1000ULL*1000ULL },
2404 { "M", 1000ULL*1000ULL },
2405 { "K", 1000ULL },
2406 { "B", 1 },
5556b5fe
LP
2407 { "", 1 },
2408 };
2409
2410 const struct table *table;
ab1f0633 2411 const char *p;
b32ff512 2412 unsigned long long r = 0;
840292be 2413 unsigned n_entries, start_pos = 0;
ab1f0633
LP
2414
2415 assert(t);
5556b5fe
LP
2416 assert(base == 1000 || base == 1024);
2417 assert(size);
2418
2419 if (base == 1000) {
2420 table = si;
2421 n_entries = ELEMENTSOF(si);
2422 } else {
2423 table = iec;
2424 n_entries = ELEMENTSOF(iec);
2425 }
ab1f0633
LP
2426
2427 p = t;
2428 do {
2429 long long l;
9480794b
ZJS
2430 unsigned long long l2;
2431 double frac = 0;
ab1f0633
LP
2432 char *e;
2433 unsigned i;
2434
2435 errno = 0;
2436 l = strtoll(p, &e, 10);
2437
8333c77e 2438 if (errno > 0)
ab1f0633
LP
2439 return -errno;
2440
2441 if (l < 0)
2442 return -ERANGE;
2443
2444 if (e == p)
2445 return -EINVAL;
2446
9480794b
ZJS
2447 if (*e == '.') {
2448 e++;
2449 if (*e >= '0' && *e <= '9') {
2450 char *e2;
2451
2452 /* strotoull itself would accept space/+/- */
2453 l2 = strtoull(e, &e2, 10);
2454
2455 if (errno == ERANGE)
2456 return -errno;
2457
2458 /* Ignore failure. E.g. 10.M is valid */
2459 frac = l2;
2460 for (; e < e2; e++)
2461 frac /= 10;
2462 }
2463 }
2464
ab1f0633
LP
2465 e += strspn(e, WHITESPACE);
2466
840292be 2467 for (i = start_pos; i < n_entries; i++)
ab1f0633 2468 if (startswith(e, table[i].suffix)) {
b32ff512 2469 unsigned long long tmp;
9480794b 2470 if ((unsigned long long) l + (frac > 0) > ULLONG_MAX / table[i].factor)
b32ff512 2471 return -ERANGE;
9480794b 2472 tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
b32ff512
ZJS
2473 if (tmp > ULLONG_MAX - r)
2474 return -ERANGE;
2475
2476 r += tmp;
2477 if ((unsigned long long) (off_t) r != r)
2478 return -ERANGE;
2479
ab1f0633 2480 p = e + strlen(table[i].suffix);
840292be
ZJS
2481
2482 start_pos = i + 1;
ab1f0633
LP
2483 break;
2484 }
2485
5556b5fe 2486 if (i >= n_entries)
ab1f0633
LP
2487 return -EINVAL;
2488
b32ff512 2489 } while (*p);
ab1f0633 2490
5556b5fe 2491 *size = r;
ab1f0633
LP
2492
2493 return 0;
2494}
2495
843d2643
LP
2496int make_stdio(int fd) {
2497 int r, s, t;
2498
2499 assert(fd >= 0);
2500
20b63d12
LP
2501 r = dup2(fd, STDIN_FILENO);
2502 s = dup2(fd, STDOUT_FILENO);
2503 t = dup2(fd, STDERR_FILENO);
843d2643
LP
2504
2505 if (fd >= 3)
03e334a1 2506 safe_close(fd);
843d2643
LP
2507
2508 if (r < 0 || s < 0 || t < 0)
2509 return -errno;
2510
20b63d12
LP
2511 /* Explicitly unset O_CLOEXEC, since if fd was < 3, then
2512 * dup2() was a NOP and the bit hence possibly set. */
2513 fd_cloexec(STDIN_FILENO, false);
2514 fd_cloexec(STDOUT_FILENO, false);
2515 fd_cloexec(STDERR_FILENO, false);
7862f62d 2516
843d2643
LP
2517 return 0;
2518}
2519
ade509ce
LP
2520int make_null_stdio(void) {
2521 int null_fd;
2522
cd3bd60a
LP
2523 null_fd = open("/dev/null", O_RDWR|O_NOCTTY);
2524 if (null_fd < 0)
ade509ce
LP
2525 return -errno;
2526
2527 return make_stdio(null_fd);
2528}
2529
8407a5d0
LP
2530bool is_device_path(const char *path) {
2531
2532 /* Returns true on paths that refer to a device, either in
2533 * sysfs or in /dev */
2534
2535 return
2536 path_startswith(path, "/dev/") ||
2537 path_startswith(path, "/sys/");
2538}
2539
01f78473 2540int dir_is_empty(const char *path) {
a05f97b3 2541 _cleanup_closedir_ DIR *d;
01f78473 2542
a05f97b3
LP
2543 d = opendir(path);
2544 if (!d)
01f78473
LP
2545 return -errno;
2546
2547 for (;;) {
7d5e9c0f 2548 struct dirent *de;
01f78473 2549
3fd11280
FW
2550 errno = 0;
2551 de = readdir(d);
2552 if (!de && errno != 0)
2553 return -errno;
01f78473 2554
a05f97b3
LP
2555 if (!de)
2556 return 1;
01f78473 2557
a34bf9db 2558 if (!hidden_file(de->d_name))
a05f97b3
LP
2559 return 0;
2560 }
01f78473
LP
2561}
2562
844ec79b
ZJS
2563char* dirname_malloc(const char *path) {
2564 char *d, *dir, *dir2;
2565
2566 d = strdup(path);
2567 if (!d)
2568 return NULL;
2569 dir = dirname(d);
2570 assert(dir);
2571
2572 if (dir != d) {
2573 dir2 = strdup(dir);
2574 free(d);
2575 return dir2;
2576 }
2577
2578 return dir;
2579}
2580
b89446bb 2581int dev_urandom(void *p, size_t n) {
539618a0
LP
2582 static int have_syscall = -1;
2583 int r, fd;
9bf3b535 2584 ssize_t k;
d3782d60 2585
97768fc5
LP
2586 /* Gathers some randomness from the kernel. This call will
2587 * never block, and will always return some data from the
2588 * kernel, regardless if the random pool is fully initialized
2589 * or not. It thus makes no guarantee for the quality of the
2590 * returned entropy, but is good enough for or usual usecases
2591 * of seeding the hash functions for hashtable */
2592
2593 /* Use the getrandom() syscall unless we know we don't have
2594 * it, or when the requested size is too large for it. */
539618a0 2595 if (have_syscall != 0 || (size_t) (int) n != n) {
97768fc5 2596 r = getrandom(p, n, GRND_NONBLOCK);
539618a0
LP
2597 if (r == (int) n) {
2598 have_syscall = true;
2599 return 0;
2600 }
2601
2602 if (r < 0) {
2603 if (errno == ENOSYS)
97768fc5
LP
2604 /* we lack the syscall, continue with
2605 * reading from /dev/urandom */
539618a0 2606 have_syscall = false;
97768fc5
LP
2607 else if (errno == EAGAIN)
2608 /* not enough entropy for now. Let's
2609 * remember to use the syscall the
2610 * next time, again, but also read
2611 * from /dev/urandom for now, which
2612 * doesn't care about the current
2613 * amount of entropy. */
2614 have_syscall = true;
539618a0
LP
2615 else
2616 return -errno;
2617 } else
2618 /* too short read? */
2619 return -EIO;
2620 }
2621
ac0930c8
LP
2622 fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
2623 if (fd < 0)
b89446bb 2624 return errno == ENOENT ? -ENOSYS : -errno;
d3782d60 2625
9bf3b535 2626 k = loop_read(fd, p, n, true);
539618a0
LP
2627 safe_close(fd);
2628
b89446bb
LP
2629 if (k < 0)
2630 return (int) k;
2631 if ((size_t) k != n)
2632 return -EIO;
2633
2634 return 0;
2635}
2636
ef309a68 2637void initialize_srand(void) {
b89446bb 2638 static bool srand_called = false;
ef309a68
LP
2639 unsigned x;
2640#ifdef HAVE_SYS_AUXV_H
2641 void *auxv;
2642#endif
2643
2644 if (srand_called)
2645 return;
2646
2647 x = 0;
2648
2649#ifdef HAVE_SYS_AUXV_H
2650 /* The kernel provides us with a bit of entropy in auxv, so
2651 * let's try to make use of that to seed the pseudo-random
2652 * generator. It's better than nothing... */
2653
2654 auxv = (void*) getauxval(AT_RANDOM);
2655 if (auxv)
2656 x ^= *(unsigned*) auxv;
2657#endif
2658
2659 x ^= (unsigned) now(CLOCK_REALTIME);
2660 x ^= (unsigned) gettid();
2661
2662 srand(x);
2663 srand_called = true;
2664}
2665
2666void random_bytes(void *p, size_t n) {
b89446bb
LP
2667 uint8_t *q;
2668 int r;
d3782d60 2669
b89446bb
LP
2670 r = dev_urandom(p, n);
2671 if (r >= 0)
2672 return;
d3782d60 2673
b89446bb
LP
2674 /* If some idiot made /dev/urandom unavailable to us, he'll
2675 * get a PRNG instead. */
d3782d60 2676
ef309a68 2677 initialize_srand();
a3b6fafe 2678
9bf3b535
LP
2679 for (q = p; q < (uint8_t*) p + n; q ++)
2680 *q = rand();
a3b6fafe
LP
2681}
2682
5b6319dc
LP
2683void rename_process(const char name[8]) {
2684 assert(name);
2685
5d6b1584
LP
2686 /* This is a like a poor man's setproctitle(). It changes the
2687 * comm field, argv[0], and also the glibc's internally used
2688 * name of the process. For the first one a limit of 16 chars
2689 * applies, to the second one usually one of 10 (i.e. length
2690 * of "/sbin/init"), to the third one one of 7 (i.e. length of
2691 * "systemd"). If you pass a longer string it will be
2692 * truncated */
5b6319dc 2693
5d6b1584 2694 prctl(PR_SET_NAME, name);
5b6319dc
LP
2695
2696 if (program_invocation_name)
2697 strncpy(program_invocation_name, name, strlen(program_invocation_name));
9a0e6896
LP
2698
2699 if (saved_argc > 0) {
2700 int i;
2701
2702 if (saved_argv[0])
2703 strncpy(saved_argv[0], name, strlen(saved_argv[0]));
2704
2705 for (i = 1; i < saved_argc; i++) {
2706 if (!saved_argv[i])
2707 break;
2708
29804cc1 2709 memzero(saved_argv[i], strlen(saved_argv[i]));
9a0e6896
LP
2710 }
2711 }
5b6319dc
LP
2712}
2713
7d793605
LP
2714void sigset_add_many(sigset_t *ss, ...) {
2715 va_list ap;
2716 int sig;
2717
2718 assert(ss);
2719
2720 va_start(ap, ss);
2721 while ((sig = va_arg(ap, int)) > 0)
2722 assert_se(sigaddset(ss, sig) == 0);
2723 va_end(ap);
2724}
2725
856a5a7d
LP
2726int sigprocmask_many(int how, ...) {
2727 va_list ap;
2728 sigset_t ss;
2729 int sig;
2730
2731 assert_se(sigemptyset(&ss) == 0);
2732
2733 va_start(ap, how);
2734 while ((sig = va_arg(ap, int)) > 0)
2735 assert_se(sigaddset(&ss, sig) == 0);
2736 va_end(ap);
2737
2738 if (sigprocmask(how, &ss, NULL) < 0)
2739 return -errno;
2740
2741 return 0;
2742}
2743
ef2f1067
LP
2744char* gethostname_malloc(void) {
2745 struct utsname u;
2746
2747 assert_se(uname(&u) >= 0);
2748
344de609 2749 if (!isempty(u.nodename) && !streq(u.nodename, "(none)"))
ef2f1067
LP
2750 return strdup(u.nodename);
2751
2752 return strdup(u.sysname);
2753}
2754
344de609
LP
2755bool hostname_is_set(void) {
2756 struct utsname u;
2757
2758 assert_se(uname(&u) >= 0);
2759
2760 return !isempty(u.nodename) && !streq(u.nodename, "(none)");
2761}
2762
f1566e63 2763char *lookup_uid(uid_t uid) {
ef2f1067 2764 long bufsize;
a05f97b3
LP
2765 char *name;
2766 _cleanup_free_ char *buf = NULL;
ef2f1067 2767 struct passwd pwbuf, *pw = NULL;
ef2f1067
LP
2768
2769 /* Shortcut things to avoid NSS lookups */
2770 if (uid == 0)
2771 return strdup("root");
2772
7c5f152a
LP
2773 bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
2774 if (bufsize <= 0)
ef2f1067
LP
2775 bufsize = 4096;
2776
7c5f152a
LP
2777 buf = malloc(bufsize);
2778 if (!buf)
ef2f1067
LP
2779 return NULL;
2780
a05f97b3
LP
2781 if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
2782 return strdup(pw->pw_name);
ef2f1067 2783
de0671ee 2784 if (asprintf(&name, UID_FMT, uid) < 0)
ef2f1067
LP
2785 return NULL;
2786
2787 return name;
2788}
2789
7c5f152a
LP
2790char* getlogname_malloc(void) {
2791 uid_t uid;
2792 struct stat st;
2793
2794 if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
2795 uid = st.st_uid;
2796 else
2797 uid = getuid();
2798
2799 return lookup_uid(uid);
2800}
2801
2802char *getusername_malloc(void) {
2803 const char *e;
2804
2805 e = getenv("USER");
2806 if (e)
2807 return strdup(e);
2808
2809 return lookup_uid(getuid());
2810}
2811
9d8c4979
LP
2812int getttyname_malloc(int fd, char **ret) {
2813 size_t l = 100;
2814 int r;
8c6db833 2815
9d8c4979
LP
2816 assert(fd >= 0);
2817 assert(ret);
ef2f1067 2818
9d8c4979
LP
2819 for (;;) {
2820 char path[l];
ef2f1067 2821
9d8c4979
LP
2822 r = ttyname_r(fd, path, sizeof(path));
2823 if (r == 0) {
2824 const char *p;
2825 char *c;
ef2f1067 2826
9d8c4979
LP
2827 p = startswith(path, "/dev/");
2828 c = strdup(p ?: path);
2829 if (!c)
2830 return -ENOMEM;
2831
2832 *ret = c;
2833 return 0;
2834 }
2835
2836 if (r != ERANGE)
2837 return -r;
2838
2839 l *= 2;
2840 }
8c6db833 2841
8c6db833
LP
2842 return 0;
2843}
2844
fc116c6a
LP
2845int getttyname_harder(int fd, char **r) {
2846 int k;
2847 char *s;
2848
a05f97b3
LP
2849 k = getttyname_malloc(fd, &s);
2850 if (k < 0)
fc116c6a
LP
2851 return k;
2852
2853 if (streq(s, "tty")) {
2854 free(s);
4d6d6518 2855 return get_ctty(0, NULL, r);
fc116c6a
LP
2856 }
2857
2858 *r = s;
2859 return 0;
2860}
2861
4d6d6518 2862int get_ctty_devnr(pid_t pid, dev_t *d) {
b4696bce
SP
2863 int r;
2864 _cleanup_free_ char *line = NULL;
2865 const char *p;
fc116c6a 2866 unsigned long ttynr;
fc116c6a 2867
49aa47c7 2868 assert(pid >= 0);
49aa47c7 2869
b4696bce
SP
2870 p = procfs_file_alloca(pid, "stat");
2871 r = read_one_line_file(p, &line);
2872 if (r < 0)
2873 return r;
fc116c6a 2874
4d6d6518
LP
2875 p = strrchr(line, ')');
2876 if (!p)
fc116c6a
LP
2877 return -EIO;
2878
2879 p++;
2880
2881 if (sscanf(p, " "
2882 "%*c " /* state */
2883 "%*d " /* ppid */
2884 "%*d " /* pgrp */
2885 "%*d " /* session */
2886 "%lu ", /* ttynr */
2887 &ttynr) != 1)
2888 return -EIO;
2889
11dc5d2b
LP
2890 if (major(ttynr) == 0 && minor(ttynr) == 0)
2891 return -ENOENT;
2892
0bee65f0
LP
2893 if (d)
2894 *d = (dev_t) ttynr;
2895
fc116c6a
LP
2896 return 0;
2897}
2898
4d6d6518 2899int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
833fce28
LP
2900 char fn[sizeof("/dev/char/")-1 + 2*DECIMAL_STR_MAX(unsigned) + 1 + 1], *b = NULL;
2901 _cleanup_free_ char *s = NULL;
2902 const char *p;
fc116c6a 2903 dev_t devnr;
833fce28 2904 int k;
fc116c6a
LP
2905
2906 assert(r);
2907
4d6d6518
LP
2908 k = get_ctty_devnr(pid, &devnr);
2909 if (k < 0)
fc116c6a
LP
2910 return k;
2911
f4934dfa 2912 sprintf(fn, "/dev/char/%u:%u", major(devnr), minor(devnr));
fc116c6a 2913
23406ce5
LP
2914 k = readlink_malloc(fn, &s);
2915 if (k < 0) {
fc116c6a
LP
2916
2917 if (k != -ENOENT)
2918 return k;
2919
46824d0e
LP
2920 /* This is an ugly hack */
2921 if (major(devnr) == 136) {
de0671ee 2922 asprintf(&b, "pts/%u", minor(devnr));
833fce28 2923 goto finish;
46824d0e
LP
2924 }
2925
fc116c6a
LP
2926 /* Probably something like the ptys which have no
2927 * symlink in /dev/char. Let's return something
2928 * vaguely useful. */
2929
23406ce5 2930 b = strdup(fn + 5);
833fce28 2931 goto finish;
fc116c6a
LP
2932 }
2933
2934 if (startswith(s, "/dev/"))
2935 p = s + 5;
2936 else if (startswith(s, "../"))
2937 p = s + 3;
2938 else
2939 p = s;
2940
2941 b = strdup(p);
fc116c6a 2942
833fce28 2943finish:
fc116c6a
LP
2944 if (!b)
2945 return -ENOMEM;
2946
2947 *r = b;
46824d0e
LP
2948 if (_devnr)
2949 *_devnr = devnr;
2950
fc116c6a
LP
2951 return 0;
2952}
2953
f56d5db9 2954int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
dede0e33 2955 _cleanup_closedir_ DIR *d = NULL;
8c6db833
LP
2956 int ret = 0;
2957
2958 assert(fd >= 0);
2959
2960 /* This returns the first error we run into, but nevertheless
7925c22a 2961 * tries to go on. This closes the passed fd. */
8c6db833 2962
d4d046e3
LP
2963 d = fdopendir(fd);
2964 if (!d) {
03e334a1 2965 safe_close(fd);
4c633005
LP
2966
2967 return errno == ENOENT ? 0 : -errno;
8c6db833
LP
2968 }
2969
2970 for (;;) {
7d5e9c0f 2971 struct dirent *de;
7925c22a
LP
2972 bool is_dir, keep_around;
2973 struct stat st;
8c6db833
LP
2974 int r;
2975
3fd11280
FW
2976 errno = 0;
2977 de = readdir(d);
dede0e33
ZJS
2978 if (!de) {
2979 if (errno != 0 && ret == 0)
3fd11280 2980 ret = -errno;
dede0e33 2981 return ret;
8c6db833
LP
2982 }
2983
8c6db833
LP
2984 if (streq(de->d_name, ".") || streq(de->d_name, ".."))
2985 continue;
2986
7925c22a
LP
2987 if (de->d_type == DT_UNKNOWN ||
2988 honour_sticky ||
2989 (de->d_type == DT_DIR && root_dev)) {
8c6db833 2990 if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
4c633005 2991 if (ret == 0 && errno != ENOENT)
8c6db833
LP
2992 ret = -errno;
2993 continue;
2994 }
2995
2996 is_dir = S_ISDIR(st.st_mode);
7925c22a
LP
2997 keep_around =
2998 honour_sticky &&
2999 (st.st_uid == 0 || st.st_uid == getuid()) &&
3000 (st.st_mode & S_ISVTX);
ad293f5a 3001 } else {
8c6db833 3002 is_dir = de->d_type == DT_DIR;
7925c22a 3003 keep_around = false;
ad293f5a 3004 }
8c6db833
LP
3005
3006 if (is_dir) {
3007 int subdir_fd;
8c6db833 3008
597f43c7 3009 /* if root_dev is set, remove subdirectories only, if device is same as dir */
7925c22a
LP
3010 if (root_dev && st.st_dev != root_dev->st_dev)
3011 continue;
8c6db833 3012
7925c22a
LP
3013 subdir_fd = openat(fd, de->d_name,
3014 O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
3015 if (subdir_fd < 0) {
3016 if (ret == 0 && errno != ENOENT)
3017 ret = -errno;
3018 continue;
3019 }
3020
b3d28469 3021 r = rm_rf_children_dangerous(subdir_fd, only_dirs, honour_sticky, root_dev);
7925c22a
LP
3022 if (r < 0 && ret == 0)
3023 ret = r;
3024
3025 if (!keep_around)
3026 if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
ad293f5a
LP
3027 if (ret == 0 && errno != ENOENT)
3028 ret = -errno;
3029 }
3030
3031 } else if (!only_dirs && !keep_around) {
8c6db833
LP
3032
3033 if (unlinkat(fd, de->d_name, 0) < 0) {
4c633005 3034 if (ret == 0 && errno != ENOENT)
8c6db833
LP
3035 ret = -errno;
3036 }
3037 }
3038 }
8c6db833
LP
3039}
3040
44a6b1b6 3041_pure_ static int is_temporary_fs(struct statfs *s) {
943aad8c 3042 assert(s);
73020ab2
SL
3043
3044 return F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) ||
3045 F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC);
943aad8c
ZJS
3046}
3047
979ef53a
DR
3048int is_fd_on_temporary_fs(int fd) {
3049 struct statfs s;
3050
3051 if (fstatfs(fd, &s) < 0)
3052 return -errno;
3053
3054 return is_temporary_fs(&s);
3055}
3056
f56d5db9
LP
3057int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
3058 struct statfs s;
3059
3060 assert(fd >= 0);
3061
3062 if (fstatfs(fd, &s) < 0) {
03e334a1 3063 safe_close(fd);
f56d5db9
LP
3064 return -errno;
3065 }
3066
3067 /* We refuse to clean disk file systems with this call. This
3068 * is extra paranoia just to be sure we never ever remove
3069 * non-state data */
943aad8c 3070 if (!is_temporary_fs(&s)) {
f56d5db9 3071 log_error("Attempted to remove disk file system, and we can't allow that.");
03e334a1 3072 safe_close(fd);
f56d5db9
LP
3073 return -EPERM;
3074 }
3075
3076 return rm_rf_children_dangerous(fd, only_dirs, honour_sticky, root_dev);
3077}
3078
b5e1fad5
LP
3079static int file_is_priv_sticky(const char *p) {
3080 struct stat st;
3081
3082 assert(p);
3083
3084 if (lstat(p, &st) < 0)
3085 return -errno;
3086
3087 return
3088 (st.st_uid == 0 || st.st_uid == getuid()) &&
3089 (st.st_mode & S_ISVTX);
3090}
3091
f56d5db9
LP
3092static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) {
3093 int fd, r;
3094 struct statfs s;
8c6db833
LP
3095
3096 assert(path);
3097
f56d5db9
LP
3098 /* We refuse to clean the root file system with this
3099 * call. This is extra paranoia to never cause a really
3100 * seriously broken system. */
3101 if (path_equal(path, "/")) {
3102 log_error("Attempted to remove entire root file system, and we can't allow that.");
3103 return -EPERM;
3104 }
461b1822 3105
d4d046e3
LP
3106 fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
3107 if (fd < 0) {
8c6db833 3108
e02d225b 3109 if (errno != ENOTDIR && errno != ELOOP)
8c6db833
LP
3110 return -errno;
3111
f56d5db9
LP
3112 if (!dangerous) {
3113 if (statfs(path, &s) < 0)
3114 return -errno;
3115
943aad8c 3116 if (!is_temporary_fs(&s)) {
f56d5db9
LP
3117 log_error("Attempted to remove disk file system, and we can't allow that.");
3118 return -EPERM;
3119 }
3120 }
3121
8c6db833 3122 if (delete_root && !only_dirs)
d4d046e3 3123 if (unlink(path) < 0 && errno != ENOENT)
8c6db833
LP
3124 return -errno;
3125
3126 return 0;
3127 }
3128
f56d5db9
LP
3129 if (!dangerous) {
3130 if (fstatfs(fd, &s) < 0) {
03e334a1 3131 safe_close(fd);
f56d5db9
LP
3132 return -errno;
3133 }
ad293f5a 3134
943aad8c 3135 if (!is_temporary_fs(&s)) {
f56d5db9 3136 log_error("Attempted to remove disk file system, and we can't allow that.");
03e334a1 3137 safe_close(fd);
f56d5db9
LP
3138 return -EPERM;
3139 }
3140 }
3141
3142 r = rm_rf_children_dangerous(fd, only_dirs, honour_sticky, NULL);
ad293f5a
LP
3143 if (delete_root) {
3144
8d53b453 3145 if (honour_sticky && file_is_priv_sticky(path) > 0)
ad293f5a 3146 return r;
8c6db833 3147
e27796a0 3148 if (rmdir(path) < 0 && errno != ENOENT) {
8c6db833
LP
3149 if (r == 0)
3150 r = -errno;
3151 }
ad293f5a 3152 }
8c6db833
LP
3153
3154 return r;
3155}
3156
f56d5db9
LP
3157int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
3158 return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, false);
3159}
3160
3161int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
3162 return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, true);
3163}
3164
8c6db833
LP
3165int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
3166 assert(path);
3167
3168 /* Under the assumption that we are running privileged we
3169 * first change the access mode and only then hand out
3170 * ownership to avoid a window where access is too open. */
3171
fed1e721 3172 if (mode != MODE_INVALID)
8d53b453
LP
3173 if (chmod(path, mode) < 0)
3174 return -errno;
8c6db833 3175
fed1e721 3176 if (uid != UID_INVALID || gid != GID_INVALID)
8d53b453
LP
3177 if (chown(path, uid, gid) < 0)
3178 return -errno;
8c6db833
LP
3179
3180 return 0;
ef2f1067
LP
3181}
3182
f4b47811
LP
3183int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
3184 assert(fd >= 0);
3185
3186 /* Under the assumption that we are running privileged we
3187 * first change the access mode and only then hand out
3188 * ownership to avoid a window where access is too open. */
3189
fed1e721 3190 if (mode != MODE_INVALID)
9588bc32
LP
3191 if (fchmod(fd, mode) < 0)
3192 return -errno;
f4b47811 3193
fed1e721 3194 if (uid != UID_INVALID || gid != GID_INVALID)
9588bc32
LP
3195 if (fchown(fd, uid, gid) < 0)
3196 return -errno;
f4b47811
LP
3197
3198 return 0;
3199}
3200
82c121a4
LP
3201cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
3202 cpu_set_t *r;
3203 unsigned n = 1024;
3204
3205 /* Allocates the cpuset in the right size */
3206
3207 for (;;) {
3208 if (!(r = CPU_ALLOC(n)))
3209 return NULL;
3210
3211 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
3212 CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
3213
3214 if (ncpus)
3215 *ncpus = n;
3216
3217 return r;
3218 }
3219
3220 CPU_FREE(r);
3221
3222 if (errno != EINVAL)
3223 return NULL;
3224
3225 n *= 2;
3226 }
3227}
3228
984a2be4 3229int status_vprintf(const char *status, bool ellipse, bool ephemeral, const char *format, va_list ap) {
9ab7a8d2 3230 static const char status_indent[] = " "; /* "[" STATUS "] " */
669bec5d
LP
3231 _cleanup_free_ char *s = NULL;
3232 _cleanup_close_ int fd = -1;
b92bea5d 3233 struct iovec iovec[6] = {};
81beb750 3234 int n = 0;
984a2be4 3235 static bool prev_ephemeral;
9e58ff9c
LP
3236
3237 assert(format);
3238
9ab7a8d2 3239 /* This is independent of logging, as status messages are
9e58ff9c
LP
3240 * optional and go exclusively to the console. */
3241
3242 if (vasprintf(&s, format, ap) < 0)
669bec5d 3243 return log_oom();
9e58ff9c 3244
67e5cc4f 3245 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
81beb750 3246 if (fd < 0)
669bec5d 3247 return fd;
9e58ff9c 3248
67e5cc4f 3249 if (ellipse) {
9ab7a8d2
MS
3250 char *e;
3251 size_t emax, sl;
3252 int c;
3253
67e5cc4f
LP
3254 c = fd_columns(fd);
3255 if (c <= 0)
3256 c = 80;
81beb750 3257
669bec5d 3258 sl = status ? sizeof(status_indent)-1 : 0;
9ab7a8d2
MS
3259
3260 emax = c - sl - 1;
3261 if (emax < 3)
3262 emax = 3;
81beb750 3263
58d61742 3264 e = ellipsize(s, emax, 50);
67e5cc4f
LP
3265 if (e) {
3266 free(s);
3267 s = e;
3268 }
81beb750
LP
3269 }
3270
984a2be4
MS
3271 if (prev_ephemeral)
3272 IOVEC_SET_STRING(iovec[n++], "\r" ANSI_ERASE_TO_END_OF_LINE);
3273 prev_ephemeral = ephemeral;
3274
9ab7a8d2
MS
3275 if (status) {
3276 if (!isempty(status)) {
3277 IOVEC_SET_STRING(iovec[n++], "[");
3278 IOVEC_SET_STRING(iovec[n++], status);
3279 IOVEC_SET_STRING(iovec[n++], "] ");
3280 } else
3281 IOVEC_SET_STRING(iovec[n++], status_indent);
81beb750
LP
3282 }
3283
9ab7a8d2 3284 IOVEC_SET_STRING(iovec[n++], s);
984a2be4
MS
3285 if (!ephemeral)
3286 IOVEC_SET_STRING(iovec[n++], "\n");
81beb750 3287
669bec5d
LP
3288 if (writev(fd, iovec, n) < 0)
3289 return -errno;
9e58ff9c 3290
669bec5d 3291 return 0;
9e58ff9c
LP
3292}
3293
984a2be4 3294int status_printf(const char *status, bool ellipse, bool ephemeral, const char *format, ...) {
c846ff47 3295 va_list ap;
669bec5d 3296 int r;
c846ff47
LP
3297
3298 assert(format);
3299
3300 va_start(ap, format);
984a2be4 3301 r = status_vprintf(status, ellipse, ephemeral, format, ap);
c846ff47 3302 va_end(ap);
669bec5d
LP
3303
3304 return r;
c846ff47
LP
3305}
3306
fab56fc5
LP
3307char *replace_env(const char *format, char **env) {
3308 enum {
3309 WORD,
c24eb49e 3310 CURLY,
fab56fc5
LP
3311 VARIABLE
3312 } state = WORD;
3313
3314 const char *e, *word = format;
3315 char *r = NULL, *k;
3316
3317 assert(format);
3318
3319 for (e = format; *e; e ++) {
3320
3321 switch (state) {
3322
3323 case WORD:
3324 if (*e == '$')
c24eb49e 3325 state = CURLY;
fab56fc5
LP
3326 break;
3327
c24eb49e
LP
3328 case CURLY:
3329 if (*e == '{') {
4a6ca457
LP
3330 k = strnappend(r, word, e-word-1);
3331 if (!k)
fab56fc5
LP
3332 goto fail;
3333
3334 free(r);
3335 r = k;
3336
3337 word = e-1;
3338 state = VARIABLE;
3339
3340 } else if (*e == '$') {
4a6ca457
LP
3341 k = strnappend(r, word, e-word);
3342 if (!k)
fab56fc5
LP
3343 goto fail;
3344
3345 free(r);
3346 r = k;
3347
3348 word = e+1;
3349 state = WORD;
3350 } else
3351 state = WORD;
3352 break;
3353
3354 case VARIABLE:
c24eb49e 3355 if (*e == '}') {
b95cf362 3356 const char *t;
fab56fc5 3357
4d1a6904 3358 t = strempty(strv_env_get_n(env, word+2, e-word-2));
fab56fc5 3359
4d1a6904
LP
3360 k = strappend(r, t);
3361 if (!k)
b95cf362 3362 goto fail;
fab56fc5 3363
b95cf362
LP
3364 free(r);
3365 r = k;
fab56fc5 3366
b95cf362 3367 word = e+1;
fab56fc5
LP
3368 state = WORD;
3369 }
3370 break;
3371 }
3372 }
3373
4a6ca457
LP
3374 k = strnappend(r, word, e-word);
3375 if (!k)
fab56fc5
LP
3376 goto fail;
3377
3378 free(r);
3379 return k;
3380
3381fail:
3382 free(r);
3383 return NULL;
3384}
3385
3386char **replace_env_argv(char **argv, char **env) {
b2fadec6 3387 char **ret, **i;
c24eb49e
LP
3388 unsigned k = 0, l = 0;
3389
3390 l = strv_length(argv);
fab56fc5 3391
b2fadec6
ZJS
3392 ret = new(char*, l+1);
3393 if (!ret)
fab56fc5
LP
3394 return NULL;
3395
3396 STRV_FOREACH(i, argv) {
c24eb49e
LP
3397
3398 /* If $FOO appears as single word, replace it by the split up variable */
b95cf362
LP
3399 if ((*i)[0] == '$' && (*i)[1] != '{') {
3400 char *e;
3401 char **w, **m;
3402 unsigned q;
c24eb49e 3403
4d1a6904
LP
3404 e = strv_env_get(env, *i+1);
3405 if (e) {
b2fadec6 3406 int r;
c24eb49e 3407
f88e6be5 3408 r = strv_split_quoted(&m, e, true);
b2fadec6
ZJS
3409 if (r < 0) {
3410 ret[k] = NULL;
3411 strv_free(ret);
c24eb49e
LP
3412 return NULL;
3413 }
b95cf362
LP
3414 } else
3415 m = NULL;
c24eb49e 3416
b95cf362
LP
3417 q = strv_length(m);
3418 l = l + q - 1;
c24eb49e 3419
b2fadec6
ZJS
3420 w = realloc(ret, sizeof(char*) * (l+1));
3421 if (!w) {
3422 ret[k] = NULL;
3423 strv_free(ret);
b95cf362
LP
3424 strv_free(m);
3425 return NULL;
3426 }
c24eb49e 3427
b2fadec6 3428 ret = w;
b95cf362 3429 if (m) {
b2fadec6 3430 memcpy(ret + k, m, q * sizeof(char*));
c24eb49e 3431 free(m);
c24eb49e 3432 }
b95cf362
LP
3433
3434 k += q;
3435 continue;
c24eb49e
LP
3436 }
3437
3438 /* If ${FOO} appears as part of a word, replace it by the variable as-is */
b2fadec6
ZJS
3439 ret[k] = replace_env(*i, env);
3440 if (!ret[k]) {
3441 strv_free(ret);
fab56fc5
LP
3442 return NULL;
3443 }
b2fadec6 3444 k++;
fab56fc5
LP
3445 }
3446
b2fadec6
ZJS
3447 ret[k] = NULL;
3448 return ret;
fab56fc5
LP
3449}
3450
81beb750 3451int fd_columns(int fd) {
b92bea5d 3452 struct winsize ws = {};
81beb750
LP
3453
3454 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3455 return -errno;
3456
3457 if (ws.ws_col <= 0)
3458 return -EIO;
3459
3460 return ws.ws_col;
3461}
3462
28917d7d 3463unsigned columns(void) {
fa776d8e 3464 const char *e;
7009eec2 3465 int c;
fa776d8e 3466
28917d7d
LP
3467 if (_likely_(cached_columns > 0))
3468 return cached_columns;
11f96fac 3469
28917d7d
LP
3470 c = 0;
3471 e = getenv("COLUMNS");
c6828d27
TG
3472 if (e)
3473 (void) safe_atoi(e, &c);
fa776d8e 3474
28917d7d
LP
3475 if (c <= 0)
3476 c = fd_columns(STDOUT_FILENO);
fa776d8e 3477
28917d7d
LP
3478 if (c <= 0)
3479 c = 80;
11f96fac 3480
28917d7d 3481 cached_columns = c;
9bc5cd6d 3482 return cached_columns;
11f96fac
ZJS
3483}
3484
8f2d43a0 3485int fd_lines(int fd) {
b92bea5d 3486 struct winsize ws = {};
8f2d43a0
LP
3487
3488 if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3489 return -errno;
3490
3491 if (ws.ws_row <= 0)
3492 return -EIO;
3493
3494 return ws.ws_row;
3495}
3496
3497unsigned lines(void) {
8f2d43a0 3498 const char *e;
9bc5cd6d 3499 int l;
8f2d43a0 3500
ed757c0c
LP
3501 if (_likely_(cached_lines > 0))
3502 return cached_lines;
8f2d43a0 3503
ed757c0c 3504 l = 0;
8f2d43a0 3505 e = getenv("LINES");
acb3b3dd 3506 if (e)
9bc5cd6d 3507 (void) safe_atoi(e, &l);
8f2d43a0 3508
ed757c0c
LP
3509 if (l <= 0)
3510 l = fd_lines(STDOUT_FILENO);
8f2d43a0 3511
ed757c0c
LP
3512 if (l <= 0)
3513 l = 24;
8f2d43a0 3514
ed757c0c
LP
3515 cached_lines = l;
3516 return cached_lines;
3517}
3518
3519/* intended to be used as a SIGWINCH sighandler */
3520void columns_lines_cache_reset(int signum) {
3521 cached_columns = 0;
3522 cached_lines = 0;
3523}
3524
3525bool on_tty(void) {
3526 static int cached_on_tty = -1;
3527
3528 if (_unlikely_(cached_on_tty < 0))
3529 cached_on_tty = isatty(STDOUT_FILENO) > 0;
3530
3531 return cached_on_tty;
8f2d43a0
LP
3532}
3533
9d9951a4
HH
3534int files_same(const char *filea, const char *fileb) {
3535 struct stat a, b;
b4f10a5e 3536
9d9951a4 3537 if (stat(filea, &a) < 0)
b4f10a5e
LP
3538 return -errno;
3539
9d9951a4 3540 if (stat(fileb, &b) < 0)
b4f10a5e
LP
3541 return -errno;
3542
9d9951a4
HH
3543 return a.st_dev == b.st_dev &&
3544 a.st_ino == b.st_ino;
3545}
3546
3547int running_in_chroot(void) {
3548 int ret;
3549
3550 ret = files_same("/proc/1/root", "/");
3551 if (ret < 0)
3552 return ret;
3553
3554 return ret == 0;
b4f10a5e
LP
3555}
3556
f405e86d 3557static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
72f59706 3558 size_t x;
8fe914ec
LP
3559 char *r;
3560
3561 assert(s);
3562 assert(percent <= 100);
72f59706 3563 assert(new_length >= 3);
8fe914ec 3564
72f59706
LP
3565 if (old_length <= 3 || old_length <= new_length)
3566 return strndup(s, old_length);
8fe914ec 3567
72f59706
LP
3568 r = new0(char, new_length+1);
3569 if (!r)
a6f0104a 3570 return NULL;
8fe914ec 3571
72f59706 3572 x = (new_length * percent) / 100;
8fe914ec 3573
72f59706
LP
3574 if (x > new_length - 3)
3575 x = new_length - 3;
8fe914ec
LP
3576
3577 memcpy(r, s, x);
3578 r[x] = '.';
3579 r[x+1] = '.';
3580 r[x+2] = '.';
3581 memcpy(r + x + 3,
72f59706
LP
3582 s + old_length - (new_length - x - 3),
3583 new_length - x - 3);
8fe914ec
LP
3584
3585 return r;
3586}
3587
f405e86d
SL
3588char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
3589 size_t x;
3590 char *e;
3591 const char *i, *j;
3592 unsigned k, len, len2;
3593
3594 assert(s);
3595 assert(percent <= 100);
3596 assert(new_length >= 3);
3597
3598 /* if no multibyte characters use ascii_ellipsize_mem for speed */
3599 if (ascii_is_valid(s))
3600 return ascii_ellipsize_mem(s, old_length, new_length, percent);
3601
3602 if (old_length <= 3 || old_length <= new_length)
3603 return strndup(s, old_length);
3604
3605 x = (new_length * percent) / 100;
3606
3607 if (x > new_length - 3)
3608 x = new_length - 3;
3609
3610 k = 0;
3611 for (i = s; k < x && i < s + old_length; i = utf8_next_char(i)) {
3612 int c;
3613
3614 c = utf8_encoded_to_unichar(i);
3615 if (c < 0)
3616 return NULL;
3617 k += unichar_iswide(c) ? 2 : 1;
3618 }
3619
3620 if (k > x) /* last character was wide and went over quota */
3621 x ++;
3622
3623 for (j = s + old_length; k < new_length && j > i; ) {
3624 int c;
3625
3626 j = utf8_prev_char(j);
3627 c = utf8_encoded_to_unichar(j);
3628 if (c < 0)
3629 return NULL;
3630 k += unichar_iswide(c) ? 2 : 1;
3631 }
3632 assert(i <= j);
3633
3634 /* we don't actually need to ellipsize */
3635 if (i == j)
3636 return memdup(s, old_length + 1);
3637
3638 /* make space for ellipsis */
3639 j = utf8_next_char(j);
3640
3641 len = i - s;
3642 len2 = s + old_length - j;
3643 e = new(char, len + 3 + len2 + 1);
3644 if (!e)
3645 return NULL;
3646
3647 /*
3648 printf("old_length=%zu new_length=%zu x=%zu len=%u len2=%u k=%u\n",
3649 old_length, new_length, x, len, len2, k);
3650 */
3651
3652 memcpy(e, s, len);
3653 e[len] = 0xe2; /* tri-dot ellipsis: … */
3654 e[len + 1] = 0x80;
3655 e[len + 2] = 0xa6;
3656
3657 memcpy(e + len + 3, j, len2 + 1);
3658
3659 return e;
3660}
3661
72f59706
LP
3662char *ellipsize(const char *s, size_t length, unsigned percent) {
3663 return ellipsize_mem(s, strlen(s), length, percent);
3664}
3665
c38dfac9 3666int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
03e334a1 3667 _cleanup_close_ int fd;
c38dfac9 3668 int r;
f6144808
LP
3669
3670 assert(path);
3671
c38dfac9
KS
3672 if (parents)
3673 mkdir_parents(path, 0755);
73836c5c 3674
c38dfac9 3675 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode > 0 ? mode : 0644);
73836c5c 3676 if (fd < 0)
f6144808
LP
3677 return -errno;
3678
c38dfac9
KS
3679 if (mode > 0) {
3680 r = fchmod(fd, mode);
3681 if (r < 0)
3682 return -errno;
3683 }
3684
fed1e721 3685 if (uid != UID_INVALID || gid != GID_INVALID) {
c38dfac9
KS
3686 r = fchown(fd, uid, gid);
3687 if (r < 0)
3688 return -errno;
3689 }
3690
3a43da28 3691 if (stamp != USEC_INFINITY) {
c38dfac9
KS
3692 struct timespec ts[2];
3693
3694 timespec_store(&ts[0], stamp);
359efc59 3695 ts[1] = ts[0];
c38dfac9
KS
3696 r = futimens(fd, ts);
3697 } else
3698 r = futimens(fd, NULL);
3699 if (r < 0)
3700 return -errno;
3701
f6144808
LP
3702 return 0;
3703}
afea26ad 3704
c38dfac9 3705int touch(const char *path) {
fed1e721 3706 return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, 0);
c38dfac9
KS
3707}
3708
97c4a07d 3709char *unquote(const char *s, const char* quotes) {
11ce3427
LP
3710 size_t l;
3711 assert(s);
3712
73836c5c
LP
3713 /* This is rather stupid, simply removes the heading and
3714 * trailing quotes if there is one. Doesn't care about
57f30678 3715 * escaping or anything. We should make this smarter one
cc13b327 3716 * day... */
73836c5c 3717
31ed59c5
LP
3718 l = strlen(s);
3719 if (l < 2)
11ce3427
LP
3720 return strdup(s);
3721
97c4a07d 3722 if (strchr(quotes, s[0]) && s[l-1] == s[0])
11ce3427
LP
3723 return strndup(s+1, l-2);
3724
3725 return strdup(s);
3726}
3727
5f7c426e 3728char *normalize_env_assignment(const char *s) {
f4934dfa
LP
3729 _cleanup_free_ char *value = NULL;
3730 const char *eq;
3731 char *p, *name;
5f7c426e 3732
57f30678
LP
3733 eq = strchr(s, '=');
3734 if (!eq) {
f4934dfa 3735 char *r, *t;
5f7c426e 3736
57f30678
LP
3737 r = strdup(s);
3738 if (!r)
5f7c426e
LP
3739 return NULL;
3740
57f30678 3741 t = strstrip(r);
f4934dfa
LP
3742 if (t != r)
3743 memmove(r, t, strlen(t) + 1);
57f30678 3744
57f30678 3745 return r;
5f7c426e
LP
3746 }
3747
f4934dfa
LP
3748 name = strndupa(s, eq - s);
3749 p = strdupa(eq + 1);
5f7c426e
LP
3750
3751 value = unquote(strstrip(p), QUOTES);
57f30678 3752 if (!value)
5f7c426e 3753 return NULL;
5f7c426e 3754
f4934dfa 3755 return strjoin(strstrip(name), "=", value, NULL);
5f7c426e
LP
3756}
3757
8e12a6ae 3758int wait_for_terminate(pid_t pid, siginfo_t *status) {
1968a360
LP
3759 siginfo_t dummy;
3760
2e78aa99 3761 assert(pid >= 1);
1968a360
LP
3762
3763 if (!status)
3764 status = &dummy;
2e78aa99
LP
3765
3766 for (;;) {
8e12a6ae
LP
3767 zero(*status);
3768
3769 if (waitid(P_PID, pid, status, WEXITED) < 0) {
2e78aa99
LP
3770
3771 if (errno == EINTR)
3772 continue;
3773
3774 return -errno;
3775 }
3776
3777 return 0;
3778 }
3779}
3780
0659e8ba
LS
3781/*
3782 * Return values:
3783 * < 0 : wait_for_terminate() failed to get the state of the
3784 * process, the process was terminated by a signal, or
3785 * failed for an unknown reason.
3786 * >=0 : The process terminated normally, and its exit code is
3787 * returned.
3788 *
3789 * That is, success is indicated by a return value of zero, and an
3790 * error is indicated by a non-zero value.
820d3acf
ZJS
3791 *
3792 * A warning is emitted if the process terminates abnormally,
3793 * and also if it returns non-zero unless check_exit_code is true.
0659e8ba 3794 */
820d3acf 3795int wait_for_terminate_and_warn(const char *name, pid_t pid, bool check_exit_code) {
97c4a07d
LP
3796 int r;
3797 siginfo_t status;
3798
3799 assert(name);
3800 assert(pid > 1);
3801
d87be9b0 3802 r = wait_for_terminate(pid, &status);
f647962d
MS
3803 if (r < 0)
3804 return log_warning_errno(r, "Failed to wait for %s: %m", name);
97c4a07d
LP
3805
3806 if (status.si_code == CLD_EXITED) {
820d3acf
ZJS
3807 if (status.si_status != 0)
3808 log_full(check_exit_code ? LOG_WARNING : LOG_DEBUG,
3809 "%s failed with error code %i.", name, status.si_status);
3810 else
3811 log_debug("%s succeeded.", name);
97c4a07d 3812
820d3acf 3813 return status.si_status;
97c4a07d
LP
3814 } else if (status.si_code == CLD_KILLED ||
3815 status.si_code == CLD_DUMPED) {
3816
3817 log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
3818 return -EPROTO;
3819 }
3820
3821 log_warning("%s failed due to unknown reason.", name);
3822 return -EPROTO;
97c4a07d
LP
3823}
3824
919ce0b7 3825noreturn void freeze(void) {
720ce21d
LP
3826
3827 /* Make sure nobody waits for us on a socket anymore */
3828 close_all_fds(NULL, 0);
3829
c29597a1
LP
3830 sync();
3831
3c14d26c
LP
3832 for (;;)
3833 pause();
3834}
3835
00dc5d76
LP
3836bool null_or_empty(struct stat *st) {
3837 assert(st);
3838
3839 if (S_ISREG(st->st_mode) && st->st_size <= 0)
3840 return true;
3841
c8f26f42 3842 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
00dc5d76
LP
3843 return true;
3844
3845 return false;
3846}
3847
83096483
LP
3848int null_or_empty_path(const char *fn) {
3849 struct stat st;
3850
3851 assert(fn);
3852
3853 if (stat(fn, &st) < 0)
3854 return -errno;
3855
3856 return null_or_empty(&st);
3857}
3858
ed88bcfb
ZJS
3859int null_or_empty_fd(int fd) {
3860 struct stat st;
3861
3862 assert(fd >= 0);
3863
3864 if (fstat(fd, &st) < 0)
3865 return -errno;
3866
3867 return null_or_empty(&st);
3868}
3869
a247755d 3870DIR *xopendirat(int fd, const char *name, int flags) {
c4731d11
LP
3871 int nfd;
3872 DIR *d;
3873
dd94c17e
LP
3874 assert(!(flags & O_CREAT));
3875
3876 nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
73836c5c 3877 if (nfd < 0)
c4731d11
LP
3878 return NULL;
3879
73836c5c
LP
3880 d = fdopendir(nfd);
3881 if (!d) {
03e334a1 3882 safe_close(nfd);
c4731d11
LP
3883 return NULL;
3884 }
3885
3886 return d;
3b63d2d3
LP
3887}
3888
8a0867d6
LP
3889int signal_from_string_try_harder(const char *s) {
3890 int signo;
3891 assert(s);
3892
73836c5c
LP
3893 signo = signal_from_string(s);
3894 if (signo <= 0)
8a0867d6
LP
3895 if (startswith(s, "SIG"))
3896 return signal_from_string(s+3);
3897
3898 return signo;
3899}
3900
383182b5 3901static char *tag_to_udev_node(const char *tagvalue, const char *by) {
22f5f628 3902 _cleanup_free_ char *t = NULL, *u = NULL;
22f5f628 3903 size_t enc_len;
e23a0ce8 3904
383182b5 3905 u = unquote(tagvalue, "\"\'");
6db615c1 3906 if (!u)
383182b5 3907 return NULL;
e23a0ce8 3908
1d5989fd 3909 enc_len = strlen(u) * 4 + 1;
22f5f628 3910 t = new(char, enc_len);
6db615c1 3911 if (!t)
383182b5 3912 return NULL;
e23a0ce8 3913
8f6ce71f 3914 if (encode_devnode_name(u, t, enc_len) < 0)
22f5f628 3915 return NULL;
e23a0ce8 3916
6db615c1 3917 return strjoin("/dev/disk/by-", by, "/", t, NULL);
383182b5 3918}
e23a0ce8 3919
383182b5 3920char *fstab_node_to_udev_node(const char *p) {
faa368e3
LP
3921 assert(p);
3922
383182b5
DR
3923 if (startswith(p, "LABEL="))
3924 return tag_to_udev_node(p+6, "label");
e23a0ce8 3925
383182b5
DR
3926 if (startswith(p, "UUID="))
3927 return tag_to_udev_node(p+5, "uuid");
e23a0ce8 3928
84cc2abf
DR
3929 if (startswith(p, "PARTUUID="))
3930 return tag_to_udev_node(p+9, "partuuid");
3931
3932 if (startswith(p, "PARTLABEL="))
3933 return tag_to_udev_node(p+10, "partlabel");
3934
e23a0ce8
LP
3935 return strdup(p);
3936}
3937
f212ac12
LP
3938bool tty_is_vc(const char *tty) {
3939 assert(tty);
3940
98a28fef
LP
3941 return vtnr_from_tty(tty) >= 0;
3942}
3943
d1122ad5
LP
3944bool tty_is_console(const char *tty) {
3945 assert(tty);
3946
3947 if (startswith(tty, "/dev/"))
3948 tty += 5;
3949
3950 return streq(tty, "console");
3951}
3952
98a28fef
LP
3953int vtnr_from_tty(const char *tty) {
3954 int i, r;
3955
3956 assert(tty);
3957
3958 if (startswith(tty, "/dev/"))
3959 tty += 5;
3960
3961 if (!startswith(tty, "tty") )
3962 return -EINVAL;
3963
3964 if (tty[3] < '0' || tty[3] > '9')
3965 return -EINVAL;
3966
3967 r = safe_atoi(tty+3, &i);
3968 if (r < 0)
3969 return r;
3970
3971 if (i < 0 || i > 63)
3972 return -EINVAL;
3973
3974 return i;
f212ac12
LP
3975}
3976
21baf21a
MS
3977char *resolve_dev_console(char **active) {
3978 char *tty;
3979
3980 /* Resolve where /dev/console is pointing to, if /sys is actually ours
3981 * (i.e. not read-only-mounted which is a sign for container setups) */
3982
3983 if (path_is_read_only_fs("/sys") > 0)
3984 return NULL;
3985
3986 if (read_one_line_file("/sys/class/tty/console/active", active) < 0)
3987 return NULL;
3988
3989 /* If multiple log outputs are configured the last one is what
3990 * /dev/console points to */
3991 tty = strrchr(*active, ' ');
3992 if (tty)
3993 tty++;
3994 else
3995 tty = *active;
3996
8aa5429a
OB
3997 if (streq(tty, "tty0")) {
3998 char *tmp;
3999
4000 /* Get the active VC (e.g. tty1) */
4001 if (read_one_line_file("/sys/class/tty/tty0/active", &tmp) >= 0) {
4002 free(*active);
4003 tty = *active = tmp;
4004 }
4005 }
4006
21baf21a
MS
4007 return tty;
4008}
4009
3043935f 4010bool tty_is_vc_resolve(const char *tty) {
9588bc32 4011 _cleanup_free_ char *active = NULL;
3030ccd7 4012
e3aa71c3
LP
4013 assert(tty);
4014
4015 if (startswith(tty, "/dev/"))
4016 tty += 5;
4017
21baf21a
MS
4018 if (streq(tty, "console")) {
4019 tty = resolve_dev_console(&active);
4020 if (!tty)
4021 return false;
4022 }
3030ccd7 4023
9588bc32 4024 return tty_is_vc(tty);
3043935f
LP
4025}
4026
4027const char *default_term_for_tty(const char *tty) {
4028 assert(tty);
4029
3c4230a5 4030 return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt220";
e3aa71c3
LP
4031}
4032
87d2c1ff 4033bool dirent_is_file(const struct dirent *de) {
fb19a739
LP
4034 assert(de);
4035
a34bf9db 4036 if (hidden_file(de->d_name))
fb19a739
LP
4037 return false;
4038
4039 if (de->d_type != DT_REG &&
4040 de->d_type != DT_LNK &&
4041 de->d_type != DT_UNKNOWN)
4042 return false;
4043
4044 return true;
4045}
4046
87d2c1ff
LP
4047bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
4048 assert(de);
4049
a228a22f
LP
4050 if (de->d_type != DT_REG &&
4051 de->d_type != DT_LNK &&
4052 de->d_type != DT_UNKNOWN)
4053 return false;
4054
a34bf9db 4055 if (hidden_file_allow_backup(de->d_name))
87d2c1ff
LP
4056 return false;
4057
4058 return endswith(de->d_name, suffix);
4059}
4060
e801700e 4061static int do_execute(char **directories, usec_t timeout, char *argv[]) {
49681057 4062 _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
e801700e
ZJS
4063 _cleanup_set_free_free_ Set *seen = NULL;
4064 char **directory;
83cc030f 4065
49681057
ZJS
4066 /* We fork this all off from a child process so that we can
4067 * somewhat cleanly make use of SIGALRM to set a time limit */
83cc030f 4068
49681057
ZJS
4069 reset_all_signal_handlers();
4070 reset_signal_mask();
83cc030f 4071
49681057 4072 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
83cc030f 4073
49681057
ZJS
4074 pids = hashmap_new(NULL);
4075 if (!pids)
4076 return log_oom();
83cc030f 4077
e801700e
ZJS
4078 seen = set_new(&string_hash_ops);
4079 if (!seen)
4080 return log_oom();
83cc030f 4081
e801700e
ZJS
4082 STRV_FOREACH(directory, directories) {
4083 _cleanup_closedir_ DIR *d;
4084 struct dirent *de;
83cc030f 4085
e801700e
ZJS
4086 d = opendir(*directory);
4087 if (!d) {
4088 if (errno == ENOENT)
4089 continue;
83cc030f 4090
e801700e
ZJS
4091 return log_error_errno(errno, "Failed to open directory %s: %m", *directory);
4092 }
83cc030f 4093
e801700e
ZJS
4094 FOREACH_DIRENT(de, d, break) {
4095 _cleanup_free_ char *path = NULL;
4096 pid_t pid;
4097 int r;
4098
4099 if (!dirent_is_file(de))
4100 continue;
83cc030f 4101
e801700e
ZJS
4102 if (set_contains(seen, de->d_name)) {
4103 log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name);
4104 continue;
4105 }
4106
4107 r = set_put_strdup(seen, de->d_name);
4108 if (r < 0)
4109 return log_oom();
4110
4111 path = strjoin(*directory, "/", de->d_name, NULL);
4112 if (!path)
4113 return log_oom();
4114
4115 if (null_or_empty_path(path)) {
4116 log_debug("%s is empty (a mask).", path);
4117 continue;
49681057 4118 } else
e801700e 4119 log_debug("%s will be executed.", path);
83cc030f 4120
e801700e
ZJS
4121 pid = fork();
4122 if (pid < 0) {
4123 log_error_errno(errno, "Failed to fork: %m");
4124 continue;
4125 } else if (pid == 0) {
4126 char *_argv[2];
83cc030f 4127
e801700e 4128 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
83cc030f 4129
e801700e
ZJS
4130 if (!argv) {
4131 _argv[0] = path;
4132 _argv[1] = NULL;
4133 argv = _argv;
4134 } else
4135 argv[0] = path;
4136
4137 execv(path, argv);
4138 return log_error_errno(errno, "Failed to execute %s: %m", path);
4139 }
4140
4141 log_debug("Spawned %s as " PID_FMT ".", path, pid);
83cc030f 4142
e801700e
ZJS
4143 r = hashmap_put(pids, UINT_TO_PTR(pid), path);
4144 if (r < 0)
4145 return log_oom();
4146 path = NULL;
4147 }
49681057 4148 }
83cc030f 4149
49681057
ZJS
4150 /* Abort execution of this process after the timout. We simply
4151 * rely on SIGALRM as default action terminating the process,
4152 * and turn on alarm(). */
83cc030f 4153
49681057
ZJS
4154 if (timeout != USEC_INFINITY)
4155 alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
83cc030f 4156
49681057
ZJS
4157 while (!hashmap_isempty(pids)) {
4158 _cleanup_free_ char *path = NULL;
4159 pid_t pid;
aa62a893 4160
49681057
ZJS
4161 pid = PTR_TO_UINT(hashmap_first_key(pids));
4162 assert(pid > 0);
83cc030f 4163
49681057
ZJS
4164 path = hashmap_remove(pids, UINT_TO_PTR(pid));
4165 assert(path);
aa62a893 4166
49681057
ZJS
4167 wait_for_terminate_and_warn(path, pid, true);
4168 }
aa62a893 4169
49681057
ZJS
4170 return 0;
4171}
aa62a893 4172
e801700e 4173void execute_directories(const char* const* directories, usec_t timeout, char *argv[]) {
49681057
ZJS
4174 pid_t executor_pid;
4175 int r;
e801700e
ZJS
4176 char *name;
4177 char **dirs = (char**) directories;
4178
4179 assert(!strv_isempty(dirs));
83cc030f 4180
e801700e
ZJS
4181 name = basename(dirs[0]);
4182 assert(!isempty(name));
aa62a893 4183
e801700e
ZJS
4184 /* Executes all binaries in the directories in parallel and waits
4185 * for them to finish. Optionally a timeout is applied. If a file
4186 * with the same name exists in more than one directory, the
4187 * earliest one wins. */
83cc030f 4188
49681057
ZJS
4189 executor_pid = fork();
4190 if (executor_pid < 0) {
4191 log_error_errno(errno, "Failed to fork: %m");
4192 return;
4193
4194 } else if (executor_pid == 0) {
e801700e 4195 r = do_execute(dirs, timeout, argv);
49681057 4196 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
aa62a893 4197 }
83cc030f 4198
e801700e 4199 wait_for_terminate_and_warn(name, executor_pid, true);
83cc030f
LP
4200}
4201
430c18ed
LP
4202int kill_and_sigcont(pid_t pid, int sig) {
4203 int r;
4204
4205 r = kill(pid, sig) < 0 ? -errno : 0;
4206
4207 if (r >= 0)
4208 kill(pid, SIGCONT);
4209
4210 return r;
4211}
4212
05feefe0
LP
4213bool nulstr_contains(const char*nulstr, const char *needle) {
4214 const char *i;
4215
4216 if (!nulstr)
4217 return false;
4218
4219 NULSTR_FOREACH(i, nulstr)
4220 if (streq(i, needle))
4221 return true;
4222
4223 return false;
4224}
4225
6faa1114 4226bool plymouth_running(void) {
9408a2d2 4227 return access("/run/plymouth/pid", F_OK) >= 0;
6faa1114
LP
4228}
4229
9beb3f4d
LP
4230char* strshorten(char *s, size_t l) {
4231 assert(s);
4232
4233 if (l < strlen(s))
4234 s[l] = 0;
4235
4236 return s;
4237}
4238
4239static bool hostname_valid_char(char c) {
4240 return
4241 (c >= 'a' && c <= 'z') ||
4242 (c >= 'A' && c <= 'Z') ||
4243 (c >= '0' && c <= '9') ||
4244 c == '-' ||
4245 c == '_' ||
4246 c == '.';
4247}
4248
4249bool hostname_is_valid(const char *s) {
4250 const char *p;
aa3c5cf8 4251 bool dot;
9beb3f4d
LP
4252
4253 if (isempty(s))
4254 return false;
4255
40672b99
LP
4256 /* Doesn't accept empty hostnames, hostnames with trailing or
4257 * leading dots, and hostnames with multiple dots in a
4258 * sequence. Also ensures that the length stays below
4259 * HOST_NAME_MAX. */
4260
aa3c5cf8
LP
4261 for (p = s, dot = true; *p; p++) {
4262 if (*p == '.') {
4263 if (dot)
4264 return false;
4265
4266 dot = true;
4267 } else {
4268 if (!hostname_valid_char(*p))
4269 return false;
4270
4271 dot = false;
4272 }
4273 }
4274
4275 if (dot)
4276 return false;
9beb3f4d
LP
4277
4278 if (p-s > HOST_NAME_MAX)
4279 return false;
4280
4281 return true;
4282}
4283
e724b063 4284char* hostname_cleanup(char *s, bool lowercase) {
9beb3f4d 4285 char *p, *d;
cec4ead9
LP
4286 bool dot;
4287
4288 for (p = s, d = s, dot = true; *p; p++) {
4289 if (*p == '.') {
e724b063 4290 if (dot)
cec4ead9 4291 continue;
9beb3f4d 4292
e724b063 4293 *(d++) = '.';
cec4ead9 4294 dot = true;
e724b063
LP
4295 } else if (hostname_valid_char(*p)) {
4296 *(d++) = lowercase ? tolower(*p) : *p;
cec4ead9 4297 dot = false;
e724b063 4298 }
cec4ead9 4299
cec4ead9 4300 }
9beb3f4d 4301
e724b063
LP
4302 if (dot && d > s)
4303 d[-1] = 0;
4304 else
4305 *d = 0;
4306
9beb3f4d 4307 strshorten(s, HOST_NAME_MAX);
cec4ead9 4308
9beb3f4d
LP
4309 return s;
4310}
4311
7f0d207d
LP
4312bool machine_name_is_valid(const char *s) {
4313
4314 if (!hostname_is_valid(s))
4315 return false;
4316
4317 /* Machine names should be useful hostnames, but also be
4318 * useful in unit names, hence we enforce a stricter length
4319 * limitation. */
4320
4321 if (strlen(s) > 64)
4322 return false;
4323
4324 return true;
4325}
4326
1325aa42 4327int pipe_eof(int fd) {
b92bea5d
ZJS
4328 struct pollfd pollfd = {
4329 .fd = fd,
4330 .events = POLLIN|POLLHUP,
4331 };
1325aa42 4332
d37a91e8
LP
4333 int r;
4334
1325aa42
LP
4335 r = poll(&pollfd, 1, 0);
4336 if (r < 0)
4337 return -errno;
4338
4339 if (r == 0)
4340 return 0;
4341
4342 return pollfd.revents & POLLHUP;
4343}
4344
8f2d43a0 4345int fd_wait_for_event(int fd, int event, usec_t t) {
968d3d24 4346
b92bea5d
ZJS
4347 struct pollfd pollfd = {
4348 .fd = fd,
4349 .events = event,
4350 };
df50185b 4351
968d3d24
LP
4352 struct timespec ts;
4353 int r;
4354
3a43da28 4355 r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
df50185b
LP
4356 if (r < 0)
4357 return -errno;
4358
4359 if (r == 0)
4360 return 0;
4361
4362 return pollfd.revents;
4363}
4364
5a3ab509
LP
4365int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
4366 FILE *f;
4367 char *t;
ae6c3cc0 4368 int r, fd;
5a3ab509
LP
4369
4370 assert(path);
4371 assert(_f);
4372 assert(_temp_path);
4373
ae6c3cc0
LP
4374 r = tempfn_xxxxxx(path, &t);
4375 if (r < 0)
4376 return r;
5a3ab509 4377
2d5bdf5b 4378 fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC);
5a3ab509
LP
4379 if (fd < 0) {
4380 free(t);
4381 return -errno;
4382 }
4383
4384 f = fdopen(fd, "we");
4385 if (!f) {
4386 unlink(t);
4387 free(t);
4388 return -errno;
4389 }
4390
4391 *_f = f;
4392 *_temp_path = t;
4393
4394 return 0;
4395}
4396
6ea832a2 4397int terminal_vhangup_fd(int fd) {
5a3ab509
LP
4398 assert(fd >= 0);
4399
6ea832a2
LP
4400 if (ioctl(fd, TIOCVHANGUP) < 0)
4401 return -errno;
4402
4403 return 0;
4404}
4405
4406int terminal_vhangup(const char *name) {
03e334a1 4407 _cleanup_close_ int fd;
6ea832a2
LP
4408
4409 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4410 if (fd < 0)
4411 return fd;
4412
03e334a1 4413 return terminal_vhangup_fd(fd);
6ea832a2
LP
4414}
4415
4416int vt_disallocate(const char *name) {
4417 int fd, r;
4418 unsigned u;
6ea832a2
LP
4419
4420 /* Deallocate the VT if possible. If not possible
4421 * (i.e. because it is the active one), at least clear it
4422 * entirely (including the scrollback buffer) */
4423
b83bc4e9
LP
4424 if (!startswith(name, "/dev/"))
4425 return -EINVAL;
4426
4427 if (!tty_is_vc(name)) {
4428 /* So this is not a VT. I guess we cannot deallocate
4429 * it then. But let's at least clear the screen */
4430
4431 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4432 if (fd < 0)
4433 return fd;
4434
8585357a
LP
4435 loop_write(fd,
4436 "\033[r" /* clear scrolling region */
4437 "\033[H" /* move home */
4438 "\033[2J", /* clear screen */
4439 10, false);
03e334a1 4440 safe_close(fd);
b83bc4e9
LP
4441
4442 return 0;
4443 }
6ea832a2
LP
4444
4445 if (!startswith(name, "/dev/tty"))
4446 return -EINVAL;
4447
4448 r = safe_atou(name+8, &u);
4449 if (r < 0)
4450 return r;
4451
4452 if (u <= 0)
b83bc4e9 4453 return -EINVAL;
6ea832a2 4454
b83bc4e9 4455 /* Try to deallocate */
6ea832a2
LP
4456 fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
4457 if (fd < 0)
4458 return fd;
4459
4460 r = ioctl(fd, VT_DISALLOCATE, u);
03e334a1 4461 safe_close(fd);
6ea832a2 4462
b83bc4e9
LP
4463 if (r >= 0)
4464 return 0;
6ea832a2 4465
b83bc4e9 4466 if (errno != EBUSY)
6ea832a2 4467 return -errno;
6ea832a2 4468
b83bc4e9
LP
4469 /* Couldn't deallocate, so let's clear it fully with
4470 * scrollback */
4471 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
6ea832a2 4472 if (fd < 0)
b83bc4e9 4473 return fd;
6ea832a2 4474
8585357a
LP
4475 loop_write(fd,
4476 "\033[r" /* clear scrolling region */
4477 "\033[H" /* move home */
4478 "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
4479 10, false);
03e334a1 4480 safe_close(fd);
6ea832a2 4481
b83bc4e9 4482 return 0;
6ea832a2
LP
4483}
4484
424a19f8 4485int symlink_atomic(const char *from, const char *to) {
2e78fa79 4486 _cleanup_free_ char *t = NULL;
ae6c3cc0 4487 int r;
34ca941c
LP
4488
4489 assert(from);
4490 assert(to);
4491
ae6c3cc0
LP
4492 r = tempfn_random(to, &t);
4493 if (r < 0)
4494 return r;
34ca941c 4495
424a19f8
LP
4496 if (symlink(from, t) < 0)
4497 return -errno;
34ca941c
LP
4498
4499 if (rename(t, to) < 0) {
2e78fa79
LP
4500 unlink_noerrno(t);
4501 return -errno;
34ca941c
LP
4502 }
4503
424a19f8 4504 return 0;
34ca941c
LP
4505}
4506
1554afae
LP
4507int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
4508 _cleanup_free_ char *t = NULL;
ae6c3cc0 4509 int r;
1554afae
LP
4510
4511 assert(path);
4512
ae6c3cc0
LP
4513 r = tempfn_random(path, &t);
4514 if (r < 0)
4515 return r;
1554afae
LP
4516
4517 if (mknod(t, mode, dev) < 0)
4518 return -errno;
4519
4520 if (rename(t, path) < 0) {
4521 unlink_noerrno(t);
4522 return -errno;
4523 }
4524
4525 return 0;
4526}
4527
4528int mkfifo_atomic(const char *path, mode_t mode) {
4529 _cleanup_free_ char *t = NULL;
ae6c3cc0 4530 int r;
1554afae
LP
4531
4532 assert(path);
4533
ae6c3cc0
LP
4534 r = tempfn_random(path, &t);
4535 if (r < 0)
4536 return r;
1554afae
LP
4537
4538 if (mkfifo(t, mode) < 0)
4539 return -errno;
4540
4541 if (rename(t, path) < 0) {
4542 unlink_noerrno(t);
4543 return -errno;
4544 }
4545
4546 return 0;
4547}
4548
4d6d6518
LP
4549bool display_is_local(const char *display) {
4550 assert(display);
4551
4552 return
4553 display[0] == ':' &&
4554 display[1] >= '0' &&
4555 display[1] <= '9';
4556}
4557
4558int socket_from_display(const char *display, char **path) {
4559 size_t k;
4560 char *f, *c;
4561
4562 assert(display);
4563 assert(path);
4564
4565 if (!display_is_local(display))
4566 return -EINVAL;
4567
4568 k = strspn(display+1, "0123456789");
4569
f8294e41 4570 f = new(char, strlen("/tmp/.X11-unix/X") + k + 1);
4d6d6518
LP
4571 if (!f)
4572 return -ENOMEM;
4573
4574 c = stpcpy(f, "/tmp/.X11-unix/X");
4575 memcpy(c, display+1, k);
4576 c[k] = 0;
4577
4578 *path = f;
4579
4580 return 0;
4581}
4582
d05c5031
LP
4583int get_user_creds(
4584 const char **username,
4585 uid_t *uid, gid_t *gid,
4586 const char **home,
4587 const char **shell) {
4588
1cccf435 4589 struct passwd *p;
ddd88763 4590 uid_t u;
1cccf435
MV
4591
4592 assert(username);
4593 assert(*username);
1cccf435
MV
4594
4595 /* We enforce some special rules for uid=0: in order to avoid
4596 * NSS lookups for root we hardcode its data. */
4597
4598 if (streq(*username, "root") || streq(*username, "0")) {
4599 *username = "root";
4b67834e
LP
4600
4601 if (uid)
4602 *uid = 0;
4603
4604 if (gid)
4605 *gid = 0;
4606
4607 if (home)
4608 *home = "/root";
d05c5031
LP
4609
4610 if (shell)
4611 *shell = "/bin/sh";
4612
1cccf435
MV
4613 return 0;
4614 }
4615
ddd88763 4616 if (parse_uid(*username, &u) >= 0) {
1cccf435 4617 errno = 0;
ddd88763 4618 p = getpwuid(u);
1cccf435
MV
4619
4620 /* If there are multiple users with the same id, make
4621 * sure to leave $USER to the configured value instead
4622 * of the first occurrence in the database. However if
4623 * the uid was configured by a numeric uid, then let's
4624 * pick the real username from /etc/passwd. */
4625 if (p)
4626 *username = p->pw_name;
4627 } else {
4628 errno = 0;
4629 p = getpwnam(*username);
4630 }
4631
4632 if (!p)
8333c77e 4633 return errno > 0 ? -errno : -ESRCH;
1cccf435 4634
4b67834e
LP
4635 if (uid)
4636 *uid = p->pw_uid;
4637
4638 if (gid)
4639 *gid = p->pw_gid;
4640
4641 if (home)
4642 *home = p->pw_dir;
4643
d05c5031
LP
4644 if (shell)
4645 *shell = p->pw_shell;
4646
4b67834e
LP
4647 return 0;
4648}
4649
59164be4
LP
4650char* uid_to_name(uid_t uid) {
4651 struct passwd *p;
4652 char *r;
4653
4654 if (uid == 0)
4655 return strdup("root");
4656
4657 p = getpwuid(uid);
4658 if (p)
4659 return strdup(p->pw_name);
4660
de0671ee 4661 if (asprintf(&r, UID_FMT, uid) < 0)
59164be4
LP
4662 return NULL;
4663
4664 return r;
4665}
4666
4468addc
LP
4667char* gid_to_name(gid_t gid) {
4668 struct group *p;
4669 char *r;
4670
4671 if (gid == 0)
4672 return strdup("root");
4673
4674 p = getgrgid(gid);
4675 if (p)
4676 return strdup(p->gr_name);
4677
de0671ee 4678 if (asprintf(&r, GID_FMT, gid) < 0)
4468addc
LP
4679 return NULL;
4680
4681 return r;
4682}
4683
4b67834e
LP
4684int get_group_creds(const char **groupname, gid_t *gid) {
4685 struct group *g;
4686 gid_t id;
4687
4688 assert(groupname);
4689
4690 /* We enforce some special rules for gid=0: in order to avoid
4691 * NSS lookups for root we hardcode its data. */
4692
4693 if (streq(*groupname, "root") || streq(*groupname, "0")) {
4694 *groupname = "root";
4695
4696 if (gid)
4697 *gid = 0;
4698
4699 return 0;
4700 }
4701
4702 if (parse_gid(*groupname, &id) >= 0) {
4703 errno = 0;
4704 g = getgrgid(id);
4705
4706 if (g)
4707 *groupname = g->gr_name;
4708 } else {
4709 errno = 0;
4710 g = getgrnam(*groupname);
4711 }
4712
4713 if (!g)
8333c77e 4714 return errno > 0 ? -errno : -ESRCH;
4b67834e
LP
4715
4716 if (gid)
4717 *gid = g->gr_gid;
4718
1cccf435
MV
4719 return 0;
4720}
4721
4468addc
LP
4722int in_gid(gid_t gid) {
4723 gid_t *gids;
43673799
LP
4724 int ngroups_max, r, i;
4725
43673799
LP
4726 if (getgid() == gid)
4727 return 1;
4728
4729 if (getegid() == gid)
4730 return 1;
4731
4732 ngroups_max = sysconf(_SC_NGROUPS_MAX);
4733 assert(ngroups_max > 0);
4734
4735 gids = alloca(sizeof(gid_t) * ngroups_max);
4736
4737 r = getgroups(ngroups_max, gids);
4738 if (r < 0)
4739 return -errno;
4740
4741 for (i = 0; i < r; i++)
4742 if (gids[i] == gid)
4743 return 1;
4744
4745 return 0;
4746}
4747
4468addc
LP
4748int in_group(const char *name) {
4749 int r;
4750 gid_t gid;
4751
4752 r = get_group_creds(&name, &gid);
4753 if (r < 0)
4754 return r;
4755
4756 return in_gid(gid);
4757}
4758
8092a428 4759int glob_exists(const char *path) {
7fd1b19b 4760 _cleanup_globfree_ glob_t g = {};
8d98da3f 4761 int k;
8092a428
LP
4762
4763 assert(path);
4764
8092a428
LP
4765 errno = 0;
4766 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
4767
4768 if (k == GLOB_NOMATCH)
8d98da3f 4769 return 0;
8092a428 4770 else if (k == GLOB_NOSPACE)
8d98da3f 4771 return -ENOMEM;
8092a428 4772 else if (k == 0)
8d98da3f 4773 return !strv_isempty(g.gl_pathv);
8092a428 4774 else
8d98da3f
ZJS
4775 return errno ? -errno : -EIO;
4776}
8092a428 4777
8d98da3f
ZJS
4778int glob_extend(char ***strv, const char *path) {
4779 _cleanup_globfree_ glob_t g = {};
4780 int k;
4781 char **p;
4782
4783 errno = 0;
a8ccacf5 4784 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
8d98da3f
ZJS
4785
4786 if (k == GLOB_NOMATCH)
4787 return -ENOENT;
4788 else if (k == GLOB_NOSPACE)
4789 return -ENOMEM;
4790 else if (k != 0 || strv_isempty(g.gl_pathv))
4791 return errno ? -errno : -EIO;
4792
4793 STRV_FOREACH(p, g.gl_pathv) {
4794 k = strv_extend(strv, *p);
4795 if (k < 0)
4796 break;
4797 }
4798
4799 return k;
8092a428
LP
4800}
4801
83096483
LP
4802int dirent_ensure_type(DIR *d, struct dirent *de) {
4803 struct stat st;
4804
4805 assert(d);
4806 assert(de);
4807
4808 if (de->d_type != DT_UNKNOWN)
4809 return 0;
4810
4811 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
4812 return -errno;
4813
4814 de->d_type =
4815 S_ISREG(st.st_mode) ? DT_REG :
4816 S_ISDIR(st.st_mode) ? DT_DIR :
4817 S_ISLNK(st.st_mode) ? DT_LNK :
4818 S_ISFIFO(st.st_mode) ? DT_FIFO :
4819 S_ISSOCK(st.st_mode) ? DT_SOCK :
4820 S_ISCHR(st.st_mode) ? DT_CHR :
4821 S_ISBLK(st.st_mode) ? DT_BLK :
4822 DT_UNKNOWN;
4823
4824 return 0;
4825}
4826
034a2a52 4827int get_files_in_directory(const char *path, char ***list) {
893fa014
ZJS
4828 _cleanup_closedir_ DIR *d = NULL;
4829 size_t bufsize = 0, n = 0;
4830 _cleanup_strv_free_ char **l = NULL;
034a2a52
LP
4831
4832 assert(path);
d60ef526
LP
4833
4834 /* Returns all files in a directory in *list, and the number
4835 * of files as return value. If list is NULL returns only the
893fa014 4836 * number. */
034a2a52
LP
4837
4838 d = opendir(path);
8ea913b2
LP
4839 if (!d)
4840 return -errno;
4841
034a2a52 4842 for (;;) {
7d5e9c0f 4843 struct dirent *de;
034a2a52 4844
3fd11280
FW
4845 errno = 0;
4846 de = readdir(d);
4847 if (!de && errno != 0)
4848 return -errno;
034a2a52
LP
4849 if (!de)
4850 break;
4851
4852 dirent_ensure_type(d, de);
4853
4854 if (!dirent_is_file(de))
4855 continue;
4856
d60ef526 4857 if (list) {
893fa014
ZJS
4858 /* one extra slot is needed for the terminating NULL */
4859 if (!GREEDY_REALLOC(l, bufsize, n + 2))
4860 return -ENOMEM;
034a2a52 4861
893fa014
ZJS
4862 l[n] = strdup(de->d_name);
4863 if (!l[n])
4864 return -ENOMEM;
034a2a52 4865
893fa014 4866 l[++n] = NULL;
d60ef526 4867 } else
893fa014 4868 n++;
034a2a52
LP
4869 }
4870
893fa014
ZJS
4871 if (list) {
4872 *list = l;
4873 l = NULL; /* avoid freeing */
4874 }
034a2a52 4875
893fa014 4876 return n;
034a2a52
LP
4877}
4878
b7def684 4879char *strjoin(const char *x, ...) {
911a4828
LP
4880 va_list ap;
4881 size_t l;
4882 char *r, *p;
4883
4884 va_start(ap, x);
4885
4886 if (x) {
4887 l = strlen(x);
4888
4889 for (;;) {
4890 const char *t;
040f18ea 4891 size_t n;
911a4828
LP
4892
4893 t = va_arg(ap, const char *);
4894 if (!t)
4895 break;
4896
040f18ea 4897 n = strlen(t);
e98055de
LN
4898 if (n > ((size_t) -1) - l) {
4899 va_end(ap);
040f18ea 4900 return NULL;
e98055de 4901 }
040f18ea
LP
4902
4903 l += n;
911a4828
LP
4904 }
4905 } else
4906 l = 0;
4907
4908 va_end(ap);
4909
4910 r = new(char, l+1);
4911 if (!r)
4912 return NULL;
4913
4914 if (x) {
4915 p = stpcpy(r, x);
4916
4917 va_start(ap, x);
4918
4919 for (;;) {
4920 const char *t;
4921
4922 t = va_arg(ap, const char *);
4923 if (!t)
4924 break;
4925
4926 p = stpcpy(p, t);
4927 }
8ea913b2
LP
4928
4929 va_end(ap);
911a4828
LP
4930 } else
4931 r[0] = 0;
4932
4933 return r;
4934}
4935
b636465b 4936bool is_main_thread(void) {
ec202eae 4937 static thread_local int cached = 0;
b636465b
LP
4938
4939 if (_unlikely_(cached == 0))
4940 cached = getpid() == gettid() ? 1 : -1;
4941
4942 return cached > 0;
4943}
4944
94959f0f
LP
4945int block_get_whole_disk(dev_t d, dev_t *ret) {
4946 char *p, *s;
4947 int r;
4948 unsigned n, m;
4949
4950 assert(ret);
4951
4952 /* If it has a queue this is good enough for us */
4953 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
4954 return -ENOMEM;
4955
4956 r = access(p, F_OK);
4957 free(p);
4958
4959 if (r >= 0) {
4960 *ret = d;
4961 return 0;
4962 }
4963
4964 /* If it is a partition find the originating device */
4965 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
4966 return -ENOMEM;
4967
4968 r = access(p, F_OK);
4969 free(p);
4970
4971 if (r < 0)
4972 return -ENOENT;
4973
4974 /* Get parent dev_t */
4975 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
4976 return -ENOMEM;
4977
4978 r = read_one_line_file(p, &s);
4979 free(p);
4980
4981 if (r < 0)
4982 return r;
4983
4984 r = sscanf(s, "%u:%u", &m, &n);
4985 free(s);
4986
4987 if (r != 2)
4988 return -EINVAL;
4989
4990 /* Only return this if it is really good enough for us. */
4991 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
4992 return -ENOMEM;
4993
4994 r = access(p, F_OK);
4995 free(p);
4996
4997 if (r >= 0) {
4998 *ret = makedev(m, n);
4999 return 0;
5000 }
5001
5002 return -ENOENT;
5003}
5004
f41607a6
LP
5005static const char *const ioprio_class_table[] = {
5006 [IOPRIO_CLASS_NONE] = "none",
5007 [IOPRIO_CLASS_RT] = "realtime",
5008 [IOPRIO_CLASS_BE] = "best-effort",
5009 [IOPRIO_CLASS_IDLE] = "idle"
5010};
5011
f8b69d1d 5012DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
f41607a6
LP
5013
5014static const char *const sigchld_code_table[] = {
5015 [CLD_EXITED] = "exited",
5016 [CLD_KILLED] = "killed",
5017 [CLD_DUMPED] = "dumped",
5018 [CLD_TRAPPED] = "trapped",
5019 [CLD_STOPPED] = "stopped",
5020 [CLD_CONTINUED] = "continued",
5021};
5022
5023DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
5024
5025static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
5026 [LOG_FAC(LOG_KERN)] = "kern",
5027 [LOG_FAC(LOG_USER)] = "user",
5028 [LOG_FAC(LOG_MAIL)] = "mail",
5029 [LOG_FAC(LOG_DAEMON)] = "daemon",
5030 [LOG_FAC(LOG_AUTH)] = "auth",
5031 [LOG_FAC(LOG_SYSLOG)] = "syslog",
5032 [LOG_FAC(LOG_LPR)] = "lpr",
5033 [LOG_FAC(LOG_NEWS)] = "news",
5034 [LOG_FAC(LOG_UUCP)] = "uucp",
5035 [LOG_FAC(LOG_CRON)] = "cron",
5036 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
5037 [LOG_FAC(LOG_FTP)] = "ftp",
5038 [LOG_FAC(LOG_LOCAL0)] = "local0",
5039 [LOG_FAC(LOG_LOCAL1)] = "local1",
5040 [LOG_FAC(LOG_LOCAL2)] = "local2",
5041 [LOG_FAC(LOG_LOCAL3)] = "local3",
5042 [LOG_FAC(LOG_LOCAL4)] = "local4",
5043 [LOG_FAC(LOG_LOCAL5)] = "local5",
5044 [LOG_FAC(LOG_LOCAL6)] = "local6",
5045 [LOG_FAC(LOG_LOCAL7)] = "local7"
5046};
5047
f8b69d1d 5048DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
f41607a6
LP
5049
5050static const char *const log_level_table[] = {
5051 [LOG_EMERG] = "emerg",
5052 [LOG_ALERT] = "alert",
5053 [LOG_CRIT] = "crit",
5054 [LOG_ERR] = "err",
5055 [LOG_WARNING] = "warning",
5056 [LOG_NOTICE] = "notice",
5057 [LOG_INFO] = "info",
5058 [LOG_DEBUG] = "debug"
5059};
5060
f8b69d1d 5061DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
f41607a6
LP
5062
5063static const char* const sched_policy_table[] = {
5064 [SCHED_OTHER] = "other",
5065 [SCHED_BATCH] = "batch",
5066 [SCHED_IDLE] = "idle",
5067 [SCHED_FIFO] = "fifo",
5068 [SCHED_RR] = "rr"
5069};
5070
f8b69d1d 5071DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
f41607a6 5072
517d56b1 5073static const char* const rlimit_table[_RLIMIT_MAX] = {
f41607a6
LP
5074 [RLIMIT_CPU] = "LimitCPU",
5075 [RLIMIT_FSIZE] = "LimitFSIZE",
5076 [RLIMIT_DATA] = "LimitDATA",
5077 [RLIMIT_STACK] = "LimitSTACK",
5078 [RLIMIT_CORE] = "LimitCORE",
5079 [RLIMIT_RSS] = "LimitRSS",
5080 [RLIMIT_NOFILE] = "LimitNOFILE",
5081 [RLIMIT_AS] = "LimitAS",
5082 [RLIMIT_NPROC] = "LimitNPROC",
5083 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
5084 [RLIMIT_LOCKS] = "LimitLOCKS",
5085 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
5086 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
5087 [RLIMIT_NICE] = "LimitNICE",
5088 [RLIMIT_RTPRIO] = "LimitRTPRIO",
5089 [RLIMIT_RTTIME] = "LimitRTTIME"
5090};
5091
5092DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
5093
5094static const char* const ip_tos_table[] = {
5095 [IPTOS_LOWDELAY] = "low-delay",
5096 [IPTOS_THROUGHPUT] = "throughput",
5097 [IPTOS_RELIABILITY] = "reliability",
5098 [IPTOS_LOWCOST] = "low-cost",
5099};
5100
f8b69d1d 5101DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
f41607a6 5102
4e240ab0 5103static const char *const __signal_table[] = {
f41607a6
LP
5104 [SIGHUP] = "HUP",
5105 [SIGINT] = "INT",
5106 [SIGQUIT] = "QUIT",
5107 [SIGILL] = "ILL",
5108 [SIGTRAP] = "TRAP",
5109 [SIGABRT] = "ABRT",
5110 [SIGBUS] = "BUS",
5111 [SIGFPE] = "FPE",
5112 [SIGKILL] = "KILL",
5113 [SIGUSR1] = "USR1",
5114 [SIGSEGV] = "SEGV",
5115 [SIGUSR2] = "USR2",
5116 [SIGPIPE] = "PIPE",
5117 [SIGALRM] = "ALRM",
5118 [SIGTERM] = "TERM",
5119#ifdef SIGSTKFLT
5120 [SIGSTKFLT] = "STKFLT", /* Linux on SPARC doesn't know SIGSTKFLT */
5121#endif
5122 [SIGCHLD] = "CHLD",
5123 [SIGCONT] = "CONT",
5124 [SIGSTOP] = "STOP",
5125 [SIGTSTP] = "TSTP",
5126 [SIGTTIN] = "TTIN",
5127 [SIGTTOU] = "TTOU",
5128 [SIGURG] = "URG",
5129 [SIGXCPU] = "XCPU",
5130 [SIGXFSZ] = "XFSZ",
5131 [SIGVTALRM] = "VTALRM",
5132 [SIGPROF] = "PROF",
5133 [SIGWINCH] = "WINCH",
5134 [SIGIO] = "IO",
5135 [SIGPWR] = "PWR",
5136 [SIGSYS] = "SYS"
5137};
5138
4e240ab0
MS
5139DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
5140
5141const char *signal_to_string(int signo) {
ec202eae 5142 static thread_local char buf[sizeof("RTMIN+")-1 + DECIMAL_STR_MAX(int) + 1];
4e240ab0
MS
5143 const char *name;
5144
5145 name = __signal_to_string(signo);
5146 if (name)
5147 return name;
5148
5149 if (signo >= SIGRTMIN && signo <= SIGRTMAX)
fa70beaa 5150 snprintf(buf, sizeof(buf), "RTMIN+%d", signo - SIGRTMIN);
4e240ab0 5151 else
fa70beaa
LP
5152 snprintf(buf, sizeof(buf), "%d", signo);
5153
4e240ab0
MS
5154 return buf;
5155}
5156
5157int signal_from_string(const char *s) {
5158 int signo;
5159 int offset = 0;
5160 unsigned u;
5161
040f18ea 5162 signo = __signal_from_string(s);
4e240ab0
MS
5163 if (signo > 0)
5164 return signo;
5165
5166 if (startswith(s, "RTMIN+")) {
5167 s += 6;
5168 offset = SIGRTMIN;
5169 }
5170 if (safe_atou(s, &u) >= 0) {
5171 signo = (int) u + offset;
5172 if (signo > 0 && signo < _NSIG)
5173 return signo;
5174 }
7e8185ef 5175 return -EINVAL;
4e240ab0 5176}
65457142
FC
5177
5178bool kexec_loaded(void) {
5179 bool loaded = false;
5180 char *s;
5181
5182 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
5183 if (s[0] == '1')
5184 loaded = true;
5185 free(s);
5186 }
5187 return loaded;
5188}
fb9de93d 5189
87d2c1ff
LP
5190int prot_from_flags(int flags) {
5191
5192 switch (flags & O_ACCMODE) {
5193
5194 case O_RDONLY:
5195 return PROT_READ;
5196
5197 case O_WRONLY:
5198 return PROT_WRITE;
5199
5200 case O_RDWR:
5201 return PROT_READ|PROT_WRITE;
5202
5203 default:
5204 return -EINVAL;
5205 }
7c99e0c1 5206}
689b9a22 5207
babfc091 5208char *format_bytes(char *buf, size_t l, off_t t) {
c0f99c21 5209 unsigned i;
babfc091
LP
5210
5211 static const struct {
5212 const char *suffix;
5213 off_t factor;
5214 } table[] = {
32895bb3
LP
5215 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
5216 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
babfc091
LP
5217 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
5218 { "G", 1024ULL*1024ULL*1024ULL },
5219 { "M", 1024ULL*1024ULL },
5220 { "K", 1024ULL },
5221 };
5222
f02ca522
LP
5223 if (t == (off_t) -1)
5224 return NULL;
5225
babfc091
LP
5226 for (i = 0; i < ELEMENTSOF(table); i++) {
5227
5228 if (t >= table[i].factor) {
5229 snprintf(buf, l,
5230 "%llu.%llu%s",
5231 (unsigned long long) (t / table[i].factor),
5232 (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
5233 table[i].suffix);
5234
5235 goto finish;
5236 }
5237 }
5238
5239 snprintf(buf, l, "%lluB", (unsigned long long) t);
5240
5241finish:
5242 buf[l-1] = 0;
5243 return buf;
5244
5245}
55d7bfc1
LP
5246
5247void* memdup(const void *p, size_t l) {
5248 void *r;
5249
5250 assert(p);
5251
5252 r = malloc(l);
5253 if (!r)
5254 return NULL;
5255
5256 memcpy(r, p, l);
5257 return r;
5258}
bb99a35a
LP
5259
5260int fd_inc_sndbuf(int fd, size_t n) {
5261 int r, value;
5262 socklen_t l = sizeof(value);
5263
5264 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
92d75ca4 5265 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
bb99a35a
LP
5266 return 0;
5267
92d75ca4
LP
5268 /* If we have the privileges we will ignore the kernel limit. */
5269
bb99a35a 5270 value = (int) n;
92d75ca4
LP
5271 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
5272 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
5273 return -errno;
bb99a35a
LP
5274
5275 return 1;
5276}
5277
5278int fd_inc_rcvbuf(int fd, size_t n) {
5279 int r, value;
5280 socklen_t l = sizeof(value);
5281
5282 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
92d75ca4 5283 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
bb99a35a
LP
5284 return 0;
5285
92d75ca4 5286 /* If we have the privileges we will ignore the kernel limit. */
bb99a35a 5287
92d75ca4
LP
5288 value = (int) n;
5289 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
5290 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
5291 return -errno;
bb99a35a
LP
5292 return 1;
5293}
6bb92a16 5294
9bdc770c 5295int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
6bb92a16 5296 bool stdout_is_tty, stderr_is_tty;
8a7c93d8
LP
5297 pid_t parent_pid, agent_pid;
5298 sigset_t ss, saved_ss;
6bb92a16
LP
5299 unsigned n, i;
5300 va_list ap;
5301 char **l;
5302
5303 assert(pid);
5304 assert(path);
5305
6bb92a16
LP
5306 /* Spawns a temporary TTY agent, making sure it goes away when
5307 * we go away */
5308
8a7c93d8
LP
5309 parent_pid = getpid();
5310
5311 /* First we temporarily block all signals, so that the new
5312 * child has them blocked initially. This way, we can be sure
5313 * that SIGTERMs are not lost we might send to the agent. */
5314 assert_se(sigfillset(&ss) >= 0);
5315 assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0);
5316
6bb92a16 5317 agent_pid = fork();
8a7c93d8
LP
5318 if (agent_pid < 0) {
5319 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
6bb92a16 5320 return -errno;
8a7c93d8 5321 }
6bb92a16
LP
5322
5323 if (agent_pid != 0) {
8a7c93d8 5324 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
6bb92a16
LP
5325 *pid = agent_pid;
5326 return 0;
5327 }
5328
5329 /* In the child:
5330 *
5331 * Make sure the agent goes away when the parent dies */
5332 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
5333 _exit(EXIT_FAILURE);
5334
8a7c93d8
LP
5335 /* Make sure we actually can kill the agent, if we need to, in
5336 * case somebody invoked us from a shell script that trapped
5337 * SIGTERM or so... */
5338 reset_all_signal_handlers();
5339 reset_signal_mask();
5340
6bb92a16 5341 /* Check whether our parent died before we were able
8a7c93d8 5342 * to set the death signal and unblock the signals */
6bb92a16
LP
5343 if (getppid() != parent_pid)
5344 _exit(EXIT_SUCCESS);
5345
5346 /* Don't leak fds to the agent */
9bdc770c 5347 close_all_fds(except, n_except);
6bb92a16
LP
5348
5349 stdout_is_tty = isatty(STDOUT_FILENO);
5350 stderr_is_tty = isatty(STDERR_FILENO);
5351
5352 if (!stdout_is_tty || !stderr_is_tty) {
8a7c93d8
LP
5353 int fd;
5354
6bb92a16
LP
5355 /* Detach from stdout/stderr. and reopen
5356 * /dev/tty for them. This is important to
5357 * ensure that when systemctl is started via
5358 * popen() or a similar call that expects to
5359 * read EOF we actually do generate EOF and
5360 * not delay this indefinitely by because we
5361 * keep an unused copy of stdin around. */
5362 fd = open("/dev/tty", O_WRONLY);
5363 if (fd < 0) {
56f64d95 5364 log_error_errno(errno, "Failed to open /dev/tty: %m");
6bb92a16
LP
5365 _exit(EXIT_FAILURE);
5366 }
5367
5368 if (!stdout_is_tty)
5369 dup2(fd, STDOUT_FILENO);
5370
5371 if (!stderr_is_tty)
5372 dup2(fd, STDERR_FILENO);
5373
5374 if (fd > 2)
5375 close(fd);
5376 }
5377
5378 /* Count arguments */
5379 va_start(ap, path);
5380 for (n = 0; va_arg(ap, char*); n++)
5381 ;
5382 va_end(ap);
5383
5384 /* Allocate strv */
5385 l = alloca(sizeof(char *) * (n + 1));
5386
5387 /* Fill in arguments */
5388 va_start(ap, path);
5389 for (i = 0; i <= n; i++)
5390 l[i] = va_arg(ap, char*);
5391 va_end(ap);
5392
5393 execv(path, l);
5394 _exit(EXIT_FAILURE);
5395}
68faf98c
LP
5396
5397int setrlimit_closest(int resource, const struct rlimit *rlim) {
5398 struct rlimit highest, fixed;
5399
5400 assert(rlim);
5401
5402 if (setrlimit(resource, rlim) >= 0)
5403 return 0;
5404
5405 if (errno != EPERM)
5406 return -errno;
5407
5408 /* So we failed to set the desired setrlimit, then let's try
5409 * to get as close as we can */
5410 assert_se(getrlimit(resource, &highest) == 0);
5411
5412 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
5413 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
5414
5415 if (setrlimit(resource, &fixed) < 0)
5416 return -errno;
5417
5418 return 0;
5419}
3d9a4122 5420
ab94af92 5421int getenv_for_pid(pid_t pid, const char *field, char **_value) {
49aa47c7
LP
5422 _cleanup_fclose_ FILE *f = NULL;
5423 char *value = NULL;
ab94af92 5424 int r;
ab94af92
LP
5425 bool done = false;
5426 size_t l;
49aa47c7 5427 const char *path;
ab94af92 5428
49aa47c7 5429 assert(pid >= 0);
ab94af92
LP
5430 assert(field);
5431 assert(_value);
5432
b68fa010 5433 path = procfs_file_alloca(pid, "environ");
ab94af92
LP
5434
5435 f = fopen(path, "re");
5436 if (!f)
5437 return -errno;
5438
5439 l = strlen(field);
5440 r = 0;
5441
5442 do {
5443 char line[LINE_MAX];
5444 unsigned i;
5445
5446 for (i = 0; i < sizeof(line)-1; i++) {
5447 int c;
5448
5449 c = getc(f);
5450 if (_unlikely_(c == EOF)) {
5451 done = true;
5452 break;
5453 } else if (c == 0)
5454 break;
5455
5456 line[i] = c;
5457 }
5458 line[i] = 0;
5459
5460 if (memcmp(line, field, l) == 0 && line[l] == '=') {
5461 value = strdup(line + l + 1);
49aa47c7
LP
5462 if (!value)
5463 return -ENOMEM;
ab94af92
LP
5464
5465 r = 1;
5466 break;
5467 }
5468
5469 } while (!done);
5470
49aa47c7 5471 *_value = value;
ab94af92
LP
5472 return r;
5473}
d889a206 5474
3d7415f4
LP
5475bool http_etag_is_valid(const char *etag) {
5476 if (isempty(etag))
5477 return false;
5478
5479 if (!endswith(etag, "\""))
5480 return false;
5481
5482 if (!startswith(etag, "\"") && !startswith(etag, "W/\""))
5483 return false;
5484
5485 return true;
5486}
5487
a2e03378
LP
5488bool http_url_is_valid(const char *url) {
5489 const char *p;
49dbfa7b 5490
a2e03378
LP
5491 if (isempty(url))
5492 return false;
49dbfa7b 5493
a2e03378
LP
5494 p = startswith(url, "http://");
5495 if (!p)
5496 p = startswith(url, "https://");
5497 if (!p)
5498 return false;
49dbfa7b 5499
a2e03378
LP
5500 if (isempty(p))
5501 return false;
49dbfa7b 5502
a2e03378
LP
5503 return ascii_is_valid(p);
5504}
49dbfa7b 5505
a2e03378
LP
5506bool documentation_url_is_valid(const char *url) {
5507 const char *p;
5508
5509 if (isempty(url))
5510 return false;
5511
5512 if (http_url_is_valid(url))
49dbfa7b
LP
5513 return true;
5514
a2e03378
LP
5515 p = startswith(url, "file:/");
5516 if (!p)
5517 p = startswith(url, "info:");
5518 if (!p)
5519 p = startswith(url, "man:");
5520
5521 if (isempty(p))
5522 return false;
5523
5524 return ascii_is_valid(p);
49dbfa7b 5525}
9be346c9
HH
5526
5527bool in_initrd(void) {
73020ab2 5528 static int saved = -1;
825c6fe5 5529 struct statfs s;
8f33b5b8 5530
825c6fe5
LP
5531 if (saved >= 0)
5532 return saved;
5533
5534 /* We make two checks here:
5535 *
5536 * 1. the flag file /etc/initrd-release must exist
5537 * 2. the root file system must be a memory file system
5538 *
5539 * The second check is extra paranoia, since misdetecting an
5540 * initrd can have bad bad consequences due the initrd
5541 * emptying when transititioning to the main systemd.
5542 */
5543
5544 saved = access("/etc/initrd-release", F_OK) >= 0 &&
5545 statfs("/", &s) >= 0 &&
943aad8c 5546 is_temporary_fs(&s);
9be346c9 5547
8f33b5b8 5548 return saved;
9be346c9 5549}
069cfc85
LP
5550
5551void warn_melody(void) {
e67f47e5 5552 _cleanup_close_ int fd = -1;
069cfc85
LP
5553
5554 fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY);
5555 if (fd < 0)
5556 return;
5557
040f18ea 5558 /* Yeah, this is synchronous. Kinda sucks. But well... */
069cfc85
LP
5559
5560 ioctl(fd, KIOCSOUND, (int)(1193180/440));
5561 usleep(125*USEC_PER_MSEC);
5562
5563 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5564 usleep(125*USEC_PER_MSEC);
5565
5566 ioctl(fd, KIOCSOUND, (int)(1193180/220));
5567 usleep(125*USEC_PER_MSEC);
5568
5569 ioctl(fd, KIOCSOUND, 0);
069cfc85 5570}
cd3bd60a
LP
5571
5572int make_console_stdio(void) {
5573 int fd, r;
5574
5575 /* Make /dev/console the controlling terminal and stdin/stdout/stderr */
5576
3a43da28 5577 fd = acquire_terminal("/dev/console", false, true, true, USEC_INFINITY);
f647962d
MS
5578 if (fd < 0)
5579 return log_error_errno(fd, "Failed to acquire terminal: %m");
cd3bd60a
LP
5580
5581 r = make_stdio(fd);
f647962d
MS
5582 if (r < 0)
5583 return log_error_errno(r, "Failed to duplicate terminal fd: %m");
cd3bd60a
LP
5584
5585 return 0;
5586}
7c5f152a
LP
5587
5588int get_home_dir(char **_h) {
2cfbd749 5589 struct passwd *p;
7c5f152a 5590 const char *e;
2cfbd749 5591 char *h;
7c5f152a 5592 uid_t u;
7c5f152a
LP
5593
5594 assert(_h);
5595
5596 /* Take the user specified one */
9a00f57a
LP
5597 e = secure_getenv("HOME");
5598 if (e && path_is_absolute(e)) {
7c5f152a
LP
5599 h = strdup(e);
5600 if (!h)
5601 return -ENOMEM;
5602
5603 *_h = h;
5604 return 0;
5605 }
5606
5607 /* Hardcode home directory for root to avoid NSS */
5608 u = getuid();
5609 if (u == 0) {
5610 h = strdup("/root");
5611 if (!h)
5612 return -ENOMEM;
5613
5614 *_h = h;
5615 return 0;
5616 }
5617
5618 /* Check the database... */
5619 errno = 0;
5620 p = getpwuid(u);
5621 if (!p)
bcb161b0 5622 return errno > 0 ? -errno : -ESRCH;
7c5f152a
LP
5623
5624 if (!path_is_absolute(p->pw_dir))
5625 return -EINVAL;
5626
5627 h = strdup(p->pw_dir);
5628 if (!h)
5629 return -ENOMEM;
5630
5631 *_h = h;
5632 return 0;
5633}
5634
2cfbd749
LP
5635int get_shell(char **_s) {
5636 struct passwd *p;
5637 const char *e;
5638 char *s;
5639 uid_t u;
5640
5641 assert(_s);
5642
5643 /* Take the user specified one */
5644 e = getenv("SHELL");
5645 if (e) {
5646 s = strdup(e);
5647 if (!s)
5648 return -ENOMEM;
5649
5650 *_s = s;
5651 return 0;
5652 }
5653
5654 /* Hardcode home directory for root to avoid NSS */
5655 u = getuid();
5656 if (u == 0) {
5657 s = strdup("/bin/sh");
5658 if (!s)
5659 return -ENOMEM;
5660
5661 *_s = s;
5662 return 0;
5663 }
5664
5665 /* Check the database... */
5666 errno = 0;
5667 p = getpwuid(u);
5668 if (!p)
5669 return errno > 0 ? -errno : -ESRCH;
5670
5671 if (!path_is_absolute(p->pw_shell))
5672 return -EINVAL;
5673
5674 s = strdup(p->pw_shell);
5675 if (!s)
5676 return -ENOMEM;
5677
5678 *_s = s;
5679 return 0;
5680}
5681
ae6c3cc0 5682bool filename_is_valid(const char *p) {
0b507b17
LP
5683
5684 if (isempty(p))
5685 return false;
5686
5687 if (strchr(p, '/'))
5688 return false;
5689
5690 if (streq(p, "."))
5691 return false;
5692
5693 if (streq(p, ".."))
5694 return false;
5695
5696 if (strlen(p) > FILENAME_MAX)
5697 return false;
5698
5699 return true;
5700}
5701
5702bool string_is_safe(const char *p) {
5703 const char *t;
5704
6294aa76
LP
5705 if (!p)
5706 return false;
0b507b17
LP
5707
5708 for (t = p; *t; t++) {
01539d6e 5709 if (*t > 0 && *t < ' ')
0b507b17
LP
5710 return false;
5711
6294aa76 5712 if (strchr("\\\"\'\0x7f", *t))
0b507b17
LP
5713 return false;
5714 }
5715
5716 return true;
5717}
cfbc22ab 5718
ac4c8d6d 5719/**
6294aa76
LP
5720 * Check if a string contains control characters. If 'ok' is non-NULL
5721 * it may be a string containing additional CCs to be considered OK.
ac4c8d6d 5722 */
6294aa76 5723bool string_has_cc(const char *p, const char *ok) {
4d1a6904
LP
5724 const char *t;
5725
5726 assert(p);
5727
3a8a9163 5728 for (t = p; *t; t++) {
6294aa76 5729 if (ok && strchr(ok, *t))
1cb1767a 5730 continue;
6294aa76
LP
5731
5732 if (*t > 0 && *t < ' ')
4d1a6904
LP
5733 return true;
5734
3a8a9163
LP
5735 if (*t == 127)
5736 return true;
5737 }
5738
4d1a6904
LP
5739 return false;
5740}
5741
e884315e
LP
5742bool path_is_safe(const char *p) {
5743
5744 if (isempty(p))
5745 return false;
5746
5747 if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
5748 return false;
5749
5750 if (strlen(p) > PATH_MAX)
5751 return false;
5752
5753 /* The following two checks are not really dangerous, but hey, they still are confusing */
5754 if (streq(p, ".") || startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
5755 return false;
5756
5757 if (strstr(p, "//"))
5758 return false;
5759
5760 return true;
5761}
5762
a9e12476
KS
5763/* hey glibc, APIs with callbacks without a user pointer are so useless */
5764void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
1c574591 5765 int (*compar) (const void *, const void *, void *), void *arg) {
a9e12476
KS
5766 size_t l, u, idx;
5767 const void *p;
5768 int comparison;
5769
5770 l = 0;
5771 u = nmemb;
5772 while (l < u) {
5773 idx = (l + u) / 2;
5774 p = (void *)(((const char *) base) + (idx * size));
5775 comparison = compar(key, p, arg);
5776 if (comparison < 0)
5777 u = idx;
5778 else if (comparison > 0)
5779 l = idx + 1;
5780 else
5781 return (void *)p;
5782 }
5783 return NULL;
5784}
09017585 5785
20f56fdd
DR
5786void init_gettext(void) {
5787 setlocale(LC_ALL, "");
5788 textdomain(GETTEXT_PACKAGE);
5789}
5790
09017585
MS
5791bool is_locale_utf8(void) {
5792 const char *set;
5793 static int cached_answer = -1;
5794
5795 if (cached_answer >= 0)
5796 goto out;
5797
5798 if (!setlocale(LC_ALL, "")) {
5799 cached_answer = true;
5800 goto out;
5801 }
5802
5803 set = nl_langinfo(CODESET);
5804 if (!set) {
5805 cached_answer = true;
5806 goto out;
5807 }
5808
f168c273 5809 if (streq(set, "UTF-8")) {
fee79e01
HH
5810 cached_answer = true;
5811 goto out;
5812 }
5813
6cf2f1d9
HH
5814 /* For LC_CTYPE=="C" return true, because CTYPE is effectly
5815 * unset and everything can do to UTF-8 nowadays. */
fee79e01
HH
5816 set = setlocale(LC_CTYPE, NULL);
5817 if (!set) {
5818 cached_answer = true;
5819 goto out;
5820 }
5821
6cf2f1d9
HH
5822 /* Check result, but ignore the result if C was set
5823 * explicitly. */
5824 cached_answer =
5825 streq(set, "C") &&
5826 !getenv("LC_ALL") &&
5827 !getenv("LC_CTYPE") &&
5828 !getenv("LANG");
fee79e01 5829
09017585 5830out:
6cf2f1d9 5831 return (bool) cached_answer;
09017585 5832}
c339d977
MS
5833
5834const char *draw_special_char(DrawSpecialChar ch) {
5835 static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
6b01f1d3 5836
c339d977 5837 /* UTF-8 */ {
6b01f1d3 5838 [DRAW_TREE_VERTICAL] = "\342\224\202 ", /* │ */
45a5ff0d
MS
5839 [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */
5840 [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */
55c0b89c 5841 [DRAW_TREE_SPACE] = " ", /* */
6b01f1d3
LP
5842 [DRAW_TRIANGULAR_BULLET] = "\342\200\243", /* ‣ */
5843 [DRAW_BLACK_CIRCLE] = "\342\227\217", /* ● */
5844 [DRAW_ARROW] = "\342\206\222", /* → */
13f8b8cb 5845 [DRAW_DASH] = "\342\200\223", /* – */
c339d977 5846 },
6b01f1d3 5847
c339d977 5848 /* ASCII fallback */ {
6b01f1d3 5849 [DRAW_TREE_VERTICAL] = "| ",
45a5ff0d
MS
5850 [DRAW_TREE_BRANCH] = "|-",
5851 [DRAW_TREE_RIGHT] = "`-",
55c0b89c 5852 [DRAW_TREE_SPACE] = " ",
6b01f1d3
LP
5853 [DRAW_TRIANGULAR_BULLET] = ">",
5854 [DRAW_BLACK_CIRCLE] = "*",
5855 [DRAW_ARROW] = "->",
13f8b8cb 5856 [DRAW_DASH] = "-",
c339d977
MS
5857 }
5858 };
5859
5860 return draw_table[!is_locale_utf8()][ch];
5861}
409bc9c3
LP
5862
5863char *strreplace(const char *text, const char *old_string, const char *new_string) {
5864 const char *f;
5865 char *t, *r;
5866 size_t l, old_len, new_len;
5867
5868 assert(text);
5869 assert(old_string);
5870 assert(new_string);
5871
5872 old_len = strlen(old_string);
5873 new_len = strlen(new_string);
5874
5875 l = strlen(text);
5876 r = new(char, l+1);
5877 if (!r)
5878 return NULL;
5879
5880 f = text;
5881 t = r;
5882 while (*f) {
5883 char *a;
5884 size_t d, nl;
5885
5886 if (!startswith(f, old_string)) {
5887 *(t++) = *(f++);
5888 continue;
5889 }
5890
5891 d = t - r;
5892 nl = l - old_len + new_len;
5893 a = realloc(r, nl + 1);
5894 if (!a)
5895 goto oom;
5896
5897 l = nl;
5898 r = a;
5899 t = r + d;
5900
5901 t = stpcpy(t, new_string);
5902 f += old_len;
5903 }
5904
5905 *t = 0;
5906 return r;
5907
5908oom:
5909 free(r);
5910 return NULL;
5911}
e8bc0ea2
LP
5912
5913char *strip_tab_ansi(char **ibuf, size_t *_isz) {
660ddc72 5914 const char *i, *begin = NULL;
e8bc0ea2
LP
5915 enum {
5916 STATE_OTHER,
5917 STATE_ESCAPE,
5918 STATE_BRACKET
5919 } state = STATE_OTHER;
5920 char *obuf = NULL;
5921 size_t osz = 0, isz;
5922 FILE *f;
5923
5924 assert(ibuf);
5925 assert(*ibuf);
5926
5927 /* Strips ANSI color and replaces TABs by 8 spaces */
5928
5929 isz = _isz ? *_isz : strlen(*ibuf);
5930
5931 f = open_memstream(&obuf, &osz);
5932 if (!f)
5933 return NULL;
5934
5935 for (i = *ibuf; i < *ibuf + isz + 1; i++) {
5936
5937 switch (state) {
5938
5939 case STATE_OTHER:
5940 if (i >= *ibuf + isz) /* EOT */
5941 break;
5942 else if (*i == '\x1B')
5943 state = STATE_ESCAPE;
5944 else if (*i == '\t')
5945 fputs(" ", f);
5946 else
5947 fputc(*i, f);
5948 break;
5949
5950 case STATE_ESCAPE:
5951 if (i >= *ibuf + isz) { /* EOT */
5952 fputc('\x1B', f);
5953 break;
5954 } else if (*i == '[') {
5955 state = STATE_BRACKET;
5956 begin = i + 1;
5957 } else {
5958 fputc('\x1B', f);
5959 fputc(*i, f);
5960 state = STATE_OTHER;
5961 }
5962
5963 break;
5964
5965 case STATE_BRACKET:
5966
5967 if (i >= *ibuf + isz || /* EOT */
5968 (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
5969 fputc('\x1B', f);
5970 fputc('[', f);
5971 state = STATE_OTHER;
5972 i = begin-1;
5973 } else if (*i == 'm')
5974 state = STATE_OTHER;
5975 break;
5976 }
5977 }
5978
5979 if (ferror(f)) {
5980 fclose(f);
5981 free(obuf);
5982 return NULL;
5983 }
5984
5985 fclose(f);
5986
5987 free(*ibuf);
5988 *ibuf = obuf;
5989
5990 if (_isz)
5991 *_isz = osz;
5992
5993 return obuf;
5994}
240dbaa4
LP
5995
5996int on_ac_power(void) {
5997 bool found_offline = false, found_online = false;
5998 _cleanup_closedir_ DIR *d = NULL;
5999
6000 d = opendir("/sys/class/power_supply");
6001 if (!d)
6d890034 6002 return errno == ENOENT ? true : -errno;
240dbaa4
LP
6003
6004 for (;;) {
6005 struct dirent *de;
240dbaa4
LP
6006 _cleanup_close_ int fd = -1, device = -1;
6007 char contents[6];
6008 ssize_t n;
240dbaa4 6009
3fd11280
FW
6010 errno = 0;
6011 de = readdir(d);
6012 if (!de && errno != 0)
6013 return -errno;
240dbaa4
LP
6014
6015 if (!de)
6016 break;
6017
a34bf9db 6018 if (hidden_file(de->d_name))
240dbaa4
LP
6019 continue;
6020
6021 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
6022 if (device < 0) {
6023 if (errno == ENOENT || errno == ENOTDIR)
6024 continue;
6025
6026 return -errno;
6027 }
6028
6029 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
6030 if (fd < 0) {
6031 if (errno == ENOENT)
6032 continue;
6033
6034 return -errno;
6035 }
6036
6037 n = read(fd, contents, sizeof(contents));
6038 if (n < 0)
6039 return -errno;
6040
6041 if (n != 6 || memcmp(contents, "Mains\n", 6))
6042 continue;
6043
03e334a1 6044 safe_close(fd);
240dbaa4
LP
6045 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
6046 if (fd < 0) {
6047 if (errno == ENOENT)
6048 continue;
6049
6050 return -errno;
6051 }
6052
6053 n = read(fd, contents, sizeof(contents));
6054 if (n < 0)
6055 return -errno;
6056
6057 if (n != 2 || contents[1] != '\n')
6058 return -EIO;
6059
6060 if (contents[0] == '1') {
6061 found_online = true;
6062 break;
6063 } else if (contents[0] == '0')
6064 found_offline = true;
6065 else
6066 return -EIO;
6067 }
6068
6069 return found_online || !found_offline;
6070}
fabe5c0e 6071
4cf7ea55 6072static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
fabe5c0e
LP
6073 char **i;
6074
6075 assert(path);
6076 assert(mode);
6077 assert(_f);
6078
7d8da2c9 6079 if (!path_strv_resolve_uniq(search, root))
fabe5c0e
LP
6080 return -ENOMEM;
6081
6082 STRV_FOREACH(i, search) {
6083 _cleanup_free_ char *p = NULL;
6084 FILE *f;
6085
375eadd9
MM
6086 if (root)
6087 p = strjoin(root, *i, "/", path, NULL);
6088 else
6089 p = strjoin(*i, "/", path, NULL);
fabe5c0e
LP
6090 if (!p)
6091 return -ENOMEM;
6092
6093 f = fopen(p, mode);
6094 if (f) {
6095 *_f = f;
6096 return 0;
6097 }
6098
6099 if (errno != ENOENT)
6100 return -errno;
6101 }
6102
6103 return -ENOENT;
6104}
6105
4cf7ea55 6106int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
fabe5c0e
LP
6107 _cleanup_strv_free_ char **copy = NULL;
6108
6109 assert(path);
6110 assert(mode);
6111 assert(_f);
6112
6113 if (path_is_absolute(path)) {
6114 FILE *f;
6115
6116 f = fopen(path, mode);
6117 if (f) {
6118 *_f = f;
6119 return 0;
6120 }
6121
6122 return -errno;
6123 }
6124
6125 copy = strv_copy((char**) search);
6126 if (!copy)
6127 return -ENOMEM;
6128
4cf7ea55 6129 return search_and_fopen_internal(path, mode, root, copy, _f);
fabe5c0e
LP
6130}
6131
4cf7ea55 6132int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
fabe5c0e
LP
6133 _cleanup_strv_free_ char **s = NULL;
6134
6135 if (path_is_absolute(path)) {
6136 FILE *f;
6137
6138 f = fopen(path, mode);
6139 if (f) {
6140 *_f = f;
6141 return 0;
6142 }
6143
6144 return -errno;
6145 }
6146
6147 s = strv_split_nulstr(search);
6148 if (!s)
6149 return -ENOMEM;
6150
4cf7ea55 6151 return search_and_fopen_internal(path, mode, root, s, _f);
fabe5c0e 6152}
c17ec25e 6153
66e35261
LP
6154char *strextend(char **x, ...) {
6155 va_list ap;
6156 size_t f, l;
6157 char *r, *p;
6158
6159 assert(x);
6160
6161 l = f = *x ? strlen(*x) : 0;
6162
6163 va_start(ap, x);
6164 for (;;) {
6165 const char *t;
6166 size_t n;
6167
6168 t = va_arg(ap, const char *);
6169 if (!t)
6170 break;
6171
6172 n = strlen(t);
6173 if (n > ((size_t) -1) - l) {
6174 va_end(ap);
6175 return NULL;
6176 }
6177
6178 l += n;
6179 }
6180 va_end(ap);
6181
6182 r = realloc(*x, l+1);
6183 if (!r)
6184 return NULL;
6185
6186 p = r + f;
6187
6188 va_start(ap, x);
6189 for (;;) {
6190 const char *t;
6191
6192 t = va_arg(ap, const char *);
6193 if (!t)
6194 break;
6195
6196 p = stpcpy(p, t);
6197 }
6198 va_end(ap);
6199
6200 *p = 0;
6201 *x = r;
6202
6203 return r + l;
6204}
9a17484d
LP
6205
6206char *strrep(const char *s, unsigned n) {
6207 size_t l;
6208 char *r, *p;
6209 unsigned i;
6210
6211 assert(s);
6212
6213 l = strlen(s);
6214 p = r = malloc(l * n + 1);
6215 if (!r)
6216 return NULL;
6217
6218 for (i = 0; i < n; i++)
6219 p = stpcpy(p, s);
6220
6221 *p = 0;
6222 return r;
6223}
392d5b37 6224
ca2d3784
ZJS
6225void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
6226 size_t a, newalloc;
392d5b37
LP
6227 void *q;
6228
98088803 6229 assert(p);
e93c33d4
SL
6230 assert(allocated);
6231
392d5b37
LP
6232 if (*allocated >= need)
6233 return *p;
6234
ca2d3784
ZJS
6235 newalloc = MAX(need * 2, 64u / size);
6236 a = newalloc * size;
98088803
LP
6237
6238 /* check for overflows */
ca2d3784 6239 if (a < size * need)
98088803
LP
6240 return NULL;
6241
392d5b37
LP
6242 q = realloc(*p, a);
6243 if (!q)
6244 return NULL;
6245
6246 *p = q;
ca2d3784 6247 *allocated = newalloc;
392d5b37
LP
6248 return q;
6249}
aa96c6cb 6250
ca2d3784 6251void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
98088803 6252 size_t prev;
4545a231
DH
6253 uint8_t *q;
6254
98088803
LP
6255 assert(p);
6256 assert(allocated);
6257
6258 prev = *allocated;
6259
ca2d3784 6260 q = greedy_realloc(p, allocated, need, size);
4545a231
DH
6261 if (!q)
6262 return NULL;
6263
6264 if (*allocated > prev)
ca2d3784 6265 memzero(q + prev * size, (*allocated - prev) * size);
4545a231
DH
6266
6267 return q;
6268}
6269
aa96c6cb
LP
6270bool id128_is_valid(const char *s) {
6271 size_t i, l;
6272
6273 l = strlen(s);
6274 if (l == 32) {
6275
6276 /* Simple formatted 128bit hex string */
6277
6278 for (i = 0; i < l; i++) {
6279 char c = s[i];
6280
6281 if (!(c >= '0' && c <= '9') &&
6282 !(c >= 'a' && c <= 'z') &&
6283 !(c >= 'A' && c <= 'Z'))
6284 return false;
6285 }
6286
6287 } else if (l == 36) {
6288
6289 /* Formatted UUID */
6290
6291 for (i = 0; i < l; i++) {
6292 char c = s[i];
6293
6294 if ((i == 8 || i == 13 || i == 18 || i == 23)) {
6295 if (c != '-')
6296 return false;
6297 } else {
6298 if (!(c >= '0' && c <= '9') &&
6299 !(c >= 'a' && c <= 'z') &&
6300 !(c >= 'A' && c <= 'Z'))
6301 return false;
6302 }
6303 }
6304
6305 } else
6306 return false;
6307
6308 return true;
6309}
7085053a 6310
d4ac85c6
LP
6311int split_pair(const char *s, const char *sep, char **l, char **r) {
6312 char *x, *a, *b;
6313
6314 assert(s);
6315 assert(sep);
6316 assert(l);
6317 assert(r);
6318
6319 if (isempty(sep))
6320 return -EINVAL;
6321
6322 x = strstr(s, sep);
6323 if (!x)
6324 return -EINVAL;
6325
6326 a = strndup(s, x - s);
6327 if (!a)
6328 return -ENOMEM;
6329
6330 b = strdup(x + strlen(sep));
6331 if (!b) {
6332 free(a);
6333 return -ENOMEM;
6334 }
6335
6336 *l = a;
6337 *r = b;
6338
6339 return 0;
6340}
295edddf 6341
74df0fca 6342int shall_restore_state(void) {
1a299299 6343 _cleanup_free_ char *value = NULL;
74df0fca 6344 int r;
295edddf 6345
1a299299 6346 r = get_proc_cmdline_key("systemd.restore_state=", &value);
74df0fca
LP
6347 if (r < 0)
6348 return r;
1a299299
LP
6349 if (r == 0)
6350 return true;
295edddf 6351
1a299299 6352 return parse_boolean(value) != 0;
74df0fca
LP
6353}
6354
6355int proc_cmdline(char **ret) {
b5884878 6356 assert(ret);
295edddf 6357
b5884878
LP
6358 if (detect_container(NULL) > 0)
6359 return get_process_cmdline(1, 0, false, ret);
6360 else
6361 return read_one_line_file("/proc/cmdline", ret);
295edddf 6362}
bc9fd78c 6363
059cb385 6364int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
141a79f4 6365 _cleanup_free_ char *line = NULL;
f32d2db1 6366 const char *p;
141a79f4
ZJS
6367 int r;
6368
059cb385
LP
6369 assert(parse_item);
6370
141a79f4
ZJS
6371 r = proc_cmdline(&line);
6372 if (r < 0)
b5884878 6373 return r;
141a79f4 6374
f32d2db1
LP
6375 p = line;
6376 for (;;) {
6377 _cleanup_free_ char *word = NULL;
6378 char *value = NULL;
141a79f4 6379
f32d2db1
LP
6380 r = unquote_first_word(&p, &word, true);
6381 if (r < 0)
6382 return r;
6383 if (r == 0)
6384 break;
141a79f4 6385
059cb385
LP
6386 /* Filter out arguments that are intended only for the
6387 * initrd */
6388 if (!in_initrd() && startswith(word, "rd."))
6389 continue;
6390
6391 value = strchr(word, '=');
6392 if (value)
6393 *(value++) = 0;
6394
6395 r = parse_item(word, value);
6396 if (r < 0)
141a79f4 6397 return r;
141a79f4
ZJS
6398 }
6399
6400 return 0;
6401}
6402
1a299299
LP
6403int get_proc_cmdline_key(const char *key, char **value) {
6404 _cleanup_free_ char *line = NULL, *ret = NULL;
6405 bool found = false;
6406 const char *p;
6407 int r;
6408
6409 assert(key);
6410
6411 r = proc_cmdline(&line);
6412 if (r < 0)
6413 return r;
6414
6415 p = line;
6416 for (;;) {
6417 _cleanup_free_ char *word = NULL;
6418 const char *e;
6419
6420 r = unquote_first_word(&p, &word, true);
6421 if (r < 0)
6422 return r;
6423 if (r == 0)
6424 break;
6425
6426 /* Filter out arguments that are intended only for the
6427 * initrd */
6428 if (!in_initrd() && startswith(word, "rd."))
6429 continue;
6430
6431 if (value) {
6432 e = startswith(word, key);
6433 if (!e)
6434 continue;
6435
6436 r = free_and_strdup(&ret, e);
6437 if (r < 0)
6438 return r;
6439
6440 found = true;
6441 } else {
6442 if (streq(word, key))
6443 found = true;
6444 }
6445 }
6446
6447 if (value) {
6448 *value = ret;
6449 ret = NULL;
6450 }
6451
6452 return found;
6453
6454}
6455
bc9fd78c
LP
6456int container_get_leader(const char *machine, pid_t *pid) {
6457 _cleanup_free_ char *s = NULL, *class = NULL;
6458 const char *p;
6459 pid_t leader;
6460 int r;
6461
6462 assert(machine);
6463 assert(pid);
6464
63c372cb 6465 p = strjoina("/run/systemd/machines/", machine);
bc9fd78c
LP
6466 r = parse_env_file(p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
6467 if (r == -ENOENT)
6468 return -EHOSTDOWN;
6469 if (r < 0)
6470 return r;
6471 if (!s)
6472 return -EIO;
6473
6474 if (!streq_ptr(class, "container"))
6475 return -EIO;
6476
6477 r = parse_pid(s, &leader);
6478 if (r < 0)
6479 return r;
6480 if (leader <= 1)
6481 return -EIO;
6482
6483 *pid = leader;
6484 return 0;
6485}
6486
878cd7e9
LP
6487int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *root_fd) {
6488 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, netnsfd = -1;
359a06aa 6489 int rfd = -1;
bc9fd78c
LP
6490
6491 assert(pid >= 0);
bc9fd78c 6492
878cd7e9
LP
6493 if (mntns_fd) {
6494 const char *mntns;
a4475f57 6495
878cd7e9
LP
6496 mntns = procfs_file_alloca(pid, "ns/mnt");
6497 mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
6498 if (mntnsfd < 0)
6499 return -errno;
6500 }
bc9fd78c 6501
878cd7e9
LP
6502 if (pidns_fd) {
6503 const char *pidns;
6504
6505 pidns = procfs_file_alloca(pid, "ns/pid");
6506 pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
6507 if (pidnsfd < 0)
6508 return -errno;
6509 }
6510
6511 if (netns_fd) {
6512 const char *netns;
6513
6514 netns = procfs_file_alloca(pid, "ns/net");
6515 netnsfd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
6516 if (netnsfd < 0)
6517 return -errno;
6518 }
6519
6520 if (root_fd) {
6521 const char *root;
6522
6523 root = procfs_file_alloca(pid, "root");
6524 rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
6525 if (rfd < 0)
6526 return -errno;
6527 }
6528
6529 if (pidns_fd)
6530 *pidns_fd = pidnsfd;
bc9fd78c 6531
878cd7e9
LP
6532 if (mntns_fd)
6533 *mntns_fd = mntnsfd;
6534
6535 if (netns_fd)
6536 *netns_fd = netnsfd;
6537
6538 if (root_fd)
6539 *root_fd = rfd;
6540
6541 pidnsfd = mntnsfd = netnsfd = -1;
bc9fd78c
LP
6542
6543 return 0;
6544}
6545
878cd7e9 6546int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int root_fd) {
bc9fd78c 6547
878cd7e9
LP
6548 if (pidns_fd >= 0)
6549 if (setns(pidns_fd, CLONE_NEWPID) < 0)
6550 return -errno;
a4475f57 6551
878cd7e9
LP
6552 if (mntns_fd >= 0)
6553 if (setns(mntns_fd, CLONE_NEWNS) < 0)
6554 return -errno;
bc9fd78c 6555
878cd7e9
LP
6556 if (netns_fd >= 0)
6557 if (setns(netns_fd, CLONE_NEWNET) < 0)
6558 return -errno;
bc9fd78c 6559
878cd7e9
LP
6560 if (root_fd >= 0) {
6561 if (fchdir(root_fd) < 0)
6562 return -errno;
6563
6564 if (chroot(".") < 0)
6565 return -errno;
6566 }
bc9fd78c 6567
5e2b3214
LP
6568 if (setresgid(0, 0, 0) < 0)
6569 return -errno;
6570
878cd7e9
LP
6571 if (setgroups(0, NULL) < 0)
6572 return -errno;
6573
5e2b3214
LP
6574 if (setresuid(0, 0, 0) < 0)
6575 return -errno;
6576
bc9fd78c
LP
6577 return 0;
6578}
bf108e55 6579
9f5650ae
LP
6580bool pid_is_unwaited(pid_t pid) {
6581 /* Checks whether a PID is still valid at all, including a zombie */
6582
bf108e55
LP
6583 if (pid <= 0)
6584 return false;
6585
6586 if (kill(pid, 0) >= 0)
6587 return true;
6588
6589 return errno != ESRCH;
6590}
eff05270 6591
9f5650ae
LP
6592bool pid_is_alive(pid_t pid) {
6593 int r;
6594
6595 /* Checks whether a PID is still valid and not a zombie */
6596
6597 if (pid <= 0)
6598 return false;
6599
6600 r = get_process_state(pid);
6601 if (r == -ENOENT || r == 'Z')
6602 return false;
6603
6604 return true;
6605}
6606
eff05270
LP
6607int getpeercred(int fd, struct ucred *ucred) {
6608 socklen_t n = sizeof(struct ucred);
6609 struct ucred u;
6610 int r;
6611
6612 assert(fd >= 0);
6613 assert(ucred);
6614
6615 r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
6616 if (r < 0)
6617 return -errno;
6618
6619 if (n != sizeof(struct ucred))
6620 return -EIO;
6621
6622 /* Check if the data is actually useful and not suppressed due
6623 * to namespacing issues */
6624 if (u.pid <= 0)
6625 return -ENODATA;
fed1e721 6626 if (u.uid == UID_INVALID)
62028d9c 6627 return -ENODATA;
fed1e721 6628 if (u.gid == GID_INVALID)
62028d9c 6629 return -ENODATA;
eff05270
LP
6630
6631 *ucred = u;
6632 return 0;
6633}
6634
6635int getpeersec(int fd, char **ret) {
6636 socklen_t n = 64;
6637 char *s;
6638 int r;
6639
6640 assert(fd >= 0);
6641 assert(ret);
6642
6643 s = new0(char, n);
6644 if (!s)
6645 return -ENOMEM;
6646
6647 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
6648 if (r < 0) {
6649 free(s);
6650
6651 if (errno != ERANGE)
6652 return -errno;
6653
6654 s = new0(char, n);
6655 if (!s)
6656 return -ENOMEM;
6657
6658 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
6659 if (r < 0) {
6660 free(s);
6661 return -errno;
6662 }
6663 }
6664
ae98841e
LP
6665 if (isempty(s)) {
6666 free(s);
6667 return -ENOTSUP;
6668 }
6669
eff05270
LP
6670 *ret = s;
6671 return 0;
6672}
8e33886e 6673
0f010ef2 6674/* This is much like like mkostemp() but is subject to umask(). */
65b3903f 6675int mkostemp_safe(char *pattern, int flags) {
2d5bdf5b 6676 _cleanup_umask_ mode_t u;
0f010ef2 6677 int fd;
65b3903f 6678
d37a91e8 6679 assert(pattern);
65b3903f 6680
2d5bdf5b
LP
6681 u = umask(077);
6682
0f010ef2
ZJS
6683 fd = mkostemp(pattern, flags);
6684 if (fd < 0)
6685 return -errno;
65b3903f 6686
0f010ef2 6687 return fd;
65b3903f
ZJS
6688}
6689
8e33886e 6690int open_tmpfile(const char *path, int flags) {
8e33886e 6691 char *p;
a6afc4ae
LP
6692 int fd;
6693
6694 assert(path);
8e33886e
ZJS
6695
6696#ifdef O_TMPFILE
7736202c
LP
6697 /* Try O_TMPFILE first, if it is supported */
6698 fd = open(path, flags|O_TMPFILE, S_IRUSR|S_IWUSR);
8e33886e
ZJS
6699 if (fd >= 0)
6700 return fd;
6701#endif
7736202c
LP
6702
6703 /* Fall back to unguessable name + unlinking */
63c372cb 6704 p = strjoina(path, "/systemd-tmp-XXXXXX");
8e33886e 6705
a6afc4ae 6706 fd = mkostemp_safe(p, flags);
8e33886e 6707 if (fd < 0)
65b3903f 6708 return fd;
8e33886e
ZJS
6709
6710 unlink(p);
6711 return fd;
6712}
fdb9161c
LP
6713
6714int fd_warn_permissions(const char *path, int fd) {
6715 struct stat st;
6716
6717 if (fstat(fd, &st) < 0)
6718 return -errno;
6719
6720 if (st.st_mode & 0111)
6721 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
6722
6723 if (st.st_mode & 0002)
6724 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
6725
6726 if (getpid() == 1 && (st.st_mode & 0044) != 0044)
6727 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);
6728
6729 return 0;
6730}
6afc95b7 6731
ac45f971 6732unsigned long personality_from_string(const char *p) {
6afc95b7
LP
6733
6734 /* Parse a personality specifier. We introduce our own
6735 * identifiers that indicate specific ABIs, rather than just
6736 * hints regarding the register size, since we want to keep
6737 * things open for multiple locally supported ABIs for the
6738 * same register size. We try to reuse the ABI identifiers
6739 * used by libseccomp. */
6740
6741#if defined(__x86_64__)
6742
6743 if (streq(p, "x86"))
6744 return PER_LINUX32;
6745
6746 if (streq(p, "x86-64"))
6747 return PER_LINUX;
6748
6749#elif defined(__i386__)
6750
6751 if (streq(p, "x86"))
6752 return PER_LINUX;
6753#endif
6754
6755 /* personality(7) documents that 0xffffffffUL is used for
6756 * querying the current personality, hence let's use that here
6757 * as error indicator. */
6758 return 0xffffffffUL;
6759}
ac45f971
LP
6760
6761const char* personality_to_string(unsigned long p) {
6762
6763#if defined(__x86_64__)
6764
6765 if (p == PER_LINUX32)
6766 return "x86";
6767
6768 if (p == PER_LINUX)
6769 return "x86-64";
6770
6771#elif defined(__i386__)
6772
6773 if (p == PER_LINUX)
6774 return "x86";
6775#endif
6776
6777 return NULL;
6778}
1c231f56
LP
6779
6780uint64_t physical_memory(void) {
6781 long mem;
6782
6783 /* We return this as uint64_t in case we are running as 32bit
6784 * process on a 64bit kernel with huge amounts of memory */
6785
6786 mem = sysconf(_SC_PHYS_PAGES);
6787 assert(mem > 0);
6788
6789 return (uint64_t) mem * (uint64_t) page_size();
6790}
6db615c1 6791
29bfbcd6
LP
6792void hexdump(FILE *f, const void *p, size_t s) {
6793 const uint8_t *b = p;
6794 unsigned n = 0;
6795
6796 assert(s == 0 || b);
6797
6798 while (s > 0) {
6799 size_t i;
6800
6801 fprintf(f, "%04x ", n);
6802
6803 for (i = 0; i < 16; i++) {
6804
6805 if (i >= s)
6806 fputs(" ", f);
6807 else
6808 fprintf(f, "%02x ", b[i]);
6809
6810 if (i == 7)
6811 fputc(' ', f);
6812 }
6813
6814 fputc(' ', f);
6815
6816 for (i = 0; i < 16; i++) {
6817
6818 if (i >= s)
6819 fputc(' ', f);
6820 else
6821 fputc(isprint(b[i]) ? (char) b[i] : '.', f);
6822 }
6823
6824 fputc('\n', f);
6825
6826 if (s < 16)
6827 break;
6828
6829 n += 16;
6830 b += 16;
6831 s -= 16;
6832 }
6833}
c5220a94 6834
966bff26 6835int update_reboot_param_file(const char *param) {
c5220a94
MO
6836 int r = 0;
6837
6838 if (param) {
6839
6840 r = write_string_file(REBOOT_PARAM_FILE, param);
6841 if (r < 0)
6842 log_error("Failed to write reboot param to "
6843 REBOOT_PARAM_FILE": %s", strerror(-r));
6844 } else
6845 unlink(REBOOT_PARAM_FILE);
6846
6847 return r;
6848}
6d313367
LP
6849
6850int umount_recursive(const char *prefix, int flags) {
6851 bool again;
6852 int n = 0, r;
6853
6854 /* Try to umount everything recursively below a
6855 * directory. Also, take care of stacked mounts, and keep
6856 * unmounting them until they are gone. */
6857
6858 do {
6859 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
6860
6861 again = false;
6862 r = 0;
6863
6864 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
6865 if (!proc_self_mountinfo)
6866 return -errno;
6867
6868 for (;;) {
6869 _cleanup_free_ char *path = NULL, *p = NULL;
6870 int k;
6871
6872 k = fscanf(proc_self_mountinfo,
6873 "%*s " /* (1) mount id */
6874 "%*s " /* (2) parent id */
6875 "%*s " /* (3) major:minor */
6876 "%*s " /* (4) root */
6877 "%ms " /* (5) mount point */
6878 "%*s" /* (6) mount options */
6879 "%*[^-]" /* (7) optional fields */
6880 "- " /* (8) separator */
6881 "%*s " /* (9) file system type */
6882 "%*s" /* (10) mount source */
6883 "%*s" /* (11) mount options 2 */
6884 "%*[^\n]", /* some rubbish at the end */
6885 &path);
6d313367
LP
6886 if (k != 1) {
6887 if (k == EOF)
6888 break;
6889
6890 continue;
6891 }
6892
6893 p = cunescape(path);
6894 if (!p)
6895 return -ENOMEM;
6896
6897 if (!path_startswith(p, prefix))
6898 continue;
6899
6900 if (umount2(p, flags) < 0) {
6901 r = -errno;
6902 continue;
6903 }
6904
6905 again = true;
6906 n++;
6907
6908 break;
6909 }
6910
6911 } while (again);
6912
6913 return r ? r : n;
6914}
d6797c92 6915
abe4aa14
TM
6916static int get_mount_flags(const char *path, unsigned long *flags) {
6917 struct statvfs buf;
6918
6919 if (statvfs(path, &buf) < 0)
6920 return -errno;
6921 *flags = buf.f_flag;
6922 return 0;
6923}
6924
d6797c92
LP
6925int bind_remount_recursive(const char *prefix, bool ro) {
6926 _cleanup_set_free_free_ Set *done = NULL;
6927 _cleanup_free_ char *cleaned = NULL;
6928 int r;
6929
6930 /* Recursively remount a directory (and all its submounts)
6931 * read-only or read-write. If the directory is already
6932 * mounted, we reuse the mount and simply mark it
6933 * MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write
6934 * operation). If it isn't we first make it one. Afterwards we
6935 * apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to all
6936 * submounts we can access, too. When mounts are stacked on
6937 * the same mount point we only care for each individual
6938 * "top-level" mount on each point, as we cannot
6939 * influence/access the underlying mounts anyway. We do not
6940 * have any effect on future submounts that might get
6941 * propagated, they migt be writable. This includes future
6942 * submounts that have been triggered via autofs. */
6943
6944 cleaned = strdup(prefix);
6945 if (!cleaned)
6946 return -ENOMEM;
6947
6948 path_kill_slashes(cleaned);
6949
d5099efc 6950 done = set_new(&string_hash_ops);
d6797c92
LP
6951 if (!done)
6952 return -ENOMEM;
6953
6954 for (;;) {
6955 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
6956 _cleanup_set_free_free_ Set *todo = NULL;
6957 bool top_autofs = false;
6958 char *x;
abe4aa14 6959 unsigned long orig_flags;
d6797c92 6960
d5099efc 6961 todo = set_new(&string_hash_ops);
d6797c92
LP
6962 if (!todo)
6963 return -ENOMEM;
6964
6965 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
6966 if (!proc_self_mountinfo)
6967 return -errno;
6968
6969 for (;;) {
6970 _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
6971 int k;
6972
6973 k = fscanf(proc_self_mountinfo,
6974 "%*s " /* (1) mount id */
6975 "%*s " /* (2) parent id */
6976 "%*s " /* (3) major:minor */
6977 "%*s " /* (4) root */
6978 "%ms " /* (5) mount point */
6979 "%*s" /* (6) mount options (superblock) */
6980 "%*[^-]" /* (7) optional fields */
6981 "- " /* (8) separator */
6982 "%ms " /* (9) file system type */
6983 "%*s" /* (10) mount source */
6984 "%*s" /* (11) mount options (bind mount) */
6985 "%*[^\n]", /* some rubbish at the end */
6986 &path,
6987 &type);
6988 if (k != 2) {
6989 if (k == EOF)
6990 break;
6991
6992 continue;
6993 }
6994
6995 p = cunescape(path);
6996 if (!p)
6997 return -ENOMEM;
6998
6999 /* Let's ignore autofs mounts. If they aren't
7000 * triggered yet, we want to avoid triggering
7001 * them, as we don't make any guarantees for
7002 * future submounts anyway. If they are
7003 * already triggered, then we will find
7004 * another entry for this. */
7005 if (streq(type, "autofs")) {
7006 top_autofs = top_autofs || path_equal(cleaned, p);
7007 continue;
7008 }
7009
7010 if (path_startswith(p, cleaned) &&
7011 !set_contains(done, p)) {
7012
7013 r = set_consume(todo, p);
7014 p = NULL;
7015
7016 if (r == -EEXIST)
7017 continue;
7018 if (r < 0)
7019 return r;
7020 }
7021 }
7022
7023 /* If we have no submounts to process anymore and if
7024 * the root is either already done, or an autofs, we
7025 * are done */
7026 if (set_isempty(todo) &&
7027 (top_autofs || set_contains(done, cleaned)))
7028 return 0;
7029
7030 if (!set_contains(done, cleaned) &&
7031 !set_contains(todo, cleaned)) {
7032 /* The prefix directory itself is not yet a
7033 * mount, make it one. */
7034 if (mount(cleaned, cleaned, NULL, MS_BIND|MS_REC, NULL) < 0)
7035 return -errno;
7036
a7e07206
LP
7037 orig_flags = 0;
7038 (void) get_mount_flags(cleaned, &orig_flags);
abe4aa14 7039 orig_flags &= ~MS_RDONLY;
a7e07206 7040
abe4aa14 7041 if (mount(NULL, prefix, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0)
d6797c92
LP
7042 return -errno;
7043
7044 x = strdup(cleaned);
7045 if (!x)
7046 return -ENOMEM;
7047
7048 r = set_consume(done, x);
7049 if (r < 0)
7050 return r;
7051 }
7052
7053 while ((x = set_steal_first(todo))) {
7054
7055 r = set_consume(done, x);
7056 if (r == -EEXIST)
7057 continue;
7058 if (r < 0)
7059 return r;
7060
a7e07206
LP
7061 /* Try to reuse the original flag set, but
7062 * don't care for errors, in case of
7063 * obstructed mounts */
7064 orig_flags = 0;
7065 (void) get_mount_flags(x, &orig_flags);
abe4aa14 7066 orig_flags &= ~MS_RDONLY;
a7e07206 7067
abe4aa14 7068 if (mount(NULL, x, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) {
d6797c92
LP
7069
7070 /* Deal with mount points that are
7071 * obstructed by a later mount */
7072
7073 if (errno != ENOENT)
7074 return -errno;
7075 }
7076
7077 }
7078 }
7079}
1b992147
LP
7080
7081int fflush_and_check(FILE *f) {
45c196a7 7082 assert(f);
1b992147
LP
7083
7084 errno = 0;
7085 fflush(f);
7086
7087 if (ferror(f))
7088 return errno ? -errno : -EIO;
7089
7090 return 0;
7091}
2e78fa79 7092
ae6c3cc0 7093int tempfn_xxxxxx(const char *p, char **ret) {
2e78fa79
LP
7094 const char *fn;
7095 char *t;
2e78fa79
LP
7096
7097 assert(p);
ae6c3cc0
LP
7098 assert(ret);
7099
c4e34a61
LP
7100 /*
7101 * Turns this:
7102 * /foo/bar/waldo
7103 *
7104 * Into this:
8eebf6ad 7105 * /foo/bar/.#waldoXXXXXX
c4e34a61
LP
7106 */
7107
ae6c3cc0
LP
7108 fn = basename(p);
7109 if (!filename_is_valid(fn))
7110 return -EINVAL;
2e78fa79 7111
8eebf6ad 7112 t = new(char, strlen(p) + 2 + 6 + 1);
2e78fa79 7113 if (!t)
ae6c3cc0 7114 return -ENOMEM;
2e78fa79 7115
8eebf6ad 7116 strcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), fn), "XXXXXX");
2e78fa79 7117
c4e34a61 7118 *ret = path_kill_slashes(t);
ae6c3cc0 7119 return 0;
2e78fa79
LP
7120}
7121
ae6c3cc0 7122int tempfn_random(const char *p, char **ret) {
2e78fa79
LP
7123 const char *fn;
7124 char *t, *x;
7125 uint64_t u;
2e78fa79
LP
7126 unsigned i;
7127
7128 assert(p);
ae6c3cc0
LP
7129 assert(ret);
7130
c4e34a61
LP
7131 /*
7132 * Turns this:
7133 * /foo/bar/waldo
7134 *
7135 * Into this:
8eebf6ad 7136 * /foo/bar/.#waldobaa2a261115984a9
c4e34a61
LP
7137 */
7138
ae6c3cc0
LP
7139 fn = basename(p);
7140 if (!filename_is_valid(fn))
7141 return -EINVAL;
2e78fa79 7142
8eebf6ad 7143 t = new(char, strlen(p) + 2 + 16 + 1);
2e78fa79 7144 if (!t)
ae6c3cc0 7145 return -ENOMEM;
2e78fa79 7146
8eebf6ad 7147 x = stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), fn);
2e78fa79
LP
7148
7149 u = random_u64();
7150 for (i = 0; i < 16; i++) {
7151 *(x++) = hexchar(u & 0xF);
7152 u >>= 4;
7153 }
7154
7155 *x = 0;
7156
c4e34a61
LP
7157 *ret = path_kill_slashes(t);
7158 return 0;
7159}
7160
7161int tempfn_random_child(const char *p, char **ret) {
7162 char *t, *x;
7163 uint64_t u;
7164 unsigned i;
7165
7166 assert(p);
7167 assert(ret);
7168
7169 /* Turns this:
7170 * /foo/bar/waldo
7171 * Into this:
8eebf6ad 7172 * /foo/bar/waldo/.#3c2b6219aa75d7d0
c4e34a61
LP
7173 */
7174
8eebf6ad 7175 t = new(char, strlen(p) + 3 + 16 + 1);
c4e34a61
LP
7176 if (!t)
7177 return -ENOMEM;
7178
8eebf6ad 7179 x = stpcpy(stpcpy(t, p), "/.#");
c4e34a61
LP
7180
7181 u = random_u64();
7182 for (i = 0; i < 16; i++) {
7183 *(x++) = hexchar(u & 0xF);
7184 u >>= 4;
7185 }
7186
7187 *x = 0;
7188
7189 *ret = path_kill_slashes(t);
ae6c3cc0 7190 return 0;
2e78fa79 7191}
fecc80c1
LP
7192
7193/* make sure the hostname is not "localhost" */
7194bool is_localhost(const char *hostname) {
7195 assert(hostname);
7196
a0627f82
LP
7197 /* This tries to identify local host and domain names
7198 * described in RFC6761 plus the redhatism of .localdomain */
fecc80c1
LP
7199
7200 return streq(hostname, "localhost") ||
7201 streq(hostname, "localhost.") ||
a0627f82
LP
7202 streq(hostname, "localdomain.") ||
7203 streq(hostname, "localdomain") ||
fecc80c1
LP
7204 endswith(hostname, ".localhost") ||
7205 endswith(hostname, ".localhost.") ||
7206 endswith(hostname, ".localdomain") ||
7207 endswith(hostname, ".localdomain.");
7208}
45035609
LP
7209
7210int take_password_lock(const char *root) {
7211
7212 struct flock flock = {
7213 .l_type = F_WRLCK,
7214 .l_whence = SEEK_SET,
7215 .l_start = 0,
7216 .l_len = 0,
7217 };
7218
7219 const char *path;
7220 int fd, r;
7221
7222 /* This is roughly the same as lckpwdf(), but not as awful. We
7223 * don't want to use alarm() and signals, hence we implement
7224 * our own trivial version of this.
7225 *
7226 * Note that shadow-utils also takes per-database locks in
7227 * addition to lckpwdf(). However, we don't given that they
7228 * are redundant as they they invoke lckpwdf() first and keep
7229 * it during everything they do. The per-database locks are
7230 * awfully racy, and thus we just won't do them. */
7231
7232 if (root)
63c372cb 7233 path = strjoina(root, "/etc/.pwd.lock");
45035609
LP
7234 else
7235 path = "/etc/.pwd.lock";
7236
7237 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
7238 if (fd < 0)
7239 return -errno;
7240
7241 r = fcntl(fd, F_SETLKW, &flock);
7242 if (r < 0) {
7243 safe_close(fd);
7244 return -errno;
7245 }
7246
7247 return fd;
7248}
5261ba90
TT
7249
7250int is_symlink(const char *path) {
7251 struct stat info;
7252
7253 if (lstat(path, &info) < 0)
7254 return -errno;
7255
be57e297
LP
7256 return !!S_ISLNK(info.st_mode);
7257}
5261ba90 7258
be57e297
LP
7259int is_dir(const char* path, bool follow) {
7260 struct stat st;
d1bddcec 7261 int r;
be57e297 7262
d1bddcec
LP
7263 if (follow)
7264 r = stat(path, &st);
7265 else
7266 r = lstat(path, &st);
7267 if (r < 0)
7268 return -errno;
be57e297
LP
7269
7270 return !!S_ISDIR(st.st_mode);
a0627f82 7271}
7629889c 7272
f32d2db1 7273int unquote_first_word(const char **p, char **ret, bool relax) {
7629889c
LP
7274 _cleanup_free_ char *s = NULL;
7275 size_t allocated = 0, sz = 0;
7276
7277 enum {
7278 START,
7279 VALUE,
7280 VALUE_ESCAPE,
7281 SINGLE_QUOTE,
7282 SINGLE_QUOTE_ESCAPE,
7283 DOUBLE_QUOTE,
7284 DOUBLE_QUOTE_ESCAPE,
7285 SPACE,
7286 } state = START;
7287
7288 assert(p);
7289 assert(*p);
7290 assert(ret);
7291
7292 /* Parses the first word of a string, and returns it in
7293 * *ret. Removes all quotes in the process. When parsing fails
7294 * (because of an uneven number of quotes or similar), leaves
7295 * the pointer *p at the first invalid character. */
7296
7297 for (;;) {
7298 char c = **p;
7299
7300 switch (state) {
7301
7302 case START:
7303 if (c == 0)
7304 goto finish;
7305 else if (strchr(WHITESPACE, c))
7306 break;
7307
7308 state = VALUE;
7309 /* fallthrough */
7310
7311 case VALUE:
7312 if (c == 0)
7313 goto finish;
7314 else if (c == '\'')
7315 state = SINGLE_QUOTE;
7316 else if (c == '\\')
7317 state = VALUE_ESCAPE;
7318 else if (c == '\"')
7319 state = DOUBLE_QUOTE;
7320 else if (strchr(WHITESPACE, c))
7321 state = SPACE;
7322 else {
7323 if (!GREEDY_REALLOC(s, allocated, sz+2))
7324 return -ENOMEM;
7325
7326 s[sz++] = c;
7327 }
7328
7329 break;
7330
7331 case VALUE_ESCAPE:
f32d2db1
LP
7332 if (c == 0) {
7333 if (relax)
7334 goto finish;
7629889c 7335 return -EINVAL;
f32d2db1 7336 }
7629889c
LP
7337
7338 if (!GREEDY_REALLOC(s, allocated, sz+2))
7339 return -ENOMEM;
7340
7341 s[sz++] = c;
7342 state = VALUE;
7343
7344 break;
7345
7346 case SINGLE_QUOTE:
f32d2db1
LP
7347 if (c == 0) {
7348 if (relax)
7349 goto finish;
7629889c 7350 return -EINVAL;
f32d2db1 7351 } else if (c == '\'')
7629889c
LP
7352 state = VALUE;
7353 else if (c == '\\')
7354 state = SINGLE_QUOTE_ESCAPE;
7355 else {
7356 if (!GREEDY_REALLOC(s, allocated, sz+2))
7357 return -ENOMEM;
7358
7359 s[sz++] = c;
7360 }
7361
7362 break;
7363
7364 case SINGLE_QUOTE_ESCAPE:
f32d2db1
LP
7365 if (c == 0) {
7366 if (relax)
7367 goto finish;
7629889c 7368 return -EINVAL;
f32d2db1 7369 }
7629889c
LP
7370
7371 if (!GREEDY_REALLOC(s, allocated, sz+2))
7372 return -ENOMEM;
7373
7374 s[sz++] = c;
7375 state = SINGLE_QUOTE;
7376 break;
7377
7378 case DOUBLE_QUOTE:
7379 if (c == 0)
7380 return -EINVAL;
7381 else if (c == '\"')
7382 state = VALUE;
7383 else if (c == '\\')
7384 state = DOUBLE_QUOTE_ESCAPE;
7385 else {
7386 if (!GREEDY_REALLOC(s, allocated, sz+2))
7387 return -ENOMEM;
7388
7389 s[sz++] = c;
7390 }
7391
7392 break;
7393
7394 case DOUBLE_QUOTE_ESCAPE:
f32d2db1
LP
7395 if (c == 0) {
7396 if (relax)
7397 goto finish;
7629889c 7398 return -EINVAL;
f32d2db1 7399 }
7629889c
LP
7400
7401 if (!GREEDY_REALLOC(s, allocated, sz+2))
7402 return -ENOMEM;
7403
7404 s[sz++] = c;
7405 state = DOUBLE_QUOTE;
7406 break;
7407
7408 case SPACE:
7409 if (c == 0)
7410 goto finish;
7411 if (!strchr(WHITESPACE, c))
7412 goto finish;
7413
7414 break;
7415 }
7416
7417 (*p) ++;
7418 }
7419
7420finish:
7421 if (!s) {
7422 *ret = NULL;
7423 return 0;
7424 }
7425
7426 s[sz] = 0;
7427 *ret = s;
7428 s = NULL;
7429
7430 return 1;
7431}
7432
7433int unquote_many_words(const char **p, ...) {
7434 va_list ap;
7435 char **l;
7436 int n = 0, i, c, r;
7437
7438 /* Parses a number of words from a string, stripping any
7439 * quotes if necessary. */
7440
7441 assert(p);
7442
7443 /* Count how many words are expected */
7444 va_start(ap, p);
7445 for (;;) {
7446 if (!va_arg(ap, char **))
7447 break;
7448 n++;
7449 }
7450 va_end(ap);
7451
7452 if (n <= 0)
7453 return 0;
7454
7455 /* Read all words into a temporary array */
7456 l = newa0(char*, n);
7457 for (c = 0; c < n; c++) {
7458
f32d2db1 7459 r = unquote_first_word(p, &l[c], false);
7629889c
LP
7460 if (r < 0) {
7461 int j;
7462
081e009b 7463 for (j = 0; j < c; j++)
7629889c 7464 free(l[j]);
081e009b
LN
7465
7466 return r;
7629889c
LP
7467 }
7468
7469 if (r == 0)
7470 break;
7471 }
7472
7473 /* If we managed to parse all words, return them in the passed
7474 * in parameters */
7475 va_start(ap, p);
7476 for (i = 0; i < n; i++) {
7477 char **v;
7478
7479 v = va_arg(ap, char **);
7480 assert(v);
7481
7482 *v = l[i];
7483 }
7484 va_end(ap);
7485
7486 return c;
7487}
2928b0a8
LP
7488
7489int free_and_strdup(char **p, const char *s) {
7490 char *t;
7491
7492 assert(p);
7493
7494 /* Replaces a string pointer with an strdup()ed new string,
7495 * possibly freeing the old one. */
7496
7497 if (s) {
7498 t = strdup(s);
7499 if (!t)
7500 return -ENOMEM;
7501 } else
7502 t = NULL;
7503
7504 free(*p);
7505 *p = t;
7506
7507 return 0;
7508}
605f81a8
MS
7509
7510int sethostname_idempotent(const char *s) {
7511 int r;
7512 char buf[HOST_NAME_MAX + 1] = {};
7513
7514 assert(s);
7515
7516 r = gethostname(buf, sizeof(buf));
7517 if (r < 0)
7518 return -errno;
7519
7520 if (streq(buf, s))
7521 return 0;
7522
a9169c1c 7523 r = sethostname(s, strlen(s));
605f81a8
MS
7524 if (r < 0)
7525 return -errno;
7526
7527 return 1;
7528}
ee451d76
LP
7529
7530int ptsname_malloc(int fd, char **ret) {
7531 size_t l = 100;
7532
9d8c4979
LP
7533 assert(fd >= 0);
7534 assert(ret);
7535
ee451d76
LP
7536 for (;;) {
7537 char *c;
7538
7539 c = new(char, l);
7540 if (!c)
7541 return -ENOMEM;
7542
7543 if (ptsname_r(fd, c, l) == 0) {
7544 *ret = c;
7545 return 0;
7546 }
7547 if (errno != ERANGE) {
7548 free(c);
7549 return -errno;
7550 }
7551
7552 free(c);
7553 l *= 2;
7554 }
7555}
5f8cc96a
LP
7556
7557int openpt_in_namespace(pid_t pid, int flags) {
7558 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, rootfd = -1;
7559 _cleanup_close_pair_ int pair[2] = { -1, -1 };
7560 union {
7561 struct cmsghdr cmsghdr;
7562 uint8_t buf[CMSG_SPACE(sizeof(int))];
7563 } control = {};
7564 struct msghdr mh = {
7565 .msg_control = &control,
7566 .msg_controllen = sizeof(control),
7567 };
7568 struct cmsghdr *cmsg;
7569 siginfo_t si;
7570 pid_t child;
7571 int r;
7572
7573 assert(pid > 0);
7574
7575 r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &rootfd);
7576 if (r < 0)
7577 return r;
7578
7579 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
7580 return -errno;
7581
7582 child = fork();
7583 if (child < 0)
7584 return -errno;
7585
7586 if (child == 0) {
7587 int master;
7588
7589 pair[0] = safe_close(pair[0]);
7590
7591 r = namespace_enter(pidnsfd, mntnsfd, -1, rootfd);
7592 if (r < 0)
7593 _exit(EXIT_FAILURE);
7594
7595 master = posix_openpt(flags);
7596 if (master < 0)
7597 _exit(EXIT_FAILURE);
7598
7599 cmsg = CMSG_FIRSTHDR(&mh);
7600 cmsg->cmsg_level = SOL_SOCKET;
7601 cmsg->cmsg_type = SCM_RIGHTS;
7602 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
7603 memcpy(CMSG_DATA(cmsg), &master, sizeof(int));
7604
7605 mh.msg_controllen = cmsg->cmsg_len;
7606
7607 if (sendmsg(pair[1], &mh, MSG_NOSIGNAL) < 0)
7608 _exit(EXIT_FAILURE);
7609
7610 _exit(EXIT_SUCCESS);
7611 }
7612
7613 pair[1] = safe_close(pair[1]);
7614
7615 r = wait_for_terminate(child, &si);
7616 if (r < 0)
7617 return r;
7618 if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
7619 return -EIO;
7620
7621 if (recvmsg(pair[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
7622 return -errno;
7623
7624 for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg))
7625 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
7626 int *fds;
7627 unsigned n_fds;
7628
7629 fds = (int*) CMSG_DATA(cmsg);
7630 n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
7631
7632 if (n_fds != 1) {
7633 close_many(fds, n_fds);
7634 return -EIO;
7635 }
7636
7637 return fds[0];
7638 }
7639
7640 return -EIO;
7641}
4a4d89b6 7642
10f9c755
LP
7643ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) {
7644 _cleanup_close_ int fd = -1;
7645 ssize_t l;
7646
7647 /* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */
7648
7649 fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOATIME|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
7650 if (fd < 0)
7651 return -errno;
7652
7653 l = fgetxattr(fd, attribute, value, size);
7654 if (l < 0)
7655 return -errno;
7656
7657 return l;
7658}
7659
7660static int parse_crtime(le64_t le, usec_t *usec) {
4a4d89b6 7661 uint64_t u;
10f9c755
LP
7662
7663 assert(usec);
7664
7665 u = le64toh(le);
7666 if (u == 0 || u == (uint64_t) -1)
7667 return -EIO;
7668
7669 *usec = (usec_t) u;
7670 return 0;
7671}
7672
7673int fd_getcrtime(int fd, usec_t *usec) {
4a4d89b6
LP
7674 le64_t le;
7675 ssize_t n;
7676
7677 assert(fd >= 0);
7678 assert(usec);
7679
7680 /* Until Linux gets a real concept of birthtime/creation time,
7681 * let's fake one with xattrs */
7682
7683 n = fgetxattr(fd, "user.crtime_usec", &le, sizeof(le));
7684 if (n < 0)
7685 return -errno;
7686 if (n != sizeof(le))
7687 return -EIO;
7688
10f9c755
LP
7689 return parse_crtime(le, usec);
7690}
7691
7692int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags) {
7693 le64_t le;
7694 ssize_t n;
7695
7696 n = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags);
7697 if (n < 0)
7698 return -errno;
7699 if (n != sizeof(le))
4a4d89b6
LP
7700 return -EIO;
7701
10f9c755 7702 return parse_crtime(le, usec);
4a4d89b6
LP
7703}
7704
7705int path_getcrtime(const char *p, usec_t *usec) {
4a4d89b6
LP
7706 le64_t le;
7707 ssize_t n;
7708
7709 assert(p);
7710 assert(usec);
7711
7712 n = getxattr(p, "user.crtime_usec", &le, sizeof(le));
7713 if (n < 0)
7714 return -errno;
7715 if (n != sizeof(le))
7716 return -EIO;
7717
10f9c755 7718 return parse_crtime(le, usec);
4a4d89b6
LP
7719}
7720
7721int fd_setcrtime(int fd, usec_t usec) {
7722 le64_t le;
7723
7724 assert(fd >= 0);
7725
d61b600d
LP
7726 if (usec <= 0)
7727 usec = now(CLOCK_REALTIME);
7728
4a4d89b6 7729 le = htole64((uint64_t) usec);
2c39ea52 7730 if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), 0) < 0)
4a4d89b6
LP
7731 return -errno;
7732
7733 return 0;
7734}
a354329f
LP
7735
7736int same_fd(int a, int b) {
7737 struct stat sta, stb;
f7ad54a3
LP
7738 pid_t pid;
7739 int r, fa, fb;
a354329f
LP
7740
7741 assert(a >= 0);
7742 assert(b >= 0);
7743
f7ad54a3
LP
7744 /* Compares two file descriptors. Note that semantics are
7745 * quite different depending on whether we have kcmp() or we
7746 * don't. If we have kcmp() this will only return true for
7747 * dup()ed file descriptors, but not otherwise. If we don't
7748 * have kcmp() this will also return true for two fds of the same
7749 * file, created by separate open() calls. Since we use this
7750 * call mostly for filtering out duplicates in the fd store
7751 * this difference hopefully doesn't matter too much. */
7752
a354329f
LP
7753 if (a == b)
7754 return true;
7755
f7ad54a3
LP
7756 /* Try to use kcmp() if we have it. */
7757 pid = getpid();
7758 r = kcmp(pid, pid, KCMP_FILE, a, b);
7759 if (r == 0)
7760 return true;
7761 if (r > 0)
7762 return false;
7763 if (errno != ENOSYS)
7764 return -errno;
7765
7766 /* We don't have kcmp(), use fstat() instead. */
a354329f
LP
7767 if (fstat(a, &sta) < 0)
7768 return -errno;
7769
7770 if (fstat(b, &stb) < 0)
7771 return -errno;
7772
7773 if ((sta.st_mode & S_IFMT) != (stb.st_mode & S_IFMT))
7774 return false;
7775
f7ad54a3
LP
7776 /* We consider all device fds different, since two device fds
7777 * might refer to quite different device contexts even though
7778 * they share the same inode and backing dev_t. */
a354329f 7779
f7ad54a3
LP
7780 if (S_ISCHR(sta.st_mode) || S_ISBLK(sta.st_mode))
7781 return false;
7782
7783 if (sta.st_dev != stb.st_dev || sta.st_ino != stb.st_ino)
7784 return false;
7785
7786 /* The fds refer to the same inode on disk, let's also check
7787 * if they have the same fd flags. This is useful to
7788 * distuingish the read and write side of a pipe created with
7789 * pipe(). */
7790 fa = fcntl(a, F_GETFL);
7791 if (fa < 0)
7792 return -errno;
7793
7794 fb = fcntl(b, F_GETFL);
7795 if (fb < 0)
7796 return -errno;
7797
7798 return fa == fb;
a354329f 7799}
11689d2a 7800
45030287
LP
7801int chattr_fd(int fd, bool b, unsigned mask) {
7802 unsigned old_attr, new_attr;
11689d2a
LP
7803
7804 assert(fd >= 0);
7805
45030287
LP
7806 if (mask == 0)
7807 return 0;
7808
11689d2a
LP
7809 if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
7810 return -errno;
7811
7812 if (b)
7813 new_attr = old_attr | mask;
7814 else
7815 new_attr = old_attr & ~mask;
7816
7817 if (new_attr == old_attr)
7818 return 0;
7819
7820 if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
7821 return -errno;
7822
7823 return 0;
7824}
7825
45030287 7826int chattr_path(const char *p, bool b, unsigned mask) {
11689d2a
LP
7827 _cleanup_close_ int fd = -1;
7828
45030287
LP
7829 assert(p);
7830
7831 if (mask == 0)
7832 return 0;
7833
01b72568 7834 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
11689d2a
LP
7835 if (fd < 0)
7836 return -errno;
7837
7838 return chattr_fd(fd, b, mask);
7839}
01b72568
LP
7840
7841int read_attr_fd(int fd, unsigned *ret) {
7842 assert(fd >= 0);
7843
7844 if (ioctl(fd, FS_IOC_GETFLAGS, ret) < 0)
7845 return -errno;
7846
7847 return 0;
7848}
7849
7850int read_attr_path(const char *p, unsigned *ret) {
7851 _cleanup_close_ int fd = -1;
7852
7853 assert(p);
7854 assert(ret);
7855
7856 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
7857 if (fd < 0)
7858 return -errno;
7859
7860 return read_attr_fd(fd, ret);
7861}
30535c16
LP
7862
7863int make_lock_file(const char *p, int operation, LockFile *ret) {
7864 _cleanup_close_ int fd = -1;
7865 _cleanup_free_ char *t = NULL;
7866 int r;
7867
7868 /*
7869 * We use UNPOSIX locks if they are available. They have nice
7870 * semantics, and are mostly compatible with NFS. However,
7871 * they are only available on new kernels. When we detect we
7872 * are running on an older kernel, then we fall back to good
7873 * old BSD locks. They also have nice semantics, but are
7874 * slightly problematic on NFS, where they are upgraded to
7875 * POSIX locks, even though locally they are orthogonal to
7876 * POSIX locks.
7877 */
7878
7879 t = strdup(p);
7880 if (!t)
7881 return -ENOMEM;
7882
7883 for (;;) {
7884 struct flock fl = {
7885 .l_type = (operation & ~LOCK_NB) == LOCK_EX ? F_WRLCK : F_RDLCK,
7886 .l_whence = SEEK_SET,
7887 };
7888 struct stat st;
7889
7890 fd = open(p, O_CREAT|O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NOCTTY, 0600);
7891 if (fd < 0)
7892 return -errno;
7893
7894 r = fcntl(fd, (operation & LOCK_NB) ? F_OFD_SETLK : F_OFD_SETLKW, &fl);
7895 if (r < 0) {
7896
7897 /* If the kernel is too old, use good old BSD locks */
7898 if (errno == EINVAL)
7899 r = flock(fd, operation);
7900
7901 if (r < 0)
7902 return errno == EAGAIN ? -EBUSY : -errno;
7903 }
7904
7905 /* If we acquired the lock, let's check if the file
7906 * still exists in the file system. If not, then the
7907 * previous exclusive owner removed it and then closed
7908 * it. In such a case our acquired lock is worthless,
7909 * hence try again. */
7910
7911 r = fstat(fd, &st);
7912 if (r < 0)
7913 return -errno;
7914 if (st.st_nlink > 0)
7915 break;
7916
7917 fd = safe_close(fd);
7918 }
7919
7920 ret->path = t;
7921 ret->fd = fd;
7922 ret->operation = operation;
7923
7924 fd = -1;
7925 t = NULL;
7926
7927 return r;
7928}
7929
7930int make_lock_file_for(const char *p, int operation, LockFile *ret) {
7931 const char *fn;
7932 char *t;
7933
7934 assert(p);
7935 assert(ret);
7936
7937 fn = basename(p);
7938 if (!filename_is_valid(fn))
7939 return -EINVAL;
7940
7941 t = newa(char, strlen(p) + 2 + 4 + 1);
7942 stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), fn), ".lck");
7943
7944 return make_lock_file(t, operation, ret);
7945}
7946
7947void release_lock_file(LockFile *f) {
7948 int r;
7949
7950 if (!f)
7951 return;
7952
7953 if (f->path) {
7954
7955 /* If we are the exclusive owner we can safely delete
7956 * the lock file itself. If we are not the exclusive
7957 * owner, we can try becoming it. */
7958
7959 if (f->fd >= 0 &&
7960 (f->operation & ~LOCK_NB) == LOCK_SH) {
7961 static const struct flock fl = {
7962 .l_type = F_WRLCK,
7963 .l_whence = SEEK_SET,
7964 };
7965
7966 r = fcntl(f->fd, F_OFD_SETLK, &fl);
7967 if (r < 0 && errno == EINVAL)
7968 r = flock(f->fd, LOCK_EX|LOCK_NB);
7969
7970 if (r >= 0)
7971 f->operation = LOCK_EX|LOCK_NB;
7972 }
7973
7974 if ((f->operation & ~LOCK_NB) == LOCK_EX)
7975 unlink_noerrno(f->path);
7976
7977 free(f->path);
7978 f->path = NULL;
7979 }
7980
7981 f->fd = safe_close(f->fd);
7982 f->operation = 0;
7983}
ff6a7460
LP
7984
7985static size_t nul_length(const uint8_t *p, size_t sz) {
7986 size_t n = 0;
7987
7988 while (sz > 0) {
7989 if (*p != 0)
7990 break;
7991
7992 n++;
7993 p++;
7994 sz--;
7995 }
7996
7997 return n;
7998}
7999
8000ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
8001 const uint8_t *q, *w, *e;
8002 ssize_t l;
8003
8004 q = w = p;
8005 e = q + sz;
8006 while (q < e) {
8007 size_t n;
8008
8009 n = nul_length(q, e - q);
8010
8011 /* If there are more than the specified run length of
8012 * NUL bytes, or if this is the beginning or the end
8013 * of the buffer, then seek instead of write */
8014 if ((n > run_length) ||
8015 (n > 0 && q == p) ||
8016 (n > 0 && q + n >= e)) {
8017 if (q > w) {
8018 l = write(fd, w, q - w);
8019 if (l < 0)
8020 return -errno;
8021 if (l != q -w)
8022 return -EIO;
8023 }
8024
8025 if (lseek(fd, n, SEEK_CUR) == (off_t) -1)
8026 return -errno;
8027
8028 q += n;
8029 w = q;
8030 } else if (n > 0)
8031 q += n;
8032 else
8033 q ++;
8034 }
8035
8036 if (q > w) {
8037 l = write(fd, w, q - w);
8038 if (l < 0)
8039 return -errno;
8040 if (l != q - w)
8041 return -EIO;
8042 }
8043
8044 return q - (const uint8_t*) p;
8045}
3576d631
LP
8046
8047void sigkill_wait(pid_t *pid) {
8048 if (!pid)
8049 return;
8050 if (*pid <= 1)
8051 return;
8052
8053 if (kill(*pid, SIGKILL) > 0)
8054 (void) wait_for_terminate(*pid, NULL);
8055}
3d7415f4
LP
8056
8057int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
8058 int a = 0, b = 0, c = 0;
8059 int k;
8060
8061 assert(p);
8062 assert(*p);
8063 assert(priority);
8064
8065 if ((*p)[0] != '<')
8066 return 0;
8067
8068 if (!strchr(*p, '>'))
8069 return 0;
8070
8071 if ((*p)[2] == '>') {
8072 c = undecchar((*p)[1]);
8073 k = 3;
8074 } else if ((*p)[3] == '>') {
8075 b = undecchar((*p)[1]);
8076 c = undecchar((*p)[2]);
8077 k = 4;
8078 } else if ((*p)[4] == '>') {
8079 a = undecchar((*p)[1]);
8080 b = undecchar((*p)[2]);
8081 c = undecchar((*p)[3]);
8082 k = 5;
8083 } else
8084 return 0;
8085
8086 if (a < 0 || b < 0 || c < 0 ||
8087 (!with_facility && (a || b || c > 7)))
8088 return 0;
8089
8090 if (with_facility)
8091 *priority = a*100 + b*10 + c;
8092 else
8093 *priority = (*priority & LOG_FACMASK) | c;
8094
8095 *p += k;
8096 return 1;
8097}
9cad100e
BB
8098
8099ssize_t string_table_lookup(const char * const *table, size_t len, const char *key) {
8100 size_t i;
8101
8102 if (!key)
8103 return -1;
8104
8105 for (i = 0; i < len; ++i)
8106 if (streq_ptr(table[i], key))
8107 return (ssize_t)i;
8108
8109 return -1;
8110}
1c8da044
LP
8111
8112void cmsg_close_all(struct msghdr *mh) {
8113 struct cmsghdr *cmsg;
8114
8115 assert(mh);
8116
8117 for (cmsg = CMSG_FIRSTHDR(mh); cmsg; cmsg = CMSG_NXTHDR(mh, cmsg))
8118 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
8119 close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int));
8120}