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