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