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