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