chiark / gitweb /
Cleaned up more unneeded functions and types in:
[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         while (nbytes > 0) {
2129                 ssize_t k;
2130
2131                 k = read(fd, p, nbytes);
2132                 if (k < 0) {
2133                         if (errno == EINTR)
2134                                 continue;
2135
2136                         if (errno == EAGAIN && do_poll) {
2137
2138                                 /* We knowingly ignore any return value here,
2139                                  * and expect that any error/EOF is reported
2140                                  * via read() */
2141
2142                                 fd_wait_for_event(fd, POLLIN, USEC_INFINITY);
2143                                 continue;
2144                         }
2145
2146                         return n > 0 ? n : -errno;
2147                 }
2148
2149                 if (k == 0)
2150                         return n;
2151
2152                 p += k;
2153                 nbytes -= k;
2154                 n += k;
2155         }
2156
2157         return n;
2158 }
2159
2160 int loop_read_exact(int fd, void *buf, size_t nbytes, bool do_poll) {
2161         ssize_t n;
2162
2163         n = loop_read(fd, buf, nbytes, do_poll);
2164         if (n < 0)
2165                 return n;
2166         if ((size_t) n != nbytes)
2167                 return -EIO;
2168         return 0;
2169 }
2170
2171 int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
2172         const uint8_t *p = buf;
2173
2174         assert(fd >= 0);
2175         assert(buf);
2176
2177         errno = 0;
2178
2179         do {
2180                 ssize_t k;
2181
2182                 k = write(fd, p, nbytes);
2183                 if (k < 0) {
2184                         if (errno == EINTR)
2185                                 continue;
2186
2187                         if (errno == EAGAIN && do_poll) {
2188                                 /* We knowingly ignore any return value here,
2189                                  * and expect that any error/EOF is reported
2190                                  * via write() */
2191
2192                                 fd_wait_for_event(fd, POLLOUT, USEC_INFINITY);
2193                                 continue;
2194                         }
2195
2196                         return -errno;
2197                 }
2198
2199                 if (nbytes > 0 && k == 0) /* Can't really happen */
2200                         return -EIO;
2201
2202                 p += k;
2203                 nbytes -= k;
2204         } while (nbytes > 0);
2205
2206         return 0;
2207 }
2208
2209 int parse_size(const char *t, off_t base, off_t *size) {
2210
2211         /* Soo, sometimes we want to parse IEC binary suffixes, and
2212          * sometimes SI decimal suffixes. This function can parse
2213          * both. Which one is the right way depends on the
2214          * context. Wikipedia suggests that SI is customary for
2215          * hardware metrics and network speeds, while IEC is
2216          * customary for most data sizes used by software and volatile
2217          * (RAM) memory. Hence be careful which one you pick!
2218          *
2219          * In either case we use just K, M, G as suffix, and not Ki,
2220          * Mi, Gi or so (as IEC would suggest). That's because that's
2221          * frickin' ugly. But this means you really need to make sure
2222          * to document which base you are parsing when you use this
2223          * call. */
2224
2225         struct table {
2226                 const char *suffix;
2227                 unsigned long long factor;
2228         };
2229
2230         static const struct table iec[] = {
2231                 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2232                 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2233                 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
2234                 { "G", 1024ULL*1024ULL*1024ULL },
2235                 { "M", 1024ULL*1024ULL },
2236                 { "K", 1024ULL },
2237                 { "B", 1 },
2238                 { "", 1 },
2239         };
2240
2241         static const struct table si[] = {
2242                 { "E", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
2243                 { "P", 1000ULL*1000ULL*1000ULL*1000ULL*1000ULL },
2244                 { "T", 1000ULL*1000ULL*1000ULL*1000ULL },
2245                 { "G", 1000ULL*1000ULL*1000ULL },
2246                 { "M", 1000ULL*1000ULL },
2247                 { "K", 1000ULL },
2248                 { "B", 1 },
2249                 { "", 1 },
2250         };
2251
2252         const struct table *table;
2253         const char *p;
2254         unsigned long long r = 0;
2255         unsigned n_entries, start_pos = 0;
2256
2257         assert(t);
2258         assert(base == 1000 || base == 1024);
2259         assert(size);
2260
2261         if (base == 1000) {
2262                 table = si;
2263                 n_entries = ELEMENTSOF(si);
2264         } else {
2265                 table = iec;
2266                 n_entries = ELEMENTSOF(iec);
2267         }
2268
2269         p = t;
2270         do {
2271                 long long l;
2272                 unsigned long long l2;
2273                 double frac = 0;
2274                 char *e;
2275                 unsigned i;
2276
2277                 errno = 0;
2278                 l = strtoll(p, &e, 10);
2279
2280                 if (errno > 0)
2281                         return -errno;
2282
2283                 if (l < 0)
2284                         return -ERANGE;
2285
2286                 if (e == p)
2287                         return -EINVAL;
2288
2289                 if (*e == '.') {
2290                         e++;
2291                         if (*e >= '0' && *e <= '9') {
2292                                 char *e2;
2293
2294                                 /* strotoull itself would accept space/+/- */
2295                                 l2 = strtoull(e, &e2, 10);
2296
2297                                 if (errno == ERANGE)
2298                                         return -errno;
2299
2300                                 /* Ignore failure. E.g. 10.M is valid */
2301                                 frac = l2;
2302                                 for (; e < e2; e++)
2303                                         frac /= 10;
2304                         }
2305                 }
2306
2307                 e += strspn(e, WHITESPACE);
2308
2309                 for (i = start_pos; i < n_entries; i++)
2310                         if (startswith(e, table[i].suffix)) {
2311                                 unsigned long long tmp;
2312                                 if ((unsigned long long) l + (frac > 0) > ULLONG_MAX / table[i].factor)
2313                                         return -ERANGE;
2314                                 tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
2315                                 if (tmp > ULLONG_MAX - r)
2316                                         return -ERANGE;
2317
2318                                 r += tmp;
2319                                 if ((unsigned long long) (off_t) r != r)
2320                                         return -ERANGE;
2321
2322                                 p = e + strlen(table[i].suffix);
2323
2324                                 start_pos = i + 1;
2325                                 break;
2326                         }
2327
2328                 if (i >= n_entries)
2329                         return -EINVAL;
2330
2331         } while (*p);
2332
2333         *size = r;
2334
2335         return 0;
2336 }
2337
2338 bool is_device_path(const char *path) {
2339
2340         /* Returns true on paths that refer to a device, either in
2341          * sysfs or in /dev */
2342
2343         return
2344                 path_startswith(path, "/dev/") ||
2345                 path_startswith(path, "/sys/");
2346 }
2347
2348 /// UNNEEDED by elogind
2349 #if 0
2350 int dir_is_empty(const char *path) {
2351         _cleanup_closedir_ DIR *d;
2352
2353         d = opendir(path);
2354         if (!d)
2355                 return -errno;
2356
2357         for (;;) {
2358                 struct dirent *de;
2359
2360                 errno = 0;
2361                 de = readdir(d);
2362                 if (!de && errno != 0)
2363                         return -errno;
2364
2365                 if (!de)
2366                         return 1;
2367
2368                 if (!hidden_file(de->d_name))
2369                         return 0;
2370         }
2371 }
2372
2373 char* dirname_malloc(const char *path) {
2374         char *d, *dir, *dir2;
2375
2376         d = strdup(path);
2377         if (!d)
2378                 return NULL;
2379         dir = dirname(d);
2380         assert(dir);
2381
2382         if (dir != d) {
2383                 dir2 = strdup(dir);
2384                 free(d);
2385                 return dir2;
2386         }
2387
2388         return dir;
2389 }
2390
2391 void rename_process(const char name[8]) {
2392         assert(name);
2393
2394         /* This is a like a poor man's setproctitle(). It changes the
2395          * comm field, argv[0], and also the glibc's internally used
2396          * name of the process. For the first one a limit of 16 chars
2397          * applies, to the second one usually one of 10 (i.e. length
2398          * of "/sbin/init"), to the third one one of 7 (i.e. length of
2399          * "systemd"). If you pass a longer string it will be
2400          * truncated */
2401
2402         prctl(PR_SET_NAME, name);
2403
2404         if (program_invocation_name)
2405                 strncpy(program_invocation_name, name, strlen(program_invocation_name));
2406
2407         if (saved_argc > 0) {
2408                 int i;
2409
2410                 if (saved_argv[0])
2411                         strncpy(saved_argv[0], name, strlen(saved_argv[0]));
2412
2413                 for (i = 1; i < saved_argc; i++) {
2414                         if (!saved_argv[i])
2415                                 break;
2416
2417                         memzero(saved_argv[i], strlen(saved_argv[i]));
2418                 }
2419         }
2420 }
2421 #endif // 0
2422
2423 char *lookup_uid(uid_t uid) {
2424         long bufsize;
2425         char *name;
2426         _cleanup_free_ char *buf = NULL;
2427         struct passwd pwbuf, *pw = NULL;
2428
2429         /* Shortcut things to avoid NSS lookups */
2430         if (uid == 0)
2431                 return strdup("root");
2432
2433         bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
2434         if (bufsize <= 0)
2435                 bufsize = 4096;
2436
2437         buf = malloc(bufsize);
2438         if (!buf)
2439                 return NULL;
2440
2441         if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
2442                 return strdup(pw->pw_name);
2443
2444         if (asprintf(&name, UID_FMT, uid) < 0)
2445                 return NULL;
2446
2447         return name;
2448 }
2449
2450 /// UNNEEDED by elogind
2451 #if 0
2452 char* getlogname_malloc(void) {
2453         uid_t uid;
2454         struct stat st;
2455
2456         if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
2457                 uid = st.st_uid;
2458         else
2459                 uid = getuid();
2460
2461         return lookup_uid(uid);
2462 }
2463
2464 char *getusername_malloc(void) {
2465         const char *e;
2466
2467         e = getenv("USER");
2468         if (e)
2469                 return strdup(e);
2470
2471         return lookup_uid(getuid());
2472 }
2473 #endif // 0
2474
2475 bool is_temporary_fs(const struct statfs *s) {
2476         assert(s);
2477
2478         return F_TYPE_EQUAL(s->f_type, TMPFS_MAGIC) ||
2479                F_TYPE_EQUAL(s->f_type, RAMFS_MAGIC);
2480 }
2481
2482 int fd_is_temporary_fs(int fd) {
2483         struct statfs s;
2484
2485         if (fstatfs(fd, &s) < 0)
2486                 return -errno;
2487
2488         return is_temporary_fs(&s);
2489 }
2490
2491 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
2492         assert(path);
2493
2494         /* Under the assumption that we are running privileged we
2495          * first change the access mode and only then hand out
2496          * ownership to avoid a window where access is too open. */
2497
2498         if (mode != MODE_INVALID)
2499                 if (chmod(path, mode) < 0)
2500                         return -errno;
2501
2502         if (uid != UID_INVALID || gid != GID_INVALID)
2503                 if (chown(path, uid, gid) < 0)
2504                         return -errno;
2505
2506         return 0;
2507 }
2508
2509 /// UNNEEDED by elogind
2510 #if 0
2511 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
2512         assert(fd >= 0);
2513
2514         /* Under the assumption that we are running privileged we
2515          * first change the access mode and only then hand out
2516          * ownership to avoid a window where access is too open. */
2517
2518         if (mode != MODE_INVALID)
2519                 if (fchmod(fd, mode) < 0)
2520                         return -errno;
2521
2522         if (uid != UID_INVALID || gid != GID_INVALID)
2523                 if (fchown(fd, uid, gid) < 0)
2524                         return -errno;
2525
2526         return 0;
2527 }
2528
2529 cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
2530         cpu_set_t *r;
2531         unsigned n = 1024;
2532
2533         /* Allocates the cpuset in the right size */
2534
2535         for (;;) {
2536                 if (!(r = CPU_ALLOC(n)))
2537                         return NULL;
2538
2539                 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
2540                         CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
2541
2542                         if (ncpus)
2543                                 *ncpus = n;
2544
2545                         return r;
2546                 }
2547
2548                 CPU_FREE(r);
2549
2550                 if (errno != EINVAL)
2551                         return NULL;
2552
2553                 n *= 2;
2554         }
2555 }
2556 #endif // 0
2557
2558 int files_same(const char *filea, const char *fileb) {
2559         struct stat a, b;
2560
2561         if (stat(filea, &a) < 0)
2562                 return -errno;
2563
2564         if (stat(fileb, &b) < 0)
2565                 return -errno;
2566
2567         return a.st_dev == b.st_dev &&
2568                a.st_ino == b.st_ino;
2569 }
2570
2571 int running_in_chroot(void) {
2572         int ret;
2573
2574         ret = files_same("/proc/1/root", "/");
2575         if (ret < 0)
2576                 return ret;
2577
2578         return ret == 0;
2579 }
2580
2581 static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
2582         size_t x;
2583         char *r;
2584
2585         assert(s);
2586         assert(percent <= 100);
2587         assert(new_length >= 3);
2588
2589         if (old_length <= 3 || old_length <= new_length)
2590                 return strndup(s, old_length);
2591
2592         r = new0(char, new_length+1);
2593         if (!r)
2594                 return NULL;
2595
2596         x = (new_length * percent) / 100;
2597
2598         if (x > new_length - 3)
2599                 x = new_length - 3;
2600
2601         memcpy(r, s, x);
2602         r[x] = '.';
2603         r[x+1] = '.';
2604         r[x+2] = '.';
2605         memcpy(r + x + 3,
2606                s + old_length - (new_length - x - 3),
2607                new_length - x - 3);
2608
2609         return r;
2610 }
2611
2612 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
2613         size_t x;
2614         char *e;
2615         const char *i, *j;
2616         unsigned k, len, len2;
2617
2618         assert(s);
2619         assert(percent <= 100);
2620         assert(new_length >= 3);
2621
2622         /* if no multibyte characters use ascii_ellipsize_mem for speed */
2623         if (ascii_is_valid(s))
2624                 return ascii_ellipsize_mem(s, old_length, new_length, percent);
2625
2626         if (old_length <= 3 || old_length <= new_length)
2627                 return strndup(s, old_length);
2628
2629         x = (new_length * percent) / 100;
2630
2631         if (x > new_length - 3)
2632                 x = new_length - 3;
2633
2634         k = 0;
2635         for (i = s; k < x && i < s + old_length; i = utf8_next_char(i)) {
2636                 int c;
2637
2638                 c = utf8_encoded_to_unichar(i);
2639                 if (c < 0)
2640                         return NULL;
2641                 k += unichar_iswide(c) ? 2 : 1;
2642         }
2643
2644         if (k > x) /* last character was wide and went over quota */
2645                 x ++;
2646
2647         for (j = s + old_length; k < new_length && j > i; ) {
2648                 int c;
2649
2650                 j = utf8_prev_char(j);
2651                 c = utf8_encoded_to_unichar(j);
2652                 if (c < 0)
2653                         return NULL;
2654                 k += unichar_iswide(c) ? 2 : 1;
2655         }
2656         assert(i <= j);
2657
2658         /* we don't actually need to ellipsize */
2659         if (i == j)
2660                 return memdup(s, old_length + 1);
2661
2662         /* make space for ellipsis */
2663         j = utf8_next_char(j);
2664
2665         len = i - s;
2666         len2 = s + old_length - j;
2667         e = new(char, len + 3 + len2 + 1);
2668         if (!e)
2669                 return NULL;
2670
2671         /*
2672         printf("old_length=%zu new_length=%zu x=%zu len=%u len2=%u k=%u\n",
2673                old_length, new_length, x, len, len2, k);
2674         */
2675
2676         memcpy(e, s, len);
2677         e[len]   = 0xe2; /* tri-dot ellipsis: … */
2678         e[len + 1] = 0x80;
2679         e[len + 2] = 0xa6;
2680
2681         memcpy(e + len + 3, j, len2 + 1);
2682
2683         return e;
2684 }
2685
2686 char *ellipsize(const char *s, size_t length, unsigned percent) {
2687         return ellipsize_mem(s, strlen(s), length, percent);
2688 }
2689
2690 int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode) {
2691         _cleanup_close_ int fd;
2692         int r;
2693
2694         assert(path);
2695
2696         if (parents)
2697                 mkdir_parents(path, 0755);
2698
2699         fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, mode > 0 ? mode : 0644);
2700         if (fd < 0)
2701                 return -errno;
2702
2703         if (mode > 0) {
2704                 r = fchmod(fd, mode);
2705                 if (r < 0)
2706                         return -errno;
2707         }
2708
2709         if (uid != UID_INVALID || gid != GID_INVALID) {
2710                 r = fchown(fd, uid, gid);
2711                 if (r < 0)
2712                         return -errno;
2713         }
2714
2715         if (stamp != USEC_INFINITY) {
2716                 struct timespec ts[2];
2717
2718                 timespec_store(&ts[0], stamp);
2719                 ts[1] = ts[0];
2720                 r = futimens(fd, ts);
2721         } else
2722                 r = futimens(fd, NULL);
2723         if (r < 0)
2724                 return -errno;
2725
2726         return 0;
2727 }
2728
2729 int touch(const char *path) {
2730         return touch_file(path, false, USEC_INFINITY, UID_INVALID, GID_INVALID, 0);
2731 }
2732
2733 /// UNNEEDED by elogind
2734 #if 0
2735 static char *unquote(const char *s, const char* quotes) {
2736         size_t l;
2737         assert(s);
2738
2739         /* This is rather stupid, simply removes the heading and
2740          * trailing quotes if there is one. Doesn't care about
2741          * escaping or anything.
2742          *
2743          * DON'T USE THIS FOR NEW CODE ANYMORE!*/
2744
2745         l = strlen(s);
2746         if (l < 2)
2747                 return strdup(s);
2748
2749         if (strchr(quotes, s[0]) && s[l-1] == s[0])
2750                 return strndup(s+1, l-2);
2751
2752         return strdup(s);
2753 }
2754 #endif // 0
2755
2756 noreturn void freeze(void) {
2757
2758         /* Make sure nobody waits for us on a socket anymore */
2759         close_all_fds(NULL, 0);
2760
2761         sync();
2762
2763         for (;;)
2764                 pause();
2765 }
2766
2767 bool null_or_empty(struct stat *st) {
2768         assert(st);
2769
2770         if (S_ISREG(st->st_mode) && st->st_size <= 0)
2771                 return true;
2772
2773         if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
2774                 return true;
2775
2776         return false;
2777 }
2778
2779 int null_or_empty_path(const char *fn) {
2780         struct stat st;
2781
2782         assert(fn);
2783
2784         if (stat(fn, &st) < 0)
2785                 return -errno;
2786
2787         return null_or_empty(&st);
2788 }
2789
2790 /// UNNEEDED by elogind
2791 #if 0
2792 int null_or_empty_fd(int fd) {
2793         struct stat st;
2794
2795         assert(fd >= 0);
2796
2797         if (fstat(fd, &st) < 0)
2798                 return -errno;
2799
2800         return null_or_empty(&st);
2801 }
2802 #endif // 0
2803
2804 DIR *xopendirat(int fd, const char *name, int flags) {
2805         int nfd;
2806         DIR *d;
2807
2808         assert(!(flags & O_CREAT));
2809
2810         nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags, 0);
2811         if (nfd < 0)
2812                 return NULL;
2813
2814         d = fdopendir(nfd);
2815         if (!d) {
2816                 safe_close(nfd);
2817                 return NULL;
2818         }
2819
2820         return d;
2821 }
2822
2823 /// UNNEEDED by elogind
2824 #if 0
2825 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
2826         _cleanup_free_ char *t = NULL, *u = NULL;
2827         size_t enc_len;
2828
2829         u = unquote(tagvalue, QUOTES);
2830         if (!u)
2831                 return NULL;
2832
2833         enc_len = strlen(u) * 4 + 1;
2834         t = new(char, enc_len);
2835         if (!t)
2836                 return NULL;
2837
2838         if (encode_devnode_name(u, t, enc_len) < 0)
2839                 return NULL;
2840
2841         return strjoin("/dev/disk/by-", by, "/", t, NULL);
2842 }
2843
2844 char *fstab_node_to_udev_node(const char *p) {
2845         assert(p);
2846
2847         if (startswith(p, "LABEL="))
2848                 return tag_to_udev_node(p+6, "label");
2849
2850         if (startswith(p, "UUID="))
2851                 return tag_to_udev_node(p+5, "uuid");
2852
2853         if (startswith(p, "PARTUUID="))
2854                 return tag_to_udev_node(p+9, "partuuid");
2855
2856         if (startswith(p, "PARTLABEL="))
2857                 return tag_to_udev_node(p+10, "partlabel");
2858
2859         return strdup(p);
2860 }
2861 #endif // 0
2862
2863 bool dirent_is_file(const struct dirent *de) {
2864         assert(de);
2865
2866         if (hidden_file(de->d_name))
2867                 return false;
2868
2869         if (de->d_type != DT_REG &&
2870             de->d_type != DT_LNK &&
2871             de->d_type != DT_UNKNOWN)
2872                 return false;
2873
2874         return true;
2875 }
2876
2877 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
2878         assert(de);
2879
2880         if (de->d_type != DT_REG &&
2881             de->d_type != DT_LNK &&
2882             de->d_type != DT_UNKNOWN)
2883                 return false;
2884
2885         if (hidden_file_allow_backup(de->d_name))
2886                 return false;
2887
2888         return endswith(de->d_name, suffix);
2889 }
2890
2891 static int do_execute(char **directories, usec_t timeout, char *argv[]) {
2892         _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
2893         _cleanup_set_free_free_ Set *seen = NULL;
2894         char **directory;
2895
2896         /* We fork this all off from a child process so that we can
2897          * somewhat cleanly make use of SIGALRM to set a time limit */
2898
2899         (void) reset_all_signal_handlers();
2900         (void) reset_signal_mask();
2901
2902         assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
2903
2904         pids = hashmap_new(NULL);
2905         if (!pids)
2906                 return log_oom();
2907
2908         seen = set_new(&string_hash_ops);
2909         if (!seen)
2910                 return log_oom();
2911
2912         STRV_FOREACH(directory, directories) {
2913                 _cleanup_closedir_ DIR *d;
2914                 struct dirent *de;
2915
2916                 d = opendir(*directory);
2917                 if (!d) {
2918                         if (errno == ENOENT)
2919                                 continue;
2920
2921                         return log_error_errno(errno, "Failed to open directory %s: %m", *directory);
2922                 }
2923
2924                 FOREACH_DIRENT(de, d, break) {
2925                         _cleanup_free_ char *path = NULL;
2926                         pid_t pid;
2927                         int r;
2928
2929                         if (!dirent_is_file(de))
2930                                 continue;
2931
2932                         if (set_contains(seen, de->d_name)) {
2933                                 log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name);
2934                                 continue;
2935                         }
2936
2937                         r = set_put_strdup(seen, de->d_name);
2938                         if (r < 0)
2939                                 return log_oom();
2940
2941                         path = strjoin(*directory, "/", de->d_name, NULL);
2942                         if (!path)
2943                                 return log_oom();
2944
2945                         if (null_or_empty_path(path)) {
2946                                 log_debug("%s is empty (a mask).", path);
2947                                 continue;
2948                         }
2949
2950                         pid = fork();
2951                         if (pid < 0) {
2952                                 log_error_errno(errno, "Failed to fork: %m");
2953                                 continue;
2954                         } else if (pid == 0) {
2955                                 char *_argv[2];
2956
2957                                 assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
2958
2959                                 if (!argv) {
2960                                         _argv[0] = path;
2961                                         _argv[1] = NULL;
2962                                         argv = _argv;
2963                                 } else
2964                                         argv[0] = path;
2965
2966                                 execv(path, argv);
2967                                 return log_error_errno(errno, "Failed to execute %s: %m", path);
2968                         }
2969
2970                         log_debug("Spawned %s as " PID_FMT ".", path, pid);
2971
2972                         r = hashmap_put(pids, UINT_TO_PTR(pid), path);
2973                         if (r < 0)
2974                                 return log_oom();
2975                         path = NULL;
2976                 }
2977         }
2978
2979         /* Abort execution of this process after the timout. We simply
2980          * rely on SIGALRM as default action terminating the process,
2981          * and turn on alarm(). */
2982
2983         if (timeout != USEC_INFINITY)
2984                 alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
2985
2986         while (!hashmap_isempty(pids)) {
2987                 _cleanup_free_ char *path = NULL;
2988                 pid_t pid;
2989
2990                 pid = PTR_TO_UINT(hashmap_first_key(pids));
2991                 assert(pid > 0);
2992
2993                 path = hashmap_remove(pids, UINT_TO_PTR(pid));
2994                 assert(path);
2995
2996                 wait_for_terminate_and_warn(path, pid, true);
2997         }
2998
2999         return 0;
3000 }
3001
3002 void execute_directories(const char* const* directories, usec_t timeout, char *argv[]) {
3003         pid_t executor_pid;
3004         int r;
3005         char *name;
3006         char **dirs = (char**) directories;
3007
3008         assert(!strv_isempty(dirs));
3009
3010         name = basename(dirs[0]);
3011         assert(!isempty(name));
3012
3013         /* Executes all binaries in the directories in parallel and waits
3014          * for them to finish. Optionally a timeout is applied. If a file
3015          * with the same name exists in more than one directory, the
3016          * earliest one wins. */
3017
3018         executor_pid = fork();
3019         if (executor_pid < 0) {
3020                 log_error_errno(errno, "Failed to fork: %m");
3021                 return;
3022
3023         } else if (executor_pid == 0) {
3024                 r = do_execute(dirs, timeout, argv);
3025                 _exit(r < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
3026         }
3027
3028         wait_for_terminate_and_warn(name, executor_pid, true);
3029 }
3030
3031 bool nulstr_contains(const char*nulstr, const char *needle) {
3032         const char *i;
3033
3034         if (!nulstr)
3035                 return false;
3036
3037         NULSTR_FOREACH(i, nulstr)
3038                 if (streq(i, needle))
3039                         return true;
3040
3041         return false;
3042 }
3043
3044 /// UNNEEDED by elogind
3045 #if 0
3046 bool plymouth_running(void) {
3047         return access("/run/plymouth/pid", F_OK) >= 0;
3048 }
3049 #endif // 0
3050
3051 char* strshorten(char *s, size_t l) {
3052         assert(s);
3053
3054         if (l < strlen(s))
3055                 s[l] = 0;
3056
3057         return s;
3058 }
3059
3060 int pipe_eof(int fd) {
3061         struct pollfd pollfd = {
3062                 .fd = fd,
3063                 .events = POLLIN|POLLHUP,
3064         };
3065
3066         int r;
3067
3068         r = poll(&pollfd, 1, 0);
3069         if (r < 0)
3070                 return -errno;
3071
3072         if (r == 0)
3073                 return 0;
3074
3075         return pollfd.revents & POLLHUP;
3076 }
3077
3078 int fd_wait_for_event(int fd, int event, usec_t t) {
3079
3080         struct pollfd pollfd = {
3081                 .fd = fd,
3082                 .events = event,
3083         };
3084
3085         struct timespec ts;
3086         int r;
3087
3088         r = ppoll(&pollfd, 1, t == USEC_INFINITY ? NULL : timespec_store(&ts, t), NULL);
3089         if (r < 0)
3090                 return -errno;
3091
3092         if (r == 0)
3093                 return 0;
3094
3095         return pollfd.revents;
3096 }
3097
3098 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
3099         FILE *f;
3100         char *t;
3101         int r, fd;
3102
3103         assert(path);
3104         assert(_f);
3105         assert(_temp_path);
3106
3107         r = tempfn_xxxxxx(path, NULL, &t);
3108         if (r < 0)
3109                 return r;
3110
3111         fd = mkostemp_safe(t, O_WRONLY|O_CLOEXEC);
3112         if (fd < 0) {
3113                 free(t);
3114                 return -errno;
3115         }
3116
3117         f = fdopen(fd, "we");
3118         if (!f) {
3119                 unlink_noerrno(t);
3120                 free(t);
3121                 safe_close(fd);
3122                 return -errno;
3123         }
3124
3125         *_f = f;
3126         *_temp_path = t;
3127
3128         return 0;
3129 }
3130
3131 /// UNNEEDED by elogind
3132 #if 0
3133 int symlink_atomic(const char *from, const char *to) {
3134         _cleanup_free_ char *t = NULL;
3135         int r;
3136
3137         assert(from);
3138         assert(to);
3139
3140         r = tempfn_random(to, NULL, &t);
3141         if (r < 0)
3142                 return r;
3143
3144         if (symlink(from, t) < 0)
3145                 return -errno;
3146
3147         if (rename(t, to) < 0) {
3148                 unlink_noerrno(t);
3149                 return -errno;
3150         }
3151
3152         return 0;
3153 }
3154
3155 int symlink_idempotent(const char *from, const char *to) {
3156         _cleanup_free_ char *p = NULL;
3157         int r;
3158
3159         assert(from);
3160         assert(to);
3161
3162         if (symlink(from, to) < 0) {
3163                 if (errno != EEXIST)
3164                         return -errno;
3165
3166                 r = readlink_malloc(to, &p);
3167                 if (r < 0)
3168                         return r;
3169
3170                 if (!streq(p, from))
3171                         return -EINVAL;
3172         }
3173
3174         return 0;
3175 }
3176
3177 int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
3178         _cleanup_free_ char *t = NULL;
3179         int r;
3180
3181         assert(path);
3182
3183         r = tempfn_random(path, NULL, &t);
3184         if (r < 0)
3185                 return r;
3186
3187         if (mknod(t, mode, dev) < 0)
3188                 return -errno;
3189
3190         if (rename(t, path) < 0) {
3191                 unlink_noerrno(t);
3192                 return -errno;
3193         }
3194
3195         return 0;
3196 }
3197
3198 int mkfifo_atomic(const char *path, mode_t mode) {
3199         _cleanup_free_ char *t = NULL;
3200         int r;
3201
3202         assert(path);
3203
3204         r = tempfn_random(path, NULL, &t);
3205         if (r < 0)
3206                 return r;
3207
3208         if (mkfifo(t, mode) < 0)
3209                 return -errno;
3210
3211         if (rename(t, path) < 0) {
3212                 unlink_noerrno(t);
3213                 return -errno;
3214         }
3215
3216         return 0;
3217 }
3218 #endif // 0
3219
3220 bool display_is_local(const char *display) {
3221         assert(display);
3222
3223         return
3224                 display[0] == ':' &&
3225                 display[1] >= '0' &&
3226                 display[1] <= '9';
3227 }
3228
3229 int socket_from_display(const char *display, char **path) {
3230         size_t k;
3231         char *f, *c;
3232
3233         assert(display);
3234         assert(path);
3235
3236         if (!display_is_local(display))
3237                 return -EINVAL;
3238
3239         k = strspn(display+1, "0123456789");
3240
3241         f = new(char, strlen("/tmp/.X11-unix/X") + k + 1);
3242         if (!f)
3243                 return -ENOMEM;
3244
3245         c = stpcpy(f, "/tmp/.X11-unix/X");
3246         memcpy(c, display+1, k);
3247         c[k] = 0;
3248
3249         *path = f;
3250
3251         return 0;
3252 }
3253
3254 int get_user_creds(
3255                 const char **username,
3256                 uid_t *uid, gid_t *gid,
3257                 const char **home,
3258                 const char **shell) {
3259
3260         struct passwd *p;
3261         uid_t u;
3262
3263         assert(username);
3264         assert(*username);
3265
3266         /* We enforce some special rules for uid=0: in order to avoid
3267          * NSS lookups for root we hardcode its data. */
3268
3269         if (streq(*username, "root") || streq(*username, "0")) {
3270                 *username = "root";
3271
3272                 if (uid)
3273                         *uid = 0;
3274
3275                 if (gid)
3276                         *gid = 0;
3277
3278                 if (home)
3279                         *home = "/root";
3280
3281                 if (shell)
3282                         *shell = "/bin/sh";
3283
3284                 return 0;
3285         }
3286
3287         if (parse_uid(*username, &u) >= 0) {
3288                 errno = 0;
3289                 p = getpwuid(u);
3290
3291                 /* If there are multiple users with the same id, make
3292                  * sure to leave $USER to the configured value instead
3293                  * of the first occurrence in the database. However if
3294                  * the uid was configured by a numeric uid, then let's
3295                  * pick the real username from /etc/passwd. */
3296                 if (p)
3297                         *username = p->pw_name;
3298         } else {
3299                 errno = 0;
3300                 p = getpwnam(*username);
3301         }
3302
3303         if (!p)
3304                 return errno > 0 ? -errno : -ESRCH;
3305
3306         if (uid)
3307                 *uid = p->pw_uid;
3308
3309         if (gid)
3310                 *gid = p->pw_gid;
3311
3312         if (home)
3313                 *home = p->pw_dir;
3314
3315         if (shell)
3316                 *shell = p->pw_shell;
3317
3318         return 0;
3319 }
3320
3321 char* uid_to_name(uid_t uid) {
3322         struct passwd *p;
3323         char *r;
3324
3325         if (uid == 0)
3326                 return strdup("root");
3327
3328         p = getpwuid(uid);
3329         if (p)
3330                 return strdup(p->pw_name);
3331
3332         if (asprintf(&r, UID_FMT, uid) < 0)
3333                 return NULL;
3334
3335         return r;
3336 }
3337
3338 char* gid_to_name(gid_t gid) {
3339         struct group *p;
3340         char *r;
3341
3342         if (gid == 0)
3343                 return strdup("root");
3344
3345         p = getgrgid(gid);
3346         if (p)
3347                 return strdup(p->gr_name);
3348
3349         if (asprintf(&r, GID_FMT, gid) < 0)
3350                 return NULL;
3351
3352         return r;
3353 }
3354
3355 int get_group_creds(const char **groupname, gid_t *gid) {
3356         struct group *g;
3357         gid_t id;
3358
3359         assert(groupname);
3360
3361         /* We enforce some special rules for gid=0: in order to avoid
3362          * NSS lookups for root we hardcode its data. */
3363
3364         if (streq(*groupname, "root") || streq(*groupname, "0")) {
3365                 *groupname = "root";
3366
3367                 if (gid)
3368                         *gid = 0;
3369
3370                 return 0;
3371         }
3372
3373         if (parse_gid(*groupname, &id) >= 0) {
3374                 errno = 0;
3375                 g = getgrgid(id);
3376
3377                 if (g)
3378                         *groupname = g->gr_name;
3379         } else {
3380                 errno = 0;
3381                 g = getgrnam(*groupname);
3382         }
3383
3384         if (!g)
3385                 return errno > 0 ? -errno : -ESRCH;
3386
3387         if (gid)
3388                 *gid = g->gr_gid;
3389
3390         return 0;
3391 }
3392
3393 int in_gid(gid_t gid) {
3394         gid_t *gids;
3395         int ngroups_max, r, i;
3396
3397         if (getgid() == gid)
3398                 return 1;
3399
3400         if (getegid() == gid)
3401                 return 1;
3402
3403         ngroups_max = sysconf(_SC_NGROUPS_MAX);
3404         assert(ngroups_max > 0);
3405
3406         gids = alloca(sizeof(gid_t) * ngroups_max);
3407
3408         r = getgroups(ngroups_max, gids);
3409         if (r < 0)
3410                 return -errno;
3411
3412         for (i = 0; i < r; i++)
3413                 if (gids[i] == gid)
3414                         return 1;
3415
3416         return 0;
3417 }
3418
3419 /// UNNEEDED by elogind
3420 #if 0
3421 int in_group(const char *name) {
3422         int r;
3423         gid_t gid;
3424
3425         r = get_group_creds(&name, &gid);
3426         if (r < 0)
3427                 return r;
3428
3429         return in_gid(gid);
3430 }
3431
3432 int glob_exists(const char *path) {
3433         _cleanup_globfree_ glob_t g = {};
3434         int k;
3435
3436         assert(path);
3437
3438         errno = 0;
3439         k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
3440
3441         if (k == GLOB_NOMATCH)
3442                 return 0;
3443         else if (k == GLOB_NOSPACE)
3444                 return -ENOMEM;
3445         else if (k == 0)
3446                 return !strv_isempty(g.gl_pathv);
3447         else
3448                 return errno ? -errno : -EIO;
3449 }
3450
3451 int glob_extend(char ***strv, const char *path) {
3452         _cleanup_globfree_ glob_t g = {};
3453         int k;
3454         char **p;
3455
3456         errno = 0;
3457         k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
3458
3459         if (k == GLOB_NOMATCH)
3460                 return -ENOENT;
3461         else if (k == GLOB_NOSPACE)
3462                 return -ENOMEM;
3463         else if (k != 0 || strv_isempty(g.gl_pathv))
3464                 return errno ? -errno : -EIO;
3465
3466         STRV_FOREACH(p, g.gl_pathv) {
3467                 k = strv_extend(strv, *p);
3468                 if (k < 0)
3469                         break;
3470         }
3471
3472         return k;
3473 }
3474 #endif // 0
3475
3476 int dirent_ensure_type(DIR *d, struct dirent *de) {
3477         struct stat st;
3478
3479         assert(d);
3480         assert(de);
3481
3482         if (de->d_type != DT_UNKNOWN)
3483                 return 0;
3484
3485         if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
3486                 return -errno;
3487
3488         de->d_type =
3489                 S_ISREG(st.st_mode)  ? DT_REG  :
3490                 S_ISDIR(st.st_mode)  ? DT_DIR  :
3491                 S_ISLNK(st.st_mode)  ? DT_LNK  :
3492                 S_ISFIFO(st.st_mode) ? DT_FIFO :
3493                 S_ISSOCK(st.st_mode) ? DT_SOCK :
3494                 S_ISCHR(st.st_mode)  ? DT_CHR  :
3495                 S_ISBLK(st.st_mode)  ? DT_BLK  :
3496                                        DT_UNKNOWN;
3497
3498         return 0;
3499 }
3500
3501 int get_files_in_directory(const char *path, char ***list) {
3502         _cleanup_closedir_ DIR *d = NULL;
3503         size_t bufsize = 0, n = 0;
3504         _cleanup_strv_free_ char **l = NULL;
3505
3506         assert(path);
3507
3508         /* Returns all files in a directory in *list, and the number
3509          * of files as return value. If list is NULL returns only the
3510          * number. */
3511
3512         d = opendir(path);
3513         if (!d)
3514                 return -errno;
3515
3516         for (;;) {
3517                 struct dirent *de;
3518
3519                 errno = 0;
3520                 de = readdir(d);
3521                 if (!de && errno != 0)
3522                         return -errno;
3523                 if (!de)
3524                         break;
3525
3526                 dirent_ensure_type(d, de);
3527
3528                 if (!dirent_is_file(de))
3529                         continue;
3530
3531                 if (list) {
3532                         /* one extra slot is needed for the terminating NULL */
3533                         if (!GREEDY_REALLOC(l, bufsize, n + 2))
3534                                 return -ENOMEM;
3535
3536                         l[n] = strdup(de->d_name);
3537                         if (!l[n])
3538                                 return -ENOMEM;
3539
3540                         l[++n] = NULL;
3541                 } else
3542                         n++;
3543         }
3544
3545         if (list) {
3546                 *list = l;
3547                 l = NULL; /* avoid freeing */
3548         }
3549
3550         return n;
3551 }
3552
3553 char *strjoin(const char *x, ...) {
3554         va_list ap;
3555         size_t l;
3556         char *r, *p;
3557
3558         va_start(ap, x);
3559
3560         if (x) {
3561                 l = strlen(x);
3562
3563                 for (;;) {
3564                         const char *t;
3565                         size_t n;
3566
3567                         t = va_arg(ap, const char *);
3568                         if (!t)
3569                                 break;
3570
3571                         n = strlen(t);
3572                         if (n > ((size_t) -1) - l) {
3573                                 va_end(ap);
3574                                 return NULL;
3575                         }
3576
3577                         l += n;
3578                 }
3579         } else
3580                 l = 0;
3581
3582         va_end(ap);
3583
3584         r = new(char, l+1);
3585         if (!r)
3586                 return NULL;
3587
3588         if (x) {
3589                 p = stpcpy(r, x);
3590
3591                 va_start(ap, x);
3592
3593                 for (;;) {
3594                         const char *t;
3595
3596                         t = va_arg(ap, const char *);
3597                         if (!t)
3598                                 break;
3599
3600                         p = stpcpy(p, t);
3601                 }
3602
3603                 va_end(ap);
3604         } else
3605                 r[0] = 0;
3606
3607         return r;
3608 }
3609
3610 bool is_main_thread(void) {
3611         static thread_local int cached = 0;
3612
3613         if (_unlikely_(cached == 0))
3614                 cached = getpid() == gettid() ? 1 : -1;
3615
3616         return cached > 0;
3617 }
3618
3619 /// UNNEEDED by elogind
3620 #if 0
3621 int block_get_whole_disk(dev_t d, dev_t *ret) {
3622         char *p, *s;
3623         int r;
3624         unsigned n, m;
3625
3626         assert(ret);
3627
3628         /* If it has a queue this is good enough for us */
3629         if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
3630                 return -ENOMEM;
3631
3632         r = access(p, F_OK);
3633         free(p);
3634
3635         if (r >= 0) {
3636                 *ret = d;
3637                 return 0;
3638         }
3639
3640         /* If it is a partition find the originating device */
3641         if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
3642                 return -ENOMEM;
3643
3644         r = access(p, F_OK);
3645         free(p);
3646
3647         if (r < 0)
3648                 return -ENOENT;
3649
3650         /* Get parent dev_t */
3651         if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
3652                 return -ENOMEM;
3653
3654         r = read_one_line_file(p, &s);
3655         free(p);
3656
3657         if (r < 0)
3658                 return r;
3659
3660         r = sscanf(s, "%u:%u", &m, &n);
3661         free(s);
3662
3663         if (r != 2)
3664                 return -EINVAL;
3665
3666         /* Only return this if it is really good enough for us. */
3667         if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
3668                 return -ENOMEM;
3669
3670         r = access(p, F_OK);
3671         free(p);
3672
3673         if (r >= 0) {
3674                 *ret = makedev(m, n);
3675                 return 0;
3676         }
3677
3678         return -ENOENT;
3679 }
3680
3681 static const char *const ioprio_class_table[] = {
3682         [IOPRIO_CLASS_NONE] = "none",
3683         [IOPRIO_CLASS_RT] = "realtime",
3684         [IOPRIO_CLASS_BE] = "best-effort",
3685         [IOPRIO_CLASS_IDLE] = "idle"
3686 };
3687
3688 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, INT_MAX);
3689 #endif // 0
3690
3691 static const char *const sigchld_code_table[] = {
3692         [CLD_EXITED] = "exited",
3693         [CLD_KILLED] = "killed",
3694         [CLD_DUMPED] = "dumped",
3695         [CLD_TRAPPED] = "trapped",
3696         [CLD_STOPPED] = "stopped",
3697         [CLD_CONTINUED] = "continued",
3698 };
3699
3700 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
3701
3702 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
3703         [LOG_FAC(LOG_KERN)] = "kern",
3704         [LOG_FAC(LOG_USER)] = "user",
3705         [LOG_FAC(LOG_MAIL)] = "mail",
3706         [LOG_FAC(LOG_DAEMON)] = "daemon",
3707         [LOG_FAC(LOG_AUTH)] = "auth",
3708         [LOG_FAC(LOG_SYSLOG)] = "syslog",
3709         [LOG_FAC(LOG_LPR)] = "lpr",
3710         [LOG_FAC(LOG_NEWS)] = "news",
3711         [LOG_FAC(LOG_UUCP)] = "uucp",
3712         [LOG_FAC(LOG_CRON)] = "cron",
3713         [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
3714         [LOG_FAC(LOG_FTP)] = "ftp",
3715         [LOG_FAC(LOG_LOCAL0)] = "local0",
3716         [LOG_FAC(LOG_LOCAL1)] = "local1",
3717         [LOG_FAC(LOG_LOCAL2)] = "local2",
3718         [LOG_FAC(LOG_LOCAL3)] = "local3",
3719         [LOG_FAC(LOG_LOCAL4)] = "local4",
3720         [LOG_FAC(LOG_LOCAL5)] = "local5",
3721         [LOG_FAC(LOG_LOCAL6)] = "local6",
3722         [LOG_FAC(LOG_LOCAL7)] = "local7"
3723 };
3724
3725 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_facility_unshifted, int, LOG_FAC(~0));
3726
3727 static const char *const log_level_table[] = {
3728         [LOG_EMERG] = "emerg",
3729         [LOG_ALERT] = "alert",
3730         [LOG_CRIT] = "crit",
3731         [LOG_ERR] = "err",
3732         [LOG_WARNING] = "warning",
3733         [LOG_NOTICE] = "notice",
3734         [LOG_INFO] = "info",
3735         [LOG_DEBUG] = "debug"
3736 };
3737
3738 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(log_level, int, LOG_DEBUG);
3739
3740 static const char* const sched_policy_table[] = {
3741         [SCHED_OTHER] = "other",
3742         [SCHED_BATCH] = "batch",
3743         [SCHED_IDLE] = "idle",
3744         [SCHED_FIFO] = "fifo",
3745         [SCHED_RR] = "rr"
3746 };
3747
3748 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
3749
3750 static const char* const rlimit_table[_RLIMIT_MAX] = {
3751         [RLIMIT_CPU] = "LimitCPU",
3752         [RLIMIT_FSIZE] = "LimitFSIZE",
3753         [RLIMIT_DATA] = "LimitDATA",
3754         [RLIMIT_STACK] = "LimitSTACK",
3755         [RLIMIT_CORE] = "LimitCORE",
3756         [RLIMIT_RSS] = "LimitRSS",
3757         [RLIMIT_NOFILE] = "LimitNOFILE",
3758         [RLIMIT_AS] = "LimitAS",
3759         [RLIMIT_NPROC] = "LimitNPROC",
3760         [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
3761         [RLIMIT_LOCKS] = "LimitLOCKS",
3762         [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
3763         [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
3764         [RLIMIT_NICE] = "LimitNICE",
3765         [RLIMIT_RTPRIO] = "LimitRTPRIO",
3766         [RLIMIT_RTTIME] = "LimitRTTIME"
3767 };
3768
3769 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
3770
3771 static const char* const ip_tos_table[] = {
3772         [IPTOS_LOWDELAY] = "low-delay",
3773         [IPTOS_THROUGHPUT] = "throughput",
3774         [IPTOS_RELIABILITY] = "reliability",
3775         [IPTOS_LOWCOST] = "low-cost",
3776 };
3777
3778 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
3779
3780 bool kexec_loaded(void) {
3781        bool loaded = false;
3782        char *s;
3783
3784        if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
3785                if (s[0] == '1')
3786                        loaded = true;
3787                free(s);
3788        }
3789        return loaded;
3790 }
3791
3792 /// UNNEEDED by elogind
3793 #if 0
3794 int prot_from_flags(int flags) {
3795
3796         switch (flags & O_ACCMODE) {
3797
3798         case O_RDONLY:
3799                 return PROT_READ;
3800
3801         case O_WRONLY:
3802                 return PROT_WRITE;
3803
3804         case O_RDWR:
3805                 return PROT_READ|PROT_WRITE;
3806
3807         default:
3808                 return -EINVAL;
3809         }
3810 }
3811
3812 char *format_bytes(char *buf, size_t l, off_t t) {
3813         unsigned i;
3814
3815         static const struct {
3816                 const char *suffix;
3817                 off_t factor;
3818         } table[] = {
3819                 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
3820                 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
3821                 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
3822                 { "G", 1024ULL*1024ULL*1024ULL },
3823                 { "M", 1024ULL*1024ULL },
3824                 { "K", 1024ULL },
3825         };
3826
3827         if (t == (off_t) -1)
3828                 return NULL;
3829
3830         for (i = 0; i < ELEMENTSOF(table); i++) {
3831
3832                 if (t >= table[i].factor) {
3833                         snprintf(buf, l,
3834                                  "%llu.%llu%s",
3835                                  (unsigned long long) (t / table[i].factor),
3836                                  (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
3837                                  table[i].suffix);
3838
3839                         goto finish;
3840                 }
3841         }
3842
3843         snprintf(buf, l, "%lluB", (unsigned long long) t);
3844
3845 finish:
3846         buf[l-1] = 0;
3847         return buf;
3848
3849 }
3850 #endif // 0
3851
3852 void* memdup(const void *p, size_t l) {
3853         void *r;
3854
3855         assert(p);
3856
3857         r = malloc(l);
3858         if (!r)
3859                 return NULL;
3860
3861         memcpy(r, p, l);
3862         return r;
3863 }
3864
3865 int fd_inc_sndbuf(int fd, size_t n) {
3866         int r, value;
3867         socklen_t l = sizeof(value);
3868
3869         r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
3870         if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
3871                 return 0;
3872
3873         /* If we have the privileges we will ignore the kernel limit. */
3874
3875         value = (int) n;
3876         if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
3877                 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
3878                         return -errno;
3879
3880         return 1;
3881 }
3882
3883 int fd_inc_rcvbuf(int fd, size_t n) {
3884         int r, value;
3885         socklen_t l = sizeof(value);
3886
3887         r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
3888         if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
3889                 return 0;
3890
3891         /* If we have the privileges we will ignore the kernel limit. */
3892
3893         value = (int) n;
3894         if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
3895                 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
3896                         return -errno;
3897         return 1;
3898 }
3899
3900 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
3901         bool stdout_is_tty, stderr_is_tty;
3902         pid_t parent_pid, agent_pid;
3903         sigset_t ss, saved_ss;
3904         unsigned n, i;
3905         va_list ap;
3906         char **l;
3907
3908         assert(pid);
3909         assert(path);
3910
3911         /* Spawns a temporary TTY agent, making sure it goes away when
3912          * we go away */
3913
3914         parent_pid = getpid();
3915
3916         /* First we temporarily block all signals, so that the new
3917          * child has them blocked initially. This way, we can be sure
3918          * that SIGTERMs are not lost we might send to the agent. */
3919         assert_se(sigfillset(&ss) >= 0);
3920         assert_se(sigprocmask(SIG_SETMASK, &ss, &saved_ss) >= 0);
3921
3922         agent_pid = fork();
3923         if (agent_pid < 0) {
3924                 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
3925                 return -errno;
3926         }
3927
3928         if (agent_pid != 0) {
3929                 assert_se(sigprocmask(SIG_SETMASK, &saved_ss, NULL) >= 0);
3930                 *pid = agent_pid;
3931                 return 0;
3932         }
3933
3934         /* In the child:
3935          *
3936          * Make sure the agent goes away when the parent dies */
3937         if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
3938                 _exit(EXIT_FAILURE);
3939
3940         /* Make sure we actually can kill the agent, if we need to, in
3941          * case somebody invoked us from a shell script that trapped
3942          * SIGTERM or so... */
3943         (void) reset_all_signal_handlers();
3944         (void) reset_signal_mask();
3945
3946         /* Check whether our parent died before we were able
3947          * to set the death signal and unblock the signals */
3948         if (getppid() != parent_pid)
3949                 _exit(EXIT_SUCCESS);
3950
3951         /* Don't leak fds to the agent */
3952         close_all_fds(except, n_except);
3953
3954         stdout_is_tty = isatty(STDOUT_FILENO);
3955         stderr_is_tty = isatty(STDERR_FILENO);
3956
3957         if (!stdout_is_tty || !stderr_is_tty) {
3958                 int fd;
3959
3960                 /* Detach from stdout/stderr. and reopen
3961                  * /dev/tty for them. This is important to
3962                  * ensure that when systemctl is started via
3963                  * popen() or a similar call that expects to
3964                  * read EOF we actually do generate EOF and
3965                  * not delay this indefinitely by because we
3966                  * keep an unused copy of stdin around. */
3967                 fd = open("/dev/tty", O_WRONLY);
3968                 if (fd < 0) {
3969                         log_error_errno(errno, "Failed to open /dev/tty: %m");
3970                         _exit(EXIT_FAILURE);
3971                 }
3972
3973                 if (!stdout_is_tty)
3974                         dup2(fd, STDOUT_FILENO);
3975
3976                 if (!stderr_is_tty)
3977                         dup2(fd, STDERR_FILENO);
3978
3979                 if (fd > 2)
3980                         close(fd);
3981         }
3982
3983         /* Count arguments */
3984         va_start(ap, path);
3985         for (n = 0; va_arg(ap, char*); n++)
3986                 ;
3987         va_end(ap);
3988
3989         /* Allocate strv */
3990         l = alloca(sizeof(char *) * (n + 1));
3991
3992         /* Fill in arguments */
3993         va_start(ap, path);
3994         for (i = 0; i <= n; i++)
3995                 l[i] = va_arg(ap, char*);
3996         va_end(ap);
3997
3998         execv(path, l);
3999         _exit(EXIT_FAILURE);
4000 }
4001
4002 /// UNNEEDED by elogind
4003 #if 0
4004 int setrlimit_closest(int resource, const struct rlimit *rlim) {
4005         struct rlimit highest, fixed;
4006
4007         assert(rlim);
4008
4009         if (setrlimit(resource, rlim) >= 0)
4010                 return 0;
4011
4012         if (errno != EPERM)
4013                 return -errno;
4014
4015         /* So we failed to set the desired setrlimit, then let's try
4016          * to get as close as we can */
4017         assert_se(getrlimit(resource, &highest) == 0);
4018
4019         fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
4020         fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
4021
4022         if (setrlimit(resource, &fixed) < 0)
4023                 return -errno;
4024
4025         return 0;
4026 }
4027
4028 bool http_etag_is_valid(const char *etag) {
4029         if (isempty(etag))
4030                 return false;
4031
4032         if (!endswith(etag, "\""))
4033                 return false;
4034
4035         if (!startswith(etag, "\"") && !startswith(etag, "W/\""))
4036                 return false;
4037
4038         return true;
4039 }
4040 #endif // 0
4041
4042 bool http_url_is_valid(const char *url) {
4043         const char *p;
4044
4045         if (isempty(url))
4046                 return false;
4047
4048         p = startswith(url, "http://");
4049         if (!p)
4050                 p = startswith(url, "https://");
4051         if (!p)
4052                 return false;
4053
4054         if (isempty(p))
4055                 return false;
4056
4057         return ascii_is_valid(p);
4058 }
4059
4060 bool documentation_url_is_valid(const char *url) {
4061         const char *p;
4062
4063         if (isempty(url))
4064                 return false;
4065
4066         if (http_url_is_valid(url))
4067                 return true;
4068
4069         p = startswith(url, "file:/");
4070         if (!p)
4071                 p = startswith(url, "info:");
4072         if (!p)
4073                 p = startswith(url, "man:");
4074
4075         if (isempty(p))
4076                 return false;
4077
4078         return ascii_is_valid(p);
4079 }
4080
4081 bool in_initrd(void) {
4082         static int saved = -1;
4083         struct statfs s;
4084
4085         if (saved >= 0)
4086                 return saved;
4087
4088         /* We make two checks here:
4089          *
4090          * 1. the flag file /etc/initrd-release must exist
4091          * 2. the root file system must be a memory file system
4092          *
4093          * The second check is extra paranoia, since misdetecting an
4094          * initrd can have bad bad consequences due the initrd
4095          * emptying when transititioning to the main systemd.
4096          */
4097
4098         saved = access("/etc/initrd-release", F_OK) >= 0 &&
4099                 statfs("/", &s) >= 0 &&
4100                 is_temporary_fs(&s);
4101
4102         return saved;
4103 }
4104
4105 int get_home_dir(char **_h) {
4106         struct passwd *p;
4107         const char *e;
4108         char *h;
4109         uid_t u;
4110
4111         assert(_h);
4112
4113         /* Take the user specified one */
4114         e = secure_getenv("HOME");
4115         if (e && path_is_absolute(e)) {
4116                 h = strdup(e);
4117                 if (!h)
4118                         return -ENOMEM;
4119
4120                 *_h = h;
4121                 return 0;
4122         }
4123
4124         /* Hardcode home directory for root to avoid NSS */
4125         u = getuid();
4126         if (u == 0) {
4127                 h = strdup("/root");
4128                 if (!h)
4129                         return -ENOMEM;
4130
4131                 *_h = h;
4132                 return 0;
4133         }
4134
4135         /* Check the database... */
4136         errno = 0;
4137         p = getpwuid(u);
4138         if (!p)
4139                 return errno > 0 ? -errno : -ESRCH;
4140
4141         if (!path_is_absolute(p->pw_dir))
4142                 return -EINVAL;
4143
4144         h = strdup(p->pw_dir);
4145         if (!h)
4146                 return -ENOMEM;
4147
4148         *_h = h;
4149         return 0;
4150 }
4151
4152 /// UNNEEDED by elogind
4153 #if 0
4154 int get_shell(char **_s) {
4155         struct passwd *p;
4156         const char *e;
4157         char *s;
4158         uid_t u;
4159
4160         assert(_s);
4161
4162         /* Take the user specified one */
4163         e = getenv("SHELL");
4164         if (e) {
4165                 s = strdup(e);
4166                 if (!s)
4167                         return -ENOMEM;
4168
4169                 *_s = s;
4170                 return 0;
4171         }
4172
4173         /* Hardcode home directory for root to avoid NSS */
4174         u = getuid();
4175         if (u == 0) {
4176                 s = strdup("/bin/sh");
4177                 if (!s)
4178                         return -ENOMEM;
4179
4180                 *_s = s;
4181                 return 0;
4182         }
4183
4184         /* Check the database... */
4185         errno = 0;
4186         p = getpwuid(u);
4187         if (!p)
4188                 return errno > 0 ? -errno : -ESRCH;
4189
4190         if (!path_is_absolute(p->pw_shell))
4191                 return -EINVAL;
4192
4193         s = strdup(p->pw_shell);
4194         if (!s)
4195                 return -ENOMEM;
4196
4197         *_s = s;
4198         return 0;
4199 }
4200 #endif // 0
4201
4202 bool filename_is_valid(const char *p) {
4203
4204         if (isempty(p))
4205                 return false;
4206
4207         if (strchr(p, '/'))
4208                 return false;
4209
4210         if (streq(p, "."))
4211                 return false;
4212
4213         if (streq(p, ".."))
4214                 return false;
4215
4216         if (strlen(p) > FILENAME_MAX)
4217                 return false;
4218
4219         return true;
4220 }
4221
4222 bool string_is_safe(const char *p) {
4223         const char *t;
4224
4225         if (!p)
4226                 return false;
4227
4228         for (t = p; *t; t++) {
4229                 if (*t > 0 && *t < ' ')
4230                         return false;
4231
4232                 if (strchr("\\\"\'\x7f", *t))
4233                         return false;
4234         }
4235
4236         return true;
4237 }
4238
4239 /**
4240  * Check if a string contains control characters. If 'ok' is non-NULL
4241  * it may be a string containing additional CCs to be considered OK.
4242  */
4243 bool string_has_cc(const char *p, const char *ok) {
4244         const char *t;
4245
4246         assert(p);
4247
4248         for (t = p; *t; t++) {
4249                 if (ok && strchr(ok, *t))
4250                         continue;
4251
4252                 if (*t > 0 && *t < ' ')
4253                         return true;
4254
4255                 if (*t == 127)
4256                         return true;
4257         }
4258
4259         return false;
4260 }
4261
4262 bool path_is_safe(const char *p) {
4263
4264         if (isempty(p))
4265                 return false;
4266
4267         if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
4268                 return false;
4269
4270         if (strlen(p)+1 > PATH_MAX)
4271                 return false;
4272
4273         /* The following two checks are not really dangerous, but hey, they still are confusing */
4274         if (streq(p, ".") || startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
4275                 return false;
4276
4277         if (strstr(p, "//"))
4278                 return false;
4279
4280         return true;
4281 }
4282
4283 /// UNNEEDED by elogind
4284 #if 0
4285 /* hey glibc, APIs with callbacks without a user pointer are so useless */
4286 void *xbsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
4287                  int (*compar) (const void *, const void *, void *), void *arg) {
4288         size_t l, u, idx;
4289         const void *p;
4290         int comparison;
4291
4292         l = 0;
4293         u = nmemb;
4294         while (l < u) {
4295                 idx = (l + u) / 2;
4296                 p = (void *)(((const char *) base) + (idx * size));
4297                 comparison = compar(key, p, arg);
4298                 if (comparison < 0)
4299                         u = idx;
4300                 else if (comparison > 0)
4301                         l = idx + 1;
4302                 else
4303                         return (void *)p;
4304         }
4305         return NULL;
4306 }
4307
4308 void init_gettext(void) {
4309         setlocale(LC_ALL, "");
4310         textdomain(GETTEXT_PACKAGE);
4311 }
4312 #endif // 0
4313
4314 bool is_locale_utf8(void) {
4315         const char *set;
4316         static int cached_answer = -1;
4317
4318         if (cached_answer >= 0)
4319                 goto out;
4320
4321         if (!setlocale(LC_ALL, "")) {
4322                 cached_answer = true;
4323                 goto out;
4324         }
4325
4326         set = nl_langinfo(CODESET);
4327         if (!set) {
4328                 cached_answer = true;
4329                 goto out;
4330         }
4331
4332         if (streq(set, "UTF-8")) {
4333                 cached_answer = true;
4334                 goto out;
4335         }
4336
4337         /* For LC_CTYPE=="C" return true, because CTYPE is effectly
4338          * unset and everything can do to UTF-8 nowadays. */
4339         set = setlocale(LC_CTYPE, NULL);
4340         if (!set) {
4341                 cached_answer = true;
4342                 goto out;
4343         }
4344
4345         /* Check result, but ignore the result if C was set
4346          * explicitly. */
4347         cached_answer =
4348                 STR_IN_SET(set, "C", "POSIX") &&
4349                 !getenv("LC_ALL") &&
4350                 !getenv("LC_CTYPE") &&
4351                 !getenv("LANG");
4352
4353 out:
4354         return (bool) cached_answer;
4355 }
4356
4357 const char *draw_special_char(DrawSpecialChar ch) {
4358         static const char *draw_table[2][_DRAW_SPECIAL_CHAR_MAX] = {
4359
4360                 /* UTF-8 */ {
4361                         [DRAW_TREE_VERTICAL]      = "\342\224\202 ",            /* │  */
4362                         [DRAW_TREE_BRANCH]        = "\342\224\234\342\224\200", /* ├─ */
4363                         [DRAW_TREE_RIGHT]         = "\342\224\224\342\224\200", /* └─ */
4364                         [DRAW_TREE_SPACE]         = "  ",                       /*    */
4365                         [DRAW_TRIANGULAR_BULLET]  = "\342\200\243",             /* ‣ */
4366                         [DRAW_BLACK_CIRCLE]       = "\342\227\217",             /* ● */
4367                         [DRAW_ARROW]              = "\342\206\222",             /* → */
4368                         [DRAW_DASH]               = "\342\200\223",             /* – */
4369                 },
4370
4371                 /* ASCII fallback */ {
4372                         [DRAW_TREE_VERTICAL]      = "| ",
4373                         [DRAW_TREE_BRANCH]        = "|-",
4374                         [DRAW_TREE_RIGHT]         = "`-",
4375                         [DRAW_TREE_SPACE]         = "  ",
4376                         [DRAW_TRIANGULAR_BULLET]  = ">",
4377                         [DRAW_BLACK_CIRCLE]       = "*",
4378                         [DRAW_ARROW]              = "->",
4379                         [DRAW_DASH]               = "-",
4380                 }
4381         };
4382
4383         return draw_table[!is_locale_utf8()][ch];
4384 }
4385
4386 /// UNNEEDED by elogind
4387 #if 0
4388 char *strreplace(const char *text, const char *old_string, const char *new_string) {
4389         const char *f;
4390         char *t, *r;
4391         size_t l, old_len, new_len;
4392
4393         assert(text);
4394         assert(old_string);
4395         assert(new_string);
4396
4397         old_len = strlen(old_string);
4398         new_len = strlen(new_string);
4399
4400         l = strlen(text);
4401         r = new(char, l+1);
4402         if (!r)
4403                 return NULL;
4404
4405         f = text;
4406         t = r;
4407         while (*f) {
4408                 char *a;
4409                 size_t d, nl;
4410
4411                 if (!startswith(f, old_string)) {
4412                         *(t++) = *(f++);
4413                         continue;
4414                 }
4415
4416                 d = t - r;
4417                 nl = l - old_len + new_len;
4418                 a = realloc(r, nl + 1);
4419                 if (!a)
4420                         goto oom;
4421
4422                 l = nl;
4423                 r = a;
4424                 t = r + d;
4425
4426                 t = stpcpy(t, new_string);
4427                 f += old_len;
4428         }
4429
4430         *t = 0;
4431         return r;
4432
4433 oom:
4434         free(r);
4435         return NULL;
4436 }
4437
4438 char *strip_tab_ansi(char **ibuf, size_t *_isz) {
4439         const char *i, *begin = NULL;
4440         enum {
4441                 STATE_OTHER,
4442                 STATE_ESCAPE,
4443                 STATE_BRACKET
4444         } state = STATE_OTHER;
4445         char *obuf = NULL;
4446         size_t osz = 0, isz;
4447         FILE *f;
4448
4449         assert(ibuf);
4450         assert(*ibuf);
4451
4452         /* Strips ANSI color and replaces TABs by 8 spaces */
4453
4454         isz = _isz ? *_isz : strlen(*ibuf);
4455
4456         f = open_memstream(&obuf, &osz);
4457         if (!f)
4458                 return NULL;
4459
4460         for (i = *ibuf; i < *ibuf + isz + 1; i++) {
4461
4462                 switch (state) {
4463
4464                 case STATE_OTHER:
4465                         if (i >= *ibuf + isz) /* EOT */
4466                                 break;
4467                         else if (*i == '\x1B')
4468                                 state = STATE_ESCAPE;
4469                         else if (*i == '\t')
4470                                 fputs("        ", f);
4471                         else
4472                                 fputc(*i, f);
4473                         break;
4474
4475                 case STATE_ESCAPE:
4476                         if (i >= *ibuf + isz) { /* EOT */
4477                                 fputc('\x1B', f);
4478                                 break;
4479                         } else if (*i == '[') {
4480                                 state = STATE_BRACKET;
4481                                 begin = i + 1;
4482                         } else {
4483                                 fputc('\x1B', f);
4484                                 fputc(*i, f);
4485                                 state = STATE_OTHER;
4486                         }
4487
4488                         break;
4489
4490                 case STATE_BRACKET:
4491
4492                         if (i >= *ibuf + isz || /* EOT */
4493                             (!(*i >= '0' && *i <= '9') && *i != ';' && *i != 'm')) {
4494                                 fputc('\x1B', f);
4495                                 fputc('[', f);
4496                                 state = STATE_OTHER;
4497                                 i = begin-1;
4498                         } else if (*i == 'm')
4499                                 state = STATE_OTHER;
4500                         break;
4501                 }
4502         }
4503
4504         if (ferror(f)) {
4505                 fclose(f);
4506                 free(obuf);
4507                 return NULL;
4508         }
4509
4510         fclose(f);
4511
4512         free(*ibuf);
4513         *ibuf = obuf;
4514
4515         if (_isz)
4516                 *_isz = osz;
4517
4518         return obuf;
4519 }
4520
4521 int on_ac_power(void) {
4522         bool found_offline = false, found_online = false;
4523         _cleanup_closedir_ DIR *d = NULL;
4524
4525         d = opendir("/sys/class/power_supply");
4526         if (!d)
4527                 return errno == ENOENT ? true : -errno;
4528
4529         for (;;) {
4530                 struct dirent *de;
4531                 _cleanup_close_ int fd = -1, device = -1;
4532                 char contents[6];
4533                 ssize_t n;
4534
4535                 errno = 0;
4536                 de = readdir(d);
4537                 if (!de && errno != 0)
4538                         return -errno;
4539
4540                 if (!de)
4541                         break;
4542
4543                 if (hidden_file(de->d_name))
4544                         continue;
4545
4546                 device = openat(dirfd(d), de->d_name, O_DIRECTORY|O_RDONLY|O_CLOEXEC|O_NOCTTY);
4547                 if (device < 0) {
4548                         if (errno == ENOENT || errno == ENOTDIR)
4549                                 continue;
4550
4551                         return -errno;
4552                 }
4553
4554                 fd = openat(device, "type", O_RDONLY|O_CLOEXEC|O_NOCTTY);
4555                 if (fd < 0) {
4556                         if (errno == ENOENT)
4557                                 continue;
4558
4559                         return -errno;
4560                 }
4561
4562                 n = read(fd, contents, sizeof(contents));
4563                 if (n < 0)
4564                         return -errno;
4565
4566                 if (n != 6 || memcmp(contents, "Mains\n", 6))
4567                         continue;
4568
4569                 safe_close(fd);
4570                 fd = openat(device, "online", O_RDONLY|O_CLOEXEC|O_NOCTTY);
4571                 if (fd < 0) {
4572                         if (errno == ENOENT)
4573                                 continue;
4574
4575                         return -errno;
4576                 }
4577
4578                 n = read(fd, contents, sizeof(contents));
4579                 if (n < 0)
4580                         return -errno;
4581
4582                 if (n != 2 || contents[1] != '\n')
4583                         return -EIO;
4584
4585                 if (contents[0] == '1') {
4586                         found_online = true;
4587                         break;
4588                 } else if (contents[0] == '0')
4589                         found_offline = true;
4590                 else
4591                         return -EIO;
4592         }
4593
4594         return found_online || !found_offline;
4595 }
4596 #endif // 0
4597
4598 static int search_and_fopen_internal(const char *path, const char *mode, const char *root, char **search, FILE **_f) {
4599         char **i;
4600
4601         assert(path);
4602         assert(mode);
4603         assert(_f);
4604
4605         if (!path_strv_resolve_uniq(search, root))
4606                 return -ENOMEM;
4607
4608         STRV_FOREACH(i, search) {
4609                 _cleanup_free_ char *p = NULL;
4610                 FILE *f;
4611
4612                 if (root)
4613                         p = strjoin(root, *i, "/", path, NULL);
4614                 else
4615                         p = strjoin(*i, "/", path, NULL);
4616                 if (!p)
4617                         return -ENOMEM;
4618
4619                 f = fopen(p, mode);
4620                 if (f) {
4621                         *_f = f;
4622                         return 0;
4623                 }
4624
4625                 if (errno != ENOENT)
4626                         return -errno;
4627         }
4628
4629         return -ENOENT;
4630 }
4631
4632 int search_and_fopen(const char *path, const char *mode, const char *root, const char **search, FILE **_f) {
4633         _cleanup_strv_free_ char **copy = NULL;
4634
4635         assert(path);
4636         assert(mode);
4637         assert(_f);
4638
4639         if (path_is_absolute(path)) {
4640                 FILE *f;
4641
4642                 f = fopen(path, mode);
4643                 if (f) {
4644                         *_f = f;
4645                         return 0;
4646                 }
4647
4648                 return -errno;
4649         }
4650
4651         copy = strv_copy((char**) search);
4652         if (!copy)
4653                 return -ENOMEM;
4654
4655         return search_and_fopen_internal(path, mode, root, copy, _f);
4656 }
4657
4658 /// UNNEEDED by elogind
4659 #if 0
4660 int search_and_fopen_nulstr(const char *path, const char *mode, const char *root, const char *search, FILE **_f) {
4661         _cleanup_strv_free_ char **s = NULL;
4662
4663         if (path_is_absolute(path)) {
4664                 FILE *f;
4665
4666                 f = fopen(path, mode);
4667                 if (f) {
4668                         *_f = f;
4669                         return 0;
4670                 }
4671
4672                 return -errno;
4673         }
4674
4675         s = strv_split_nulstr(search);
4676         if (!s)
4677                 return -ENOMEM;
4678
4679         return search_and_fopen_internal(path, mode, root, s, _f);
4680 }
4681 #endif // 0
4682
4683 char *strextend(char **x, ...) {
4684         va_list ap;
4685         size_t f, l;
4686         char *r, *p;
4687
4688         assert(x);
4689
4690         l = f = *x ? strlen(*x) : 0;
4691
4692         va_start(ap, x);
4693         for (;;) {
4694                 const char *t;
4695                 size_t n;
4696
4697                 t = va_arg(ap, const char *);
4698                 if (!t)
4699                         break;
4700
4701                 n = strlen(t);
4702                 if (n > ((size_t) -1) - l) {
4703                         va_end(ap);
4704                         return NULL;
4705                 }
4706
4707                 l += n;
4708         }
4709         va_end(ap);
4710
4711         r = realloc(*x, l+1);
4712         if (!r)
4713                 return NULL;
4714
4715         p = r + f;
4716
4717         va_start(ap, x);
4718         for (;;) {
4719                 const char *t;
4720
4721                 t = va_arg(ap, const char *);
4722                 if (!t)
4723                         break;
4724
4725                 p = stpcpy(p, t);
4726         }
4727         va_end(ap);
4728
4729         *p = 0;
4730         *x = r;
4731
4732         return r + l;
4733 }
4734
4735 char *strrep(const char *s, unsigned n) {
4736         size_t l;
4737         char *r, *p;
4738         unsigned i;
4739
4740         assert(s);
4741
4742         l = strlen(s);
4743         p = r = malloc(l * n + 1);
4744         if (!r)
4745                 return NULL;
4746
4747         for (i = 0; i < n; i++)
4748                 p = stpcpy(p, s);
4749
4750         *p = 0;
4751         return r;
4752 }
4753
4754 void* greedy_realloc(void **p, size_t *allocated, size_t need, size_t size) {
4755         size_t a, newalloc;
4756         void *q;
4757
4758         assert(p);
4759         assert(allocated);
4760
4761         if (*allocated >= need)
4762                 return *p;
4763
4764         newalloc = MAX(need * 2, 64u / size);
4765         a = newalloc * size;
4766
4767         /* check for overflows */
4768         if (a < size * need)
4769                 return NULL;
4770
4771         q = realloc(*p, a);
4772         if (!q)
4773                 return NULL;
4774
4775         *p = q;
4776         *allocated = newalloc;
4777         return q;
4778 }
4779
4780 void* greedy_realloc0(void **p, size_t *allocated, size_t need, size_t size) {
4781         size_t prev;
4782         uint8_t *q;
4783
4784         assert(p);
4785         assert(allocated);
4786
4787         prev = *allocated;
4788
4789         q = greedy_realloc(p, allocated, need, size);
4790         if (!q)
4791                 return NULL;
4792
4793         if (*allocated > prev)
4794                 memzero(q + prev * size, (*allocated - prev) * size);
4795
4796         return q;
4797 }
4798
4799 bool id128_is_valid(const char *s) {
4800         size_t i, l;
4801
4802         l = strlen(s);
4803         if (l == 32) {
4804
4805                 /* Simple formatted 128bit hex string */
4806
4807                 for (i = 0; i < l; i++) {
4808                         char c = s[i];
4809
4810                         if (!(c >= '0' && c <= '9') &&
4811                             !(c >= 'a' && c <= 'z') &&
4812                             !(c >= 'A' && c <= 'Z'))
4813                                 return false;
4814                 }
4815
4816         } else if (l == 36) {
4817
4818                 /* Formatted UUID */
4819
4820                 for (i = 0; i < l; i++) {
4821                         char c = s[i];
4822
4823                         if ((i == 8 || i == 13 || i == 18 || i == 23)) {
4824                                 if (c != '-')
4825                                         return false;
4826                         } else {
4827                                 if (!(c >= '0' && c <= '9') &&
4828                                     !(c >= 'a' && c <= 'z') &&
4829                                     !(c >= 'A' && c <= 'Z'))
4830                                         return false;
4831                         }
4832                 }
4833
4834         } else
4835                 return false;
4836
4837         return true;
4838 }
4839
4840 /// UNNEEDED by elogind
4841 #if 0
4842 int split_pair(const char *s, const char *sep, char **l, char **r) {
4843         char *x, *a, *b;
4844
4845         assert(s);
4846         assert(sep);
4847         assert(l);
4848         assert(r);
4849
4850         if (isempty(sep))
4851                 return -EINVAL;
4852
4853         x = strstr(s, sep);
4854         if (!x)
4855                 return -EINVAL;
4856
4857         a = strndup(s, x - s);
4858         if (!a)
4859                 return -ENOMEM;
4860
4861         b = strdup(x + strlen(sep));
4862         if (!b) {
4863                 free(a);
4864                 return -ENOMEM;
4865         }
4866
4867         *l = a;
4868         *r = b;
4869
4870         return 0;
4871 }
4872
4873 int shall_restore_state(void) {
4874         _cleanup_free_ char *value = NULL;
4875         int r;
4876
4877         r = get_proc_cmdline_key("systemd.restore_state=", &value);
4878         if (r < 0)
4879                 return r;
4880         if (r == 0)
4881                 return true;
4882
4883         return parse_boolean(value) != 0;
4884 }
4885 #endif // 0
4886
4887 int proc_cmdline(char **ret) {
4888         assert(ret);
4889
4890         if (detect_container(NULL) > 0)
4891                 return get_process_cmdline(1, 0, false, ret);
4892         else
4893                 return read_one_line_file("/proc/cmdline", ret);
4894 }
4895
4896 int parse_proc_cmdline(int (*parse_item)(const char *key, const char *value)) {
4897         _cleanup_free_ char *line = NULL;
4898         const char *p;
4899         int r;
4900
4901         assert(parse_item);
4902
4903         r = proc_cmdline(&line);
4904         if (r < 0)
4905                 return r;
4906
4907         p = line;
4908         for (;;) {
4909                 _cleanup_free_ char *word = NULL;
4910                 char *value = NULL;
4911
4912                 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
4913                 if (r < 0)
4914                         return r;
4915                 if (r == 0)
4916                         break;
4917
4918                 /* Filter out arguments that are intended only for the
4919                  * initrd */
4920                 if (!in_initrd() && startswith(word, "rd."))
4921                         continue;
4922
4923                 value = strchr(word, '=');
4924                 if (value)
4925                         *(value++) = 0;
4926
4927                 r = parse_item(word, value);
4928                 if (r < 0)
4929                         return r;
4930         }
4931
4932         return 0;
4933 }
4934
4935 int get_proc_cmdline_key(const char *key, char **value) {
4936         _cleanup_free_ char *line = NULL, *ret = NULL;
4937         bool found = false;
4938         const char *p;
4939         int r;
4940
4941         assert(key);
4942
4943         r = proc_cmdline(&line);
4944         if (r < 0)
4945                 return r;
4946
4947         p = line;
4948         for (;;) {
4949                 _cleanup_free_ char *word = NULL;
4950                 const char *e;
4951
4952                 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_RELAX);
4953                 if (r < 0)
4954                         return r;
4955                 if (r == 0)
4956                         break;
4957
4958                 /* Filter out arguments that are intended only for the
4959                  * initrd */
4960                 if (!in_initrd() && startswith(word, "rd."))
4961                         continue;
4962
4963                 if (value) {
4964                         e = startswith(word, key);
4965                         if (!e)
4966                                 continue;
4967
4968                         r = free_and_strdup(&ret, e);
4969                         if (r < 0)
4970                                 return r;
4971
4972                         found = true;
4973                 } else {
4974                         if (streq(word, key))
4975                                 found = true;
4976                 }
4977         }
4978
4979         if (value) {
4980                 *value = ret;
4981                 ret = NULL;
4982         }
4983
4984         return found;
4985
4986 }
4987
4988 int container_get_leader(const char *machine, pid_t *pid) {
4989         _cleanup_free_ char *s = NULL, *class = NULL;
4990         const char *p;
4991         pid_t leader;
4992         int r;
4993
4994         assert(machine);
4995         assert(pid);
4996
4997         if (!machine_name_is_valid(machine))
4998                 return -EINVAL;
4999
5000         p = strjoina("/run/systemd/machines/", machine);
5001         r = parse_env_file(p, NEWLINE, "LEADER", &s, "CLASS", &class, NULL);
5002         if (r == -ENOENT)
5003                 return -EHOSTDOWN;
5004         if (r < 0)
5005                 return r;
5006         if (!s)
5007                 return -EIO;
5008
5009         if (!streq_ptr(class, "container"))
5010                 return -EIO;
5011
5012         r = parse_pid(s, &leader);
5013         if (r < 0)
5014                 return r;
5015         if (leader <= 1)
5016                 return -EIO;
5017
5018         *pid = leader;
5019         return 0;
5020 }
5021
5022 int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd) {
5023         _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, netnsfd = -1, usernsfd = -1;
5024         int rfd = -1;
5025
5026         assert(pid >= 0);
5027
5028         if (mntns_fd) {
5029                 const char *mntns;
5030
5031                 mntns = procfs_file_alloca(pid, "ns/mnt");
5032                 mntnsfd = open(mntns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5033                 if (mntnsfd < 0)
5034                         return -errno;
5035         }
5036
5037         if (pidns_fd) {
5038                 const char *pidns;
5039
5040                 pidns = procfs_file_alloca(pid, "ns/pid");
5041                 pidnsfd = open(pidns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5042                 if (pidnsfd < 0)
5043                         return -errno;
5044         }
5045
5046         if (netns_fd) {
5047                 const char *netns;
5048
5049                 netns = procfs_file_alloca(pid, "ns/net");
5050                 netnsfd = open(netns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5051                 if (netnsfd < 0)
5052                         return -errno;
5053         }
5054
5055         if (userns_fd) {
5056                 const char *userns;
5057
5058                 userns = procfs_file_alloca(pid, "ns/user");
5059                 usernsfd = open(userns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
5060                 if (usernsfd < 0 && errno != ENOENT)
5061                         return -errno;
5062         }
5063
5064         if (root_fd) {
5065                 const char *root;
5066
5067                 root = procfs_file_alloca(pid, "root");
5068                 rfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
5069                 if (rfd < 0)
5070                         return -errno;
5071         }
5072
5073         if (pidns_fd)
5074                 *pidns_fd = pidnsfd;
5075
5076         if (mntns_fd)
5077                 *mntns_fd = mntnsfd;
5078
5079         if (netns_fd)
5080                 *netns_fd = netnsfd;
5081
5082         if (userns_fd)
5083                 *userns_fd = usernsfd;
5084
5085         if (root_fd)
5086                 *root_fd = rfd;
5087
5088         pidnsfd = mntnsfd = netnsfd = usernsfd = -1;
5089
5090         return 0;
5091 }
5092
5093 int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd) {
5094         if (userns_fd >= 0) {
5095                 /* Can't setns to your own userns, since then you could
5096                  * escalate from non-root to root in your own namespace, so
5097                  * check if namespaces equal before attempting to enter. */
5098                 _cleanup_free_ char *userns_fd_path = NULL;
5099                 int r;
5100                 if (asprintf(&userns_fd_path, "/proc/self/fd/%d", userns_fd) < 0)
5101                         return -ENOMEM;
5102
5103                 r = files_same(userns_fd_path, "/proc/self/ns/user");
5104                 if (r < 0)
5105                         return r;
5106                 if (r)
5107                         userns_fd = -1;
5108         }
5109
5110         if (pidns_fd >= 0)
5111                 if (setns(pidns_fd, CLONE_NEWPID) < 0)
5112                         return -errno;
5113
5114         if (mntns_fd >= 0)
5115                 if (setns(mntns_fd, CLONE_NEWNS) < 0)
5116                         return -errno;
5117
5118         if (netns_fd >= 0)
5119                 if (setns(netns_fd, CLONE_NEWNET) < 0)
5120                         return -errno;
5121
5122         if (userns_fd >= 0)
5123                 if (setns(userns_fd, CLONE_NEWUSER) < 0)
5124                         return -errno;
5125
5126         if (root_fd >= 0) {
5127                 if (fchdir(root_fd) < 0)
5128                         return -errno;
5129
5130                 if (chroot(".") < 0)
5131                         return -errno;
5132         }
5133
5134         return reset_uid_gid();
5135 }
5136
5137 int getpeercred(int fd, struct ucred *ucred) {
5138         socklen_t n = sizeof(struct ucred);
5139         struct ucred u;
5140         int r;
5141
5142         assert(fd >= 0);
5143         assert(ucred);
5144
5145         r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
5146         if (r < 0)
5147                 return -errno;
5148
5149         if (n != sizeof(struct ucred))
5150                 return -EIO;
5151
5152         /* Check if the data is actually useful and not suppressed due
5153          * to namespacing issues */
5154         if (u.pid <= 0)
5155                 return -ENODATA;
5156         if (u.uid == UID_INVALID)
5157                 return -ENODATA;
5158         if (u.gid == GID_INVALID)
5159                 return -ENODATA;
5160
5161         *ucred = u;
5162         return 0;
5163 }
5164
5165 int getpeersec(int fd, char **ret) {
5166         socklen_t n = 64;
5167         char *s;
5168         int r;
5169
5170         assert(fd >= 0);
5171         assert(ret);
5172
5173         s = new0(char, n);
5174         if (!s)
5175                 return -ENOMEM;
5176
5177         r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
5178         if (r < 0) {
5179                 free(s);
5180
5181                 if (errno != ERANGE)
5182                         return -errno;
5183
5184                 s = new0(char, n);
5185                 if (!s)
5186                         return -ENOMEM;
5187
5188                 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
5189                 if (r < 0) {
5190                         free(s);
5191                         return -errno;
5192                 }
5193         }
5194
5195         if (isempty(s)) {
5196                 free(s);
5197                 return -EOPNOTSUPP;
5198         }
5199
5200         *ret = s;
5201         return 0;
5202 }
5203
5204 /* This is much like like mkostemp() but is subject to umask(). */
5205 int mkostemp_safe(char *pattern, int flags) {
5206         _cleanup_umask_ mode_t u;
5207         int fd;
5208
5209         assert(pattern);
5210
5211         u = umask(077);
5212
5213         fd = mkostemp(pattern, flags);
5214         if (fd < 0)
5215                 return -errno;
5216
5217         return fd;
5218 }
5219
5220 /// UNNEEDED by elogind
5221 #if 0
5222 int open_tmpfile(const char *path, int flags) {
5223         char *p;
5224         int fd;
5225
5226         assert(path);
5227
5228 #ifdef O_TMPFILE
5229         /* Try O_TMPFILE first, if it is supported */
5230         fd = open(path, flags|O_TMPFILE|O_EXCL, S_IRUSR|S_IWUSR);
5231         if (fd >= 0)
5232                 return fd;
5233 #endif
5234
5235         /* Fall back to unguessable name + unlinking */
5236         p = strjoina(path, "/systemd-tmp-XXXXXX");
5237
5238         fd = mkostemp_safe(p, flags);
5239         if (fd < 0)
5240                 return fd;
5241
5242         unlink(p);
5243         return fd;
5244 }
5245 #endif // 0
5246
5247 int fd_warn_permissions(const char *path, int fd) {
5248         struct stat st;
5249
5250         if (fstat(fd, &st) < 0)
5251                 return -errno;
5252
5253         if (st.st_mode & 0111)
5254                 log_warning("Configuration file %s is marked executable. Please remove executable permission bits. Proceeding anyway.", path);
5255
5256         if (st.st_mode & 0002)
5257                 log_warning("Configuration file %s is marked world-writable. Please remove world writability permission bits. Proceeding anyway.", path);
5258
5259         if (getpid() == 1 && (st.st_mode & 0044) != 0044)
5260                 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);
5261
5262         return 0;
5263 }
5264
5265 /// UNNEEDED by elogind
5266 #if 0
5267 unsigned long personality_from_string(const char *p) {
5268
5269         /* Parse a personality specifier. We introduce our own
5270          * identifiers that indicate specific ABIs, rather than just
5271          * hints regarding the register size, since we want to keep
5272          * things open for multiple locally supported ABIs for the
5273          * same register size. We try to reuse the ABI identifiers
5274          * used by libseccomp. */
5275
5276 #if defined(__x86_64__)
5277
5278         if (streq(p, "x86"))
5279                 return PER_LINUX32;
5280
5281         if (streq(p, "x86-64"))
5282                 return PER_LINUX;
5283
5284 #elif defined(__i386__)
5285
5286         if (streq(p, "x86"))
5287                 return PER_LINUX;
5288 #endif
5289
5290         return PERSONALITY_INVALID;
5291 }
5292
5293 const char* personality_to_string(unsigned long p) {
5294
5295 #if defined(__x86_64__)
5296
5297         if (p == PER_LINUX32)
5298                 return "x86";
5299
5300         if (p == PER_LINUX)
5301                 return "x86-64";
5302
5303 #elif defined(__i386__)
5304
5305         if (p == PER_LINUX)
5306                 return "x86";
5307 #endif
5308
5309         return NULL;
5310 }
5311 #endif // 0
5312
5313 uint64_t physical_memory(void) {
5314         long mem;
5315
5316         /* We return this as uint64_t in case we are running as 32bit
5317          * process on a 64bit kernel with huge amounts of memory */
5318
5319         mem = sysconf(_SC_PHYS_PAGES);
5320         assert(mem > 0);
5321
5322         return (uint64_t) mem * (uint64_t) page_size();
5323 }
5324
5325 /// UNNEEDED by elogind
5326 #if 0
5327 void hexdump(FILE *f, const void *p, size_t s) {
5328         const uint8_t *b = p;
5329         unsigned n = 0;
5330
5331         assert(s == 0 || b);
5332
5333         while (s > 0) {
5334                 size_t i;
5335
5336                 fprintf(f, "%04x  ", n);
5337
5338                 for (i = 0; i < 16; i++) {
5339
5340                         if (i >= s)
5341                                 fputs("   ", f);
5342                         else
5343                                 fprintf(f, "%02x ", b[i]);
5344
5345                         if (i == 7)
5346                                 fputc(' ', f);
5347                 }
5348
5349                 fputc(' ', f);
5350
5351                 for (i = 0; i < 16; i++) {
5352
5353                         if (i >= s)
5354                                 fputc(' ', f);
5355                         else
5356                                 fputc(isprint(b[i]) ? (char) b[i] : '.', f);
5357                 }
5358
5359                 fputc('\n', f);
5360
5361                 if (s < 16)
5362                         break;
5363
5364                 n += 16;
5365                 b += 16;
5366                 s -= 16;
5367         }
5368 }
5369
5370 int update_reboot_param_file(const char *param) {
5371         int r = 0;
5372
5373         if (param) {
5374
5375                 r = write_string_file(REBOOT_PARAM_FILE, param, WRITE_STRING_FILE_CREATE);
5376                 if (r < 0)
5377                         log_error("Failed to write reboot param to "
5378                                   REBOOT_PARAM_FILE": %s", strerror(-r));
5379         } else
5380                 unlink(REBOOT_PARAM_FILE);
5381
5382         return r;
5383 }
5384
5385 int umount_recursive(const char *prefix, int flags) {
5386         bool again;
5387         int n = 0, r;
5388
5389         /* Try to umount everything recursively below a
5390          * directory. Also, take care of stacked mounts, and keep
5391          * unmounting them until they are gone. */
5392
5393         do {
5394                 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
5395
5396                 again = false;
5397                 r = 0;
5398
5399                 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
5400                 if (!proc_self_mountinfo)
5401                         return -errno;
5402
5403                 for (;;) {
5404                         _cleanup_free_ char *path = NULL, *p = NULL;
5405                         int k;
5406
5407                         k = fscanf(proc_self_mountinfo,
5408                                    "%*s "       /* (1) mount id */
5409                                    "%*s "       /* (2) parent id */
5410                                    "%*s "       /* (3) major:minor */
5411                                    "%*s "       /* (4) root */
5412                                    "%ms "       /* (5) mount point */
5413                                    "%*s"        /* (6) mount options */
5414                                    "%*[^-]"     /* (7) optional fields */
5415                                    "- "         /* (8) separator */
5416                                    "%*s "       /* (9) file system type */
5417                                    "%*s"        /* (10) mount source */
5418                                    "%*s"        /* (11) mount options 2 */
5419                                    "%*[^\n]",   /* some rubbish at the end */
5420                                    &path);
5421                         if (k != 1) {
5422                                 if (k == EOF)
5423                                         break;
5424
5425                                 continue;
5426                         }
5427
5428                         r = cunescape(path, UNESCAPE_RELAX, &p);
5429                         if (r < 0)
5430                                 return r;
5431
5432                         if (!path_startswith(p, prefix))
5433                                 continue;
5434
5435                         if (umount2(p, flags) < 0) {
5436                                 r = -errno;
5437                                 continue;
5438                         }
5439
5440                         again = true;
5441                         n++;
5442
5443                         break;
5444                 }
5445
5446         } while (again);
5447
5448         return r ? r : n;
5449 }
5450
5451 static int get_mount_flags(const char *path, unsigned long *flags) {
5452         struct statvfs buf;
5453
5454         if (statvfs(path, &buf) < 0)
5455                 return -errno;
5456         *flags = buf.f_flag;
5457         return 0;
5458 }
5459
5460 int bind_remount_recursive(const char *prefix, bool ro) {
5461         _cleanup_set_free_free_ Set *done = NULL;
5462         _cleanup_free_ char *cleaned = NULL;
5463         int r;
5464
5465         /* Recursively remount a directory (and all its submounts)
5466          * read-only or read-write. If the directory is already
5467          * mounted, we reuse the mount and simply mark it
5468          * MS_BIND|MS_RDONLY (or remove the MS_RDONLY for read-write
5469          * operation). If it isn't we first make it one. Afterwards we
5470          * apply MS_BIND|MS_RDONLY (or remove MS_RDONLY) to all
5471          * submounts we can access, too. When mounts are stacked on
5472          * the same mount point we only care for each individual
5473          * "top-level" mount on each point, as we cannot
5474          * influence/access the underlying mounts anyway. We do not
5475          * have any effect on future submounts that might get
5476          * propagated, they migt be writable. This includes future
5477          * submounts that have been triggered via autofs. */
5478
5479         cleaned = strdup(prefix);
5480         if (!cleaned)
5481                 return -ENOMEM;
5482
5483         path_kill_slashes(cleaned);
5484
5485         done = set_new(&string_hash_ops);
5486         if (!done)
5487                 return -ENOMEM;
5488
5489         for (;;) {
5490                 _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
5491                 _cleanup_set_free_free_ Set *todo = NULL;
5492                 bool top_autofs = false;
5493                 char *x;
5494                 unsigned long orig_flags;
5495
5496                 todo = set_new(&string_hash_ops);
5497                 if (!todo)
5498                         return -ENOMEM;
5499
5500                 proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
5501                 if (!proc_self_mountinfo)
5502                         return -errno;
5503
5504                 for (;;) {
5505                         _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
5506                         int k;
5507
5508                         k = fscanf(proc_self_mountinfo,
5509                                    "%*s "       /* (1) mount id */
5510                                    "%*s "       /* (2) parent id */
5511                                    "%*s "       /* (3) major:minor */
5512                                    "%*s "       /* (4) root */
5513                                    "%ms "       /* (5) mount point */
5514                                    "%*s"        /* (6) mount options (superblock) */
5515                                    "%*[^-]"     /* (7) optional fields */
5516                                    "- "         /* (8) separator */
5517                                    "%ms "       /* (9) file system type */
5518                                    "%*s"        /* (10) mount source */
5519                                    "%*s"        /* (11) mount options (bind mount) */
5520                                    "%*[^\n]",   /* some rubbish at the end */
5521                                    &path,
5522                                    &type);
5523                         if (k != 2) {
5524                                 if (k == EOF)
5525                                         break;
5526
5527                                 continue;
5528                         }
5529
5530                         r = cunescape(path, UNESCAPE_RELAX, &p);
5531                         if (r < 0)
5532                                 return r;
5533
5534                         /* Let's ignore autofs mounts.  If they aren't
5535                          * triggered yet, we want to avoid triggering
5536                          * them, as we don't make any guarantees for
5537                          * future submounts anyway.  If they are
5538                          * already triggered, then we will find
5539                          * another entry for this. */
5540                         if (streq(type, "autofs")) {
5541                                 top_autofs = top_autofs || path_equal(cleaned, p);
5542                                 continue;
5543                         }
5544
5545                         if (path_startswith(p, cleaned) &&
5546                             !set_contains(done, p)) {
5547
5548                                 r = set_consume(todo, p);
5549                                 p = NULL;
5550
5551                                 if (r == -EEXIST)
5552                                         continue;
5553                                 if (r < 0)
5554                                         return r;
5555                         }
5556                 }
5557
5558                 /* If we have no submounts to process anymore and if
5559                  * the root is either already done, or an autofs, we
5560                  * are done */
5561                 if (set_isempty(todo) &&
5562                     (top_autofs || set_contains(done, cleaned)))
5563                         return 0;
5564
5565                 if (!set_contains(done, cleaned) &&
5566                     !set_contains(todo, cleaned)) {
5567                         /* The prefix directory itself is not yet a
5568                          * mount, make it one. */
5569                         if (mount(cleaned, cleaned, NULL, MS_BIND|MS_REC, NULL) < 0)
5570                                 return -errno;
5571
5572                         orig_flags = 0;
5573                         (void) get_mount_flags(cleaned, &orig_flags);
5574                         orig_flags &= ~MS_RDONLY;
5575
5576                         if (mount(NULL, prefix, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0)
5577                                 return -errno;
5578
5579                         x = strdup(cleaned);
5580                         if (!x)
5581                                 return -ENOMEM;
5582
5583                         r = set_consume(done, x);
5584                         if (r < 0)
5585                                 return r;
5586                 }
5587
5588                 while ((x = set_steal_first(todo))) {
5589
5590                         r = set_consume(done, x);
5591                         if (r == -EEXIST || r == 0)
5592                                 continue;
5593                         if (r < 0)
5594                                 return r;
5595
5596                         /* Try to reuse the original flag set, but
5597                          * don't care for errors, in case of
5598                          * obstructed mounts */
5599                         orig_flags = 0;
5600                         (void) get_mount_flags(x, &orig_flags);
5601                         orig_flags &= ~MS_RDONLY;
5602
5603                         if (mount(NULL, x, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) {
5604
5605                                 /* Deal with mount points that are
5606                                  * obstructed by a later mount */
5607
5608                                 if (errno != ENOENT)
5609                                         return -errno;
5610                         }
5611
5612                 }
5613         }
5614 }
5615 #endif // 0
5616
5617 int fflush_and_check(FILE *f) {
5618         assert(f);
5619
5620         errno = 0;
5621         fflush(f);
5622
5623         if (ferror(f))
5624                 return errno ? -errno : -EIO;
5625
5626         return 0;
5627 }
5628
5629 int tempfn_xxxxxx(const char *p, const char *extra, char **ret) {
5630         const char *fn;
5631         char *t;
5632
5633         assert(p);
5634         assert(ret);
5635
5636         /*
5637          * Turns this:
5638          *         /foo/bar/waldo
5639          *
5640          * Into this:
5641          *         /foo/bar/.#<extra>waldoXXXXXX
5642          */
5643
5644         fn = basename(p);
5645         if (!filename_is_valid(fn))
5646                 return -EINVAL;
5647
5648         if (extra == NULL)
5649                 extra = "";
5650
5651         t = new(char, strlen(p) + 2 + strlen(extra) + 6 + 1);
5652         if (!t)
5653                 return -ENOMEM;
5654
5655         strcpy(stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn), "XXXXXX");
5656
5657         *ret = path_kill_slashes(t);
5658         return 0;
5659 }
5660
5661 int tempfn_random(const char *p, const char *extra, char **ret) {
5662         const char *fn;
5663         char *t, *x;
5664         uint64_t u;
5665         unsigned i;
5666
5667         assert(p);
5668         assert(ret);
5669
5670         /*
5671          * Turns this:
5672          *         /foo/bar/waldo
5673          *
5674          * Into this:
5675          *         /foo/bar/.#<extra>waldobaa2a261115984a9
5676          */
5677
5678         fn = basename(p);
5679         if (!filename_is_valid(fn))
5680                 return -EINVAL;
5681
5682         if (!extra)
5683                 extra = "";
5684
5685         t = new(char, strlen(p) + 2 + strlen(extra) + 16 + 1);
5686         if (!t)
5687                 return -ENOMEM;
5688
5689         x = stpcpy(stpcpy(stpcpy(mempcpy(t, p, fn - p), ".#"), extra), fn);
5690
5691         u = random_u64();
5692         for (i = 0; i < 16; i++) {
5693                 *(x++) = hexchar(u & 0xF);
5694                 u >>= 4;
5695         }
5696
5697         *x = 0;
5698
5699         *ret = path_kill_slashes(t);
5700         return 0;
5701 }
5702
5703 /// UNNEEDED by elogind
5704 #if 0
5705 int tempfn_random_child(const char *p, const char *extra, char **ret) {
5706         char *t, *x;
5707         uint64_t u;
5708         unsigned i;
5709
5710         assert(p);
5711         assert(ret);
5712
5713         /* Turns this:
5714          *         /foo/bar/waldo
5715          * Into this:
5716          *         /foo/bar/waldo/.#<extra>3c2b6219aa75d7d0
5717          */
5718
5719         if (!extra)
5720                 extra = "";
5721
5722         t = new(char, strlen(p) + 3 + strlen(extra) + 16 + 1);
5723         if (!t)
5724                 return -ENOMEM;
5725
5726         x = stpcpy(stpcpy(stpcpy(t, p), "/.#"), extra);
5727
5728         u = random_u64();
5729         for (i = 0; i < 16; i++) {
5730                 *(x++) = hexchar(u & 0xF);
5731                 u >>= 4;
5732         }
5733
5734         *x = 0;
5735
5736         *ret = path_kill_slashes(t);
5737         return 0;
5738 }
5739
5740 int take_password_lock(const char *root) {
5741
5742         struct flock flock = {
5743                 .l_type = F_WRLCK,
5744                 .l_whence = SEEK_SET,
5745                 .l_start = 0,
5746                 .l_len = 0,
5747         };
5748
5749         const char *path;
5750         int fd, r;
5751
5752         /* This is roughly the same as lckpwdf(), but not as awful. We
5753          * don't want to use alarm() and signals, hence we implement
5754          * our own trivial version of this.
5755          *
5756          * Note that shadow-utils also takes per-database locks in
5757          * addition to lckpwdf(). However, we don't given that they
5758          * are redundant as they they invoke lckpwdf() first and keep
5759          * it during everything they do. The per-database locks are
5760          * awfully racy, and thus we just won't do them. */
5761
5762         if (root)
5763                 path = strjoina(root, "/etc/.pwd.lock");
5764         else
5765                 path = "/etc/.pwd.lock";
5766
5767         fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
5768         if (fd < 0)
5769                 return -errno;
5770
5771         r = fcntl(fd, F_SETLKW, &flock);
5772         if (r < 0) {
5773                 safe_close(fd);
5774                 return -errno;
5775         }
5776
5777         return fd;
5778 }
5779
5780 int is_symlink(const char *path) {
5781         struct stat info;
5782
5783         if (lstat(path, &info) < 0)
5784                 return -errno;
5785
5786         return !!S_ISLNK(info.st_mode);
5787 }
5788 #endif // 0
5789
5790 int is_dir(const char* path, bool follow) {
5791         struct stat st;
5792         int r;
5793
5794         if (follow)
5795                 r = stat(path, &st);
5796         else
5797                 r = lstat(path, &st);
5798         if (r < 0)
5799                 return -errno;
5800
5801         return !!S_ISDIR(st.st_mode);
5802 }
5803
5804 /// UNNEEDED by elogind
5805 #if 0
5806 int is_device_node(const char *path) {
5807         struct stat info;
5808
5809         if (lstat(path, &info) < 0)
5810                 return -errno;
5811
5812         return !!(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode));
5813 }
5814 #endif // 0
5815
5816 int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) {
5817         _cleanup_free_ char *s = NULL;
5818         size_t allocated = 0, sz = 0;
5819         int r;
5820
5821         enum {
5822                 START,
5823                 VALUE,
5824                 VALUE_ESCAPE,
5825                 SINGLE_QUOTE,
5826                 SINGLE_QUOTE_ESCAPE,
5827                 DOUBLE_QUOTE,
5828                 DOUBLE_QUOTE_ESCAPE,
5829                 SEPARATOR,
5830         } state = START;
5831
5832         assert(p);
5833         assert(ret);
5834
5835         if (!separators)
5836                 separators = WHITESPACE;
5837
5838         /* Bail early if called after last value or with no input */
5839         if (!*p)
5840                 goto finish_force_terminate;
5841
5842         /* Parses the first word of a string, and returns it in
5843          * *ret. Removes all quotes in the process. When parsing fails
5844          * (because of an uneven number of quotes or similar), leaves
5845          * the pointer *p at the first invalid character. */
5846
5847         for (;;) {
5848                 char c = **p;
5849
5850                 switch (state) {
5851
5852                 case START:
5853                         if (flags & EXTRACT_DONT_COALESCE_SEPARATORS)
5854                                 if (!GREEDY_REALLOC(s, allocated, sz+1))
5855                                         return -ENOMEM;
5856
5857                         if (c == 0)
5858                                 goto finish_force_terminate;
5859                         else if (strchr(separators, c)) {
5860                                 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
5861                                         (*p) ++;
5862                                         goto finish_force_next;
5863                                 }
5864                                 break;
5865                         }
5866
5867                         /* We found a non-blank character, so we will always
5868                          * want to return a string (even if it is empty),
5869                          * allocate it here. */
5870                         if (!GREEDY_REALLOC(s, allocated, sz+1))
5871                                 return -ENOMEM;
5872
5873                         state = VALUE;
5874                         /* fallthrough */
5875
5876                 case VALUE:
5877                         if (c == 0)
5878                                 goto finish_force_terminate;
5879                         else if (c == '\'' && (flags & EXTRACT_QUOTES))
5880                                 state = SINGLE_QUOTE;
5881                         else if (c == '\\')
5882                                 state = VALUE_ESCAPE;
5883                         else if (c == '\"' && (flags & EXTRACT_QUOTES))
5884                                 state = DOUBLE_QUOTE;
5885                         else if (strchr(separators, c)) {
5886                                 if (flags & EXTRACT_DONT_COALESCE_SEPARATORS) {
5887                                         (*p) ++;
5888                                         goto finish_force_next;
5889                                 }
5890                                 state = SEPARATOR;
5891                         } else {
5892                                 if (!GREEDY_REALLOC(s, allocated, sz+2))
5893                                         return -ENOMEM;
5894
5895                                 s[sz++] = c;
5896                         }
5897
5898                         break;
5899
5900                 case SINGLE_QUOTE:
5901                         if (c == 0) {
5902                                 if (flags & EXTRACT_RELAX)
5903                                         goto finish_force_terminate;
5904                                 return -EINVAL;
5905                         } else if (c == '\'')
5906                                 state = VALUE;
5907                         else if (c == '\\')
5908                                 state = SINGLE_QUOTE_ESCAPE;
5909                         else {
5910                                 if (!GREEDY_REALLOC(s, allocated, sz+2))
5911                                         return -ENOMEM;
5912
5913                                 s[sz++] = c;
5914                         }
5915
5916                         break;
5917
5918                 case DOUBLE_QUOTE:
5919                         if (c == 0)
5920                                 return -EINVAL;
5921                         else if (c == '\"')
5922                                 state = VALUE;
5923                         else if (c == '\\')
5924                                 state = DOUBLE_QUOTE_ESCAPE;
5925                         else {
5926                                 if (!GREEDY_REALLOC(s, allocated, sz+2))
5927                                         return -ENOMEM;
5928
5929                                 s[sz++] = c;
5930                         }
5931
5932                         break;
5933
5934                 case SINGLE_QUOTE_ESCAPE:
5935                 case DOUBLE_QUOTE_ESCAPE:
5936                 case VALUE_ESCAPE:
5937                         if (!GREEDY_REALLOC(s, allocated, sz+7))
5938                                 return -ENOMEM;
5939
5940                         if (c == 0) {
5941                                 if ((flags & EXTRACT_CUNESCAPE_RELAX) &&
5942                                     (state == VALUE_ESCAPE || flags & EXTRACT_RELAX)) {
5943                                         /* If we find an unquoted trailing backslash and we're in
5944                                          * EXTRACT_CUNESCAPE_RELAX mode, keep it verbatim in the
5945                                          * output.
5946                                          *
5947                                          * Unbalanced quotes will only be allowed in EXTRACT_RELAX
5948                                          * mode, EXTRACT_CUNESCAPE_RELAX mode does not allow them.
5949                                          */
5950                                         s[sz++] = '\\';
5951                                         goto finish_force_terminate;
5952                                 }
5953                                 if (flags & EXTRACT_RELAX)
5954                                         goto finish_force_terminate;
5955                                 return -EINVAL;
5956                         }
5957
5958                         if (flags & EXTRACT_CUNESCAPE) {
5959                                 uint32_t u;
5960
5961                                 r = cunescape_one(*p, (size_t) -1, &c, &u);
5962                                 if (r < 0) {
5963                                         if (flags & EXTRACT_CUNESCAPE_RELAX) {
5964                                                 s[sz++] = '\\';
5965                                                 s[sz++] = c;
5966                                                 goto end_escape;
5967                                         }
5968                                         return -EINVAL;
5969                                 }
5970
5971                                 (*p) += r - 1;
5972
5973                                 if (c != 0)
5974                                         s[sz++] = c; /* normal explicit char */
5975                                 else
5976                                         sz += utf8_encode_unichar(s + sz, u); /* unicode chars we'll encode as utf8 */
5977                         } else
5978                                 s[sz++] = c;
5979
5980 end_escape:
5981                         state = (state == SINGLE_QUOTE_ESCAPE) ? SINGLE_QUOTE :
5982                                 (state == DOUBLE_QUOTE_ESCAPE) ? DOUBLE_QUOTE :
5983                                 VALUE;
5984                         break;
5985
5986                 case SEPARATOR:
5987                         if (c == 0)
5988                                 goto finish_force_terminate;
5989                         if (!strchr(separators, c))
5990                                 goto finish;
5991                         break;
5992                 }
5993
5994                 (*p) ++;
5995         }
5996
5997 finish_force_terminate:
5998         *p = NULL;
5999 finish:
6000         if (!s) {
6001                 *p = NULL;
6002                 *ret = NULL;
6003                 return 0;
6004         }
6005
6006 finish_force_next:
6007         s[sz] = 0;
6008         *ret = s;
6009         s = NULL;
6010
6011         return 1;
6012 }
6013
6014 /// UNNEEDED by elogind
6015 #if 0
6016 int extract_first_word_and_warn(
6017                 const char **p,
6018                 char **ret,
6019                 const char *separators,
6020                 ExtractFlags flags,
6021                 const char *unit,
6022                 const char *filename,
6023                 unsigned line,
6024                 const char *rvalue) {
6025         /* Try to unquote it, if it fails, warn about it and try again but this
6026          * time using EXTRACT_CUNESCAPE_RELAX to keep the backslashes verbatim
6027          * in invalid escape sequences. */
6028         const char *save;
6029         int r;
6030
6031         save = *p;
6032         r = extract_first_word(p, ret, separators, flags);
6033         if (r < 0 && !(flags&EXTRACT_CUNESCAPE_RELAX)) {
6034                 /* Retry it with EXTRACT_CUNESCAPE_RELAX. */
6035                 *p = save;
6036                 r = extract_first_word(p, ret, separators, flags|EXTRACT_CUNESCAPE_RELAX);
6037                 if (r < 0)
6038                         log_syntax(unit, LOG_ERR, filename, line, EINVAL,
6039                                    "Unbalanced quoting in command line, ignoring: \"%s\"", rvalue);
6040                 else
6041                         log_syntax(unit, LOG_WARNING, filename, line, EINVAL,
6042                                    "Invalid escape sequences in command line: \"%s\"", rvalue);
6043         }
6044         return r;
6045 }
6046
6047 int extract_many_words(const char **p, const char *separators, ExtractFlags flags, ...) {
6048         va_list ap;
6049         char **l;
6050         int n = 0, i, c, r;
6051
6052         /* Parses a number of words from a string, stripping any
6053          * quotes if necessary. */
6054
6055         assert(p);
6056
6057         /* Count how many words are expected */
6058         va_start(ap, flags);
6059         for (;;) {
6060                 if (!va_arg(ap, char **))
6061                         break;
6062                 n++;
6063         }
6064         va_end(ap);
6065
6066         if (n <= 0)
6067                 return 0;
6068
6069         /* Read all words into a temporary array */
6070         l = newa0(char*, n);
6071         for (c = 0; c < n; c++) {
6072
6073                 r = extract_first_word(p, &l[c], separators, flags);
6074                 if (r < 0) {
6075                         int j;
6076
6077                         for (j = 0; j < c; j++)
6078                                 free(l[j]);
6079
6080                         return r;
6081                 }
6082
6083                 if (r == 0)
6084                         break;
6085         }
6086
6087         /* If we managed to parse all words, return them in the passed
6088          * in parameters */
6089         va_start(ap, flags);
6090         for (i = 0; i < n; i++) {
6091                 char **v;
6092
6093                 v = va_arg(ap, char **);
6094                 assert(v);
6095
6096                 *v = l[i];
6097         }
6098         va_end(ap);
6099
6100         return c;
6101 }
6102 #endif // 0
6103
6104 int free_and_strdup(char **p, const char *s) {
6105         char *t;
6106
6107         assert(p);
6108
6109         /* Replaces a string pointer with an strdup()ed new string,
6110          * possibly freeing the old one. */
6111
6112         if (streq_ptr(*p, s))
6113                 return 0;
6114
6115         if (s) {
6116                 t = strdup(s);
6117                 if (!t)
6118                         return -ENOMEM;
6119         } else
6120                 t = NULL;
6121
6122         free(*p);
6123         *p = t;
6124
6125         return 1;
6126 }
6127
6128 /// UNNEEDED by elogind
6129 #if 0
6130 int ptsname_malloc(int fd, char **ret) {
6131         size_t l = 100;
6132
6133         assert(fd >= 0);
6134         assert(ret);
6135
6136         for (;;) {
6137                 char *c;
6138
6139                 c = new(char, l);
6140                 if (!c)
6141                         return -ENOMEM;
6142
6143                 if (ptsname_r(fd, c, l) == 0) {
6144                         *ret = c;
6145                         return 0;
6146                 }
6147                 if (errno != ERANGE) {
6148                         free(c);
6149                         return -errno;
6150                 }
6151
6152                 free(c);
6153                 l *= 2;
6154         }
6155 }
6156
6157 int openpt_in_namespace(pid_t pid, int flags) {
6158         _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, usernsfd = -1, rootfd = -1;
6159         _cleanup_close_pair_ int pair[2] = { -1, -1 };
6160         union {
6161                 struct cmsghdr cmsghdr;
6162                 uint8_t buf[CMSG_SPACE(sizeof(int))];
6163         } control = {};
6164         struct msghdr mh = {
6165                 .msg_control = &control,
6166                 .msg_controllen = sizeof(control),
6167         };
6168         struct cmsghdr *cmsg;
6169         siginfo_t si;
6170         pid_t child;
6171         int r;
6172
6173         assert(pid > 0);
6174
6175         r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &usernsfd, &rootfd);
6176         if (r < 0)
6177                 return r;
6178
6179         if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
6180                 return -errno;
6181
6182         child = fork();
6183         if (child < 0)
6184                 return -errno;
6185
6186         if (child == 0) {
6187                 int master;
6188
6189                 pair[0] = safe_close(pair[0]);
6190
6191                 r = namespace_enter(pidnsfd, mntnsfd, -1, usernsfd, rootfd);
6192                 if (r < 0)
6193                         _exit(EXIT_FAILURE);
6194
6195                 master = posix_openpt(flags);
6196                 if (master < 0)
6197                         _exit(EXIT_FAILURE);
6198
6199                 if (unlockpt(master) < 0)
6200                         _exit(EXIT_FAILURE);
6201
6202                 cmsg = CMSG_FIRSTHDR(&mh);
6203                 cmsg->cmsg_level = SOL_SOCKET;
6204                 cmsg->cmsg_type = SCM_RIGHTS;
6205                 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
6206                 memcpy(CMSG_DATA(cmsg), &master, sizeof(int));
6207
6208                 mh.msg_controllen = cmsg->cmsg_len;
6209
6210                 if (sendmsg(pair[1], &mh, MSG_NOSIGNAL) < 0)
6211                         _exit(EXIT_FAILURE);
6212
6213                 _exit(EXIT_SUCCESS);
6214         }
6215
6216         pair[1] = safe_close(pair[1]);
6217
6218         r = wait_for_terminate(child, &si);
6219         if (r < 0)
6220                 return r;
6221         if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
6222                 return -EIO;
6223
6224         if (recvmsg(pair[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
6225                 return -errno;
6226
6227         CMSG_FOREACH(cmsg, &mh)
6228                 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
6229                         int *fds;
6230                         unsigned n_fds;
6231
6232                         fds = (int*) CMSG_DATA(cmsg);
6233                         n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
6234
6235                         if (n_fds != 1) {
6236                                 close_many(fds, n_fds);
6237                                 return -EIO;
6238                         }
6239
6240                         return fds[0];
6241                 }
6242
6243         return -EIO;
6244 }
6245 #endif // 0
6246
6247 ssize_t fgetxattrat_fake(int dirfd, const char *filename, const char *attribute, void *value, size_t size, int flags) {
6248         _cleanup_close_ int fd = -1;
6249         ssize_t l;
6250
6251         /* The kernel doesn't have a fgetxattrat() command, hence let's emulate one */
6252
6253         fd = openat(dirfd, filename, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOATIME|(flags & AT_SYMLINK_NOFOLLOW ? O_NOFOLLOW : 0));
6254         if (fd < 0)
6255                 return -errno;
6256
6257         l = fgetxattr(fd, attribute, value, size);
6258         if (l < 0)
6259                 return -errno;
6260
6261         return l;
6262 }
6263
6264 static int parse_crtime(le64_t le, usec_t *usec) {
6265         uint64_t u;
6266
6267         assert(usec);
6268
6269         u = le64toh(le);
6270         if (u == 0 || u == (uint64_t) -1)
6271                 return -EIO;
6272
6273         *usec = (usec_t) u;
6274         return 0;
6275 }
6276
6277 int fd_getcrtime(int fd, usec_t *usec) {
6278         le64_t le;
6279         ssize_t n;
6280
6281         assert(fd >= 0);
6282         assert(usec);
6283
6284         /* Until Linux gets a real concept of birthtime/creation time,
6285          * let's fake one with xattrs */
6286
6287         n = fgetxattr(fd, "user.crtime_usec", &le, sizeof(le));
6288         if (n < 0)
6289                 return -errno;
6290         if (n != sizeof(le))
6291                 return -EIO;
6292
6293         return parse_crtime(le, usec);
6294 }
6295
6296 /// UNNEEDED by elogind
6297 #if 0
6298 int fd_getcrtime_at(int dirfd, const char *name, usec_t *usec, int flags) {
6299         le64_t le;
6300         ssize_t n;
6301
6302         n = fgetxattrat_fake(dirfd, name, "user.crtime_usec", &le, sizeof(le), flags);
6303         if (n < 0)
6304                 return -errno;
6305         if (n != sizeof(le))
6306                 return -EIO;
6307
6308         return parse_crtime(le, usec);
6309 }
6310
6311 int path_getcrtime(const char *p, usec_t *usec) {
6312         le64_t le;
6313         ssize_t n;
6314
6315         assert(p);
6316         assert(usec);
6317
6318         n = getxattr(p, "user.crtime_usec", &le, sizeof(le));
6319         if (n < 0)
6320                 return -errno;
6321         if (n != sizeof(le))
6322                 return -EIO;
6323
6324         return parse_crtime(le, usec);
6325 }
6326
6327 int fd_setcrtime(int fd, usec_t usec) {
6328         le64_t le;
6329
6330         assert(fd >= 0);
6331
6332         if (usec <= 0)
6333                 usec = now(CLOCK_REALTIME);
6334
6335         le = htole64((uint64_t) usec);
6336         if (fsetxattr(fd, "user.crtime_usec", &le, sizeof(le), 0) < 0)
6337                 return -errno;
6338
6339         return 0;
6340 }
6341
6342 int same_fd(int a, int b) {
6343         struct stat sta, stb;
6344         pid_t pid;
6345         int r, fa, fb;
6346
6347         assert(a >= 0);
6348         assert(b >= 0);
6349
6350         /* Compares two file descriptors. Note that semantics are
6351          * quite different depending on whether we have kcmp() or we
6352          * don't. If we have kcmp() this will only return true for
6353          * dup()ed file descriptors, but not otherwise. If we don't
6354          * have kcmp() this will also return true for two fds of the same
6355          * file, created by separate open() calls. Since we use this
6356          * call mostly for filtering out duplicates in the fd store
6357          * this difference hopefully doesn't matter too much. */
6358
6359         if (a == b)
6360                 return true;
6361
6362         /* Try to use kcmp() if we have it. */
6363         pid = getpid();
6364         r = kcmp(pid, pid, KCMP_FILE, a, b);
6365         if (r == 0)
6366                 return true;
6367         if (r > 0)
6368                 return false;
6369         if (errno != ENOSYS)
6370                 return -errno;
6371
6372         /* We don't have kcmp(), use fstat() instead. */
6373         if (fstat(a, &sta) < 0)
6374                 return -errno;
6375
6376         if (fstat(b, &stb) < 0)
6377                 return -errno;
6378
6379         if ((sta.st_mode & S_IFMT) != (stb.st_mode & S_IFMT))
6380                 return false;
6381
6382         /* We consider all device fds different, since two device fds
6383          * might refer to quite different device contexts even though
6384          * they share the same inode and backing dev_t. */
6385
6386         if (S_ISCHR(sta.st_mode) || S_ISBLK(sta.st_mode))
6387                 return false;
6388
6389         if (sta.st_dev != stb.st_dev || sta.st_ino != stb.st_ino)
6390                 return false;
6391
6392         /* The fds refer to the same inode on disk, let's also check
6393          * if they have the same fd flags. This is useful to
6394          * distinguish the read and write side of a pipe created with
6395          * pipe(). */
6396         fa = fcntl(a, F_GETFL);
6397         if (fa < 0)
6398                 return -errno;
6399
6400         fb = fcntl(b, F_GETFL);
6401         if (fb < 0)
6402                 return -errno;
6403
6404         return fa == fb;
6405 }
6406 #endif // 0
6407
6408 int chattr_fd(int fd, unsigned value, unsigned mask) {
6409         unsigned old_attr, new_attr;
6410         struct stat st;
6411
6412         assert(fd >= 0);
6413
6414         if (fstat(fd, &st) < 0)
6415                 return -errno;
6416
6417         /* Explicitly check whether this is a regular file or
6418          * directory. If it is anything else (such as a device node or
6419          * fifo), then the ioctl will not hit the file systems but
6420          * possibly drivers, where the ioctl might have different
6421          * effects. Notably, DRM is using the same ioctl() number. */
6422
6423         if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
6424                 return -ENOTTY;
6425
6426         if (mask == 0)
6427                 return 0;
6428
6429         if (ioctl(fd, FS_IOC_GETFLAGS, &old_attr) < 0)
6430                 return -errno;
6431
6432         new_attr = (old_attr & ~mask) | (value & mask);
6433         if (new_attr == old_attr)
6434                 return 0;
6435
6436         if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) < 0)
6437                 return -errno;
6438
6439         return 1;
6440 }
6441
6442 /// UNNEEDED by elogind
6443 #if 0
6444 int chattr_path(const char *p, unsigned value, unsigned mask) {
6445         _cleanup_close_ int fd = -1;
6446
6447         assert(p);
6448
6449         if (mask == 0)
6450                 return 0;
6451
6452         fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
6453         if (fd < 0)
6454                 return -errno;
6455
6456         return chattr_fd(fd, value, mask);
6457 }
6458 #endif // 0
6459
6460 int read_attr_fd(int fd, unsigned *ret) {
6461         struct stat st;
6462
6463         assert(fd >= 0);
6464
6465         if (fstat(fd, &st) < 0)
6466                 return -errno;
6467
6468         if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
6469                 return -ENOTTY;
6470
6471         if (ioctl(fd, FS_IOC_GETFLAGS, ret) < 0)
6472                 return -errno;
6473
6474         return 0;
6475 }
6476
6477 /// UNNEEDED by elogind
6478 #if 0
6479 int read_attr_path(const char *p, unsigned *ret) {
6480         _cleanup_close_ int fd = -1;
6481
6482         assert(p);
6483         assert(ret);
6484
6485         fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
6486         if (fd < 0)
6487                 return -errno;
6488
6489         return read_attr_fd(fd, ret);
6490 }
6491
6492 static size_t nul_length(const uint8_t *p, size_t sz) {
6493         size_t n = 0;
6494
6495         while (sz > 0) {
6496                 if (*p != 0)
6497                         break;
6498
6499                 n++;
6500                 p++;
6501                 sz--;
6502         }
6503
6504         return n;
6505 }
6506
6507 ssize_t sparse_write(int fd, const void *p, size_t sz, size_t run_length) {
6508         const uint8_t *q, *w, *e;
6509         ssize_t l;
6510
6511         q = w = p;
6512         e = q + sz;
6513         while (q < e) {
6514                 size_t n;
6515
6516                 n = nul_length(q, e - q);
6517
6518                 /* If there are more than the specified run length of
6519                  * NUL bytes, or if this is the beginning or the end
6520                  * of the buffer, then seek instead of write */
6521                 if ((n > run_length) ||
6522                     (n > 0 && q == p) ||
6523                     (n > 0 && q + n >= e)) {
6524                         if (q > w) {
6525                                 l = write(fd, w, q - w);
6526                                 if (l < 0)
6527                                         return -errno;
6528                                 if (l != q -w)
6529                                         return -EIO;
6530                         }
6531
6532                         if (lseek(fd, n, SEEK_CUR) == (off_t) -1)
6533                                 return -errno;
6534
6535                         q += n;
6536                         w = q;
6537                 } else if (n > 0)
6538                         q += n;
6539                 else
6540                         q ++;
6541         }
6542
6543         if (q > w) {
6544                 l = write(fd, w, q - w);
6545                 if (l < 0)
6546                         return -errno;
6547                 if (l != q - w)
6548                         return -EIO;
6549         }
6550
6551         return q - (const uint8_t*) p;
6552 }
6553 #endif // 0
6554
6555 void sigkill_wait(pid_t *pid) {
6556         if (!pid)
6557                 return;
6558         if (*pid <= 1)
6559                 return;
6560
6561         if (kill(*pid, SIGKILL) > 0)
6562                 (void) wait_for_terminate(*pid, NULL);
6563 }
6564
6565 /// UNNEEDED by elogind
6566 #if 0
6567 int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
6568         int a = 0, b = 0, c = 0;
6569         int k;
6570
6571         assert(p);
6572         assert(*p);
6573         assert(priority);
6574
6575         if ((*p)[0] != '<')
6576                 return 0;
6577
6578         if (!strchr(*p, '>'))
6579                 return 0;
6580
6581         if ((*p)[2] == '>') {
6582                 c = undecchar((*p)[1]);
6583                 k = 3;
6584         } else if ((*p)[3] == '>') {
6585                 b = undecchar((*p)[1]);
6586                 c = undecchar((*p)[2]);
6587                 k = 4;
6588         } else if ((*p)[4] == '>') {
6589                 a = undecchar((*p)[1]);
6590                 b = undecchar((*p)[2]);
6591                 c = undecchar((*p)[3]);
6592                 k = 5;
6593         } else
6594                 return 0;
6595
6596         if (a < 0 || b < 0 || c < 0 ||
6597             (!with_facility && (a || b || c > 7)))
6598                 return 0;
6599
6600         if (with_facility)
6601                 *priority = a*100 + b*10 + c;
6602         else
6603                 *priority = (*priority & LOG_FACMASK) | c;
6604
6605         *p += k;
6606         return 1;
6607 }
6608 #endif // 0
6609
6610 ssize_t string_table_lookup(const char * const *table, size_t len, const char *key) {
6611         size_t i;
6612
6613         if (!key)
6614                 return -1;
6615
6616         for (i = 0; i < len; ++i)
6617                 if (streq_ptr(table[i], key))
6618                         return (ssize_t)i;
6619
6620         return -1;
6621 }
6622
6623 /// UNNEEDED by elogind
6624 #if 0
6625 void cmsg_close_all(struct msghdr *mh) {
6626         struct cmsghdr *cmsg;
6627
6628         assert(mh);
6629
6630         CMSG_FOREACH(cmsg, mh)
6631                 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
6632                         close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int));
6633 }
6634
6635 int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char *newpath) {
6636         struct stat buf;
6637         int ret;
6638
6639         ret = renameat2(olddirfd, oldpath, newdirfd, newpath, RENAME_NOREPLACE);
6640         if (ret >= 0)
6641                 return 0;
6642
6643         /* renameat2() exists since Linux 3.15, btrfs added support for it later.
6644          * If it is not implemented, fallback to another method. */
6645         if (!IN_SET(errno, EINVAL, ENOSYS))
6646                 return -errno;
6647
6648         /* The link()/unlink() fallback does not work on directories. But
6649          * renameat() without RENAME_NOREPLACE gives the same semantics on
6650          * directories, except when newpath is an *empty* directory. This is
6651          * good enough. */
6652         ret = fstatat(olddirfd, oldpath, &buf, AT_SYMLINK_NOFOLLOW);
6653         if (ret >= 0 && S_ISDIR(buf.st_mode)) {
6654                 ret = renameat(olddirfd, oldpath, newdirfd, newpath);
6655                 return ret >= 0 ? 0 : -errno;
6656         }
6657
6658         /* If it is not a directory, use the link()/unlink() fallback. */
6659         ret = linkat(olddirfd, oldpath, newdirfd, newpath, 0);
6660         if (ret < 0)
6661                 return -errno;
6662
6663         ret = unlinkat(olddirfd, oldpath, 0);
6664         if (ret < 0) {
6665                 /* backup errno before the following unlinkat() alters it */
6666                 ret = errno;
6667                 (void) unlinkat(newdirfd, newpath, 0);
6668                 errno = ret;
6669                 return -errno;
6670         }
6671
6672         return 0;
6673 }
6674
6675 static char *strcpy_backslash_escaped(char *t, const char *s, const char *bad) {
6676         assert(bad);
6677
6678         for (; *s; s++) {
6679                 if (*s == '\\' || strchr(bad, *s))
6680                         *(t++) = '\\';
6681
6682                 *(t++) = *s;
6683         }
6684
6685         return t;
6686 }
6687
6688 char *shell_escape(const char *s, const char *bad) {
6689         char *r, *t;
6690
6691         r = new(char, strlen(s)*2+1);
6692         if (!r)
6693                 return NULL;
6694
6695         t = strcpy_backslash_escaped(r, s, bad);
6696         *t = 0;
6697
6698         return r;
6699 }
6700
6701 char *shell_maybe_quote(const char *s) {
6702         const char *p;
6703         char *r, *t;
6704
6705         assert(s);
6706
6707         /* Encloses a string in double quotes if necessary to make it
6708          * OK as shell string. */
6709
6710         for (p = s; *p; p++)
6711                 if (*p <= ' ' ||
6712                     *p >= 127 ||
6713                     strchr(SHELL_NEED_QUOTES, *p))
6714                         break;
6715
6716         if (!*p)
6717                 return strdup(s);
6718
6719         r = new(char, 1+strlen(s)*2+1+1);
6720         if (!r)
6721                 return NULL;
6722
6723         t = r;
6724         *(t++) = '"';
6725         t = mempcpy(t, s, p - s);
6726
6727         t = strcpy_backslash_escaped(t, p, SHELL_NEED_ESCAPE);
6728
6729         *(t++)= '"';
6730         *t = 0;
6731
6732         return r;
6733 }
6734 #endif // 0
6735
6736 int parse_mode(const char *s, mode_t *ret) {
6737         char *x;
6738         long l;
6739
6740         assert(s);
6741         assert(ret);
6742
6743         errno = 0;
6744         l = strtol(s, &x, 8);
6745         if (errno != 0)
6746                 return -errno;
6747
6748         if (!x || x == s || *x)
6749                 return -EINVAL;
6750         if (l < 0 || l  > 07777)
6751                 return -ERANGE;
6752
6753         *ret = (mode_t) l;
6754         return 0;
6755 }
6756
6757 /// UNNEEDED by elogind
6758 #if 0
6759 int mount_move_root(const char *path) {
6760         assert(path);
6761
6762         if (chdir(path) < 0)
6763                 return -errno;
6764
6765         if (mount(path, "/", NULL, MS_MOVE, NULL) < 0)
6766                 return -errno;
6767
6768         if (chroot(".") < 0)
6769                 return -errno;
6770
6771         if (chdir("/") < 0)
6772                 return -errno;
6773
6774         return 0;
6775 }
6776 #endif // 0
6777
6778 int reset_uid_gid(void) {
6779
6780         if (setgroups(0, NULL) < 0)
6781                 return -errno;
6782
6783         if (setresgid(0, 0, 0) < 0)
6784                 return -errno;
6785
6786         if (setresuid(0, 0, 0) < 0)
6787                 return -errno;
6788
6789         return 0;
6790 }
6791
6792 int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink) {
6793         char *v;
6794         size_t l;
6795         ssize_t n;
6796
6797         assert(path);
6798         assert(name);
6799         assert(value);
6800
6801         for (l = 100; ; l = (size_t) n + 1) {
6802                 v = new0(char, l);
6803                 if (!v)
6804                         return -ENOMEM;
6805
6806                 if (allow_symlink)
6807                         n = lgetxattr(path, name, v, l);
6808                 else
6809                         n = getxattr(path, name, v, l);
6810
6811                 if (n >= 0 && (size_t) n < l) {
6812                         *value = v;
6813                         return n;
6814                 }
6815
6816                 free(v);
6817
6818                 if (n < 0 && errno != ERANGE)
6819                         return -errno;
6820
6821                 if (allow_symlink)
6822                         n = lgetxattr(path, name, NULL, 0);
6823                 else
6824                         n = getxattr(path, name, NULL, 0);
6825                 if (n < 0)
6826                         return -errno;
6827         }
6828 }
6829
6830 int fgetxattr_malloc(int fd, const char *name, char **value) {
6831         char *v;
6832         size_t l;
6833         ssize_t n;
6834
6835         assert(fd >= 0);
6836         assert(name);
6837         assert(value);
6838
6839         for (l = 100; ; l = (size_t) n + 1) {
6840                 v = new0(char, l);
6841                 if (!v)
6842                         return -ENOMEM;
6843
6844                 n = fgetxattr(fd, name, v, l);
6845
6846                 if (n >= 0 && (size_t) n < l) {
6847                         *value = v;
6848                         return n;
6849                 }
6850
6851                 free(v);
6852
6853                 if (n < 0 && errno != ERANGE)
6854                         return -errno;
6855
6856                 n = fgetxattr(fd, name, NULL, 0);
6857                 if (n < 0)
6858                         return -errno;
6859         }
6860 }