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