]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/util.c
Merge pull request #1467 from jacob-keller/master
[thirdparty/systemd.git] / src / basic / 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 <ctype.h>
23 #include <dirent.h>
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <glob.h>
27 #include <grp.h>
28 #include <langinfo.h>
29 #include <libintl.h>
30 #include <limits.h>
31 #include <linux/magic.h>
32 #include <linux/sched.h>
33 #include <locale.h>
34 #include <netinet/ip.h>
35 #include <poll.h>
36 #include <pwd.h>
37 #include <sched.h>
38 #include <signal.h>
39 #include <stdarg.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <sys/file.h>
44 #include <sys/ioctl.h>
45 #include <sys/mman.h>
46 #include <sys/mount.h>
47 #include <sys/personality.h>
48 #include <sys/prctl.h>
49 #include <sys/resource.h>
50 #include <sys/stat.h>
51 #include <sys/statvfs.h>
52 #include <sys/time.h>
53 #include <sys/types.h>
54 #include <sys/utsname.h>
55 #include <sys/vfs.h>
56 #include <sys/wait.h>
57 #include <sys/xattr.h>
58 #include <syslog.h>
59 #include <unistd.h>
60
61 /* When we include libgen.h because we need dirname() we immediately
62 * undefine basename() since libgen.h defines it as a macro to the
63 * POSIX version which is really broken. We prefer GNU basename(). */
64 #include <libgen.h>
65 #undef basename
66
67 #ifdef HAVE_SYS_AUXV_H
68 #include <sys/auxv.h>
69 #endif
70
71 /* We include linux/fs.h as last of the system headers, as it
72 * otherwise conflicts with sys/mount.h. Yay, Linux is great! */
73 #include <linux/fs.h>
74
75 #include "build.h"
76 #include "def.h"
77 #include "device-nodes.h"
78 #include "env-util.h"
79 #include "exit-status.h"
80 #include "fileio.h"
81 #include "formats-util.h"
82 #include "gunicode.h"
83 #include "hashmap.h"
84 #include "hostname-util.h"
85 #include "ioprio.h"
86 #include "log.h"
87 #include "macro.h"
88 #include "missing.h"
89 #include "mkdir.h"
90 #include "path-util.h"
91 #include "process-util.h"
92 #include "random-util.h"
93 #include "signal-util.h"
94 #include "sparse-endian.h"
95 #include "strv.h"
96 #include "terminal-util.h"
97 #include "utf8.h"
98 #include "util.h"
99 #include "virt.h"
100
101 /* Put this test here for a lack of better place */
102 assert_cc(EAGAIN == EWOULDBLOCK);
103
104 int saved_argc = 0;
105 char **saved_argv = NULL;
106
107 size_t page_size(void) {
108 static thread_local size_t pgsz = 0;
109 long r;
110
111 if (_likely_(pgsz > 0))
112 return pgsz;
113
114 r = sysconf(_SC_PAGESIZE);
115 assert(r > 0);
116
117 pgsz = (size_t) r;
118 return pgsz;
119 }
120
121 int strcmp_ptr(const char *a, const char *b) {
122
123 /* Like strcmp(), but tries to make sense of NULL pointers */
124 if (a && b)
125 return strcmp(a, b);
126
127 if (!a && b)
128 return -1;
129
130 if (a && !b)
131 return 1;
132
133 return 0;
134 }
135
136 bool streq_ptr(const char *a, const char *b) {
137 return strcmp_ptr(a, b) == 0;
138 }
139
140 char* endswith(const char *s, const char *postfix) {
141 size_t sl, pl;
142
143 assert(s);
144 assert(postfix);
145
146 sl = strlen(s);
147 pl = strlen(postfix);
148
149 if (pl == 0)
150 return (char*) s + sl;
151
152 if (sl < pl)
153 return NULL;
154
155 if (memcmp(s + sl - pl, postfix, pl) != 0)
156 return NULL;
157
158 return (char*) s + sl - pl;
159 }
160
161 char* endswith_no_case(const char *s, const char *postfix) {
162 size_t sl, pl;
163
164 assert(s);
165 assert(postfix);
166
167 sl = strlen(s);
168 pl = strlen(postfix);
169
170 if (pl == 0)
171 return (char*) s + sl;
172
173 if (sl < pl)
174 return NULL;
175
176 if (strcasecmp(s + sl - pl, postfix) != 0)
177 return NULL;
178
179 return (char*) s + sl - pl;
180 }
181
182 char* first_word(const char *s, const char *word) {
183 size_t sl, wl;
184 const char *p;
185
186 assert(s);
187 assert(word);
188
189 /* Checks if the string starts with the specified word, either
190 * followed by NUL or by whitespace. Returns a pointer to the
191 * NUL or the first character after the whitespace. */
192
193 sl = strlen(s);
194 wl = strlen(word);
195
196 if (sl < wl)
197 return NULL;
198
199 if (wl == 0)
200 return (char*) s;
201
202 if (memcmp(s, word, wl) != 0)
203 return NULL;
204
205 p = s + wl;
206 if (*p == 0)
207 return (char*) p;
208
209 if (!strchr(WHITESPACE, *p))
210 return NULL;
211
212 p += strspn(p, WHITESPACE);
213 return (char*) p;
214 }
215
216 size_t cescape_char(char c, char *buf) {
217 char * buf_old = buf;
218
219 switch (c) {
220
221 case '\a':
222 *(buf++) = '\\';
223 *(buf++) = 'a';
224 break;
225 case '\b':
226 *(buf++) = '\\';
227 *(buf++) = 'b';
228 break;
229 case '\f':
230 *(buf++) = '\\';
231 *(buf++) = 'f';
232 break;
233 case '\n':
234 *(buf++) = '\\';
235 *(buf++) = 'n';
236 break;
237 case '\r':
238 *(buf++) = '\\';
239 *(buf++) = 'r';
240 break;
241 case '\t':
242 *(buf++) = '\\';
243 *(buf++) = 't';
244 break;
245 case '\v':
246 *(buf++) = '\\';
247 *(buf++) = 'v';
248 break;
249 case '\\':
250 *(buf++) = '\\';
251 *(buf++) = '\\';
252 break;
253 case '"':
254 *(buf++) = '\\';
255 *(buf++) = '"';
256 break;
257 case '\'':
258 *(buf++) = '\\';
259 *(buf++) = '\'';
260 break;
261
262 default:
263 /* For special chars we prefer octal over
264 * hexadecimal encoding, simply because glib's
265 * g_strescape() does the same */
266 if ((c < ' ') || (c >= 127)) {
267 *(buf++) = '\\';
268 *(buf++) = octchar((unsigned char) c >> 6);
269 *(buf++) = octchar((unsigned char) c >> 3);
270 *(buf++) = octchar((unsigned char) c);
271 } else
272 *(buf++) = c;
273 break;
274 }
275
276 return buf - buf_old;
277 }
278
279 int close_nointr(int fd) {
280 assert(fd >= 0);
281
282 if (close(fd) >= 0)
283 return 0;
284
285 /*
286 * Just ignore EINTR; a retry loop is the wrong thing to do on
287 * Linux.
288 *
289 * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
290 * https://bugzilla.gnome.org/show_bug.cgi?id=682819
291 * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
292 * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
293 */
294 if (errno == EINTR)
295 return 0;
296
297 return -errno;
298 }
299
300 int safe_close(int fd) {
301
302 /*
303 * Like close_nointr() but cannot fail. Guarantees errno is
304 * unchanged. Is a NOP with negative fds passed, and returns
305 * -1, so that it can be used in this syntax:
306 *
307 * fd = safe_close(fd);
308 */
309
310 if (fd >= 0) {
311 PROTECT_ERRNO;
312
313 /* The kernel might return pretty much any error code
314 * via close(), but the fd will be closed anyway. The
315 * only condition we want to check for here is whether
316 * the fd was invalid at all... */
317
318 assert_se(close_nointr(fd) != -EBADF);
319 }
320
321 return -1;
322 }
323
324 void close_many(const int fds[], unsigned n_fd) {
325 unsigned i;
326
327 assert(fds || n_fd <= 0);
328
329 for (i = 0; i < n_fd; i++)
330 safe_close(fds[i]);
331 }
332
333 int fclose_nointr(FILE *f) {
334 assert(f);
335
336 /* Same as close_nointr(), but for fclose() */
337
338 if (fclose(f) == 0)
339 return 0;
340
341 if (errno == EINTR)
342 return 0;
343
344 return -errno;
345 }
346
347 FILE* safe_fclose(FILE *f) {
348
349 /* Same as safe_close(), but for fclose() */
350
351 if (f) {
352 PROTECT_ERRNO;
353
354 assert_se(fclose_nointr(f) != EBADF);
355 }
356
357 return NULL;
358 }
359
360 DIR* safe_closedir(DIR *d) {
361
362 if (d) {
363 PROTECT_ERRNO;
364
365 assert_se(closedir(d) >= 0 || errno != EBADF);
366 }
367
368 return NULL;
369 }
370
371 int unlink_noerrno(const char *path) {
372 PROTECT_ERRNO;
373 int r;
374
375 r = unlink(path);
376 if (r < 0)
377 return -errno;
378
379 return 0;
380 }
381
382 int parse_boolean(const char *v) {
383 assert(v);
384
385 if (streq(v, "1") || strcaseeq(v, "yes") || strcaseeq(v, "y") || strcaseeq(v, "true") || strcaseeq(v, "t") || strcaseeq(v, "on"))
386 return 1;
387 else if (streq(v, "0") || strcaseeq(v, "no") || strcaseeq(v, "n") || strcaseeq(v, "false") || strcaseeq(v, "f") || strcaseeq(v, "off"))
388 return 0;
389
390 return -EINVAL;
391 }
392
393 int parse_pid(const char *s, pid_t* ret_pid) {
394 unsigned long ul = 0;
395 pid_t pid;
396 int r;
397
398 assert(s);
399 assert(ret_pid);
400
401 r = safe_atolu(s, &ul);
402 if (r < 0)
403 return r;
404
405 pid = (pid_t) ul;
406
407 if ((unsigned long) pid != ul)
408 return -ERANGE;
409
410 if (pid <= 0)
411 return -ERANGE;
412
413 *ret_pid = pid;
414 return 0;
415 }
416
417 bool uid_is_valid(uid_t uid) {
418
419 /* Some libc APIs use UID_INVALID as special placeholder */
420 if (uid == (uid_t) 0xFFFFFFFF)
421 return false;
422
423 /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
424 if (uid == (uid_t) 0xFFFF)
425 return false;
426
427 return true;
428 }
429
430 int parse_uid(const char *s, uid_t* ret_uid) {
431 unsigned long ul = 0;
432 uid_t uid;
433 int r;
434
435 assert(s);
436
437 r = safe_atolu(s, &ul);
438 if (r < 0)
439 return r;
440
441 uid = (uid_t) ul;
442
443 if ((unsigned long) uid != ul)
444 return -ERANGE;
445
446 if (!uid_is_valid(uid))
447 return -ENXIO; /* we return ENXIO instead of EINVAL
448 * here, to make it easy to distuingish
449 * invalid numeric uids invalid
450 * strings. */
451
452 if (ret_uid)
453 *ret_uid = uid;
454
455 return 0;
456 }
457
458 int safe_atou(const char *s, unsigned *ret_u) {
459 char *x = NULL;
460 unsigned long l;
461
462 assert(s);
463 assert(ret_u);
464
465 errno = 0;
466 l = strtoul(s, &x, 0);
467
468 if (!x || x == s || *x || errno)
469 return errno > 0 ? -errno : -EINVAL;
470
471 if ((unsigned long) (unsigned) l != l)
472 return -ERANGE;
473
474 *ret_u = (unsigned) l;
475 return 0;
476 }
477
478 int safe_atoi(const char *s, int *ret_i) {
479 char *x = NULL;
480 long l;
481
482 assert(s);
483 assert(ret_i);
484
485 errno = 0;
486 l = strtol(s, &x, 0);
487
488 if (!x || x == s || *x || errno)
489 return errno > 0 ? -errno : -EINVAL;
490
491 if ((long) (int) l != l)
492 return -ERANGE;
493
494 *ret_i = (int) l;
495 return 0;
496 }
497
498 int safe_atou8(const char *s, uint8_t *ret) {
499 char *x = NULL;
500 unsigned long l;
501
502 assert(s);
503 assert(ret);
504
505 errno = 0;
506 l = strtoul(s, &x, 0);
507
508 if (!x || x == s || *x || errno)
509 return errno > 0 ? -errno : -EINVAL;
510
511 if ((unsigned long) (uint8_t) l != l)
512 return -ERANGE;
513
514 *ret = (uint8_t) l;
515 return 0;
516 }
517
518 int safe_atou16(const char *s, uint16_t *ret) {
519 char *x = NULL;
520 unsigned long l;
521
522 assert(s);
523 assert(ret);
524
525 errno = 0;
526 l = strtoul(s, &x, 0);
527
528 if (!x || x == s || *x || errno)
529 return errno > 0 ? -errno : -EINVAL;
530
531 if ((unsigned long) (uint16_t) l != l)
532 return -ERANGE;
533
534 *ret = (uint16_t) l;
535 return 0;
536 }
537
538 int safe_atoi16(const char *s, int16_t *ret) {
539 char *x = NULL;
540 long l;
541
542 assert(s);
543 assert(ret);
544
545 errno = 0;
546 l = strtol(s, &x, 0);
547
548 if (!x || x == s || *x || errno)
549 return errno > 0 ? -errno : -EINVAL;
550
551 if ((long) (int16_t) l != l)
552 return -ERANGE;
553
554 *ret = (int16_t) l;
555 return 0;
556 }
557
558 int safe_atollu(const char *s, long long unsigned *ret_llu) {
559 char *x = NULL;
560 unsigned long long l;
561
562 assert(s);
563 assert(ret_llu);
564
565 errno = 0;
566 l = strtoull(s, &x, 0);
567
568 if (!x || x == s || *x || errno)
569 return errno ? -errno : -EINVAL;
570
571 *ret_llu = l;
572 return 0;
573 }
574
575 int safe_atolli(const char *s, long long int *ret_lli) {
576 char *x = NULL;
577 long long l;
578
579 assert(s);
580 assert(ret_lli);
581
582 errno = 0;
583 l = strtoll(s, &x, 0);
584
585 if (!x || x == s || *x || errno)
586 return errno ? -errno : -EINVAL;
587
588 *ret_lli = l;
589 return 0;
590 }
591
592 int safe_atod(const char *s, double *ret_d) {
593 char *x = NULL;
594 double d = 0;
595 locale_t loc;
596
597 assert(s);
598 assert(ret_d);
599
600 loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
601 if (loc == (locale_t) 0)
602 return -errno;
603
604 errno = 0;
605 d = strtod_l(s, &x, loc);
606
607 if (!x || x == s || *x || errno) {
608 freelocale(loc);
609 return errno ? -errno : -EINVAL;
610 }
611
612 freelocale(loc);
613 *ret_d = (double) d;
614 return 0;
615 }
616
617 static size_t strcspn_escaped(const char *s, const char *reject) {
618 bool escaped = false;
619 int n;
620
621 for (n=0; s[n]; n++) {
622 if (escaped)
623 escaped = false;
624 else if (s[n] == '\\')
625 escaped = true;
626 else if (strchr(reject, s[n]))
627 break;
628 }
629
630 /* if s ends in \, return index of previous char */
631 return n - escaped;
632 }
633
634 /* Split a string into words. */
635 const char* split(const char **state, size_t *l, const char *separator, bool quoted) {
636 const char *current;
637
638 current = *state;
639
640 if (!*current) {
641 assert(**state == '\0');
642 return NULL;
643 }
644
645 current += strspn(current, separator);
646 if (!*current) {
647 *state = current;
648 return NULL;
649 }
650
651 if (quoted && strchr("\'\"", *current)) {
652 char quotechars[2] = {*current, '\0'};
653
654 *l = strcspn_escaped(current + 1, quotechars);
655 if (current[*l + 1] == '\0' || current[*l + 1] != quotechars[0] ||
656 (current[*l + 2] && !strchr(separator, current[*l + 2]))) {
657 /* right quote missing or garbage at the end */
658 *state = current;
659 return NULL;
660 }
661 *state = current++ + *l + 2;
662 } else if (quoted) {
663 *l = strcspn_escaped(current, separator);
664 if (current[*l] && !strchr(separator, current[*l])) {
665 /* unfinished escape */
666 *state = current;
667 return NULL;
668 }
669 *state = current + *l;
670 } else {
671 *l = strcspn(current, separator);
672 *state = current + *l;
673 }
674
675 return current;
676 }
677
678 int fchmod_umask(int fd, mode_t m) {
679 mode_t u;
680 int r;
681
682 u = umask(0777);
683 r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
684 umask(u);
685
686 return r;
687 }
688
689 char *truncate_nl(char *s) {
690 assert(s);
691
692 s[strcspn(s, NEWLINE)] = 0;
693 return s;
694 }
695
696 char *strnappend(const char *s, const char *suffix, size_t b) {
697 size_t a;
698 char *r;
699
700 if (!s && !suffix)
701 return strdup("");
702
703 if (!s)
704 return strndup(suffix, b);
705
706 if (!suffix)
707 return strdup(s);
708
709 assert(s);
710 assert(suffix);
711
712 a = strlen(s);
713 if (b > ((size_t) -1) - a)
714 return NULL;
715
716 r = new(char, a+b+1);
717 if (!r)
718 return NULL;
719
720 memcpy(r, s, a);
721 memcpy(r+a, suffix, b);
722 r[a+b] = 0;
723
724 return r;
725 }
726
727 char *strappend(const char *s, const char *suffix) {
728 return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
729 }
730
731 int readlinkat_malloc(int fd, const char *p, char **ret) {
732 size_t l = 100;
733 int r;
734
735 assert(p);
736 assert(ret);
737
738 for (;;) {
739 char *c;
740 ssize_t n;
741
742 c = new(char, l);
743 if (!c)
744 return -ENOMEM;
745
746 n = readlinkat(fd, p, c, l-1);
747 if (n < 0) {
748 r = -errno;
749 free(c);
750 return r;
751 }
752
753 if ((size_t) n < l-1) {
754 c[n] = 0;
755 *ret = c;
756 return 0;
757 }
758
759 free(c);
760 l *= 2;
761 }
762 }
763
764 int readlink_malloc(const char *p, char **ret) {
765 return readlinkat_malloc(AT_FDCWD, p, ret);
766 }
767
768 int readlink_value(const char *p, char **ret) {
769 _cleanup_free_ char *link = NULL;
770 char *value;
771 int r;
772
773 r = readlink_malloc(p, &link);
774 if (r < 0)
775 return r;
776
777 value = basename(link);
778 if (!value)
779 return -ENOENT;
780
781 value = strdup(value);
782 if (!value)
783 return -ENOMEM;
784
785 *ret = value;
786
787 return 0;
788 }
789
790 int readlink_and_make_absolute(const char *p, char **r) {
791 _cleanup_free_ char *target = NULL;
792 char *k;
793 int j;
794
795 assert(p);
796 assert(r);
797
798 j = readlink_malloc(p, &target);
799 if (j < 0)
800 return j;
801
802 k = file_in_same_dir(p, target);
803 if (!k)
804 return -ENOMEM;
805
806 *r = k;
807 return 0;
808 }
809
810 int readlink_and_canonicalize(const char *p, char **r) {
811 char *t, *s;
812 int j;
813
814 assert(p);
815 assert(r);
816
817 j = readlink_and_make_absolute(p, &t);
818 if (j < 0)
819 return j;
820
821 s = canonicalize_file_name(t);
822 if (s) {
823 free(t);
824 *r = s;
825 } else
826 *r = t;
827
828 path_kill_slashes(*r);
829
830 return 0;
831 }
832
833 char *strstrip(char *s) {
834 char *e;
835
836 /* Drops trailing whitespace. Modifies the string in
837 * place. Returns pointer to first non-space character */
838
839 s += strspn(s, WHITESPACE);
840
841 for (e = strchr(s, 0); e > s; e --)
842 if (!strchr(WHITESPACE, e[-1]))
843 break;
844
845 *e = 0;
846
847 return s;
848 }
849
850 char *delete_chars(char *s, const char *bad) {
851 char *f, *t;
852
853 /* Drops all whitespace, regardless where in the string */
854
855 for (f = s, t = s; *f; f++) {
856 if (strchr(bad, *f))
857 continue;
858
859 *(t++) = *f;
860 }
861
862 *t = 0;
863
864 return s;
865 }
866
867 char *file_in_same_dir(const char *path, const char *filename) {
868 char *e, *ret;
869 size_t k;
870
871 assert(path);
872 assert(filename);
873
874 /* This removes the last component of path and appends
875 * filename, unless the latter is absolute anyway or the
876 * former isn't */
877
878 if (path_is_absolute(filename))
879 return strdup(filename);
880
881 e = strrchr(path, '/');
882 if (!e)
883 return strdup(filename);
884
885 k = strlen(filename);
886 ret = new(char, (e + 1 - path) + k + 1);
887 if (!ret)
888 return NULL;
889
890 memcpy(mempcpy(ret, path, e + 1 - path), filename, k + 1);
891 return ret;
892 }
893
894 int rmdir_parents(const char *path, const char *stop) {
895 size_t l;
896 int r = 0;
897
898 assert(path);
899 assert(stop);
900
901 l = strlen(path);
902
903 /* Skip trailing slashes */
904 while (l > 0 && path[l-1] == '/')
905 l--;
906
907 while (l > 0) {
908 char *t;
909
910 /* Skip last component */
911 while (l > 0 && path[l-1] != '/')
912 l--;
913
914 /* Skip trailing slashes */
915 while (l > 0 && path[l-1] == '/')
916 l--;
917
918 if (l <= 0)
919 break;
920
921 if (!(t = strndup(path, l)))
922 return -ENOMEM;
923
924 if (path_startswith(stop, t)) {
925 free(t);
926 return 0;
927 }
928
929 r = rmdir(t);
930 free(t);
931
932 if (r < 0)
933 if (errno != ENOENT)
934 return -errno;
935 }
936
937 return 0;
938 }
939
940 char hexchar(int x) {
941 static const char table[16] = "0123456789abcdef";
942
943 return table[x & 15];
944 }
945
946 int unhexchar(char c) {
947
948 if (c >= '0' && c <= '9')
949 return c - '0';
950
951 if (c >= 'a' && c <= 'f')
952 return c - 'a' + 10;
953
954 if (c >= 'A' && c <= 'F')
955 return c - 'A' + 10;
956
957 return -EINVAL;
958 }
959
960 char *hexmem(const void *p, size_t l) {
961 char *r, *z;
962 const uint8_t *x;
963
964 z = r = malloc(l * 2 + 1);
965 if (!r)
966 return NULL;
967
968 for (x = p; x < (const uint8_t*) p + l; x++) {
969 *(z++) = hexchar(*x >> 4);
970 *(z++) = hexchar(*x & 15);
971 }
972
973 *z = 0;
974 return r;
975 }
976
977 int unhexmem(const char *p, size_t l, void **mem, size_t *len) {
978 _cleanup_free_ uint8_t *r = NULL;
979 uint8_t *z;
980 const char *x;
981
982 assert(mem);
983 assert(len);
984 assert(p);
985
986 z = r = malloc((l + 1) / 2 + 1);
987 if (!r)
988 return -ENOMEM;
989
990 for (x = p; x < p + l; x += 2) {
991 int a, b;
992
993 a = unhexchar(x[0]);
994 if (a < 0)
995 return a;
996 else if (x+1 < p + l) {
997 b = unhexchar(x[1]);
998 if (b < 0)
999 return b;
1000 } else
1001 b = 0;
1002
1003 *(z++) = (uint8_t) a << 4 | (uint8_t) b;
1004 }
1005
1006 *z = 0;
1007
1008 *mem = r;
1009 r = NULL;
1010 *len = (l + 1) / 2;
1011
1012 return 0;
1013 }
1014
1015 /* https://tools.ietf.org/html/rfc4648#section-6
1016 * Notice that base32hex differs from base32 in the alphabet it uses.
1017 * The distinction is that the base32hex representation preserves the
1018 * order of the underlying data when compared as bytestrings, this is
1019 * useful when representing NSEC3 hashes, as one can then verify the
1020 * order of hashes directly from their representation. */
1021 char base32hexchar(int x) {
1022 static const char table[32] = "0123456789"
1023 "ABCDEFGHIJKLMNOPQRSTUV";
1024
1025 return table[x & 31];
1026 }
1027
1028 int unbase32hexchar(char c) {
1029 unsigned offset;
1030
1031 if (c >= '0' && c <= '9')
1032 return c - '0';
1033
1034 offset = '9' - '0' + 1;
1035
1036 if (c >= 'A' && c <= 'V')
1037 return c - 'A' + offset;
1038
1039 return -EINVAL;
1040 }
1041
1042 char *base32hexmem(const void *p, size_t l, bool padding) {
1043 char *r, *z;
1044 const uint8_t *x;
1045 size_t len;
1046
1047 if (padding)
1048 /* five input bytes makes eight output bytes, padding is added so we must round up */
1049 len = 8 * (l + 4) / 5;
1050 else {
1051 /* same, but round down as there is no padding */
1052 len = 8 * l / 5;
1053
1054 switch (l % 5) {
1055 case 4:
1056 len += 7;
1057 break;
1058 case 3:
1059 len += 5;
1060 break;
1061 case 2:
1062 len += 4;
1063 break;
1064 case 1:
1065 len += 2;
1066 break;
1067 }
1068 }
1069
1070 z = r = malloc(len + 1);
1071 if (!r)
1072 return NULL;
1073
1074 for (x = p; x < (const uint8_t*) p + (l / 5) * 5; x += 5) {
1075 /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ
1076 x[3] == QQQQQQQQ; x[4] == WWWWWWWW */
1077 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1078 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1079 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1080 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
1081 *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */
1082 *(z++) = base32hexchar((x[3] & 127) >> 2); /* 000QQQQQ */
1083 *(z++) = base32hexchar((x[3] & 3) << 3 | x[4] >> 5); /* 000QQWWW */
1084 *(z++) = base32hexchar((x[4] & 31)); /* 000WWWWW */
1085 }
1086
1087 switch (l % 5) {
1088 case 4:
1089 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1090 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1091 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1092 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
1093 *(z++) = base32hexchar((x[2] & 15) << 1 | x[3] >> 7); /* 000ZZZZQ */
1094 *(z++) = base32hexchar((x[3] & 127) >> 2); /* 000QQQQQ */
1095 *(z++) = base32hexchar((x[3] & 3) << 3); /* 000QQ000 */
1096 if (padding)
1097 *(z++) = '=';
1098
1099 break;
1100
1101 case 3:
1102 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1103 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1104 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1105 *(z++) = base32hexchar((x[1] & 1) << 4 | x[2] >> 4); /* 000YZZZZ */
1106 *(z++) = base32hexchar((x[2] & 15) << 1); /* 000ZZZZ0 */
1107 if (padding) {
1108 *(z++) = '=';
1109 *(z++) = '=';
1110 *(z++) = '=';
1111 }
1112
1113 break;
1114
1115 case 2:
1116 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1117 *(z++) = base32hexchar((x[0] & 7) << 2 | x[1] >> 6); /* 000XXXYY */
1118 *(z++) = base32hexchar((x[1] & 63) >> 1); /* 000YYYYY */
1119 *(z++) = base32hexchar((x[1] & 1) << 4); /* 000Y0000 */
1120 if (padding) {
1121 *(z++) = '=';
1122 *(z++) = '=';
1123 *(z++) = '=';
1124 *(z++) = '=';
1125 }
1126
1127 break;
1128
1129 case 1:
1130 *(z++) = base32hexchar(x[0] >> 3); /* 000XXXXX */
1131 *(z++) = base32hexchar((x[0] & 7) << 2); /* 000XXX00 */
1132 if (padding) {
1133 *(z++) = '=';
1134 *(z++) = '=';
1135 *(z++) = '=';
1136 *(z++) = '=';
1137 *(z++) = '=';
1138 *(z++) = '=';
1139 }
1140
1141 break;
1142 }
1143
1144 *z = 0;
1145 return r;
1146 }
1147
1148 int unbase32hexmem(const char *p, size_t l, bool padding, void **mem, size_t *_len) {
1149 _cleanup_free_ uint8_t *r = NULL;
1150 int a, b, c, d, e, f, g, h;
1151 uint8_t *z;
1152 const char *x;
1153 size_t len;
1154 unsigned pad = 0;
1155
1156 assert(p);
1157
1158 /* padding ensures any base32hex input has input divisible by 8 */
1159 if (padding && l % 8 != 0)
1160 return -EINVAL;
1161
1162 if (padding) {
1163 /* strip the padding */
1164 while (l > 0 && p[l - 1] == '=' && pad < 7) {
1165 pad ++;
1166 l --;
1167 }
1168 }
1169
1170 /* a group of eight input bytes needs five output bytes, in case of
1171 padding we need to add some extra bytes */
1172 len = (l / 8) * 5;
1173
1174 switch (l % 8) {
1175 case 7:
1176 len += 4;
1177 break;
1178 case 5:
1179 len += 3;
1180 break;
1181 case 4:
1182 len += 2;
1183 break;
1184 case 2:
1185 len += 1;
1186 break;
1187 case 0:
1188 break;
1189 default:
1190 return -EINVAL;
1191 }
1192
1193 z = r = malloc(len + 1);
1194 if (!r)
1195 return -ENOMEM;
1196
1197 for (x = p; x < p + (l / 8) * 8; x += 8) {
1198 /* a == 000XXXXX; b == 000YYYYY; c == 000ZZZZZ; d == 000WWWWW
1199 e == 000SSSSS; f == 000QQQQQ; g == 000VVVVV; h == 000RRRRR */
1200 a = unbase32hexchar(x[0]);
1201 if (a < 0)
1202 return -EINVAL;
1203
1204 b = unbase32hexchar(x[1]);
1205 if (b < 0)
1206 return -EINVAL;
1207
1208 c = unbase32hexchar(x[2]);
1209 if (c < 0)
1210 return -EINVAL;
1211
1212 d = unbase32hexchar(x[3]);
1213 if (d < 0)
1214 return -EINVAL;
1215
1216 e = unbase32hexchar(x[4]);
1217 if (e < 0)
1218 return -EINVAL;
1219
1220 f = unbase32hexchar(x[5]);
1221 if (f < 0)
1222 return -EINVAL;
1223
1224 g = unbase32hexchar(x[6]);
1225 if (g < 0)
1226 return -EINVAL;
1227
1228 h = unbase32hexchar(x[7]);
1229 if (h < 0)
1230 return -EINVAL;
1231
1232 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1233 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1234 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
1235 *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */
1236 *(z++) = (uint8_t) g << 5 | (uint8_t) h; /* VVVRRRRR */
1237 }
1238
1239 switch (l % 8) {
1240 case 7:
1241 a = unbase32hexchar(x[0]);
1242 if (a < 0)
1243 return -EINVAL;
1244
1245 b = unbase32hexchar(x[1]);
1246 if (b < 0)
1247 return -EINVAL;
1248
1249 c = unbase32hexchar(x[2]);
1250 if (c < 0)
1251 return -EINVAL;
1252
1253 d = unbase32hexchar(x[3]);
1254 if (d < 0)
1255 return -EINVAL;
1256
1257 e = unbase32hexchar(x[4]);
1258 if (e < 0)
1259 return -EINVAL;
1260
1261 f = unbase32hexchar(x[5]);
1262 if (f < 0)
1263 return -EINVAL;
1264
1265 g = unbase32hexchar(x[6]);
1266 if (g < 0)
1267 return -EINVAL;
1268
1269 /* g == 000VV000 */
1270 if (g & 7)
1271 return -EINVAL;
1272
1273 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1274 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1275 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
1276 *(z++) = (uint8_t) e << 7 | (uint8_t) f << 2 | (uint8_t) g >> 3; /* SQQQQQVV */
1277
1278 break;
1279 case 5:
1280 a = unbase32hexchar(x[0]);
1281 if (a < 0)
1282 return -EINVAL;
1283
1284 b = unbase32hexchar(x[1]);
1285 if (b < 0)
1286 return -EINVAL;
1287
1288 c = unbase32hexchar(x[2]);
1289 if (c < 0)
1290 return -EINVAL;
1291
1292 d = unbase32hexchar(x[3]);
1293 if (d < 0)
1294 return -EINVAL;
1295
1296 e = unbase32hexchar(x[4]);
1297 if (e < 0)
1298 return -EINVAL;
1299
1300 /* e == 000SSSS0 */
1301 if (e & 1)
1302 return -EINVAL;
1303
1304 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1305 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1306 *(z++) = (uint8_t) d << 4 | (uint8_t) e >> 1; /* WWWWSSSS */
1307
1308 break;
1309 case 4:
1310 a = unbase32hexchar(x[0]);
1311 if (a < 0)
1312 return -EINVAL;
1313
1314 b = unbase32hexchar(x[1]);
1315 if (b < 0)
1316 return -EINVAL;
1317
1318 c = unbase32hexchar(x[2]);
1319 if (c < 0)
1320 return -EINVAL;
1321
1322 d = unbase32hexchar(x[3]);
1323 if (d < 0)
1324 return -EINVAL;
1325
1326 /* d == 000W0000 */
1327 if (d & 15)
1328 return -EINVAL;
1329
1330 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1331 *(z++) = (uint8_t) b << 6 | (uint8_t) c << 1 | (uint8_t) d >> 4; /* YYZZZZZW */
1332
1333 break;
1334 case 2:
1335 a = unbase32hexchar(x[0]);
1336 if (a < 0)
1337 return -EINVAL;
1338
1339 b = unbase32hexchar(x[1]);
1340 if (b < 0)
1341 return -EINVAL;
1342
1343 /* b == 000YYY00 */
1344 if (b & 3)
1345 return -EINVAL;
1346
1347 *(z++) = (uint8_t) a << 3 | (uint8_t) b >> 2; /* XXXXXYYY */
1348
1349 break;
1350 case 0:
1351 break;
1352 default:
1353 return -EINVAL;
1354 }
1355
1356 *z = 0;
1357
1358 *mem = r;
1359 r = NULL;
1360 *_len = len;
1361
1362 return 0;
1363 }
1364
1365 /* https://tools.ietf.org/html/rfc4648#section-4 */
1366 char base64char(int x) {
1367 static const char table[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1368 "abcdefghijklmnopqrstuvwxyz"
1369 "0123456789+/";
1370 return table[x & 63];
1371 }
1372
1373 int unbase64char(char c) {
1374 unsigned offset;
1375
1376 if (c >= 'A' && c <= 'Z')
1377 return c - 'A';
1378
1379 offset = 'Z' - 'A' + 1;
1380
1381 if (c >= 'a' && c <= 'z')
1382 return c - 'a' + offset;
1383
1384 offset += 'z' - 'a' + 1;
1385
1386 if (c >= '0' && c <= '9')
1387 return c - '0' + offset;
1388
1389 offset += '9' - '0' + 1;
1390
1391 if (c == '+')
1392 return offset;
1393
1394 offset ++;
1395
1396 if (c == '/')
1397 return offset;
1398
1399 return -EINVAL;
1400 }
1401
1402 char *base64mem(const void *p, size_t l) {
1403 char *r, *z;
1404 const uint8_t *x;
1405
1406 /* three input bytes makes four output bytes, padding is added so we must round up */
1407 z = r = malloc(4 * (l + 2) / 3 + 1);
1408 if (!r)
1409 return NULL;
1410
1411 for (x = p; x < (const uint8_t*) p + (l / 3) * 3; x += 3) {
1412 /* x[0] == XXXXXXXX; x[1] == YYYYYYYY; x[2] == ZZZZZZZZ */
1413 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1414 *(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4); /* 00XXYYYY */
1415 *(z++) = base64char((x[1] & 15) << 2 | x[2] >> 6); /* 00YYYYZZ */
1416 *(z++) = base64char(x[2] & 63); /* 00ZZZZZZ */
1417 }
1418
1419 switch (l % 3) {
1420 case 2:
1421 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1422 *(z++) = base64char((x[0] & 3) << 4 | x[1] >> 4); /* 00XXYYYY */
1423 *(z++) = base64char((x[1] & 15) << 2); /* 00YYYY00 */
1424 *(z++) = '=';
1425
1426 break;
1427 case 1:
1428 *(z++) = base64char(x[0] >> 2); /* 00XXXXXX */
1429 *(z++) = base64char((x[0] & 3) << 4); /* 00XX0000 */
1430 *(z++) = '=';
1431 *(z++) = '=';
1432
1433 break;
1434 }
1435
1436 *z = 0;
1437 return r;
1438 }
1439
1440 int unbase64mem(const char *p, size_t l, void **mem, size_t *_len) {
1441 _cleanup_free_ uint8_t *r = NULL;
1442 int a, b, c, d;
1443 uint8_t *z;
1444 const char *x;
1445 size_t len;
1446
1447 assert(p);
1448
1449 /* padding ensures any base63 input has input divisible by 4 */
1450 if (l % 4 != 0)
1451 return -EINVAL;
1452
1453 /* strip the padding */
1454 if (l > 0 && p[l - 1] == '=')
1455 l --;
1456 if (l > 0 && p[l - 1] == '=')
1457 l --;
1458
1459 /* a group of four input bytes needs three output bytes, in case of
1460 padding we need to add two or three extra bytes */
1461 len = (l / 4) * 3 + (l % 4 ? (l % 4) - 1 : 0);
1462
1463 z = r = malloc(len + 1);
1464 if (!r)
1465 return -ENOMEM;
1466
1467 for (x = p; x < p + (l / 4) * 4; x += 4) {
1468 /* a == 00XXXXXX; b == 00YYYYYY; c == 00ZZZZZZ; d == 00WWWWWW */
1469 a = unbase64char(x[0]);
1470 if (a < 0)
1471 return -EINVAL;
1472
1473 b = unbase64char(x[1]);
1474 if (b < 0)
1475 return -EINVAL;
1476
1477 c = unbase64char(x[2]);
1478 if (c < 0)
1479 return -EINVAL;
1480
1481 d = unbase64char(x[3]);
1482 if (d < 0)
1483 return -EINVAL;
1484
1485 *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
1486 *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
1487 *(z++) = (uint8_t) c << 6 | (uint8_t) d; /* ZZWWWWWW */
1488 }
1489
1490 switch (l % 4) {
1491 case 3:
1492 a = unbase64char(x[0]);
1493 if (a < 0)
1494 return -EINVAL;
1495
1496 b = unbase64char(x[1]);
1497 if (b < 0)
1498 return -EINVAL;
1499
1500 c = unbase64char(x[2]);
1501 if (c < 0)
1502 return -EINVAL;
1503
1504 /* c == 00ZZZZ00 */
1505 if (c & 3)
1506 return -EINVAL;
1507
1508 *(z++) = (uint8_t) a << 2 | (uint8_t) b >> 4; /* XXXXXXYY */
1509 *(z++) = (uint8_t) b << 4 | (uint8_t) c >> 2; /* YYYYZZZZ */
1510
1511 break;
1512 case 2:
1513 a = unbase64char(x[0]);
1514 if (a < 0)
1515 return -EINVAL;
1516
1517 b = unbase64char(x[1]);
1518 if (b < 0)
1519 return -EINVAL;
1520
1521 /* b == 00YY0000 */
1522 if (b & 15)
1523 return -EINVAL;
1524
1525 *(z++) = (uint8_t) a << 2 | (uint8_t) (b >> 4); /* XXXXXXYY */
1526
1527 break;
1528 case 0:
1529
1530 break;
1531 default:
1532 return -EINVAL;
1533 }
1534
1535 *z = 0;
1536
1537 *mem = r;
1538 r = NULL;
1539 *_len = len;
1540
1541 return 0;
1542 }
1543
1544 char octchar(int x) {
1545 return '0' + (x & 7);
1546 }
1547
1548 int unoctchar(char c) {
1549
1550 if (c >= '0' && c <= '7')
1551 return c - '0';
1552
1553 return -EINVAL;
1554 }
1555
1556 char decchar(int x) {
1557 return '0' + (x % 10);
1558 }
1559
1560 int undecchar(char c) {
1561
1562 if (c >= '0' && c <= '9')
1563 return c - '0';
1564
1565 return -EINVAL;
1566 }
1567
1568 char *cescape(const char *s) {
1569 char *r, *t;
1570 const char *f;
1571
1572 assert(s);
1573
1574 /* Does C style string escaping. May be reversed with
1575 * cunescape(). */
1576
1577 r = new(char, strlen(s)*4 + 1);
1578 if (!r)
1579 return NULL;
1580
1581 for (f = s, t = r; *f; f++)
1582 t += cescape_char(*f, t);
1583
1584 *t = 0;
1585
1586 return r;
1587 }
1588
1589 static int cunescape_one(const char *p, size_t length, char *ret, uint32_t *ret_unicode) {
1590 int r = 1;
1591
1592 assert(p);
1593 assert(*p);
1594 assert(ret);
1595
1596 /* Unescapes C style. Returns the unescaped character in ret,
1597 * unless we encountered a \u sequence in which case the full
1598 * unicode character is returned in ret_unicode, instead. */
1599
1600 if (length != (size_t) -1 && length < 1)
1601 return -EINVAL;
1602
1603 switch (p[0]) {
1604
1605 case 'a':
1606 *ret = '\a';
1607 break;
1608 case 'b':
1609 *ret = '\b';
1610 break;
1611 case 'f':
1612 *ret = '\f';
1613 break;
1614 case 'n':
1615 *ret = '\n';
1616 break;
1617 case 'r':
1618 *ret = '\r';
1619 break;
1620 case 't':
1621 *ret = '\t';
1622 break;
1623 case 'v':
1624 *ret = '\v';
1625 break;
1626 case '\\':
1627 *ret = '\\';
1628 break;
1629 case '"':
1630 *ret = '"';
1631 break;
1632 case '\'':
1633 *ret = '\'';
1634 break;
1635
1636 case 's':
1637 /* This is an extension of the XDG syntax files */
1638 *ret = ' ';
1639 break;
1640
1641 case 'x': {
1642 /* hexadecimal encoding */
1643 int a, b;
1644
1645 if (length != (size_t) -1 && length < 3)
1646 return -EINVAL;
1647
1648 a = unhexchar(p[1]);
1649 if (a < 0)
1650 return -EINVAL;
1651
1652 b = unhexchar(p[2]);
1653 if (b < 0)
1654 return -EINVAL;
1655
1656 /* Don't allow NUL bytes */
1657 if (a == 0 && b == 0)
1658 return -EINVAL;
1659
1660 *ret = (char) ((a << 4U) | b);
1661 r = 3;
1662 break;
1663 }
1664
1665 case 'u': {
1666 /* C++11 style 16bit unicode */
1667
1668 int a[4];
1669 unsigned i;
1670 uint32_t c;
1671
1672 if (length != (size_t) -1 && length < 5)
1673 return -EINVAL;
1674
1675 for (i = 0; i < 4; i++) {
1676 a[i] = unhexchar(p[1 + i]);
1677 if (a[i] < 0)
1678 return a[i];
1679 }
1680
1681 c = ((uint32_t) a[0] << 12U) | ((uint32_t) a[1] << 8U) | ((uint32_t) a[2] << 4U) | (uint32_t) a[3];
1682
1683 /* Don't allow 0 chars */
1684 if (c == 0)
1685 return -EINVAL;
1686
1687 if (c < 128)
1688 *ret = c;
1689 else {
1690 if (!ret_unicode)
1691 return -EINVAL;
1692
1693 *ret = 0;
1694 *ret_unicode = c;
1695 }
1696
1697 r = 5;
1698 break;
1699 }
1700
1701 case 'U': {
1702 /* C++11 style 32bit unicode */
1703
1704 int a[8];
1705 unsigned i;
1706 uint32_t c;
1707
1708 if (length != (size_t) -1 && length < 9)
1709 return -EINVAL;
1710
1711 for (i = 0; i < 8; i++) {
1712 a[i] = unhexchar(p[1 + i]);
1713 if (a[i] < 0)
1714 return a[i];
1715 }
1716
1717 c = ((uint32_t) a[0] << 28U) | ((uint32_t) a[1] << 24U) | ((uint32_t) a[2] << 20U) | ((uint32_t) a[3] << 16U) |
1718 ((uint32_t) a[4] << 12U) | ((uint32_t) a[5] << 8U) | ((uint32_t) a[6] << 4U) | (uint32_t) a[7];
1719
1720 /* Don't allow 0 chars */
1721 if (c == 0)
1722 return -EINVAL;
1723
1724 /* Don't allow invalid code points */
1725 if (!unichar_is_valid(c))
1726 return -EINVAL;
1727
1728 if (c < 128)
1729 *ret = c;
1730 else {
1731 if (!ret_unicode)
1732 return -EINVAL;
1733
1734 *ret = 0;
1735 *ret_unicode = c;
1736 }
1737
1738 r = 9;
1739 break;
1740 }
1741
1742 case '0':
1743 case '1':
1744 case '2':
1745 case '3':
1746 case '4':
1747 case '5':
1748 case '6':
1749 case '7': {
1750 /* octal encoding */
1751 int a, b, c;
1752 uint32_t m;
1753
1754 if (length != (size_t) -1 && length < 3)
1755 return -EINVAL;
1756
1757 a = unoctchar(p[0]);
1758 if (a < 0)
1759 return -EINVAL;
1760
1761 b = unoctchar(p[1]);
1762 if (b < 0)
1763 return -EINVAL;
1764
1765 c = unoctchar(p[2]);
1766 if (c < 0)
1767 return -EINVAL;
1768
1769 /* don't allow NUL bytes */
1770 if (a == 0 && b == 0 && c == 0)
1771 return -EINVAL;
1772
1773 /* Don't allow bytes above 255 */
1774 m = ((uint32_t) a << 6U) | ((uint32_t) b << 3U) | (uint32_t) c;
1775 if (m > 255)
1776 return -EINVAL;
1777
1778 *ret = m;
1779 r = 3;
1780 break;
1781 }
1782
1783 default:
1784 return -EINVAL;
1785 }
1786
1787 return r;
1788 }
1789
1790 int cunescape_length_with_prefix(const char *s, size_t length, const char *prefix, UnescapeFlags flags, char **ret) {
1791 char *r, *t;
1792 const char *f;
1793 size_t pl;
1794
1795 assert(s);
1796 assert(ret);
1797
1798 /* Undoes C style string escaping, and optionally prefixes it. */
1799
1800 pl = prefix ? strlen(prefix) : 0;
1801
1802 r = new(char, pl+length+1);
1803 if (!r)
1804 return -ENOMEM;
1805
1806 if (prefix)
1807 memcpy(r, prefix, pl);
1808
1809 for (f = s, t = r + pl; f < s + length; f++) {
1810 size_t remaining;
1811 uint32_t u;
1812 char c;
1813 int k;
1814
1815 remaining = s + length - f;
1816 assert(remaining > 0);
1817
1818 if (*f != '\\') {
1819 /* A literal literal, copy verbatim */
1820 *(t++) = *f;
1821 continue;
1822 }
1823
1824 if (remaining == 1) {
1825 if (flags & UNESCAPE_RELAX) {
1826 /* A trailing backslash, copy verbatim */
1827 *(t++) = *f;
1828 continue;
1829 }
1830
1831 free(r);
1832 return -EINVAL;
1833 }
1834
1835 k = cunescape_one(f + 1, remaining - 1, &c, &u);
1836 if (k < 0) {
1837 if (flags & UNESCAPE_RELAX) {
1838 /* Invalid escape code, let's take it literal then */
1839 *(t++) = '\\';
1840 continue;
1841 }
1842
1843 free(r);
1844 return k;
1845 }
1846
1847 if (c != 0)
1848 /* Non-Unicode? Let's encode this directly */
1849 *(t++) = c;
1850 else
1851 /* Unicode? Then let's encode this in UTF-8 */
1852 t += utf8_encode_unichar(t, u);
1853
1854 f += k;
1855 }
1856
1857 *t = 0;
1858
1859 *ret = r;
1860 return t - r;
1861 }
1862
1863 int cunescape_length(const char *s, size_t length, UnescapeFlags flags, char **ret) {
1864 return cunescape_length_with_prefix(s, length, NULL, flags, ret);
1865 }
1866
1867 int cunescape(const char *s, UnescapeFlags flags, char **ret) {
1868 return cunescape_length(s, strlen(s), flags, ret);
1869 }
1870
1871 char *xescape(const char *s, const char *bad) {
1872 char *r, *t;
1873 const char *f;
1874
1875 /* Escapes all chars in bad, in addition to \ and all special
1876 * chars, in \xFF style escaping. May be reversed with
1877 * cunescape(). */
1878
1879 r = new(char, strlen(s) * 4 + 1);
1880 if (!r)
1881 return NULL;
1882
1883 for (f = s, t = r; *f; f++) {
1884
1885 if ((*f < ' ') || (*f >= 127) ||
1886 (*f == '\\') || strchr(bad, *f)) {
1887 *(t++) = '\\';
1888 *(t++) = 'x';
1889 *(t++) = hexchar(*f >> 4);
1890 *(t++) = hexchar(*f);
1891 } else
1892 *(t++) = *f;
1893 }
1894
1895 *t = 0;
1896
1897 return r;
1898 }
1899
1900 char *ascii_strlower(char *t) {
1901 char *p;
1902
1903 assert(t);
1904
1905 for (p = t; *p; p++)
1906 if (*p >= 'A' && *p <= 'Z')
1907 *p = *p - 'A' + 'a';
1908
1909 return t;
1910 }
1911
1912 _pure_ static bool hidden_file_allow_backup(const char *filename) {
1913 assert(filename);
1914
1915 return
1916 filename[0] == '.' ||
1917 streq(filename, "lost+found") ||
1918 streq(filename, "aquota.user") ||
1919 streq(filename, "aquota.group") ||
1920 endswith(filename, ".rpmnew") ||
1921 endswith(filename, ".rpmsave") ||
1922 endswith(filename, ".rpmorig") ||
1923 endswith(filename, ".dpkg-old") ||
1924 endswith(filename, ".dpkg-new") ||
1925 endswith(filename, ".dpkg-tmp") ||
1926 endswith(filename, ".dpkg-dist") ||
1927 endswith(filename, ".dpkg-bak") ||
1928 endswith(filename, ".dpkg-backup") ||
1929 endswith(filename, ".dpkg-remove") ||
1930 endswith(filename, ".swp");
1931 }
1932
1933 bool hidden_file(const char *filename) {
1934 assert(filename);
1935
1936 if (endswith(filename, "~"))
1937 return true;
1938
1939 return hidden_file_allow_backup(filename);
1940 }
1941
1942 int fd_nonblock(int fd, bool nonblock) {
1943 int flags, nflags;
1944
1945 assert(fd >= 0);
1946
1947 flags = fcntl(fd, F_GETFL, 0);
1948 if (flags < 0)
1949 return -errno;
1950
1951 if (nonblock)
1952 nflags = flags | O_NONBLOCK;
1953 else
1954 nflags = flags & ~O_NONBLOCK;
1955
1956 if (nflags == flags)
1957 return 0;
1958
1959 if (fcntl(fd, F_SETFL, nflags) < 0)
1960 return -errno;
1961
1962 return 0;
1963 }
1964
1965 int fd_cloexec(int fd, bool cloexec) {
1966 int flags, nflags;
1967
1968 assert(fd >= 0);
1969
1970 flags = fcntl(fd, F_GETFD, 0);
1971 if (flags < 0)
1972 return -errno;
1973
1974 if (cloexec)
1975 nflags = flags | FD_CLOEXEC;
1976 else
1977 nflags = flags & ~FD_CLOEXEC;
1978
1979 if (nflags == flags)
1980 return 0;
1981
1982 if (fcntl(fd, F_SETFD, nflags) < 0)
1983 return -errno;
1984
1985 return 0;
1986 }
1987
1988 _pure_ static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
1989 unsigned i;
1990
1991 assert(n_fdset == 0 || fdset);
1992
1993 for (i = 0; i < n_fdset; i++)
1994 if (fdset[i] == fd)
1995 return true;
1996
1997 return false;
1998 }
1999
2000 int close_all_fds(const int except[], unsigned n_except) {
2001 _cleanup_closedir_ DIR *d = NULL;
2002 struct dirent *de;
2003 int r = 0;
2004
2005 assert(n_except == 0 || except);
2006
2007 d = opendir("/proc/self/fd");
2008 if (!d) {
2009 int fd;
2010 struct rlimit rl;
2011
2012 /* When /proc isn't available (for example in chroots)
2013 * the fallback is brute forcing through the fd
2014 * table */
2015
2016 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
2017 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
2018
2019 if (fd_in_set(fd, except, n_except))
2020 continue;
2021
2022 if (close_nointr(fd) < 0)
2023 if (errno != EBADF && r == 0)
2024 r = -errno;
2025 }
2026
2027 return r;
2028 }
2029
2030 while ((de = readdir(d))) {
2031 int fd = -1;
2032
2033 if (hidden_file(de->d_name))
2034 continue;
2035
2036 if (safe_atoi(de->d_name, &fd) < 0)
2037 /* Let's better ignore this, just in case */
2038 continue;
2039
2040 if (fd < 3)
2041 continue;
2042
2043 if (fd == dirfd(d))
2044 continue;
2045
2046 if (fd_in_set(fd, except, n_except))
2047 continue;
2048
2049 if (close_nointr(fd) < 0) {
2050 /* Valgrind has its own FD and doesn't want to have it closed */
2051 if (errno != EBADF && r == 0)
2052 r = -errno;
2053 }
2054 }
2055
2056 return r;
2057 }
2058
2059 bool chars_intersect(const char *a, const char *b) {
2060 const char *p;
2061
2062 /* Returns true if any of the chars in a are in b. */
2063 for (p = a; *p; p++)
2064 if (strchr(b, *p))
2065 return true;
2066
2067 return false;
2068 }
2069
2070 bool fstype_is_network(const char *fstype) {
2071 static const char table[] =
2072 "afs\0"
2073 "cifs\0"
2074 "smbfs\0"
2075 "sshfs\0"
2076 "ncpfs\0"
2077 "ncp\0"
2078 "nfs\0"
2079 "nfs4\0"
2080 "gfs\0"
2081 "gfs2\0"
2082 "glusterfs\0";
2083
2084 const char *x;
2085
2086 x = startswith(fstype, "fuse.");
2087 if (x)
2088 fstype = x;
2089
2090 return nulstr_contains(table, fstype);
2091 }
2092
2093 int flush_fd(int fd) {
2094 struct pollfd pollfd = {
2095 .fd = fd,
2096 .events = POLLIN,
2097 };
2098
2099 for (;;) {
2100 char buf[LINE_MAX];
2101 ssize_t l;
2102 int r;
2103
2104 r = poll(&pollfd, 1, 0);
2105 if (r < 0) {
2106 if (errno == EINTR)
2107 continue;
2108
2109 return -errno;
2110
2111 } else if (r == 0)
2112 return 0;
2113
2114 l = read(fd, buf, sizeof(buf));
2115 if (l < 0) {
2116
2117 if (errno == EINTR)
2118 continue;
2119
2120 if (errno == EAGAIN)
2121 return 0;
2122
2123 return -errno;
2124 } else if (l == 0)
2125 return 0;
2126 }
2127 }
2128
2129 void safe_close_pair(int p[]) {
2130 assert(p);
2131
2132 if (p[0] == p[1]) {
2133 /* Special case pairs which use the same fd in both
2134 * directions... */
2135 p[0] = p[1] = safe_close(p[0]);
2136 return;
2137 }
2138
2139 p[0] = safe_close(p[0]);
2140 p[1] = safe_close(p[1]);
2141 }
2142
2143 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
2144 uint8_t *p = buf;
2145 ssize_t n = 0;
2146
2147 assert(fd >= 0);
2148 assert(buf);
2149
2150 /* If called with nbytes == 0, let's call read() at least
2151 * once, to validate the operation */
2152
2153 if (nbytes > (size_t) SSIZE_MAX)
2154 return -EINVAL;
2155
2156 do {
2157 ssize_t k;
2158
2159 k = read(fd, p, nbytes);
2160 if (k < 0) {
2161 if (errno == EINTR)
2162 continue;
2163
2164 if (errno == EAGAIN && do_poll) {
2165
2166 /* We knowingly ignore any return value here,
2167 * and expect that any error/EOF is reported
2168 * via read() */
2169
2170 (void) fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
2171 continue;
2172 }
2173
2174 return n > 0 ? n : -errno;
2175 }
2176
2177 if (k == 0)
2178 return n;
2179
2180 assert((size_t) k <= nbytes);
2181
2182 p += k;
2183 nbytes -= k;
2184 n += k;
2185 } while (nbytes > 0);
2186
2187 return n;
2188 }
2189
2190 int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
2191 ssize_t n;
2192
2193 n = loop_read(fd, buf, nbytes, do_poll);
2194 if (n < 0)
2195 return (int) n;
2196 if ((size_t) n != nbytes)
2197 return -EIO;
2198
2199 return 0;
2200 }
2201
2202 int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
2203 const uint8_t *p = buf;
2204
2205 assert(fd >= 0);
2206 assert(buf);
2207
2208 if (nbytes > (size_t) SSIZE_MAX)
2209 return -EINVAL;
2210
2211 do {
2212 ssize_t k;
2213
2214 k = write(fd, p, nbytes);
2215 if (k < 0) {
2216 if (errno == EINTR)
2217 continue;
2218
2219 if (errno == EAGAIN && do_poll) {
2220 /* We knowingly ignore any return value here,
2221 * and expect that any error/EOF is reported
2222 * via write() */
2223
2224 (void) fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
2225 continue;
2226 }
2227
2228 return -errno;
2229 }
2230
2231 if (_unlikely_(nbytes > 0 && k == 0)) /* Can't really happen */
2232 return -EIO;
2233
2234 assert((size_t) k <= nbytes);
2235
2236 p += k;
2237 nbytes -= k;
2238 } while (nbytes > 0);
2239
2240 return 0;
2241 }
2242
2243 int parse_size(const char *t, uint64_t base, uint64_t *size) {
2244
2245 /* Soo, sometimes we want to parse IEC binary suffixes, and
2246 * sometimes SI decimal suffixes. This function can parse
2247 * both. Which one is the right way depends on the
2248 * context. Wikipedia suggests that SI is customary for
2249 * hardware metrics and network speeds, while IEC is
2250 * customary for most data sizes used by software and volatile
2251 * (RAM) memory. Hence be careful which one you pick!
2252 *
2253 * In either case we use just K, M, G as suffix, and not Ki,
2254 * Mi, Gi or so (as IEC would suggest). That's because that's
2255 * frickin' ugly. But this means you really need to make sure
2256 * to document which base you are parsing when you use this
2257 * call. */
2258
2259 struct table {
2260 const char *suffix;
2261 unsigned long long factor;
2262 };
2263
2264 static const struct table iec[] = {
2265 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2266 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2267 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
2268 { "G", 1024ULL*1024ULL*1024ULL },
2269 { "M", 1024ULL*1024ULL },
2270 { "K", 1024ULL },
2271 { "B", 1ULL },
2272 { "", 1ULL },
2273 };
2274
2275 static const struct table si[] = {
2276 { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
2277 { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
2278 { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
2279 { "G", 1000ULL*1000ULL*1000ULL },
2280 { "M", 1000ULL*1000ULL },
2281 { "K", 1000ULL },
2282 { "B", 1ULL },
2283 { "", 1ULL },
2284 };
2285
2286 const struct table *table;
2287 const char *p;
2288 unsigned long long r = 0;
2289 unsigned n_entries, start_pos = 0;
2290
2291 assert(t);
2292 assert(base == 1000 || base == 1024);
2293 assert(size);
2294
2295 if (base == 1000) {
2296 table = si;
2297 n_entries = ELEMENTSOF(si);
2298 } else {
2299 table = iec;
2300 n_entries = ELEMENTSOF(iec);
2301 }
2302
2303 p = t;
2304 do {
2305 unsigned long long l, tmp;
2306 double frac = 0;
2307 char *e;
2308 unsigned i;
2309
2310 p += strspn(p, WHITESPACE);
2311 if (*p == '-')
2312 return -ERANGE;
2313
2314 errno = 0;
2315 l = strtoull(p, &e, 10);
2316 if (errno > 0)
2317 return -errno;
2318 if (e == p)
2319 return -EINVAL;
2320
2321 if (*e == '.') {
2322 e++;
2323
2324 /* strtoull() itself would accept space/+/- */
2325 if (*e >= '0' && *e <= '9') {
2326 unsigned long long l2;
2327 char *e2;
2328
2329 l2 = strtoull(e, &e2, 10);
2330 if (errno > 0)
2331 return -errno;
2332
2333 /* Ignore failure. E.g. 10.M is valid */
2334 frac = l2;
2335 for (; e < e2; e++)
2336 frac /= 10;
2337 }
2338 }
2339
2340 e += strspn(e, WHITESPACE);
2341
2342 for (i = start_pos; i < n_entries; i++)
2343 if (startswith(e, table[i].suffix))
2344 break;
2345
2346 if (i >= n_entries)
2347 return -EINVAL;
2348
2349 if (l + (frac > 0) > ULLONG_MAX / table[i].factor)
2350 return -ERANGE;
2351
2352 tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
2353 if (tmp > ULLONG_MAX - r)
2354 return -ERANGE;
2355
2356 r += tmp;
2357 if ((unsigned long long) (uint64_t) r != r)
2358 return -ERANGE;
2359
2360 p = e + strlen(table[i].suffix);
2361
2362 start_pos = i + 1;
2363
2364 } while (*p);
2365
2366 *size = r;
2367
2368 return 0;
2369 }
2370
2371 bool is_device_path(const char *path) {
2372
2373 /* Returns true on paths that refer to a device, either in
2374 * sysfs or in /dev */
2375
2376 return
2377 path_startswith(path, "/dev/") ||
2378 path_startswith(path, "/sys/");
2379 }
2380
2381 int dir_is_empty(const char *path) {
2382 _cleanup_closedir_ DIR *d;
2383
2384 d = opendir(path);
2385 if (!d)
2386 return -errno;
2387
2388 for (;;) {
2389 struct dirent *de;
2390
2391 errno = 0;
2392 de = readdir(d);
2393 if (!de && errno != 0)
2394 return -errno;
2395
2396 if (!de)
2397 return 1;
2398
2399 if (!hidden_file(de->d_name))
2400 return 0;
2401 }
2402 }
2403
2404 char* dirname_malloc(const char *path) {
2405 char *d, *dir, *dir2;
2406
2407 d = strdup(path);
2408 if (!d)
2409 return NULL;
2410 dir = dirname(d);
2411 assert(dir);
2412
2413 if (dir != d) {
2414 dir2 = strdup(dir);
2415 free(d);
2416 return dir2;
2417 }
2418
2419 return dir;
2420 }
2421
2422 void rename_process(const char name[8]) {
2423 assert(name);
2424
2425 /* This is a like a poor man's setproctitle(). It changes the
2426 * comm field, argv[0], and also the glibc's internally used
2427 * name of the process. For the first one a limit of 16 chars
2428 * applies, to the second one usually one of 10 (i.e. length
2429 * of "/sbin/init"), to the third one one of 7 (i.e. length of
2430 * "systemd"). If you pass a longer string it will be
2431 * truncated */
2432
2433 prctl(PR_SET_NAME, name);
2434
2435 if (program_invocation_name)
2436 strncpy(program_invocation_name, name, strlen(program_invocation_name));
2437
2438 if (saved_argc > 0) {
2439 int i;
2440
2441 if (saved_argv[0])
2442 strncpy(saved_argv[0], name, strlen(saved_argv[0]));
2443
2444 for (i = 1; i < saved_argc; i++) {
2445 if (!saved_argv[i])
2446 break;
2447
2448 memzero(saved_argv[i], strlen(saved_argv[i]));
2449 }
2450 }
2451 }
2452
2453 char *lookup_uid(uid_t uid) {
2454 long bufsize;
2455 char *name;
2456 _cleanup_free_ char *buf = NULL;
2457 struct passwd pwbuf, *pw = NULL;
2458
2459 /* Shortcut things to avoid NSS lookups */
2460 if (uid == 0)
2461 return strdup("root");
2462
2463 bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
2464 if (bufsize <= 0)
2465 bufsize = 4096;
2466
2467 buf = malloc(bufsize);
2468 if (!buf)
2469 return NULL;
2470
2471 if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
2472 return strdup(pw->pw_name);
2473
2474 if (asprintf(&name, UID_FMT, uid) < 0)
2475 return NULL;
2476
2477 return name;
2478 }
2479
2480 char* getlogname_malloc(void) {
2481 uid_t uid;
2482 struct stat st;
2483
2484 if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
2485 uid = st.st_uid;
2486 else
2487 uid = getuid();
2488
2489 return lookup_uid(uid);
2490 }
2491
2492 char *getusername_malloc(void) {
2493 const char *e;
2494
2495 e = getenv("USER");
2496 if (e)
2497 return strdup(e);
2498
2499 return lookup_uid(getuid());
2500 }
2501
2502 bool is_temporary_fs(const struct statfs *s) {
2503 assert(s);
2504
2505 return F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) ||
2506 F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC);
2507 }
2508
2509 int fd_is_temporary_fs(int fd) {
2510 struct statfs s;
2511
2512 if (fstatfs(fd, &s) < 0)
2513 return -errno;
2514
2515 return is_temporary_fs(&s);
2516 }
2517
2518 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
2519 assert(path);
2520
2521 /* Under the assumption that we are running privileged we
2522 * first change the access mode and only then hand out
2523 * ownership to avoid a window where access is too open. */
2524
2525 if (mode != MODE_INVALID)
2526 if (chmod(path, mode) < 0)
2527 return -errno;
2528
2529 if (uid != UID_INVALID || gid != GID_INVALID)
2530 if (chown(path, uid, gid) < 0)
2531 return -errno;
2532
2533 return 0;
2534 }
2535
2536 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
2537 assert(fd >= 0);
2538
2539 /* Under the assumption that we are running privileged we
2540 * first change the access mode and only then hand out
2541 * ownership to avoid a window where access is too open. */
2542
2543 if (mode != MODE_INVALID)
2544 if (fchmod(fd, mode) < 0)
2545 return -errno;
2546
2547 if (uid != UID_INVALID || gid != GID_INVALID)
2548 if (fchown(fd, uid, gid) < 0)
2549 return -errno;
2550
2551 return 0;
2552 }
2553
2554 int files_same(const char *filea, const char *fileb) {
2555 struct stat a, b;
2556
2557 if (stat(filea, &a) < 0)
2558 return -errno;
2559
2560 if (stat(fileb, &b) < 0)
2561 return -errno;
2562
2563 return a.st_dev == b.st_dev &&
2564 a.st_ino == b.st_ino;
2565 }
2566
2567 int running_in_chroot(void) {
2568 int ret;
2569
2570 ret = files_same("/proc/1/root", "/");
2571 if (ret < 0)
2572 return ret;
2573
2574 return ret == 0;
2575 }
2576
2577 static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
2578 size_t x;
2579 char *r;
2580
2581 assert(s);
2582 assert(percent <= 100);
2583 assert(new_length >= 3);
2584
2585 if (old_length <= 3 || old_length <= new_length)
2586 return strndup(s, old_length);
2587
2588 r = new0(char, new_length+1);
2589 if (!r)
2590 return NULL;
2591
2592 x = (new_length * percent) / 100;
2593
2594 if (x > new_length - 3)
2595 x = new_length - 3;
2596
2597 memcpy(r, s, x);
2598 r[x] = '.';
2599 r[x+1] = '.';
2600 r[x+2] = '.';
2601 memcpy(r + x + 3,
2602 s + old_length - (new_length - x - 3),
2603 new_length - x - 3);
2604
2605 return r;
2606 }
2607
2608 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
2609 size_t x;
2610 char *e;
2611 const char *i, *j;
2612 unsigned k, len, len2;
2613
2614 assert(s);
2615 assert(percent <= 100);
2616 assert(new_length >= 3);
2617
2618 /* if no multibyte characters use ascii_ellipsize_mem for speed */
2619 if (ascii_is_valid(s))
2620 return ascii_ellipsize_mem(s, old_length, new_length, percent);
2621
2622 if (old_length <= 3 || old_length <= new_length)
2623 return strndup(s, old_length);
2624
2625 x = (new_length * percent) / 100;
2626
2627 if (x > new_length - 3)
2628 x = new_length - 3;
2629
2630 k = 0;
2631 for (i = s; k < x && i < s + old_length; i = utf8_next_char(i)) {
2632 int c;
2633
2634 c = utf8_encoded_to_unichar(i);
2635 if (c < 0)
2636 return NULL;
2637 k += unichar_iswide(c) ? 2 : 1;
2638 }
2639
2640 if (k > x) /* last character was wide and went over quota */
2641 x ++;
2642
2643 for (j = s + old_length; k < new_length && j > i; ) {
2644 int c;
2645
2646 j = utf8_prev_char(j);
2647 c = utf8_encoded_to_unichar(j);
2648 if (c < 0)
2649 return NULL;
2650 k += unichar_iswide(c) ? 2 : 1;
2651 }
2652 assert(i <= j);
2653
2654 /* we don't actually need to ellipsize */
2655 if (i == j)
2656 return memdup(s, old_length + 1);
2657
2658 /* make space for ellipsis */
2659 j = utf8_next_char(j);
2660
2661 len = i - s;
2662 len2 = s + old_length - j;
2663 e = new(char, len + 3 + len2 + 1);
2664 if (!e)
2665 return NULL;
2666
2667 /*
2668 printf("old_length=%zu new_length=%zu x=%zu len=%u len2=%u k=%u\n",
2669 old_length, new_length, x, len, len2, k);
2670 */
2671
2672 memcpy(e, s, len);
2673 e[len] = 0xe2; /* tri-dot ellipsis: … */
2674 e[len + 1] = 0x80;
2675 e[len + 2] = 0xa6;
2676
2677 memcpy(e + len + 3, j, len2 + 1);
2678
2679 return e;
2680 }
2681
2682 char *ellipsize(const char *s, size_t length, unsigned percent) {
2683 return ellipsize_mem(s, strlen(s), length, percent);
2684 }
2685
2686 int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
2687 _cleanup_close_ int fd;
2688 int r;
2689
2690 assert(path);
2691
2692 if (parents)
2693 mkdir_parents(path, 0755);
2694
2695 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode > 0 ? mode : 0644);
2696 if (fd < 0)
2697 return -errno;
2698
2699 if (mode > 0) {
2700 r = fchmod(fd, mode);
2701 if (r < 0)
2702 return -errno;
2703 }
2704
2705 if (uid != UID_INVALID || gid != GID_INVALID) {
2706 r = fchown(fd, uid, gid);
2707 if (r < 0)
2708 return -errno;
2709 }
2710
2711 if (stamp != USEC_INFINITY) {
2712 struct timespec ts[2];
2713
2714 timespec_store(&ts[0], stamp);
2715 ts[1] = ts[0];
2716 r = futimens(fd, ts);
2717 } else
2718 r = futimens(fd, NULL);
2719 if (r < 0)
2720 return -errno;
2721
2722 return 0;
2723 }
2724
2725 int touch(const char *path) {
2726 return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, 0);
2727 }
2728
2729 static char *unquote(const char *s, const char* quotes) {
2730 size_t l;
2731 assert(s);
2732
2733 /* This is rather stupid, simply removes the heading and
2734 * trailing quotes if there is one. Doesn't care about
2735 * escaping or anything.
2736 *
2737 * DON'T USE THIS FOR NEW CODE ANYMORE!*/
2738
2739 l = strlen(s);
2740 if (l < 2)
2741 return strdup(s);
2742
2743 if (strchr(quotes, s[0]) && s[l-1] == s[0])
2744 return strndup(s+1, l-2);
2745
2746 return strdup(s);
2747 }
2748
2749 noreturn void freeze(void) {
2750
2751 /* Make sure nobody waits for us on a socket anymore */
2752 close_all_fds(NULL, 0);
2753
2754 sync();
2755
2756 for (;;)
2757 pause();
2758 }
2759
2760 bool null_or_empty(struct stat *st) {
2761 assert(st);
2762
2763 if (S_ISREG(st->st_mode) && st->st_size <= 0)
2764 return true;
2765
2766 if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
2767 return true;
2768
2769 return false;
2770 }
2771
2772 int null_or_empty_path(const char *fn) {
2773 struct stat st;
2774
2775 assert(fn);
2776
2777 if (stat(fn, &st) < 0)
2778 return -errno;
2779
2780 return null_or_empty(&st);
2781 }
2782
2783 int null_or_empty_fd(int fd) {
2784 struct stat st;
2785
2786 assert(fd >= 0);
2787
2788 if (fstat(fd, &st) < 0)
2789 return -errno;
2790
2791 return null_or_empty(&st);
2792 }
2793
2794 DIR *xopendirat(int fd, const char *name, int flags) {
2795 int nfd;
2796 DIR *d;
2797
2798 assert(!(flags & O_CREAT));
2799
2800 nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
2801 if (nfd < 0)
2802 return NULL;
2803
2804 d = fdopendir(nfd);
2805 if (!d) {
2806 safe_close(nfd);
2807 return NULL;
2808 }
2809
2810 return d;
2811 }
2812
2813 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
2814 _cleanup_free_ char *t = NULL, *u = NULL;
2815 size_t enc_len;
2816
2817 u = unquote(tagvalue, QUOTES);
2818 if (!u)
2819 return NULL;
2820
2821 enc_len = strlen(u) * 4 + 1;
2822 t = new(char, enc_len);
2823 if (!t)
2824 return NULL;
2825
2826 if (encode_devnode_name(u, t, enc_len) < 0)
2827 return NULL;
2828
2829 return strjoin("/dev/disk/by-", by, "/", t, NULL);
2830 }
2831
2832 char *fstab_node_to_udev_node(const char *p) {
2833 assert(p);
2834
2835 if (startswith(p, "LABEL="))
2836 return tag_to_udev_node(p+6, "label");
2837
2838 if (startswith(p, "UUID="))
2839 return tag_to_udev_node(p+5, "uuid");
2840
2841 if (startswith(p, "PARTUUID="))
2842 return tag_to_udev_node(p+9, "partuuid");
2843
2844 if (startswith(p, "PARTLABEL="))
2845 return tag_to_udev_node(p+10, "partlabel");
2846
2847 return strdup(p);
2848 }
2849
2850 bool dirent_is_file(const struct dirent *de) {
2851 assert(de);
2852
2853 if (hidden_file(de->d_name))
2854 return false;
2855
2856 if (de->d_type != DT_REG &&
2857 de->d_type != DT_LNK &&
2858 de->d_type != DT_UNKNOWN)
2859 return false;
2860
2861 return true;
2862 }
2863
2864 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
2865 assert(de);
2866
2867 if (de->d_type != DT_REG &&
2868 de->d_type != DT_LNK &&
2869 de->d_type != DT_UNKNOWN)
2870 return false;
2871
2872 if (hidden_file_allow_backup(de->d_name))
2873 return false;
2874
2875 return endswith(de->d_name, suffix);
2876 }
2877
2878 static int do_execute(char **directories, usec_t timeout, char *argv[]) {
2879 _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
2880 _cleanup_set_free_free_ Set *seen = NULL;
2881 char **directory;
2882
2883 /* We fork this all off from a child process so that we can
2884 * somewhat cleanly make use of SIGALRM to set a time limit */
2885
2886 (void) reset_all_signal_handlers();
2887 (void) reset_signal_mask();
2888
2889 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
2890
2891 pids = hashmap_new(NULL);
2892 if (!pids)
2893 return log_oom();
2894
2895 seen = set_new(&string_hash_ops);
2896 if (!seen)
2897 return log_oom();
2898
2899 STRV_FOREACH(directory, directories) {
2900 _cleanup_closedir_ DIR *d;
2901 struct dirent *de;
2902
2903 d = opendir(*directory);
2904 if (!d) {
2905 if (errno == ENOENT)
2906 continue;
2907
2908 return log_error_errno(errno, "Failed to open directory %s: %m", *directory);
2909 }
2910
2911 FOREACH_DIRENT(de, d, break) {
2912 _cleanup_free_ char *path = NULL;
2913 pid_t pid;
2914 int r;
2915
2916 if (!dirent_is_file(de))
2917 continue;
2918
2919 if (set_contains(seen, de->d_name)) {
2920 log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name);
2921 continue;
2922 }
2923
2924 r = set_put_strdup(seen, de->d_name);
2925 if (r < 0)
2926 return log_oom();
2927
2928 path = strjoin(*directory, "/", de->d_name, NULL);
2929 if (!path)
2930 return log_oom();
2931
2932 if (null_or_empty_path(path)) {
2933 log_debug("%s is empty (a mask).", path);
2934 continue;
2935 }
2936
2937 pid = fork();
2938 if (pid < 0) {
2939 log_error_errno(errno, "Failed to fork: %m");
2940 continue;
2941 } else if (pid == 0) {
2942 char *_argv[2];
2943
2944 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
2945
2946 if (!argv) {
2947 _argv[0] = path;
2948 _argv[1] = NULL;
2949 argv = _argv;
2950 } else
2951 argv[0] = path;
2952
2953 execv(path, argv);
2954 return log_error_errno(errno, "Failed to execute %s: %m", path);
2955 }
2956
2957 log_debug("Spawned %s as " PID_FMT ".", path, pid);
2958
2959 r = hashmap_put(pids, UINT_TO_PTR(pid), path);
2960 if (r < 0)
2961 return log_oom();
2962 path = NULL;
2963 }
2964 }
2965
2966 /* Abort execution of this process after the timout. We simply
2967 * rely on SIGALRM as default action terminating the process,
2968 * and turn on alarm(). */
2969
2970 if (timeout != USEC_INFINITY)
2971 alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
2972
2973 while (!hashmap_isempty(pids)) {
2974 _cleanup_free_ char *path = NULL;
2975 pid_t pid;
2976
2977 pid = PTR_TO_UINT(hashmap_first_key(pids));
2978 assert(pid > 0);
2979
2980 path = hashmap_remove(pids, UINT_TO_PTR(pid));
2981 assert(path);
2982
2983 wait_for_terminate_and_warn(path, pid, true);
2984 }
2985
2986 return 0;
2987 }
2988
2989 void execute_directories(const char* const* directories, usec_t timeout, char *argv[]) {
2990 pid_t executor_pid;
2991 int r;
2992 char *name;
2993 char **dirs = (char**) directories;
2994
2995 assert(!strv_isempty(dirs));
2996
2997 name = basename(dirs[0]);
2998 assert(!isempty(name));
2999
3000 /* Executes all binaries in the directories in parallel and waits
3001 * for them to finish. Optionally a timeout is applied. If a file
3002 * with the same name exists in more than one directory, the
3003 * earliest one wins. */
3004
3005 executor_pid = fork();
3006 if (executor_pid < 0) {
3007 log_error_errno(errno, "Failed to fork: %m");
3008 return;
3009
3010 } else if (executor_pid == 0) {
3011 r = do_execute(dirs, timeout, argv);
3012 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
3013 }
3014
3015 wait_for_terminate_and_warn(name, executor_pid, true);
3016 }
3017
3018 bool nulstr_contains(const char*nulstr, const char *needle) {
3019 const char *i;
3020
3021 if (!nulstr)
3022 return false;
3023
3024 NULSTR_FOREACH(i, nulstr)
3025 if (streq(i, needle))
3026 return true;
3027
3028 return false;
3029 }
3030
3031 bool plymouth_running(void) {
3032 return access("/run/plymouth/pid", F_OK) >= 0;
3033 }
3034
3035 char* strshorten(char *s, size_t l) {
3036 assert(s);
3037
3038 if (l < strlen(s))
3039 s[l] = 0;
3040
3041 return s;
3042 }
3043
3044 int pipe_eof(int fd) {
3045 struct pollfd pollfd = {
3046 .fd = fd,
3047 .events = POLLIN|POLLHUP,
3048 };
3049
3050 int r;
3051
3052 r = poll(&pollfd, 1, 0);
3053 if (r < 0)
3054 return -errno;
3055
3056 if (r == 0)
3057 return 0;
3058
3059 return pollfd.revents & POLLHUP;
3060 }
3061
3062 int fd_wait_for_event(int fd, int event, usec_t t) {
3063
3064 struct pollfd pollfd = {
3065 .fd = fd,
3066 .events = event,
3067 };
3068
3069 struct timespec ts;
3070 int r;
3071
3072 r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
3073 if (r < 0)
3074 return -errno;
3075
3076 if (r == 0)
3077 return 0;
3078
3079 return pollfd.revents;
3080 }
3081
3082 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
3083 FILE *f;
3084 char *t;
3085 int r, fd;
3086
3087 assert(path);
3088 assert(_f);
3089 assert(_temp_path);
3090
3091 r = tempfn_xxxxxx(path, NULL, &t);
3092 if (r < 0)
3093 return r;
3094
3095 fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC);
3096 if (fd < 0) {
3097 free(t);
3098 return -errno;
3099 }
3100
3101 f = fdopen(fd, "we");
3102 if (!f) {
3103 unlink_noerrno(t);
3104 free(t);
3105 safe_close(fd);
3106 return -errno;
3107 }
3108
3109 *_f = f;
3110 *_temp_path = t;
3111
3112 return 0;
3113 }
3114
3115 int symlink_atomic(const char *from, const char *to) {
3116 _cleanup_free_ char *t = NULL;
3117 int r;
3118
3119 assert(from);
3120 assert(to);
3121
3122 r = tempfn_random(to, NULL, &t);
3123 if (r < 0)
3124 return r;
3125
3126 if (symlink(from, t) < 0)
3127 return -errno;
3128
3129 if (rename(t, to) < 0) {
3130 unlink_noerrno(t);
3131 return -errno;
3132 }
3133
3134 return 0;
3135 }
3136
3137 int symlink_idempotent(const char *from, const char *to) {
3138 _cleanup_free_ char *p = NULL;
3139 int r;
3140
3141 assert(from);
3142 assert(to);
3143
3144 if (symlink(from, to) < 0) {
3145 if (errno != EEXIST)
3146 return -errno;
3147
3148 r = readlink_malloc(to, &p);
3149 if (r < 0)
3150 return r;
3151
3152 if (!streq(p, from))
3153 return -EINVAL;
3154 }
3155
3156 return 0;
3157 }
3158
3159 int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
3160 _cleanup_free_ char *t = NULL;
3161 int r;
3162
3163 assert(path);
3164
3165 r = tempfn_random(path, NULL, &t);
3166 if (r < 0)
3167 return r;
3168
3169 if (mknod(t, mode, dev) < 0)
3170 return -errno;
3171
3172 if (rename(t, path) < 0) {
3173 unlink_noerrno(t);
3174 return -errno;
3175 }
3176
3177 return 0;
3178 }
3179
3180 int mkfifo_atomic(const char *path, mode_t mode) {
3181 _cleanup_free_ char *t = NULL;
3182 int r;
3183
3184 assert(path);
3185
3186 r = tempfn_random(path, NULL, &t);
3187 if (r < 0)
3188 return r;
3189
3190 if (mkfifo(t, mode) < 0)
3191 return -errno;
3192
3193 if (rename(t, path) < 0) {
3194 unlink_noerrno(t);
3195 return -errno;
3196 }
3197
3198 return 0;
3199 }
3200
3201 bool display_is_local(const char *display) {
3202 assert(display);
3203
3204 return
3205 display[0] == ':' &&
3206 display[1] >= '0' &&
3207 display[1] <= '9';
3208 }
3209
3210 int socket_from_display(const char *display, char **path) {
3211 size_t k;
3212 char *f, *c;
3213
3214 assert(display);
3215 assert(path);
3216
3217 if (!display_is_local(display))
3218 return -EINVAL;
3219
3220 k = strspn(display+1, "0123456789");
3221
3222 f = new(char, strlen("/tmp/.X11-unix/X") + k + 1);
3223 if (!f)
3224 return -ENOMEM;
3225
3226 c = stpcpy(f, "/tmp/.X11-unix/X");
3227 memcpy(c, display+1, k);
3228 c[k] = 0;
3229
3230 *path = f;
3231
3232 return 0;
3233 }
3234
3235 int get_user_creds(
3236 const char **username,
3237 uid_t *uid, gid_t *gid,
3238 const char **home,
3239 const char **shell) {
3240
3241 struct passwd *p;
3242 uid_t u;
3243
3244 assert(username);
3245 assert(*username);
3246
3247 /* We enforce some special rules for uid=0: in order to avoid
3248 * NSS lookups for root we hardcode its data. */
3249
3250 if (streq(*username, "root") || streq(*username, "0")) {
3251 *username = "root";
3252
3253 if (uid)
3254 *uid = 0;
3255
3256 if (gid)
3257 *gid = 0;
3258
3259 if (home)
3260 *home = "/root";
3261
3262 if (shell)
3263 *shell = "/bin/sh";
3264
3265 return 0;
3266 }
3267
3268 if (parse_uid(*username, &u) >= 0) {
3269 errno = 0;
3270 p = getpwuid(u);
3271
3272 /* If there are multiple users with the same id, make
3273 * sure to leave $USER to the configured value instead
3274 * of the first occurrence in the database. However if
3275 * the uid was configured by a numeric uid, then let's
3276 * pick the real username from /etc/passwd. */
3277 if (p)
3278 *username = p->pw_name;
3279 } else {
3280 errno = 0;
3281 p = getpwnam(*username);
3282 }
3283
3284 if (!p)
3285 return errno > 0 ? -errno : -ESRCH;
3286
3287 if (uid)
3288 *uid = p->pw_uid;
3289
3290 if (gid)
3291 *gid = p->pw_gid;
3292
3293 if (home)
3294 *home = p->pw_dir;
3295
3296 if (shell)
3297 *shell = p->pw_shell;
3298
3299 return 0;
3300 }
3301
3302 char* uid_to_name(uid_t uid) {
3303 struct passwd *p;
3304 char *r;
3305
3306 if (uid == 0)
3307 return strdup("root");
3308
3309 p = getpwuid(uid);
3310 if (p)
3311 return strdup(p->pw_name);
3312
3313 if (asprintf(&r, UID_FMT, uid) < 0)
3314 return NULL;
3315
3316 return r;
3317 }
3318
3319 char* gid_to_name(gid_t gid) {
3320 struct group *p;
3321 char *r;
3322
3323 if (gid == 0)
3324 return strdup("root");
3325
3326 p = getgrgid(gid);
3327 if (p)
3328 return strdup(p->gr_name);
3329
3330 if (asprintf(&r, GID_FMT, gid) < 0)
3331 return NULL;
3332
3333 return r;
3334 }
3335
3336 int get_group_creds(const char **groupname, gid_t *gid) {
3337 struct group *g;
3338 gid_t id;
3339
3340 assert(groupname);
3341
3342 /* We enforce some special rules for gid=0: in order to avoid
3343 * NSS lookups for root we hardcode its data. */
3344
3345 if (streq(*groupname, "root") || streq(*groupname, "0")) {
3346 *groupname = "root";
3347
3348 if (gid)
3349 *gid = 0;
3350
3351 return 0;
3352 }
3353
3354 if (parse_gid(*groupname, &id) >= 0) {
3355 errno = 0;
3356 g = getgrgid(id);
3357
3358 if (g)
3359 *groupname = g->gr_name;
3360 } else {
3361 errno = 0;
3362 g = getgrnam(*groupname);
3363 }
3364
3365 if (!g)
3366 return errno > 0 ? -errno : -ESRCH;
3367
3368 if (gid)
3369 *gid = g->gr_gid;
3370
3371 return 0;
3372 }
3373
3374 int in_gid(gid_t gid) {
3375 gid_t *gids;
3376 int ngroups_max, r, i;
3377
3378 if (getgid() == gid)
3379 return 1;
3380
3381 if (getegid() == gid)
3382 return 1;
3383
3384 ngroups_max = sysconf(_SC_NGROUPS_MAX);
3385 assert(ngroups_max > 0);
3386
3387 gids = alloca(sizeof(gid_t) * ngroups_max);
3388
3389 r = getgroups(ngroups_max, gids);
3390 if (r < 0)
3391 return -errno;
3392
3393 for (i = 0; i < r; i++)
3394 if (gids[i] == gid)
3395 return 1;
3396
3397 return 0;
3398 }
3399
3400 int in_group(const char *name) {
3401 int r;
3402 gid_t gid;
3403
3404 r = get_group_creds(&name, &gid);
3405 if (r < 0)
3406 return r;
3407
3408 return in_gid(gid);
3409 }
3410
3411 int glob_exists(const char *path) {
3412 _cleanup_globfree_ glob_t g = {};
3413 int k;
3414
3415 assert(path);
3416
3417 errno = 0;
3418 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
3419
3420 if (k == GLOB_NOMATCH)
3421 return 0;
3422 else if (k == GLOB_NOSPACE)
3423 return -ENOMEM;
3424 else if (k == 0)
3425 return !strv_isempty(g.gl_pathv);
3426 else
3427 return errno ? -errno : -EIO;
3428 }
3429
3430 int glob_extend(char ***strv, const char *path) {
3431 _cleanup_globfree_ glob_t g = {};
3432 int k;
3433 char **p;
3434
3435 errno = 0;
3436 k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
3437
3438 if (k == GLOB_NOMATCH)
3439 return -ENOENT;
3440 else if (k == GLOB_NOSPACE)
3441 return -ENOMEM;
3442 else if (k != 0 || strv_isempty(g.gl_pathv))
3443 return errno ? -errno : -EIO;
3444
3445 STRV_FOREACH(p, g.gl_pathv) {
3446 k = strv_extend(strv, *p);
3447 if (k < 0)
3448 break;
3449 }
3450
3451 return k;
3452 }
3453
3454 int dirent_ensure_type(DIR *d, struct dirent *de) {
3455 struct stat st;
3456
3457 assert(d);
3458 assert(de);
3459
3460 if (de->d_type != DT_UNKNOWN)
3461 return 0;
3462
3463 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
3464 return -errno;
3465
3466 de->d_type =
3467 S_ISREG(st.st_mode) ? DT_REG :
3468 S_ISDIR(st.st_mode) ? DT_DIR :
3469 S_ISLNK(st.st_mode) ? DT_LNK :
3470 S_ISFIFO(st.st_mode) ? DT_FIFO :
3471 S_ISSOCK(st.st_mode) ? DT_SOCK :
3472 S_ISCHR(st.st_mode) ? DT_CHR :
3473 S_ISBLK(st.st_mode) ? DT_BLK :
3474 DT_UNKNOWN;
3475
3476 return 0;
3477 }
3478
3479 int get_files_in_directory(const char *path, char ***list) {
3480 _cleanup_closedir_ DIR *d = NULL;
3481 size_t bufsize = 0, n = 0;
3482 _cleanup_strv_free_ char **l = NULL;
3483
3484 assert(path);
3485
3486 /* Returns all files in a directory in *list, and the number
3487 * of files as return value. If list is NULL returns only the
3488 * number. */
3489
3490 d = opendir(path);
3491 if (!d)
3492 return -errno;
3493
3494 for (;;) {
3495 struct dirent *de;
3496
3497 errno = 0;
3498 de = readdir(d);
3499 if (!de && errno != 0)
3500 return -errno;
3501 if (!de)
3502 break;
3503
3504 dirent_ensure_type(d, de);
3505
3506 if (!dirent_is_file(de))
3507 continue;
3508
3509 if (list) {
3510 /* one extra slot is needed for the terminating NULL */
3511 if (!GREEDY_REALLOC(l, bufsize, n + 2))
3512 return -ENOMEM;
3513
3514 l[n] = strdup(de->d_name);
3515 if (!l[n])
3516 return -ENOMEM;
3517
3518 l[++n] = NULL;
3519 } else
3520 n++;
3521 }
3522
3523 if (list) {
3524 *list = l;
3525 l = NULL; /* avoid freeing */
3526 }
3527
3528 return n;
3529 }
3530
3531 char *strjoin(const char *x, ...) {
3532 va_list ap;
3533 size_t l;
3534 char *r, *p;
3535
3536 va_start(ap, x);
3537
3538 if (x) {
3539 l = strlen(x);
3540
3541 for (;;) {
3542 const char *t;
3543 size_t n;
3544
3545 t = va_arg(ap, const char *);
3546 if (!t)
3547 break;
3548
3549 n = strlen(t);
3550 if (n > ((size_t) -1) - l) {
3551 va_end(ap);
3552 return NULL;
3553 }
3554
3555 l += n;
3556 }
3557 } else
3558 l = 0;
3559
3560 va_end(ap);
3561
3562 r = new(char, l+1);
3563 if (!r)
3564 return NULL;
3565
3566 if (x) {
3567 p = stpcpy(r, x);
3568
3569 va_start(ap, x);
3570
3571 for (;;) {
3572 const char *t;
3573
3574 t = va_arg(ap, const char *);
3575 if (!t)
3576 break;
3577
3578 p = stpcpy(p, t);
3579 }
3580
3581 va_end(ap);
3582 } else
3583 r[0] = 0;
3584
3585 return r;
3586 }
3587
3588 bool is_main_thread(void) {
3589 static thread_local int cached = 0;
3590
3591 if (_unlikely_(cached == 0))
3592 cached = getpid() == gettid() ? 1 : -1;
3593
3594 return cached > 0;
3595 }
3596
3597 int block_get_whole_disk(dev_t d, dev_t *ret) {
3598 char *p, *s;
3599 int r;
3600 unsigned n, m;
3601
3602 assert(ret);
3603
3604 /* If it has a queue this is good enough for us */
3605 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
3606 return -ENOMEM;
3607
3608 r = access(p, F_OK);
3609 free(p);
3610
3611 if (r >= 0) {
3612 *ret = d;
3613 return 0;
3614 }
3615
3616 /* If it is a partition find the originating device */
3617 if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
3618 return -ENOMEM;
3619
3620 r = access(p, F_OK);
3621 free(p);
3622
3623 if (r < 0)
3624 return -ENOENT;
3625
3626 /* Get parent dev_t */
3627 if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
3628 return -ENOMEM;
3629
3630 r = read_one_line_file(p, &s);
3631 free(p);
3632
3633 if (r < 0)
3634 return r;
3635
3636 r = sscanf(s, "%u:%u", &m, &n);
3637 free(s);
3638
3639 if (r != 2)
3640 return -EINVAL;
3641
3642 /* Only return this if it is really good enough for us. */
3643 if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
3644 return -ENOMEM;
3645
3646 r = access(p, F_OK);
3647 free(p);
3648
3649 if (r >= 0) {
3650 *ret = makedev(m, n);
3651 return 0;
3652 }
3653
3654 return -ENOENT;
3655 }
3656
3657 static const char *const ioprio_class_table[] = {
3658 [IOPRIO_CLASS_NONE] = "none",
3659 [IOPRIO_CLASS_RT] = "realtime",
3660 [IOPRIO_CLASS_BE] = "best-effort",
3661 [IOPRIO_CLASS_IDLE] = "idle"
3662 };
3663
3664 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
3665
3666 static const char *const sigchld_code_table[] = {
3667 [CLD_EXITED] = "exited",
3668 [CLD_KILLED] = "killed",
3669 [CLD_DUMPED] = "dumped",
3670 [CLD_TRAPPED] = "trapped",
3671 [CLD_STOPPED] = "stopped",
3672 [CLD_CONTINUED] = "continued",
3673 };
3674
3675 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
3676
3677 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
3678 [LOG_FAC(LOG_KERN)] = "kern",
3679 [LOG_FAC(LOG_USER)] = "user",
3680 [LOG_FAC(LOG_MAIL)] = "mail",
3681 [LOG_FAC(LOG_DAEMON)] = "daemon",
3682 [LOG_FAC(LOG_AUTH)] = "auth",
3683 [LOG_FAC(LOG_SYSLOG)] = "syslog",
3684 [LOG_FAC(LOG_LPR)] = "lpr",
3685 [LOG_FAC(LOG_NEWS)] = "news",
3686 [LOG_FAC(LOG_UUCP)] = "uucp",
3687 [LOG_FAC(LOG_CRON)] = "cron",
3688 [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
3689 [LOG_FAC(LOG_FTP)] = "ftp",
3690 [LOG_FAC(LOG_LOCAL0)] = "local0",
3691 [LOG_FAC(LOG_LOCAL1)] = "local1",
3692 [LOG_FAC(LOG_LOCAL2)] = "local2",
3693 [LOG_FAC(LOG_LOCAL3)] = "local3",
3694 [LOG_FAC(LOG_LOCAL4)] = "local4",
3695 [LOG_FAC(LOG_LOCAL5)] = "local5",
3696 [LOG_FAC(LOG_LOCAL6)] = "local6",
3697 [LOG_FAC(LOG_LOCAL7)] = "local7"
3698 };
3699
3700 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
3701
3702 static const char *const log_level_table[] = {
3703 [LOG_EMERG] = "emerg",
3704 [LOG_ALERT] = "alert",
3705 [LOG_CRIT] = "crit",
3706 [LOG_ERR] = "err",
3707 [LOG_WARNING] = "warning",
3708 [LOG_NOTICE] = "notice",
3709 [LOG_INFO] = "info",
3710 [LOG_DEBUG] = "debug"
3711 };
3712
3713 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
3714
3715 static const char* const sched_policy_table[] = {
3716 [SCHED_OTHER] = "other",
3717 [SCHED_BATCH] = "batch",
3718 [SCHED_IDLE] = "idle",
3719 [SCHED_FIFO] = "fifo",
3720 [SCHED_RR] = "rr"
3721 };
3722
3723 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
3724
3725 static const char* const rlimit_table[_RLIMIT_MAX] = {
3726 [RLIMIT_CPU] = "LimitCPU",
3727 [RLIMIT_FSIZE] = "LimitFSIZE",
3728 [RLIMIT_DATA] = "LimitDATA",
3729 [RLIMIT_STACK] = "LimitSTACK",
3730 [RLIMIT_CORE] = "LimitCORE",
3731 [RLIMIT_RSS] = "LimitRSS",
3732 [RLIMIT_NOFILE] = "LimitNOFILE",
3733 [RLIMIT_AS] = "LimitAS",
3734 [RLIMIT_NPROC] = "LimitNPROC",
3735 [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
3736 [RLIMIT_LOCKS] = "LimitLOCKS",
3737 [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
3738 [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
3739 [RLIMIT_NICE] = "LimitNICE",
3740 [RLIMIT_RTPRIO] = "LimitRTPRIO",
3741 [RLIMIT_RTTIME] = "LimitRTTIME"
3742 };
3743
3744 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
3745
3746 static const char* const ip_tos_table[] = {
3747 [IPTOS_LOWDELAY] = "low-delay",
3748 [IPTOS_THROUGHPUT] = "throughput",
3749 [IPTOS_RELIABILITY] = "reliability",
3750 [IPTOS_LOWCOST] = "low-cost",
3751 };
3752
3753 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
3754
3755 bool kexec_loaded(void) {
3756 bool loaded = false;
3757 char *s;
3758
3759 if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
3760 if (s[0] == '1')
3761 loaded = true;
3762 free(s);
3763 }
3764 return loaded;
3765 }
3766
3767 int prot_from_flags(int flags) {
3768
3769 switch (flags & O_ACCMODE) {
3770
3771 case O_RDONLY:
3772 return PROT_READ;
3773
3774 case O_WRONLY:
3775 return PROT_WRITE;
3776
3777 case O_RDWR:
3778 return PROT_READ|PROT_WRITE;
3779
3780 default:
3781 return -EINVAL;
3782 }
3783 }
3784
3785 char *format_bytes(char *buf, size_t l, uint64_t t) {
3786 unsigned i;
3787
3788 static const struct {
3789 const char *suffix;
3790 uint64_t factor;
3791 } table[] = {
3792 { "E", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
3793 { "P", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
3794 { "T", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
3795 { "G", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
3796 { "M", UINT64_C(1024)*UINT64_C(1024) },
3797 { "K", UINT64_C(1024) },
3798 };
3799
3800 if (t == (uint64_t) -1)
3801 return NULL;
3802
3803 for (i = 0; i < ELEMENTSOF(table); i++) {
3804
3805 if (t >= table[i].factor) {
3806 snprintf(buf, l,
3807 "%" PRIu64 ".%" PRIu64 "%s",
3808 t / table[i].factor,
3809 ((t*UINT64_C(10)) / table[i].factor) % UINT64_C(10),
3810 table[i].suffix);
3811
3812 goto finish;
3813 }
3814 }
3815
3816 snprintf(buf, l, "%" PRIu64 "B", t);
3817
3818 finish:
3819 buf[l-1] = 0;
3820 return buf;
3821
3822 }
3823
3824 void* memdup(const void *p, size_t l) {
3825 void *r;
3826
3827 assert(p);
3828
3829 r = malloc(l);
3830 if (!r)
3831 return NULL;
3832
3833 memcpy(r, p, l);
3834 return r;
3835 }
3836
3837 int fd_inc_sndbuf(int fd, size_t n) {
3838 int r, value;
3839 socklen_t l = sizeof(value);
3840
3841 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
3842 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
3843 return 0;
3844
3845 /* If we have the privileges we will ignore the kernel limit. */
3846
3847 value = (int) n;
3848 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
3849 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
3850 return -errno;
3851
3852 return 1;
3853 }
3854
3855 int fd_inc_rcvbuf(int fd, size_t n) {
3856 int r, value;
3857 socklen_t l = sizeof(value);
3858
3859 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
3860 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
3861 return 0;
3862
3863 /* If we have the privileges we will ignore the kernel limit. */
3864
3865 value = (int) n;
3866 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
3867 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
3868 return -errno;
3869 return 1;
3870 }
3871
3872 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
3873 bool stdout_is_tty, stderr_is_tty;
3874 pid_t parent_pid, agent_pid;
3875 sigset_t ss, saved_ss;
3876 unsigned n, i;
3877 va_list ap;
3878 char **l;
3879
3880 assert(pid);
3881 assert(path);
3882
3883 /* Spawns a temporary TTY agent, making sure it goes away when
3884 * we go away */
3885
3886 parent_pid = getpid();
3887
3888 /* First we temporarily block all signals, so that the new
3889 * child has them blocked initially. This way, we can be sure
3890 * that SIGTERMs are not lost we might send to the agent. */
3891 assert_se(sigfillset(&ss) >= 0);
3892 assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0);
3893
3894 agent_pid = fork();
3895 if (agent_pid < 0) {
3896 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
3897 return -errno;
3898 }
3899
3900 if (agent_pid != 0) {
3901 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
3902 *pid = agent_pid;
3903 return 0;
3904 }
3905
3906 /* In the child:
3907 *
3908 * Make sure the agent goes away when the parent dies */
3909 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
3910 _exit(EXIT_FAILURE);
3911
3912 /* Make sure we actually can kill the agent, if we need to, in
3913 * case somebody invoked us from a shell script that trapped
3914 * SIGTERM or so... */
3915 (void) reset_all_signal_handlers();
3916 (void) reset_signal_mask();
3917
3918 /* Check whether our parent died before we were able
3919 * to set the death signal and unblock the signals */
3920 if (getppid() != parent_pid)
3921 _exit(EXIT_SUCCESS);
3922
3923 /* Don't leak fds to the agent */
3924 close_all_fds(except, n_except);
3925
3926 stdout_is_tty = isatty(STDOUT_FILENO);
3927 stderr_is_tty = isatty(STDERR_FILENO);
3928
3929 if (!stdout_is_tty || !stderr_is_tty) {
3930 int fd;
3931
3932 /* Detach from stdout/stderr. and reopen
3933 * /dev/tty for them. This is important to
3934 * ensure that when systemctl is started via
3935 * popen() or a similar call that expects to
3936 * read EOF we actually do generate EOF and
3937 * not delay this indefinitely by because we
3938 * keep an unused copy of stdin around. */
3939 fd = open("/dev/tty", O_WRONLY);
3940 if (fd < 0) {
3941 log_error_errno(errno, "Failed to open /dev/tty: %m");
3942 _exit(EXIT_FAILURE);
3943 }
3944
3945 if (!stdout_is_tty)
3946 dup2(fd, STDOUT_FILENO);
3947
3948 if (!stderr_is_tty)
3949 dup2(fd, STDERR_FILENO);
3950
3951 if (fd > 2)
3952 close(fd);
3953 }
3954
3955 /* Count arguments */
3956 va_start(ap, path);
3957 for (n = 0; va_arg(ap, char*); n++)
3958 ;
3959 va_end(ap);
3960
3961 /* Allocate strv */
3962 l = alloca(sizeof(char *) * (n + 1));
3963
3964 /* Fill in arguments */
3965 va_start(ap, path);
3966 for (i = 0; i <= n; i++)
3967 l[i] = va_arg(ap, char*);
3968 va_end(ap);
3969
3970 execv(path, l);
3971 _exit(EXIT_FAILURE);
3972 }
3973
3974 int setrlimit_closest(int resource, const struct rlimit *rlim) {
3975 struct rlimit highest, fixed;
3976
3977 assert(rlim);
3978
3979 if (setrlimit(resource, rlim) >= 0)
3980 return 0;
3981
3982 if (errno != EPERM)
3983 return -errno;
3984
3985 /* So we failed to set the desired setrlimit, then let's try
3986 * to get as close as we can */
3987 assert_se(getrlimit(resource, &highest) == 0);
3988
3989 fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
3990 fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
3991
3992 if (setrlimit(resource, &fixed) < 0)
3993 return -errno;
3994
3995 return 0;
3996 }
3997
3998 bool http_etag_is_valid(const char *etag) {
3999 if (isempty(etag))
4000 return false;
4001
4002 if (!endswith(etag, "\""))
4003 return false;
4004
4005 if (!startswith(etag, "\"") && !startswith(etag, "W/\""))
4006 return false;
4007
4008 return true;
4009 }
4010
4011 bool http_url_is_valid(const char *url) {
4012 const char *p;
4013
4014 if (isempty(url))
4015 return false;
4016
4017 p = startswith(url, "http://");
4018 if (!p)
4019 p = startswith(url, "https://");
4020 if (!p)
4021 return false;
4022
4023 if (isempty(p))
4024 return false;
4025
4026 return ascii_is_valid(p);
4027 }
4028
4029 bool documentation_url_is_valid(const char *url) {
4030 const char *p;
4031
4032 if (isempty(url))
4033 return false;
4034
4035 if (http_url_is_valid(url))
4036 return true;
4037
4038 p = startswith(url, "file:/");
4039 if (!p)
4040 p = startswith(url, "info:");
4041 if (!p)
4042 p = startswith(url, "man:");
4043
4044 if (isempty(p))
4045 return false;
4046
4047 return ascii_is_valid(p);
4048 }
4049
4050 bool in_initrd(void) {
4051 static int saved = -1;
4052 struct statfs s;
4053
4054 if (saved >= 0)
4055 return saved;
4056
4057 /* We make two checks here:
4058 *
4059 * 1. the flag file /etc/initrd-release must exist
4060 * 2. the root file system must be a memory file system
4061 *
4062 * The second check is extra paranoia, since misdetecting an
4063 * initrd can have bad bad consequences due the initrd
4064 * emptying when transititioning to the main systemd.
4065 */
4066
4067 saved = access("/etc/initrd-release", F_OK) >= 0 &&
4068 statfs("/", &s) >= 0 &&
4069 is_temporary_fs(&s);
4070
4071 return saved;
4072 }
4073
4074 int get_home_dir(char **_h) {
4075 struct passwd *p;
4076 const char *e;
4077 char *h;
4078 uid_t u;
4079
4080 assert(_h);
4081
4082 /* Take the user specified one */
4083 e = secure_getenv("HOME");
4084 if (e && path_is_absolute(e)) {
4085 h = strdup(e);
4086 if (!h)
4087 return -ENOMEM;
4088
4089 *_h = h;
4090 return 0;
4091 }
4092
4093 /* Hardcode home directory for root to avoid NSS */
4094 u = getuid();
4095 if (u == 0) {
4096 h = strdup("/root");
4097 if (!h)
4098 return -ENOMEM;
4099
4100 *_h = h;
4101 return 0;
4102 }
4103
4104 /* Check the database... */
4105 errno = 0;
4106 p = getpwuid(u);
4107 if (!p)
4108 return errno > 0 ? -errno : -ESRCH;
4109
4110 if (!path_is_absolute(p->pw_dir))
4111 return -EINVAL;
4112
4113 h = strdup(p->pw_dir);
4114 if (!h)
4115 return -ENOMEM;
4116
4117 *_h = h;
4118 return 0;
4119 }
4120
4121 int get_shell(char **_s) {
4122 struct passwd *p;
4123 const char *e;
4124 char *s;
4125 uid_t u;
4126
4127 assert(_s);
4128
4129 /* Take the user specified one */
4130 e = getenv("SHELL");
4131 if (e) {
4132 s = strdup(e);
4133 if (!s)
4134 return -ENOMEM;
4135
4136 *_s = s;
4137 return 0;
4138 }
4139
4140 /* Hardcode home directory for root to avoid NSS */
4141 u = getuid();
4142 if (u == 0) {
4143 s = strdup("/bin/sh");
4144 if (!s)
4145 return -ENOMEM;
4146
4147 *_s = s;
4148 return 0;
4149 }
4150
4151 /* Check the database... */
4152 errno = 0;
4153 p = getpwuid(u);
4154 if (!p)
4155 return errno > 0 ? -errno : -ESRCH;
4156
4157 if (!path_is_absolute(p->pw_shell))
4158 return -EINVAL;
4159
4160 s = strdup(p->pw_shell);
4161 if (!s)
4162 return -ENOMEM;
4163
4164 *_s = s;
4165 return 0;
4166 }
4167
4168 bool filename_is_valid(const char *p) {
4169
4170 if (isempty(p))
4171 return false;
4172
4173 if (strchr(p, '/'))
4174 return false;
4175
4176 if (streq(p, "."))
4177 return false;
4178
4179 if (streq(p, ".."))
4180 return false;
4181
4182 if (strlen(p) > FILENAME_MAX)
4183 return false;
4184
4185 return true;
4186 }
4187
4188 bool string_is_safe(const char *p) {
4189 const char *t;
4190
4191 if (!p)
4192 return false;
4193
4194 for (t = p; *t; t++) {
4195 if (*t > 0 && *t < ' ')
4196 return false;
4197
4198 if (strchr("\\\"\'\x7f", *t))
4199 return false;
4200 }
4201
4202 return true;
4203 }
4204
4205 /**
4206 * Check if a string contains control characters. If 'ok' is non-NULL
4207 * it may be a string containing additional CCs to be considered OK.
4208 */
4209 bool string_has_cc(const char *p, const char *ok) {
4210 const char *t;
4211
4212 assert(p);
4213
4214 for (t = p; *t; t++) {
4215 if (ok && strchr(ok, *t))
4216 continue;
4217
4218 if (*t > 0 && *t < ' ')
4219 return true;
4220
4221 if (*t == 127)
4222 return true;
4223 }
4224
4225 return false;
4226 }
4227
4228 bool path_is_safe(const char *p) {
4229
4230 if (isempty(p))
4231 return false;
4232
4233 if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
4234 return false;
4235
4236 if (strlen(p)+1 > PATH_MAX)
4237 return false;
4238
4239 /* The following two checks are not really dangerous, but hey, they still are confusing */
4240 if (streq(p, ".") || startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
4241 return false;
4242
4243 if (strstr(p, "//"))
4244 return false;
4245
4246 return true;
4247 }
4248
4249 /* hey glibc, APIs with callbacks without a user pointer are so useless */
4250 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
4251 int (*compar) (const void *, const void *, void *), void *arg) {
4252 size_t l, u, idx;
4253 const void *p;
4254 int comparison;
4255
4256 l = 0;
4257 u = nmemb;
4258 while (l < u) {
4259 idx = (l + u) / 2;
4260 p = (void *)(((const char *) base) + (idx * size));
4261 comparison = compar(key, p, arg);
4262 if (comparison < 0)
4263 u = idx;
4264 else if (comparison > 0)
4265 l = idx + 1;
4266 else
4267 return (void *)p;
4268 }
4269 return NULL;
4270 }
4271
4272 void init_gettext(void) {
4273 setlocale(LC_ALL, "");
4274 textdomain(GETTEXT_PACKAGE);
4275 }
4276
4277 bool is_locale_utf8(void) {
4278 const char *set;
4279 static int cached_answer = -1;
4280
4281 if (cached_answer >= 0)
4282 goto out;
4283
4284 if (!setlocale(LC_ALL, "")) {
4285 cached_answer = true;
4286 goto out;
4287 }
4288
4289 set = nl_langinfo(CODESET);
4290 if (!set) {
4291 cached_answer = true;
4292 goto out;
4293 }
4294
4295 if (streq(set, "UTF-8")) {
4296 cached_answer = true;
4297 goto out;
4298 }
4299
4300 /* For LC_CTYPE=="C" return true, because CTYPE is effectly
4301 * unset and everything can do to UTF-8 nowadays. */
4302 set = setlocale(LC_CTYPE, NULL);
4303 if (!set) {
4304 cached_answer = true;
4305 goto out;
4306 }
4307
4308 /* Check result, but ignore the result if C was set
4309 * explicitly. */
4310 cached_answer =
4311 STR_IN_SET(set, "C", "POSIX") &&
4312 !getenv("LC_ALL") &&
4313 !getenv("LC_CTYPE") &&
4314 !getenv("LANG");
4315
4316 out:
4317 return (bool) cached_answer;
4318 }
4319
4320 const char *draw_special_char(DrawSpecialChar ch) {
4321 static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
4322
4323 /* UTF-8 */ {
4324 [DRAW_TREE_VERTICAL] = "\342\224\202 ", /* │ */
4325 [DRAW_TREE_BRANCH] = "\342\224\234\342\224\200", /* ├─ */
4326 [DRAW_TREE_RIGHT] = "\342\224\224\342\224\200", /* └─ */
4327 [DRAW_TREE_SPACE] = " ", /* */
4328 [DRAW_TRIANGULAR_BULLET] = "\342\200\243", /* ‣ */
4329 [DRAW_BLACK_CIRCLE] = "\342\227\217", /* ● */
4330 [DRAW_ARROW] = "\342\206\222", /* → */
4331 [DRAW_DASH] = "\342\200\223", /* – */
4332 },
4333
4334 /* ASCII fallback */ {
4335 [DRAW_TREE_VERTICAL] = "| ",
4336 [DRAW_TREE_BRANCH] = "|-",
4337 [DRAW_TREE_RIGHT] = "`-",
4338 [DRAW_TREE_SPACE] = " ",
4339 [DRAW_TRIANGULAR_BULLET] = ">",
4340 [DRAW_BLACK_CIRCLE] = "*",
4341 [DRAW_ARROW] = "->",
4342 [DRAW_DASH] = "-",
4343 }
4344 };
4345
4346 return draw_table[!is_locale_utf8()][ch];
4347 }
4348
4349 char *strreplace(const char *text, const char *old_string, const char *new_string) {
4350 const char *f;
4351 char *t, *r;
4352 size_t l, old_len, new_len;
4353
4354 assert(text);
4355 assert(old_string);
4356 assert(new_string);
4357
4358 old_len = strlen(old_string);
4359 new_len = strlen(new_string);
4360
4361 l = strlen(text);
4362 r = new(char, l+1);
4363 if (!r)
4364 return NULL;
4365
4366 f = text;
4367 t = r;
4368 while (*f) {
4369 char *a;
4370 size_t d, nl;
4371
4372 if (!startswith(f, old_string)) {
4373 *(t++) = *(f++);
4374 continue;
4375 }
4376
4377 d = t - r;
4378 nl = l - old_len + new_len;
4379 a = realloc(r, nl + 1);
4380 if (!a)
4381 goto oom;
4382
4383 l = nl;
4384 r = a;
4385 t = r + d;
4386
4387 t = stpcpy(t, new_string);
4388 f += old_len;
4389 }
4390
4391 *t = 0;
4392 return r;
4393
4394 oom:
4395 free(r);
4396 return NULL;
4397 }
4398
4399 char *strip_tab_ansi(char **ibuf, size_t *_isz) {
4400 const char *i, *begin = NULL;
4401 enum {
4402 STATE_OTHER,
4403 STATE_ESCAPE,
4404 STATE_BRACKET
4405 } state = STATE_OTHER;
4406 char *obuf = NULL;
4407 size_t osz = 0, isz;
4408 FILE *f;
4409
4410 assert(ibuf);
4411 assert(*ibuf);
4412
4413 /* Strips ANSI color and replaces TABs by 8 spaces */
4414
4415 isz = _isz ? *_isz : strlen(*ibuf);
4416
4417 f = open_memstream(&obuf, &osz);
4418 if (!f)
4419 return NULL;
4420
4421 for (i = *ibuf; i < *ibuf + isz + 1; i++) {
4422
4423 switch (state) {
4424
4425 case STATE_OTHER:
4426 if (i >= *ibuf + isz) /* EOT */
4427 break;
4428 else if (*i == '\x1B')
4429 state = STATE_ESCAPE;
4430 else if (*i == '\t')
4431 fputs(" ", f);
4432 else
4433 fputc(*i, f);
4434 break;
4435
4436 case STATE_ESCAPE:
4437 if (i >= *ibuf + isz) { /* EOT */
4438 fputc('\x1B', f);
4439 break;
4440 } else if (*i == '[') {
4441 state = STATE_BRACKET;
4442 begin = i + 1;
4443 } else {
4444 fputc('\x1B', f);
4445 fputc(*i, f);
4446 state = STATE_OTHER;
4447 }
4448
4449 break;
4450
4451 case STATE_BRACKET:
4452
4453 if (i >= *ibuf + isz || /* EOT */
4454 (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
4455 fputc('\x1B', f);
4456 fputc('[', f);
4457 state = STATE_OTHER;
4458 i = begin-1;
4459 } else if (*i == 'm')
4460 state = STATE_OTHER;
4461 break;
4462 }
4463 }
4464
4465 if (ferror(f)) {
4466 fclose(f);
4467 free(obuf);
4468 return NULL;
4469 }
4470
4471 fclose(f);
4472
4473 free(*ibuf);
4474 *ibuf = obuf;
4475
4476 if (_isz)
4477 *_isz = osz;
4478
4479 return obuf;
4480 }
4481
4482 int on_ac_power(void) {
4483 bool found_offline = false, found_online = false;
4484 _cleanup_closedir_ DIR *d = NULL;
4485
4486 d = opendir("/sys/class/power_supply");
4487 if (!d)
4488 return errno == ENOENT ? true : -errno;
4489
4490 for (;;) {
4491 struct dirent *de;
4492 _cleanup_close_ int fd = -1, device = -1;
4493 char contents[6];
4494 ssize_t n;
4495
4496 errno = 0;
4497 de = readdir(d);
4498 if (!de && errno != 0)
4499 return -errno;
4500
4501 if (!de)
4502 break;
4503
4504 if (hidden_file(de->d_name))
4505 continue;
4506
4507 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
4508 if (device < 0) {
4509 if (errno == ENOENT || errno == ENOTDIR)
4510 continue;
4511
4512 return -errno;
4513 }
4514
4515 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
4516 if (fd < 0) {
4517 if (errno == ENOENT)
4518 continue;
4519
4520 return -errno;
4521 }
4522
4523 n = read(fd, contents, sizeof(contents));
4524 if (n < 0)
4525 return -errno;
4526
4527 if (n != 6 || memcmp(contents, "Mains\n", 6))
4528 continue;
4529
4530 safe_close(fd);
4531 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
4532 if (fd < 0) {
4533 if (errno == ENOENT)
4534 continue;
4535
4536 return -errno;
4537 }
4538
4539 n = read(fd, contents, sizeof(contents));
4540 if (n < 0)
4541 return -errno;
4542
4543 if (n != 2 || contents[1] != '\n')
4544 return -EIO;
4545
4546 if (contents[0] == '1') {
4547 found_online = true;
4548 break;
4549 } else if (contents[0] == '0')
4550 found_offline = true;
4551 else
4552 return -EIO;
4553 }
4554
4555 return found_online || !found_offline;
4556 }
4557
4558 static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
4559 char **i;
4560
4561 assert(path);
4562 assert(mode);
4563 assert(_f);
4564
4565 if (!path_strv_resolve_uniq(search, root))
4566 return -ENOMEM;
4567
4568 STRV_FOREACH(i, search) {
4569 _cleanup_free_ char *p = NULL;
4570 FILE *f;
4571
4572 if (root)
4573 p = strjoin(root, *i, "/", path, NULL);
4574 else
4575 p = strjoin(*i, "/", path, NULL);
4576 if (!p)
4577 return -ENOMEM;
4578
4579 f = fopen(p, mode);
4580 if (f) {
4581 *_f = f;
4582 return 0;
4583 }
4584
4585 if (errno != ENOENT)
4586 return -errno;
4587 }
4588
4589 return -ENOENT;
4590 }
4591
4592 int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
4593 _cleanup_strv_free_ char **copy = NULL;
4594
4595 assert(path);
4596 assert(mode);
4597 assert(_f);
4598
4599 if (path_is_absolute(path)) {
4600 FILE *f;
4601
4602 f = fopen(path, mode);
4603 if (f) {
4604 *_f = f;
4605 return 0;
4606 }
4607
4608 return -errno;
4609 }
4610
4611 copy = strv_copy((char**) search);
4612 if (!copy)
4613 return -ENOMEM;
4614
4615 return search_and_fopen_internal(path, mode, root, copy, _f);
4616 }
4617
4618 int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
4619 _cleanup_strv_free_ char **s = NULL;
4620
4621 if (path_is_absolute(path)) {
4622 FILE *f;
4623
4624 f = fopen(path, mode);
4625 if (f) {
4626 *_f = f;
4627 return 0;
4628 }
4629
4630 return -errno;
4631 }
4632
4633 s = strv_split_nulstr(search);
4634 if (!s)
4635 return -ENOMEM;
4636
4637 return search_and_fopen_internal(path, mode, root, s, _f);
4638 }
4639
4640 char *strextend(char **x, ...) {
4641 va_list ap;
4642 size_t f, l;
4643 char *r, *p;
4644
4645 assert(x);
4646
4647 l = f = *x ? strlen(*x) : 0;
4648
4649 va_start(ap, x);
4650 for (;;) {
4651 const char *t;
4652 size_t n;
4653
4654 t = va_arg(ap, const char *);
4655 if (!t)
4656 break;
4657
4658 n = strlen(t);
4659 if (n > ((size_t) -1) - l) {
4660 va_end(ap);
4661 return NULL;
4662 }
4663
4664 l += n;
4665 }
4666 va_end(ap);
4667
4668 r = realloc(*x, l+1);
4669 if (!r)
4670 return NULL;
4671
4672 p = r + f;
4673
4674 va_start(ap, x);
4675 for (;;) {
4676 const char *t;
4677
4678 t = va_arg(ap, const char *);
4679 if (!t)
4680 break;
4681
4682 p = stpcpy(p, t);
4683 }
4684 va_end(ap);
4685
4686 *p = 0;
4687 *x = r;
4688
4689 return r + l;
4690 }
4691
4692 char *strrep(const char *s, unsigned n) {
4693 size_t l;
4694 char *r, *p;
4695 unsigned i;
4696
4697 assert(s);
4698
4699 l = strlen(s);
4700 p = r = malloc(l * n + 1);
4701 if (!r)
4702 return NULL;
4703
4704 for (i = 0; i < n; i++)
4705 p = stpcpy(p, s);
4706
4707 *p = 0;
4708 return r;
4709 }
4710
4711 void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
4712 size_t a, newalloc;
4713 void *q;
4714
4715 assert(p);
4716 assert(allocated);
4717
4718 if (*allocated >= need)
4719 return *p;
4720
4721 newalloc = MAX(need * 2, 64u / size);
4722 a = newalloc * size;
4723
4724 /* check for overflows */
4725 if (a < size * need)
4726 return NULL;
4727
4728 q = realloc(*p, a);
4729 if (!q)
4730 return NULL;
4731
4732 *p = q;
4733 *allocated = newalloc;
4734 return q;
4735 }
4736
4737 void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
4738 size_t prev;
4739 uint8_t *q;
4740
4741 assert(p);
4742 assert(allocated);
4743
4744 prev = *allocated;
4745
4746 q = greedy_realloc(p, allocated, need, size);
4747 if (!q)
4748 return NULL;
4749
4750 if (*allocated > prev)
4751 memzero(q + prev * size, (*allocated - prev) * size);
4752
4753 return q;
4754 }
4755
4756 bool id128_is_valid(const char *s) {
4757 size_t i, l;
4758
4759 l = strlen(s);
4760 if (l == 32) {
4761
4762 /* Simple formatted 128bit hex string */
4763
4764 for (i = 0; i < l; i++) {
4765 char c = s[i];
4766
4767 if (!(c >= '0' && c <= '9') &&
4768 !(c >= 'a' && c <= 'z') &&
4769 !(c >= 'A' && c <= 'Z'))
4770 return false;
4771 }
4772
4773 } else if (l == 36) {
4774
4775 /* Formatted UUID */
4776
4777 for (i = 0; i < l; i++) {
4778 char c = s[i];
4779
4780 if ((i == 8 || i == 13 || i == 18 || i == 23)) {
4781 if (c != '-')
4782 return false;
4783 } else {
4784 if (!(c >= '0' && c <= '9') &&
4785 !(c >= 'a' && c <= 'z') &&
4786 !(c >= 'A' && c <= 'Z'))
4787 return false;
4788 }
4789 }
4790
4791 } else
4792 return false;
4793
4794 return true;
4795 }
4796
4797 int split_pair(const char *s, const char *sep, char **l, char **r) {
4798 char *x, *a, *b;
4799
4800 assert(s);
4801 assert(sep);
4802 assert(l);
4803 assert(r);
4804
4805 if (isempty(sep))
4806 return -EINVAL;
4807
4808 x = strstr(s, sep);
4809 if (!x)
4810 return -EINVAL;
4811
4812 a = strndup(s, x - s);
4813 if (!a)
4814 return -ENOMEM;
4815
4816 b = strdup(x + strlen(sep));
4817 if (!b) {
4818 free(a);
4819 return -ENOMEM;
4820 }
4821
4822 *l = a;
4823 *r = b;
4824
4825 return 0;
4826 }
4827
4828 int shall_restore_state(void) {
4829 _cleanup_free_ char *value = NULL;
4830 int r;
4831
4832 r = get_proc_cmdline_key("systemd.restore_state=", &value);
4833 if (r < 0)
4834 return r;
4835 if (r == 0)
4836 return true;
4837
4838 return parse_boolean(value) != 0;
4839 }
4840
4841 int proc_cmdline(char **ret) {
4842 assert(ret);
4843
4844 if (detect_container() > 0)
4845 return get_process_cmdline(1, 0, false, ret);
4846 else
4847 return read_one_line_file("/proc/cmdline", ret);
4848 }
4849
4850 int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
4851 _cleanup_free_ char *line = NULL;
4852 const char *p;
4853 int r;
4854
4855 assert(parse_item);
4856
4857 r = proc_cmdline(&line);
4858 if (r < 0)
4859 return r;
4860
4861 p = line;
4862 for (;;) {
4863 _cleanup_free_ char *word = NULL;
4864 char *value = NULL;
4865
4866 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
4867 if (r < 0)
4868 return r;
4869 if (r == 0)
4870 break;
4871
4872 /* Filter out arguments that are intended only for the
4873 * initrd */
4874 if (!in_initrd() && startswith(word, "rd."))
4875 continue;
4876
4877 value = strchr(word, '=');
4878 if (value)
4879 *(value++) = 0;
4880
4881 r = parse_item(word, value);
4882 if (r < 0)
4883 return r;
4884 }
4885
4886 return 0;
4887 }
4888
4889 int get_proc_cmdline_key(const char *key, char **value) {
4890 _cleanup_free_ char *line = NULL, *ret = NULL;
4891 bool found = false;
4892 const char *p;
4893 int r;
4894
4895 assert(key);
4896
4897 r = proc_cmdline(&line);
4898 if (r < 0)
4899 return r;
4900
4901 p = line;
4902 for (;;) {
4903 _cleanup_free_ char *word = NULL;
4904 const char *e;
4905
4906 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
4907 if (r < 0)
4908 return r;
4909 if (r == 0)
4910 break;
4911
4912 /* Filter out arguments that are intended only for the
4913 * initrd */
4914 if (!in_initrd() && startswith(word, "rd."))
4915 continue;
4916
4917 if (value) {
4918 e = startswith(word, key);
4919 if (!e)
4920 continue;
4921
4922 r = free_and_strdup(&ret, e);
4923 if (r < 0)
4924 return r;
4925
4926 found = true;
4927 } else {
4928 if (streq(word, key))
4929 found = true;
4930 }
4931 }
4932
4933 if (value) {
4934 *value = ret;
4935 ret = NULL;
4936 }
4937
4938 return found;
4939
4940 }
4941
4942 int container_get_leader(const char *machine, pid_t *pid) {
4943 _cleanup_free_ char *s = NULL, *class = NULL;
4944 const char *p;
4945 pid_t leader;
4946 int r;
4947
4948 assert(machine);
4949 assert(pid);
4950
4951 if (!machine_name_is_valid(machine))
4952 return -EINVAL;
4953
4954 p = strjoina("/run/systemd/machines/", machine);
4955 r = parse_env_file(p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
4956 if (r == -ENOENT)
4957 return -EHOSTDOWN;
4958 if (r < 0)
4959 return r;
4960 if (!s)
4961 return -EIO;
4962
4963 if (!streq_ptr(class, "container"))
4964 return -EIO;
4965
4966 r = parse_pid(s, &leader);
4967 if (r < 0)
4968 return r;
4969 if (leader <= 1)
4970 return -EIO;
4971
4972 *pid = leader;
4973 return 0;
4974 }
4975
4976 int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd) {
4977 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, netnsfd = -1, usernsfd = -1;
4978 int rfd = -1;
4979
4980 assert(pid >= 0);
4981
4982 if (mntns_fd) {
4983 const char *mntns;
4984
4985 mntns = procfs_file_alloca(pid, "ns/mnt");
4986 mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
4987 if (mntnsfd < 0)
4988 return -errno;
4989 }
4990
4991 if (pidns_fd) {
4992 const char *pidns;
4993
4994 pidns = procfs_file_alloca(pid, "ns/pid");
4995 pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
4996 if (pidnsfd < 0)
4997 return -errno;
4998 }
4999
5000 if (netns_fd) {
5001 const char *netns;
5002
5003 netns = procfs_file_alloca(pid, "ns/net");
5004 netnsfd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5005 if (netnsfd < 0)
5006 return -errno;
5007 }
5008
5009 if (userns_fd) {
5010 const char *userns;
5011
5012 userns = procfs_file_alloca(pid, "ns/user");
5013 usernsfd = open(userns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5014 if (usernsfd < 0 && errno != ENOENT)
5015 return -errno;
5016 }
5017
5018 if (root_fd) {
5019 const char *root;
5020
5021 root = procfs_file_alloca(pid, "root");
5022 rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
5023 if (rfd < 0)
5024 return -errno;
5025 }
5026
5027 if (pidns_fd)
5028 *pidns_fd = pidnsfd;
5029
5030 if (mntns_fd)
5031 *mntns_fd = mntnsfd;
5032
5033 if (netns_fd)
5034 *netns_fd = netnsfd;
5035
5036 if (userns_fd)
5037 *userns_fd = usernsfd;
5038
5039 if (root_fd)
5040 *root_fd = rfd;
5041
5042 pidnsfd = mntnsfd = netnsfd = usernsfd = -1;
5043
5044 return 0;
5045 }
5046
5047 int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd) {
5048 if (userns_fd >= 0) {
5049 /* Can't setns to your own userns, since then you could
5050 * escalate from non-root to root in your own namespace, so
5051 * check if namespaces equal before attempting to enter. */
5052 _cleanup_free_ char *userns_fd_path = NULL;
5053 int r;
5054 if (asprintf(&userns_fd_path, "/proc/self/fd/%d", userns_fd) < 0)
5055 return -ENOMEM;
5056
5057 r = files_same(userns_fd_path, "/proc/self/ns/user");
5058 if (r < 0)
5059 return r;
5060 if (r)
5061 userns_fd = -1;
5062 }
5063
5064 if (pidns_fd >= 0)
5065 if (setns(pidns_fd, CLONE_NEWPID) < 0)
5066 return -errno;
5067
5068 if (mntns_fd >= 0)
5069 if (setns(mntns_fd, CLONE_NEWNS) < 0)
5070 return -errno;
5071
5072 if (netns_fd >= 0)
5073 if (setns(netns_fd, CLONE_NEWNET) < 0)
5074 return -errno;
5075
5076 if (userns_fd >= 0)
5077 if (setns(userns_fd, CLONE_NEWUSER) < 0)
5078 return -errno;
5079
5080 if (root_fd >= 0) {
5081 if (fchdir(root_fd) < 0)
5082 return -errno;
5083
5084 if (chroot(".") < 0)
5085 return -errno;
5086 }
5087
5088 return reset_uid_gid();
5089 }
5090
5091 int getpeercred(int fd, struct ucred *ucred) {
5092 socklen_t n = sizeof(struct ucred);
5093 struct ucred u;
5094 int r;
5095
5096 assert(fd >= 0);
5097 assert(ucred);
5098
5099 r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
5100 if (r < 0)
5101 return -errno;
5102
5103 if (n != sizeof(struct ucred))
5104 return -EIO;
5105
5106 /* Check if the data is actually useful and not suppressed due
5107 * to namespacing issues */
5108 if (u.pid <= 0)
5109 return -ENODATA;
5110 if (u.uid == UID_INVALID)
5111 return -ENODATA;
5112 if (u.gid == GID_INVALID)
5113 return -ENODATA;
5114
5115 *ucred = u;
5116 return 0;
5117 }
5118
5119 int getpeersec(int fd, char **ret) {
5120 socklen_t n = 64;
5121 char *s;
5122 int r;
5123
5124 assert(fd >= 0);
5125 assert(ret);
5126
5127 s = new0(char, n);
5128 if (!s)
5129 return -ENOMEM;
5130
5131 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
5132 if (r < 0) {
5133 free(s);
5134
5135 if (errno != ERANGE)
5136 return -errno;
5137
5138 s = new0(char, n);
5139 if (!s)
5140 return -ENOMEM;
5141
5142 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
5143 if (r < 0) {
5144 free(s);
5145 return -errno;
5146 }
5147 }
5148
5149 if (isempty(s)) {
5150 free(s);
5151 return -EOPNOTSUPP;
5152 }
5153
5154 *ret = s;
5155 return 0;
5156 }
5157
5158 /* This is much like like mkostemp() but is subject to umask(). */
5159 int mkostemp_safe(char *pattern, int flags) {
5160 _cleanup_umask_ mode_t u;
5161 int fd;
5162
5163 assert(pattern);
5164
5165 u = umask(077);
5166
5167 fd = mkostemp(pattern, flags);
5168 if (fd < 0)
5169 return -errno;
5170
5171 return fd;
5172 }
5173
5174 int open_tmpfile(const char *path, int flags) {
5175 char *p;
5176 int fd;
5177
5178 assert(path);
5179
5180 #ifdef O_TMPFILE
5181 /* Try O_TMPFILE first, if it is supported */
5182 fd = open(path, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
5183 if (fd >= 0)
5184 return fd;
5185 #endif
5186
5187 /* Fall back to unguessable name + unlinking */
5188 p = strjoina(path, "/systemd-tmp-XXXXXX");
5189
5190 fd = mkostemp_safe(p, flags);
5191 if (fd < 0)
5192 return fd;
5193
5194 unlink(p);
5195 return fd;
5196 }
5197
5198 int fd_warn_permissions(const char *path, int fd) {
5199 struct stat st;
5200
5201 if (fstat(fd, &st) < 0)
5202 return -errno;
5203
5204 if (st.st_mode & 0111)
5205 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
5206
5207 if (st.st_mode & 0002)
5208 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
5209
5210 if (getpid() == 1 && (st.st_mode & 0044) != 0044)
5211 log_warning("Configuration file %s is marked world-inaccessible. This has no effect as configuration data is accessible via APIs without restrictions. Proceeding anyway.", path);
5212
5213 return 0;
5214 }
5215
5216 unsigned long personality_from_string(const char *p) {
5217
5218 /* Parse a personality specifier. We introduce our own
5219 * identifiers that indicate specific ABIs, rather than just
5220 * hints regarding the register size, since we want to keep
5221 * things open for multiple locally supported ABIs for the
5222 * same register size. We try to reuse the ABI identifiers
5223 * used by libseccomp. */
5224
5225 #if defined(__x86_64__)
5226
5227 if (streq(p, "x86"))
5228 return PER_LINUX32;
5229
5230 if (streq(p, "x86-64"))
5231 return PER_LINUX;
5232
5233 #elif defined(__i386__)
5234
5235 if (streq(p, "x86"))
5236 return PER_LINUX;
5237
5238 #elif defined(__s390x__)
5239
5240 if (streq(p, "s390"))
5241 return PER_LINUX32;
5242
5243 if (streq(p, "s390x"))
5244 return PER_LINUX;
5245
5246 #elif defined(__s390__)
5247
5248 if (streq(p, "s390"))
5249 return PER_LINUX;
5250 #endif
5251
5252 return PERSONALITY_INVALID;
5253 }
5254
5255 const char* personality_to_string(unsigned long p) {
5256
5257 #if defined(__x86_64__)
5258
5259 if (p == PER_LINUX32)
5260 return "x86";
5261
5262 if (p == PER_LINUX)
5263 return "x86-64";
5264
5265 #elif defined(__i386__)
5266
5267 if (p == PER_LINUX)
5268 return "x86";
5269
5270 #elif defined(__s390x__)
5271
5272 if (p == PER_LINUX)
5273 return "s390x";
5274
5275 if (p == PER_LINUX32)
5276 return "s390";
5277
5278 #elif defined(__s390__)
5279
5280 if (p == PER_LINUX)
5281 return "s390";
5282
5283 #endif
5284
5285 return NULL;
5286 }
5287
5288 uint64_t physical_memory(void) {
5289 long mem;
5290
5291 /* We return this as uint64_t in case we are running as 32bit
5292 * process on a 64bit kernel with huge amounts of memory */
5293
5294 mem = sysconf(_SC_PHYS_PAGES);
5295 assert(mem > 0);
5296
5297 return (uint64_t) mem * (uint64_t) page_size();
5298 }
5299
5300 void hexdump(FILE *f, const void *p, size_t s) {
5301 const uint8_t *b = p;
5302 unsigned n = 0;
5303
5304 assert(s == 0 || b);
5305
5306 while (s > 0) {
5307 size_t i;
5308
5309 fprintf(f, "%04x ", n);
5310
5311 for (i = 0; i < 16; i++) {
5312
5313 if (i >= s)
5314 fputs(" ", f);
5315 else
5316 fprintf(f, "%02x ", b[i]);
5317
5318 if (i == 7)
5319 fputc(' ', f);
5320 }
5321
5322 fputc(' ', f);
5323
5324 for (i = 0; i < 16; i++) {
5325
5326 if (i >= s)
5327 fputc(' ', f);
5328 else
5329 fputc(isprint(b[i]) ? (char) b[i] : '.', f);
5330 }
5331
5332 fputc('\n', f);
5333
5334 if (s < 16)
5335 break;
5336
5337 n += 16;
5338 b += 16;
5339 s -= 16;
5340 }
5341 }
5342
5343 int update_reboot_param_file(const char *param) {
5344 int r = 0;
5345
5346 if (param) {
5347 r = write_string_file(REBOOT_PARAM_FILE, param, WRITE_STRING_FILE_CREATE);
5348 if (r < 0)
5349 return log_error_errno(r, "Failed to write reboot param to "REBOOT_PARAM_FILE": %m");
5350 } else
5351 (void) unlink(REBOOT_PARAM_FILE);
5352
5353 return 0;
5354 }
5355
5356 int umount_recursive(const char *prefix, int flags) {
5357 bool again;
5358 int n = 0, r;
5359
5360 /* Try to umount everything recursively below a
5361 * directory. Also, take care of stacked mounts, and keep
5362 * unmounting them until they are gone. */
5363
5364 do {
5365 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
5366
5367 again = false;
5368 r = 0;
5369
5370 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
5371 if (!proc_self_mountinfo)
5372 return -errno;
5373
5374 for (;;) {
5375 _cleanup_free_ char *path = NULL, *p = NULL;
5376 int k;
5377
5378 k = fscanf(proc_self_mountinfo,
5379 "%*s " /* (1) mount id */
5380 "%*s " /* (2) parent id */
5381 "%*s " /* (3) major:minor */
5382 "%*s " /* (4) root */
5383 "%ms " /* (5) mount point */
5384 "%*s" /* (6) mount options */
5385 "%*[^-]" /* (7) optional fields */
5386 "- " /* (8) separator */
5387 "%*s " /* (9) file system type */
5388 "%*s" /* (10) mount source */
5389 "%*s" /* (11) mount options 2 */
5390 "%*[^\n]", /* some rubbish at the end */
5391 &path);
5392 if (k != 1) {
5393 if (k == EOF)
5394 break;
5395
5396 continue;
5397 }
5398
5399 r = cunescape(path, UNESCAPE_RELAX, &p);
5400 if (r < 0)
5401 return r;
5402
5403 if (!path_startswith(p, prefix))
5404 continue;
5405
5406 if (umount2(p, flags) < 0) {
5407 r = -errno;
5408 continue;
5409 }
5410
5411 again = true;
5412 n++;
5413
5414 break;
5415 }
5416
5417 } while (again);
5418
5419 return r ? r : n;
5420 }
5421
5422 static int get_mount_flags(const char *path, unsigned long *flags) {
5423 struct statvfs buf;
5424
5425 if (statvfs(path, &buf) < 0)
5426 return -errno;
5427 *flags = buf.f_flag;
5428 return 0;
5429 }
5430
5431 int bind_remount_recursive(const char *prefix, bool ro) {
5432 _cleanup_set_free_free_ Set *done = NULL;
5433 _cleanup_free_ char *cleaned = NULL;
5434 int r;
5435
5436 /* Recursively remount a directory (and all its submounts)
5437 * read-only or read-write. If the directory is already
5438 * mounted, we reuse the mount and simply mark it
5439 * MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write
5440 * operation). If it isn't we first make it one. Afterwards we
5441 * apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to all
5442 * submounts we can access, too. When mounts are stacked on
5443 * the same mount point we only care for each individual
5444 * "top-level" mount on each point, as we cannot
5445 * influence/access the underlying mounts anyway. We do not
5446 * have any effect on future submounts that might get
5447 * propagated, they migt be writable. This includes future
5448 * submounts that have been triggered via autofs. */
5449
5450 cleaned = strdup(prefix);
5451 if (!cleaned)
5452 return -ENOMEM;
5453
5454 path_kill_slashes(cleaned);
5455
5456 done = set_new(&string_hash_ops);
5457 if (!done)
5458 return -ENOMEM;
5459
5460 for (;;) {
5461 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
5462 _cleanup_set_free_free_ Set *todo = NULL;
5463 bool top_autofs = false;
5464 char *x;
5465 unsigned long orig_flags;
5466
5467 todo = set_new(&string_hash_ops);
5468 if (!todo)
5469 return -ENOMEM;
5470
5471 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
5472 if (!proc_self_mountinfo)
5473 return -errno;
5474
5475 for (;;) {
5476 _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
5477 int k;
5478
5479 k = fscanf(proc_self_mountinfo,
5480 "%*s " /* (1) mount id */
5481 "%*s " /* (2) parent id */
5482 "%*s " /* (3) major:minor */
5483 "%*s " /* (4) root */
5484 "%ms " /* (5) mount point */
5485 "%*s" /* (6) mount options (superblock) */
5486 "%*[^-]" /* (7) optional fields */
5487 "- " /* (8) separator */
5488 "%ms " /* (9) file system type */
5489 "%*s" /* (10) mount source */
5490 "%*s" /* (11) mount options (bind mount) */
5491 "%*[^\n]", /* some rubbish at the end */
5492 &path,
5493 &type);
5494 if (k != 2) {
5495 if (k == EOF)
5496 break;
5497
5498 continue;
5499 }
5500
5501 r = cunescape(path, UNESCAPE_RELAX, &p);
5502 if (r < 0)
5503 return r;
5504
5505 /* Let's ignore autofs mounts. If they aren't
5506 * triggered yet, we want to avoid triggering
5507 * them, as we don't make any guarantees for
5508 * future submounts anyway. If they are
5509 * already triggered, then we will find
5510 * another entry for this. */
5511 if (streq(type, "autofs")) {
5512 top_autofs = top_autofs || path_equal(cleaned, p);
5513 continue;
5514 }
5515
5516 if (path_startswith(p, cleaned) &&
5517 !set_contains(done, p)) {
5518
5519 r = set_consume(todo, p);
5520 p = NULL;
5521
5522 if (r == -EEXIST)
5523 continue;
5524 if (r < 0)
5525 return r;
5526 }
5527 }
5528
5529 /* If we have no submounts to process anymore and if
5530 * the root is either already done, or an autofs, we
5531 * are done */
5532 if (set_isempty(todo) &&
5533 (top_autofs || set_contains(done, cleaned)))
5534 return 0;
5535
5536 if (!set_contains(done, cleaned) &&
5537 !set_contains(todo, cleaned)) {
5538 /* The prefix directory itself is not yet a
5539 * mount, make it one. */
5540 if (mount(cleaned, cleaned, NULL, MS_BIND|MS_REC, NULL) < 0)
5541 return -errno;
5542
5543 orig_flags = 0;
5544 (void) get_mount_flags(cleaned, &orig_flags);
5545 orig_flags &= ~MS_RDONLY;
5546
5547 if (mount(NULL, prefix, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0)
5548 return -errno;
5549
5550 x = strdup(cleaned);
5551 if (!x)
5552 return -ENOMEM;
5553
5554 r = set_consume(done, x);
5555 if (r < 0)
5556 return r;
5557 }
5558
5559 while ((x = set_steal_first(todo))) {
5560
5561 r = set_consume(done, x);
5562 if (r == -EEXIST || r == 0)
5563 continue;
5564 if (r < 0)
5565 return r;
5566
5567 /* Try to reuse the original flag set, but
5568 * don't care for errors, in case of
5569 * obstructed mounts */
5570 orig_flags = 0;
5571 (void) get_mount_flags(x, &orig_flags);
5572 orig_flags &= ~MS_RDONLY;
5573
5574 if (mount(NULL, x, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) {
5575
5576 /* Deal with mount points that are
5577 * obstructed by a later mount */
5578
5579 if (errno != ENOENT)
5580 return -errno;
5581 }
5582
5583 }
5584 }
5585 }
5586
5587 int fflush_and_check(FILE *f) {
5588 assert(f);
5589
5590 errno = 0;
5591 fflush(f);
5592
5593 if (ferror(f))
5594 return errno ? -errno : -EIO;
5595
5596 return 0;
5597 }
5598
5599 int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
5600 const char *fn;
5601 char *t;
5602
5603 assert(p);
5604 assert(ret);
5605
5606 /*
5607 * Turns this:
5608 * /foo/bar/waldo
5609 *
5610 * Into this:
5611 * /foo/bar/.#<extra>waldoXXXXXX
5612 */
5613
5614 fn = basename(p);
5615 if (!filename_is_valid(fn))
5616 return -EINVAL;
5617
5618 if (extra == NULL)
5619 extra = "";
5620
5621 t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
5622 if (!t)
5623 return -ENOMEM;
5624
5625 strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn), "XXXXXX");
5626
5627 *ret = path_kill_slashes(t);
5628 return 0;
5629 }
5630
5631 int tempfn_random(const char *p, const char *extra, char **ret) {
5632 const char *fn;
5633 char *t, *x;
5634 uint64_t u;
5635 unsigned i;
5636
5637 assert(p);
5638 assert(ret);
5639
5640 /*
5641 * Turns this:
5642 * /foo/bar/waldo
5643 *
5644 * Into this:
5645 * /foo/bar/.#<extra>waldobaa2a261115984a9
5646 */
5647
5648 fn = basename(p);
5649 if (!filename_is_valid(fn))
5650 return -EINVAL;
5651
5652 if (!extra)
5653 extra = "";
5654
5655 t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1);
5656 if (!t)
5657 return -ENOMEM;
5658
5659 x = stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn);
5660
5661 u = random_u64();
5662 for (i = 0; i < 16; i++) {
5663 *(x++) = hexchar(u & 0xF);
5664 u >>= 4;
5665 }
5666
5667 *x = 0;
5668
5669 *ret = path_kill_slashes(t);
5670 return 0;
5671 }
5672
5673 int tempfn_random_child(const char *p, const char *extra, char **ret) {
5674 char *t, *x;
5675 uint64_t u;
5676 unsigned i;
5677
5678 assert(p);
5679 assert(ret);
5680
5681 /* Turns this:
5682 * /foo/bar/waldo
5683 * Into this:
5684 * /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
5685 */
5686
5687 if (!extra)
5688 extra = "";
5689
5690 t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1);
5691 if (!t)
5692 return -ENOMEM;
5693
5694 x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra);
5695
5696 u = random_u64();
5697 for (i = 0; i < 16; i++) {
5698 *(x++) = hexchar(u & 0xF);
5699 u >>= 4;
5700 }
5701
5702 *x = 0;
5703
5704 *ret = path_kill_slashes(t);
5705 return 0;
5706 }
5707
5708 int take_password_lock(const char *root) {
5709
5710 struct flock flock = {
5711 .l_type = F_WRLCK,
5712 .l_whence = SEEK_SET,
5713 .l_start = 0,
5714 .l_len = 0,
5715 };
5716
5717 const char *path;
5718 int fd, r;
5719
5720 /* This is roughly the same as lckpwdf(), but not as awful. We
5721 * don't want to use alarm() and signals, hence we implement
5722 * our own trivial version of this.
5723 *
5724 * Note that shadow-utils also takes per-database locks in
5725 * addition to lckpwdf(). However, we don't given that they
5726 * are redundant as they they invoke lckpwdf() first and keep
5727 * it during everything they do. The per-database locks are
5728 * awfully racy, and thus we just won't do them. */
5729
5730 if (root)
5731 path = strjoina(root, "/etc/.pwd.lock");
5732 else
5733 path = "/etc/.pwd.lock";
5734
5735 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
5736 if (fd < 0)
5737 return -errno;
5738
5739 r = fcntl(fd, F_SETLKW, &flock);
5740 if (r < 0) {
5741 safe_close(fd);
5742 return -errno;
5743 }
5744
5745 return fd;
5746 }
5747
5748 int is_symlink(const char *path) {
5749 struct stat info;
5750
5751 if (lstat(path, &info) < 0)
5752 return -errno;
5753
5754 return !!S_ISLNK(info.st_mode);
5755 }
5756
5757 int is_dir(const char* path, bool follow) {
5758 struct stat st;
5759 int r;
5760
5761 if (follow)
5762 r = stat(path, &st);
5763 else
5764 r = lstat(path, &st);
5765 if (r < 0)
5766 return -errno;
5767
5768 return !!S_ISDIR(st.st_mode);
5769 }
5770
5771 int is_device_node(const char *path) {
5772 struct stat info;
5773
5774 if (lstat(path, &info) < 0)
5775 return -errno;
5776
5777 return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode));
5778 }
5779
5780 int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) {
5781 _cleanup_free_ char *s = NULL;
5782 size_t allocated = 0, sz = 0;
5783 int r;
5784
5785 enum {
5786 START,
5787 VALUE,
5788 VALUE_ESCAPE,
5789 SINGLE_QUOTE,
5790 SINGLE_QUOTE_ESCAPE,
5791 DOUBLE_QUOTE,
5792 DOUBLE_QUOTE_ESCAPE,
5793 SEPARATOR,
5794 } state = START;
5795
5796 assert(p);
5797 assert(ret);
5798
5799 if (!separators)
5800 separators = WHITESPACE;
5801
5802 /* Bail early if called after last value or with no input */
5803 if (!*p)
5804 goto finish_force_terminate;
5805
5806 /* Parses the first word of a string, and returns it in
5807 * *ret. Removes all quotes in the process. When parsing fails
5808 * (because of an uneven number of quotes or similar), leaves
5809 * the pointer *p at the first invalid character. */
5810
5811 for (;;) {
5812 char c = **p;
5813
5814 switch (state) {
5815
5816 case START:
5817 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
5818 if (!GREEDY_REALLOC(s, allocated, sz+1))
5819 return -ENOMEM;
5820
5821 if (c == 0)
5822 goto finish_force_terminate;
5823 else if (strchr(separators, c)) {
5824 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
5825 (*p) ++;
5826 goto finish_force_next;
5827 }
5828 break;
5829 }
5830
5831 /* We found a non-blank character, so we will always
5832 * want to return a string (even if it is empty),
5833 * allocate it here. */
5834 if (!GREEDY_REALLOC(s, allocated, sz+1))
5835 return -ENOMEM;
5836
5837 state = VALUE;
5838 /* fallthrough */
5839
5840 case VALUE:
5841 if (c == 0)
5842 goto finish_force_terminate;
5843 else if (c == '\'' && (flags & EXTRACT_QUOTES))
5844 state = SINGLE_QUOTE;
5845 else if (c == '\\')
5846 state = VALUE_ESCAPE;
5847 else if (c == '\"' && (flags & EXTRACT_QUOTES))
5848 state = DOUBLE_QUOTE;
5849 else if (strchr(separators, c)) {
5850 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
5851 (*p) ++;
5852 goto finish_force_next;
5853 }
5854 state = SEPARATOR;
5855 } else {
5856 if (!GREEDY_REALLOC(s, allocated, sz+2))
5857 return -ENOMEM;
5858
5859 s[sz++] = c;
5860 }
5861
5862 break;
5863
5864 case SINGLE_QUOTE:
5865 if (c == 0) {
5866 if (flags & EXTRACT_RELAX)
5867 goto finish_force_terminate;
5868 return -EINVAL;
5869 } else if (c == '\'')
5870 state = VALUE;
5871 else if (c == '\\')
5872 state = SINGLE_QUOTE_ESCAPE;
5873 else {
5874 if (!GREEDY_REALLOC(s, allocated, sz+2))
5875 return -ENOMEM;
5876
5877 s[sz++] = c;
5878 }
5879
5880 break;
5881
5882 case DOUBLE_QUOTE:
5883 if (c == 0)
5884 return -EINVAL;
5885 else if (c == '\"')
5886 state = VALUE;
5887 else if (c == '\\')
5888 state = DOUBLE_QUOTE_ESCAPE;
5889 else {
5890 if (!GREEDY_REALLOC(s, allocated, sz+2))
5891 return -ENOMEM;
5892
5893 s[sz++] = c;
5894 }
5895
5896 break;
5897
5898 case SINGLE_QUOTE_ESCAPE:
5899 case DOUBLE_QUOTE_ESCAPE:
5900 case VALUE_ESCAPE:
5901 if (!GREEDY_REALLOC(s, allocated, sz+7))
5902 return -ENOMEM;
5903
5904 if (c == 0) {
5905 if ((flags & EXTRACT_CUNESCAPE_RELAX) &&
5906 (state == VALUE_ESCAPE || flags & EXTRACT_RELAX)) {
5907 /* If we find an unquoted trailing backslash and we're in
5908 * EXTRACT_CUNESCAPE_RELAX mode, keep it verbatim in the
5909 * output.
5910 *
5911 * Unbalanced quotes will only be allowed in EXTRACT_RELAX
5912 * mode, EXTRACT_CUNESCAPE_RELAX mode does not allow them.
5913 */
5914 s[sz++] = '\\';
5915 goto finish_force_terminate;
5916 }
5917 if (flags & EXTRACT_RELAX)
5918 goto finish_force_terminate;
5919 return -EINVAL;
5920 }
5921
5922 if (flags & EXTRACT_CUNESCAPE) {
5923 uint32_t u;
5924
5925 r = cunescape_one(*p, (size_t) -1, &c, &u);
5926 if (r < 0) {
5927 if (flags & EXTRACT_CUNESCAPE_RELAX) {
5928 s[sz++] = '\\';
5929 s[sz++] = c;
5930 goto end_escape;
5931 }
5932 return -EINVAL;
5933 }
5934
5935 (*p) += r - 1;
5936
5937 if (c != 0)
5938 s[sz++] = c; /* normal explicit char */
5939 else
5940 sz += utf8_encode_unichar(s + sz, u); /* unicode chars we'll encode as utf8 */
5941 } else
5942 s[sz++] = c;
5943
5944 end_escape:
5945 state = (state == SINGLE_QUOTE_ESCAPE) ? SINGLE_QUOTE :
5946 (state == DOUBLE_QUOTE_ESCAPE) ? DOUBLE_QUOTE :
5947 VALUE;
5948 break;
5949
5950 case SEPARATOR:
5951 if (c == 0)
5952 goto finish_force_terminate;
5953 if (!strchr(separators, c))
5954 goto finish;
5955 break;
5956 }
5957
5958 (*p) ++;
5959 }
5960
5961 finish_force_terminate:
5962 *p = NULL;
5963 finish:
5964 if (!s) {
5965 *p = NULL;
5966 *ret = NULL;
5967 return 0;
5968 }
5969
5970 finish_force_next:
5971 s[sz] = 0;
5972 *ret = s;
5973 s = NULL;
5974
5975 return 1;
5976 }
5977
5978 int extract_first_word_and_warn(
5979 const char **p,
5980 char **ret,
5981 const char *separators,
5982 ExtractFlags flags,
5983 const char *unit,
5984 const char *filename,
5985 unsigned line,
5986 const char *rvalue) {
5987
5988 /* Try to unquote it, if it fails, warn about it and try again but this
5989 * time using EXTRACT_CUNESCAPE_RELAX to keep the backslashes verbatim
5990 * in invalid escape sequences. */
5991 const char *save;
5992 int r;
5993
5994 save = *p;
5995 r = extract_first_word(p, ret, separators, flags);
5996 if (r < 0 && !(flags & EXTRACT_CUNESCAPE_RELAX)) {
5997
5998 /* Retry it with EXTRACT_CUNESCAPE_RELAX. */
5999 *p = save;
6000 r = extract_first_word(p, ret, separators, flags|EXTRACT_CUNESCAPE_RELAX);
6001 if (r < 0)
6002 log_syntax(unit, LOG_ERR, filename, line, r, "Unbalanced quoting in command line, ignoring: \"%s\"", rvalue);
6003 else
6004 log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid escape sequences in command line: \"%s\"", rvalue);
6005 }
6006
6007 return r;
6008 }
6009
6010 int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) {
6011 va_list ap;
6012 char **l;
6013 int n = 0, i, c, r;
6014
6015 /* Parses a number of words from a string, stripping any
6016 * quotes if necessary. */
6017
6018 assert(p);
6019
6020 /* Count how many words are expected */
6021 va_start(ap, flags);
6022 for (;;) {
6023 if (!va_arg(ap, char **))
6024 break;
6025 n++;
6026 }
6027 va_end(ap);
6028
6029 if (n <= 0)
6030 return 0;
6031
6032 /* Read all words into a temporary array */
6033 l = newa0(char*, n);
6034 for (c = 0; c < n; c++) {
6035
6036 r = extract_first_word(p, &l[c], separators, flags);
6037 if (r < 0) {
6038 int j;
6039
6040 for (j = 0; j < c; j++)
6041 free(l[j]);
6042
6043 return r;
6044 }
6045
6046 if (r == 0)
6047 break;
6048 }
6049
6050 /* If we managed to parse all words, return them in the passed
6051 * in parameters */
6052 va_start(ap, flags);
6053 for (i = 0; i < n; i++) {
6054 char **v;
6055
6056 v = va_arg(ap, char **);
6057 assert(v);
6058
6059 *v = l[i];
6060 }
6061 va_end(ap);
6062
6063 return c;
6064 }
6065
6066 int free_and_strdup(char **p, const char *s) {
6067 char *t;
6068
6069 assert(p);
6070
6071 /* Replaces a string pointer with an strdup()ed new string,
6072 * possibly freeing the old one. */
6073
6074 if (streq_ptr(*p, s))
6075 return 0;
6076
6077 if (s) {
6078 t = strdup(s);
6079 if (!t)
6080 return -ENOMEM;
6081 } else
6082 t = NULL;
6083
6084 free(*p);
6085 *p = t;
6086
6087 return 1;
6088 }
6089
6090 int ptsname_malloc(int fd, char **ret) {
6091 size_t l = 100;
6092
6093 assert(fd >= 0);
6094 assert(ret);
6095
6096 for (;;) {
6097 char *c;
6098
6099 c = new(char, l);
6100 if (!c)
6101 return -ENOMEM;
6102
6103 if (ptsname_r(fd, c, l) == 0) {
6104 *ret = c;
6105 return 0;
6106 }
6107 if (errno != ERANGE) {
6108 free(c);
6109 return -errno;
6110 }
6111
6112 free(c);
6113 l *= 2;
6114 }
6115 }
6116
6117 int openpt_in_namespace(pid_t pid, int flags) {
6118 _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1;
6119 _cleanup_close_pair_ int pair[2] = { -1, -1 };
6120 siginfo_t si;
6121 pid_t child;
6122 int r;
6123
6124 assert(pid > 0);
6125
6126 r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &usernsfd, &rootfd);
6127 if (r < 0)
6128 return r;
6129
6130 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
6131 return -errno;
6132
6133 child = fork();
6134 if (child < 0)
6135 return -errno;
6136
6137 if (child == 0) {
6138 int master;
6139
6140 pair[0] = safe_close(pair[0]);
6141
6142 r = namespace_enter(pidnsfd, mntnsfd, -1, usernsfd, rootfd);
6143 if (r < 0)
6144 _exit(EXIT_FAILURE);
6145
6146 master = posix_openpt(flags);
6147 if (master < 0)
6148 _exit(EXIT_FAILURE);
6149
6150 if (unlockpt(master) < 0)
6151 _exit(EXIT_FAILURE);
6152
6153 if (send_one_fd(pair[1], master, 0) < 0)
6154 _exit(EXIT_FAILURE);
6155
6156 _exit(EXIT_SUCCESS);
6157 }
6158
6159 pair[1] = safe_close(pair[1]);
6160
6161 r = wait_for_terminate(child, &si);
6162 if (r < 0)
6163 return r;
6164 if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
6165 return -EIO;
6166
6167 return receive_one_fd(pair[0], 0);
6168 }
6169
6170 ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) {
6171 char fn[strlen("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1];
6172 _cleanup_close_ int fd = -1;
6173 ssize_t l;
6174
6175 /* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */
6176
6177 fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
6178 if (fd < 0)
6179 return -errno;
6180
6181 xsprintf(fn, "/proc/self/fd/%i", fd);
6182
6183 l = getxattr(fn, attribute, value, size);
6184 if (l < 0)
6185 return -errno;
6186
6187 return l;
6188 }
6189
6190 static int parse_crtime(le64_t le, usec_t *usec) {
6191 uint64_t u;
6192
6193 assert(usec);
6194
6195 u = le64toh(le);
6196 if (u == 0 || u == (uint64_t) -1)
6197 return -EIO;
6198
6199 *usec = (usec_t) u;
6200 return 0;
6201 }
6202
6203 int fd_getcrtime(int fd, usec_t *usec) {
6204 le64_t le;
6205 ssize_t n;
6206
6207 assert(fd >= 0);
6208 assert(usec);
6209
6210 /* Until Linux gets a real concept of birthtime/creation time,
6211 * let's fake one with xattrs */
6212
6213 n = fgetxattr(fd, "user.crtime_usec", &le, sizeof(le));
6214 if (n < 0)
6215 return -errno;
6216 if (n != sizeof(le))
6217 return -EIO;
6218
6219 return parse_crtime(le, usec);
6220 }
6221
6222 int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags) {
6223 le64_t le;
6224 ssize_t n;
6225
6226 n = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags);
6227 if (n < 0)
6228 return -errno;
6229 if (n != sizeof(le))
6230 return -EIO;
6231
6232 return parse_crtime(le, usec);
6233 }
6234
6235 int path_getcrtime(const char *p, usec_t *usec) {
6236 le64_t le;
6237 ssize_t n;
6238
6239 assert(p);
6240 assert(usec);
6241
6242 n = getxattr(p, "user.crtime_usec", &le, sizeof(le));
6243 if (n < 0)
6244 return -errno;
6245 if (n != sizeof(le))
6246 return -EIO;
6247
6248 return parse_crtime(le, usec);
6249 }
6250
6251 int fd_setcrtime(int fd, usec_t usec) {
6252 le64_t le;
6253
6254 assert(fd >= 0);
6255
6256 if (usec <= 0)
6257 usec = now(CLOCK_REALTIME);
6258
6259 le = htole64((uint64_t) usec);
6260 if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), 0) < 0)
6261 return -errno;
6262
6263 return 0;
6264 }
6265
6266 int same_fd(int a, int b) {
6267 struct stat sta, stb;
6268 pid_t pid;
6269 int r, fa, fb;
6270
6271 assert(a >= 0);
6272 assert(b >= 0);
6273
6274 /* Compares two file descriptors. Note that semantics are
6275 * quite different depending on whether we have kcmp() or we
6276 * don't. If we have kcmp() this will only return true for
6277 * dup()ed file descriptors, but not otherwise. If we don't
6278 * have kcmp() this will also return true for two fds of the same
6279 * file, created by separate open() calls. Since we use this
6280 * call mostly for filtering out duplicates in the fd store
6281 * this difference hopefully doesn't matter too much. */
6282
6283 if (a == b)
6284 return true;
6285
6286 /* Try to use kcmp() if we have it. */
6287 pid = getpid();
6288 r = kcmp(pid, pid, KCMP_FILE, a, b);
6289 if (r == 0)
6290 return true;
6291 if (r > 0)
6292 return false;
6293 if (errno != ENOSYS)
6294 return -errno;
6295
6296 /* We don't have kcmp(), use fstat() instead. */
6297 if (fstat(a, &sta) < 0)
6298 return -errno;
6299
6300 if (fstat(b, &stb) < 0)
6301 return -errno;
6302
6303 if ((sta.st_mode & S_IFMT) != (stb.st_mode & S_IFMT))
6304 return false;
6305
6306 /* We consider all device fds different, since two device fds
6307 * might refer to quite different device contexts even though
6308 * they share the same inode and backing dev_t. */
6309
6310 if (S_ISCHR(sta.st_mode) || S_ISBLK(sta.st_mode))
6311 return false;
6312
6313 if (sta.st_dev != stb.st_dev || sta.st_ino != stb.st_ino)
6314 return false;
6315
6316 /* The fds refer to the same inode on disk, let's also check
6317 * if they have the same fd flags. This is useful to
6318 * distinguish the read and write side of a pipe created with
6319 * pipe(). */
6320 fa = fcntl(a, F_GETFL);
6321 if (fa < 0)
6322 return -errno;
6323
6324 fb = fcntl(b, F_GETFL);
6325 if (fb < 0)
6326 return -errno;
6327
6328 return fa == fb;
6329 }
6330
6331 int chattr_fd(int fd, unsigned value, unsigned mask) {
6332 unsigned old_attr, new_attr;
6333 struct stat st;
6334
6335 assert(fd >= 0);
6336
6337 if (fstat(fd, &st) < 0)
6338 return -errno;
6339
6340 /* Explicitly check whether this is a regular file or
6341 * directory. If it is anything else (such as a device node or
6342 * fifo), then the ioctl will not hit the file systems but
6343 * possibly drivers, where the ioctl might have different
6344 * effects. Notably, DRM is using the same ioctl() number. */
6345
6346 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
6347 return -ENOTTY;
6348
6349 if (mask == 0)
6350 return 0;
6351
6352 if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
6353 return -errno;
6354
6355 new_attr = (old_attr & ~mask) | (value & mask);
6356 if (new_attr == old_attr)
6357 return 0;
6358
6359 if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
6360 return -errno;
6361
6362 return 1;
6363 }
6364
6365 int chattr_path(const char *p, unsigned value, unsigned mask) {
6366 _cleanup_close_ int fd = -1;
6367
6368 assert(p);
6369
6370 if (mask == 0)
6371 return 0;
6372
6373 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
6374 if (fd < 0)
6375 return -errno;
6376
6377 return chattr_fd(fd, value, mask);
6378 }
6379
6380 int read_attr_fd(int fd, unsigned *ret) {
6381 struct stat st;
6382
6383 assert(fd >= 0);
6384
6385 if (fstat(fd, &st) < 0)
6386 return -errno;
6387
6388 if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
6389 return -ENOTTY;
6390
6391 if (ioctl(fd, FS_IOC_GETFLAGS, ret) < 0)
6392 return -errno;
6393
6394 return 0;
6395 }
6396
6397 int read_attr_path(const char *p, unsigned *ret) {
6398 _cleanup_close_ int fd = -1;
6399
6400 assert(p);
6401 assert(ret);
6402
6403 fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
6404 if (fd < 0)
6405 return -errno;
6406
6407 return read_attr_fd(fd, ret);
6408 }
6409
6410 static size_t nul_length(const uint8_t *p, size_t sz) {
6411 size_t n = 0;
6412
6413 while (sz > 0) {
6414 if (*p != 0)
6415 break;
6416
6417 n++;
6418 p++;
6419 sz--;
6420 }
6421
6422 return n;
6423 }
6424
6425 ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
6426 const uint8_t *q, *w, *e;
6427 ssize_t l;
6428
6429 q = w = p;
6430 e = q + sz;
6431 while (q < e) {
6432 size_t n;
6433
6434 n = nul_length(q, e - q);
6435
6436 /* If there are more than the specified run length of
6437 * NUL bytes, or if this is the beginning or the end
6438 * of the buffer, then seek instead of write */
6439 if ((n > run_length) ||
6440 (n > 0 && q == p) ||
6441 (n > 0 && q + n >= e)) {
6442 if (q > w) {
6443 l = write(fd, w, q - w);
6444 if (l < 0)
6445 return -errno;
6446 if (l != q -w)
6447 return -EIO;
6448 }
6449
6450 if (lseek(fd, n, SEEK_CUR) == (off_t) -1)
6451 return -errno;
6452
6453 q += n;
6454 w = q;
6455 } else if (n > 0)
6456 q += n;
6457 else
6458 q ++;
6459 }
6460
6461 if (q > w) {
6462 l = write(fd, w, q - w);
6463 if (l < 0)
6464 return -errno;
6465 if (l != q - w)
6466 return -EIO;
6467 }
6468
6469 return q - (const uint8_t*) p;
6470 }
6471
6472 void sigkill_wait(pid_t *pid) {
6473 if (!pid)
6474 return;
6475 if (*pid <= 1)
6476 return;
6477
6478 if (kill(*pid, SIGKILL) > 0)
6479 (void) wait_for_terminate(*pid, NULL);
6480 }
6481
6482 int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
6483 int a = 0, b = 0, c = 0;
6484 int k;
6485
6486 assert(p);
6487 assert(*p);
6488 assert(priority);
6489
6490 if ((*p)[0] != '<')
6491 return 0;
6492
6493 if (!strchr(*p, '>'))
6494 return 0;
6495
6496 if ((*p)[2] == '>') {
6497 c = undecchar((*p)[1]);
6498 k = 3;
6499 } else if ((*p)[3] == '>') {
6500 b = undecchar((*p)[1]);
6501 c = undecchar((*p)[2]);
6502 k = 4;
6503 } else if ((*p)[4] == '>') {
6504 a = undecchar((*p)[1]);
6505 b = undecchar((*p)[2]);
6506 c = undecchar((*p)[3]);
6507 k = 5;
6508 } else
6509 return 0;
6510
6511 if (a < 0 || b < 0 || c < 0 ||
6512 (!with_facility && (a || b || c > 7)))
6513 return 0;
6514
6515 if (with_facility)
6516 *priority = a*100 + b*10 + c;
6517 else
6518 *priority = (*priority & LOG_FACMASK) | c;
6519
6520 *p += k;
6521 return 1;
6522 }
6523
6524 ssize_t string_table_lookup(const char * const *table, size_t len, const char *key) {
6525 size_t i;
6526
6527 if (!key)
6528 return -1;
6529
6530 for (i = 0; i < len; ++i)
6531 if (streq_ptr(table[i], key))
6532 return (ssize_t) i;
6533
6534 return -1;
6535 }
6536
6537 void cmsg_close_all(struct msghdr *mh) {
6538 struct cmsghdr *cmsg;
6539
6540 assert(mh);
6541
6542 CMSG_FOREACH(cmsg, mh)
6543 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
6544 close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int));
6545 }
6546
6547 int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
6548 struct stat buf;
6549 int ret;
6550
6551 ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
6552 if (ret >= 0)
6553 return 0;
6554
6555 /* renameat2() exists since Linux 3.15, btrfs added support for it later.
6556 * If it is not implemented, fallback to another method. */
6557 if (!IN_SET(errno, EINVAL, ENOSYS))
6558 return -errno;
6559
6560 /* The link()/unlink() fallback does not work on directories. But
6561 * renameat() without RENAME_NOREPLACE gives the same semantics on
6562 * directories, except when newpath is an *empty* directory. This is
6563 * good enough. */
6564 ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW);
6565 if (ret >= 0 && S_ISDIR(buf.st_mode)) {
6566 ret = renameat(olddirfd, oldpath, newdirfd, newpath);
6567 return ret >= 0 ? 0 : -errno;
6568 }
6569
6570 /* If it is not a directory, use the link()/unlink() fallback. */
6571 ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0);
6572 if (ret < 0)
6573 return -errno;
6574
6575 ret = unlinkat(olddirfd, oldpath, 0);
6576 if (ret < 0) {
6577 /* backup errno before the following unlinkat() alters it */
6578 ret = errno;
6579 (void) unlinkat(newdirfd, newpath, 0);
6580 errno = ret;
6581 return -errno;
6582 }
6583
6584 return 0;
6585 }
6586
6587 static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad) {
6588 assert(bad);
6589
6590 for (; *s; s++) {
6591 if (*s == '\\' || strchr(bad, *s))
6592 *(t++) = '\\';
6593
6594 *(t++) = *s;
6595 }
6596
6597 return t;
6598 }
6599
6600 char *shell_escape(const char *s, const char *bad) {
6601 char *r, *t;
6602
6603 r = new(char, strlen(s)*2+1);
6604 if (!r)
6605 return NULL;
6606
6607 t = strcpy_backslash_escaped(r, s, bad);
6608 *t = 0;
6609
6610 return r;
6611 }
6612
6613 char *shell_maybe_quote(const char *s) {
6614 const char *p;
6615 char *r, *t;
6616
6617 assert(s);
6618
6619 /* Encloses a string in double quotes if necessary to make it
6620 * OK as shell string. */
6621
6622 for (p = s; *p; p++)
6623 if (*p <= ' ' ||
6624 *p >= 127 ||
6625 strchr(SHELL_NEED_QUOTES, *p))
6626 break;
6627
6628 if (!*p)
6629 return strdup(s);
6630
6631 r = new(char, 1+strlen(s)*2+1+1);
6632 if (!r)
6633 return NULL;
6634
6635 t = r;
6636 *(t++) = '"';
6637 t = mempcpy(t, s, p - s);
6638
6639 t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE);
6640
6641 *(t++)= '"';
6642 *t = 0;
6643
6644 return r;
6645 }
6646
6647 int parse_mode(const char *s, mode_t *ret) {
6648 char *x;
6649 long l;
6650
6651 assert(s);
6652 assert(ret);
6653
6654 errno = 0;
6655 l = strtol(s, &x, 8);
6656 if (errno != 0)
6657 return -errno;
6658
6659 if (!x || x == s || *x)
6660 return -EINVAL;
6661 if (l < 0 || l > 07777)
6662 return -ERANGE;
6663
6664 *ret = (mode_t) l;
6665 return 0;
6666 }
6667
6668 int mount_move_root(const char *path) {
6669 assert(path);
6670
6671 if (chdir(path) < 0)
6672 return -errno;
6673
6674 if (mount(path, "/", NULL, MS_MOVE, NULL) < 0)
6675 return -errno;
6676
6677 if (chroot(".") < 0)
6678 return -errno;
6679
6680 if (chdir("/") < 0)
6681 return -errno;
6682
6683 return 0;
6684 }
6685
6686 int reset_uid_gid(void) {
6687
6688 if (setgroups(0, NULL) < 0)
6689 return -errno;
6690
6691 if (setresgid(0, 0, 0) < 0)
6692 return -errno;
6693
6694 if (setresuid(0, 0, 0) < 0)
6695 return -errno;
6696
6697 return 0;
6698 }
6699
6700 int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink) {
6701 char *v;
6702 size_t l;
6703 ssize_t n;
6704
6705 assert(path);
6706 assert(name);
6707 assert(value);
6708
6709 for (l = 100; ; l = (size_t) n + 1) {
6710 v = new0(char, l);
6711 if (!v)
6712 return -ENOMEM;
6713
6714 if (allow_symlink)
6715 n = lgetxattr(path, name, v, l);
6716 else
6717 n = getxattr(path, name, v, l);
6718
6719 if (n >= 0 && (size_t) n < l) {
6720 *value = v;
6721 return n;
6722 }
6723
6724 free(v);
6725
6726 if (n < 0 && errno != ERANGE)
6727 return -errno;
6728
6729 if (allow_symlink)
6730 n = lgetxattr(path, name, NULL, 0);
6731 else
6732 n = getxattr(path, name, NULL, 0);
6733 if (n < 0)
6734 return -errno;
6735 }
6736 }
6737
6738 int fgetxattr_malloc(int fd, const char *name, char **value) {
6739 char *v;
6740 size_t l;
6741 ssize_t n;
6742
6743 assert(fd >= 0);
6744 assert(name);
6745 assert(value);
6746
6747 for (l = 100; ; l = (size_t) n + 1) {
6748 v = new0(char, l);
6749 if (!v)
6750 return -ENOMEM;
6751
6752 n = fgetxattr(fd, name, v, l);
6753
6754 if (n >= 0 && (size_t) n < l) {
6755 *value = v;
6756 return n;
6757 }
6758
6759 free(v);
6760
6761 if (n < 0 && errno != ERANGE)
6762 return -errno;
6763
6764 n = fgetxattr(fd, name, NULL, 0);
6765 if (n < 0)
6766 return -errno;
6767 }
6768 }
6769
6770 int send_one_fd(int transport_fd, int fd, int flags) {
6771 union {
6772 struct cmsghdr cmsghdr;
6773 uint8_t buf[CMSG_SPACE(sizeof(int))];
6774 } control = {};
6775 struct msghdr mh = {
6776 .msg_control = &control,
6777 .msg_controllen = sizeof(control),
6778 };
6779 struct cmsghdr *cmsg;
6780
6781 assert(transport_fd >= 0);
6782 assert(fd >= 0);
6783
6784 cmsg = CMSG_FIRSTHDR(&mh);
6785 cmsg->cmsg_level = SOL_SOCKET;
6786 cmsg->cmsg_type = SCM_RIGHTS;
6787 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
6788 memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
6789
6790 mh.msg_controllen = CMSG_SPACE(sizeof(int));
6791 if (sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags) < 0)
6792 return -errno;
6793
6794 return 0;
6795 }
6796
6797 int receive_one_fd(int transport_fd, int flags) {
6798 union {
6799 struct cmsghdr cmsghdr;
6800 uint8_t buf[CMSG_SPACE(sizeof(int))];
6801 } control = {};
6802 struct msghdr mh = {
6803 .msg_control = &control,
6804 .msg_controllen = sizeof(control),
6805 };
6806 struct cmsghdr *cmsg, *found = NULL;
6807
6808 assert(transport_fd >= 0);
6809
6810 /*
6811 * Receive a single FD via @transport_fd. We don't care for
6812 * the transport-type. We retrieve a single FD at most, so for
6813 * packet-based transports, the caller must ensure to send
6814 * only a single FD per packet. This is best used in
6815 * combination with send_one_fd().
6816 */
6817
6818 if (recvmsg(transport_fd, &mh, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC | flags) < 0)
6819 return -errno;
6820
6821 CMSG_FOREACH(cmsg, &mh) {
6822 if (cmsg->cmsg_level == SOL_SOCKET &&
6823 cmsg->cmsg_type == SCM_RIGHTS &&
6824 cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
6825 assert(!found);
6826 found = cmsg;
6827 break;
6828 }
6829 }
6830
6831 if (!found) {
6832 cmsg_close_all(&mh);
6833 return -EIO;
6834 }
6835
6836 return *(int*) CMSG_DATA(found);
6837 }
6838
6839 void nop_signal_handler(int sig) {
6840 /* nothing here */
6841 }
6842
6843 int version(void) {
6844 puts(PACKAGE_STRING "\n"
6845 SYSTEMD_FEATURES);
6846 return 0;
6847 }