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