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