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