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