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