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