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