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