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