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