chiark / gitweb /
527a5800fec407d6cc096f66d22dc22cbfa6d7cf
[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
77 size_t page_size(void) {
78         static __thread size_t pgsz = 0;
79         long r;
80
81         if (_likely_(pgsz > 0))
82                 return pgsz;
83
84         r = sysconf(_SC_PAGESIZE);
85         assert(r > 0);
86
87         pgsz = (size_t) r;
88         return pgsz;
89 }
90
91 bool streq_ptr(const char *a, const char *b) {
92
93         /* Like streq(), but tries to make sense of NULL pointers */
94
95         if (a && b)
96                 return streq(a, b);
97
98         if (!a && !b)
99                 return true;
100
101         return false;
102 }
103
104 usec_t now(clockid_t clock_id) {
105         struct timespec ts;
106
107         assert_se(clock_gettime(clock_id, &ts) == 0);
108
109         return timespec_load(&ts);
110 }
111
112 dual_timestamp* dual_timestamp_get(dual_timestamp *ts) {
113         assert(ts);
114
115         ts->realtime = now(CLOCK_REALTIME);
116         ts->monotonic = now(CLOCK_MONOTONIC);
117
118         return ts;
119 }
120
121 dual_timestamp* dual_timestamp_from_realtime(dual_timestamp *ts, usec_t u) {
122         int64_t delta;
123         assert(ts);
124
125         ts->realtime = u;
126
127         if (u == 0)
128                 ts->monotonic = 0;
129         else {
130                 delta = (int64_t) now(CLOCK_REALTIME) - (int64_t) u;
131
132                 ts->monotonic = now(CLOCK_MONOTONIC);
133
134                 if ((int64_t) ts->monotonic > delta)
135                         ts->monotonic -= delta;
136                 else
137                         ts->monotonic = 0;
138         }
139
140         return ts;
141 }
142
143 usec_t timespec_load(const struct timespec *ts) {
144         assert(ts);
145
146         if (ts->tv_sec == (time_t) -1 &&
147             ts->tv_nsec == (long) -1)
148                 return (usec_t) -1;
149
150         return
151                 (usec_t) ts->tv_sec * USEC_PER_SEC +
152                 (usec_t) ts->tv_nsec / NSEC_PER_USEC;
153 }
154
155 struct timespec *timespec_store(struct timespec *ts, usec_t u)  {
156         assert(ts);
157
158         if (u == (usec_t) -1) {
159                 ts->tv_sec = (time_t) -1;
160                 ts->tv_nsec = (long) -1;
161                 return ts;
162         }
163
164         ts->tv_sec = (time_t) (u / USEC_PER_SEC);
165         ts->tv_nsec = (long int) ((u % USEC_PER_SEC) * NSEC_PER_USEC);
166
167         return ts;
168 }
169
170 usec_t timeval_load(const struct timeval *tv) {
171         assert(tv);
172
173         if (tv->tv_sec == (time_t) -1 &&
174             tv->tv_usec == (suseconds_t) -1)
175                 return (usec_t) -1;
176
177         return
178                 (usec_t) tv->tv_sec * USEC_PER_SEC +
179                 (usec_t) tv->tv_usec;
180 }
181
182 struct timeval *timeval_store(struct timeval *tv, usec_t u) {
183         assert(tv);
184
185         if (u == (usec_t) -1) {
186                 tv->tv_sec = (time_t) -1;
187                 tv->tv_usec = (suseconds_t) -1;
188                 return tv;
189         }
190
191         tv->tv_sec = (time_t) (u / USEC_PER_SEC);
192         tv->tv_usec = (suseconds_t) (u % USEC_PER_SEC);
193
194         return tv;
195 }
196
197 bool endswith(const char *s, const char *postfix) {
198         size_t sl, pl;
199
200         assert(s);
201         assert(postfix);
202
203         sl = strlen(s);
204         pl = strlen(postfix);
205
206         if (pl == 0)
207                 return true;
208
209         if (sl < pl)
210                 return false;
211
212         return memcmp(s + sl - pl, postfix, pl) == 0;
213 }
214
215 bool startswith(const char *s, const char *prefix) {
216         size_t sl, pl;
217
218         assert(s);
219         assert(prefix);
220
221         sl = strlen(s);
222         pl = strlen(prefix);
223
224         if (pl == 0)
225                 return true;
226
227         if (sl < pl)
228                 return false;
229
230         return memcmp(s, prefix, pl) == 0;
231 }
232
233 bool startswith_no_case(const char *s, const char *prefix) {
234         size_t sl, pl;
235         unsigned i;
236
237         assert(s);
238         assert(prefix);
239
240         sl = strlen(s);
241         pl = strlen(prefix);
242
243         if (pl == 0)
244                 return true;
245
246         if (sl < pl)
247                 return false;
248
249         for(i = 0; i < pl; ++i)
250                 if (tolower(s[i]) != tolower(prefix[i]))
251                         return false;
252
253         return true;
254 }
255
256 bool first_word(const char *s, const char *word) {
257         size_t sl, wl;
258
259         assert(s);
260         assert(word);
261
262         sl = strlen(s);
263         wl = strlen(word);
264
265         if (sl < wl)
266                 return false;
267
268         if (wl == 0)
269                 return true;
270
271         if (memcmp(s, word, wl) != 0)
272                 return false;
273
274         return s[wl] == 0 ||
275                 strchr(WHITESPACE, s[wl]);
276 }
277
278 int close_nointr(int fd) {
279         assert(fd >= 0);
280
281         for (;;) {
282                 int r;
283
284                 r = close(fd);
285                 if (r >= 0)
286                         return r;
287
288                 if (errno != EINTR)
289                         return -errno;
290         }
291 }
292
293 void close_nointr_nofail(int fd) {
294         int saved_errno = errno;
295
296         /* like close_nointr() but cannot fail, and guarantees errno
297          * is unchanged */
298
299         assert_se(close_nointr(fd) == 0);
300
301         errno = saved_errno;
302 }
303
304 void close_many(const int fds[], unsigned n_fd) {
305         unsigned i;
306
307         for (i = 0; i < n_fd; i++)
308                 close_nointr_nofail(fds[i]);
309 }
310
311 int parse_boolean(const char *v) {
312         assert(v);
313
314         if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on"))
315                 return 1;
316         else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off"))
317                 return 0;
318
319         return -EINVAL;
320 }
321
322 int parse_pid(const char *s, pid_t* ret_pid) {
323         unsigned long ul = 0;
324         pid_t pid;
325         int r;
326
327         assert(s);
328         assert(ret_pid);
329
330         r = safe_atolu(s, &ul);
331         if (r < 0)
332                 return r;
333
334         pid = (pid_t) ul;
335
336         if ((unsigned long) pid != ul)
337                 return -ERANGE;
338
339         if (pid <= 0)
340                 return -ERANGE;
341
342         *ret_pid = pid;
343         return 0;
344 }
345
346 int parse_uid(const char *s, uid_t* ret_uid) {
347         unsigned long ul = 0;
348         uid_t uid;
349         int r;
350
351         assert(s);
352         assert(ret_uid);
353
354         r = safe_atolu(s, &ul);
355         if (r < 0)
356                 return r;
357
358         uid = (uid_t) ul;
359
360         if ((unsigned long) uid != ul)
361                 return -ERANGE;
362
363         *ret_uid = uid;
364         return 0;
365 }
366
367 int safe_atou(const char *s, unsigned *ret_u) {
368         char *x = NULL;
369         unsigned long l;
370
371         assert(s);
372         assert(ret_u);
373
374         errno = 0;
375         l = strtoul(s, &x, 0);
376
377         if (!x || *x || errno)
378                 return errno ? -errno : -EINVAL;
379
380         if ((unsigned long) (unsigned) l != l)
381                 return -ERANGE;
382
383         *ret_u = (unsigned) l;
384         return 0;
385 }
386
387 int safe_atoi(const char *s, int *ret_i) {
388         char *x = NULL;
389         long l;
390
391         assert(s);
392         assert(ret_i);
393
394         errno = 0;
395         l = strtol(s, &x, 0);
396
397         if (!x || *x || errno)
398                 return errno ? -errno : -EINVAL;
399
400         if ((long) (int) l != l)
401                 return -ERANGE;
402
403         *ret_i = (int) l;
404         return 0;
405 }
406
407 int safe_atollu(const char *s, long long unsigned *ret_llu) {
408         char *x = NULL;
409         unsigned long long l;
410
411         assert(s);
412         assert(ret_llu);
413
414         errno = 0;
415         l = strtoull(s, &x, 0);
416
417         if (!x || *x || errno)
418                 return errno ? -errno : -EINVAL;
419
420         *ret_llu = l;
421         return 0;
422 }
423
424 int safe_atolli(const char *s, long long int *ret_lli) {
425         char *x = NULL;
426         long long l;
427
428         assert(s);
429         assert(ret_lli);
430
431         errno = 0;
432         l = strtoll(s, &x, 0);
433
434         if (!x || *x || errno)
435                 return errno ? -errno : -EINVAL;
436
437         *ret_lli = l;
438         return 0;
439 }
440
441 /* Split a string into words. */
442 char *split(const char *c, size_t *l, const char *separator, char **state) {
443         char *current;
444
445         current = *state ? *state : (char*) c;
446
447         if (!*current || *c == 0)
448                 return NULL;
449
450         current += strspn(current, separator);
451         *l = strcspn(current, separator);
452         *state = current+*l;
453
454         return (char*) current;
455 }
456
457 /* Split a string into words, but consider strings enclosed in '' and
458  * "" as words even if they include spaces. */
459 char *split_quoted(const char *c, size_t *l, char **state) {
460         char *current, *e;
461         bool escaped = false;
462
463         current = *state ? *state : (char*) c;
464
465         if (!*current || *c == 0)
466                 return NULL;
467
468         current += strspn(current, WHITESPACE);
469
470         if (*current == '\'') {
471                 current ++;
472
473                 for (e = current; *e; e++) {
474                         if (escaped)
475                                 escaped = false;
476                         else if (*e == '\\')
477                                 escaped = true;
478                         else if (*e == '\'')
479                                 break;
480                 }
481
482                 *l = e-current;
483                 *state = *e == 0 ? e : e+1;
484         } else if (*current == '\"') {
485                 current ++;
486
487                 for (e = current; *e; e++) {
488                         if (escaped)
489                                 escaped = false;
490                         else if (*e == '\\')
491                                 escaped = true;
492                         else if (*e == '\"')
493                                 break;
494                 }
495
496                 *l = e-current;
497                 *state = *e == 0 ? e : e+1;
498         } else {
499                 for (e = current; *e; e++) {
500                         if (escaped)
501                                 escaped = false;
502                         else if (*e == '\\')
503                                 escaped = true;
504                         else if (strchr(WHITESPACE, *e))
505                                 break;
506                 }
507                 *l = e-current;
508                 *state = e;
509         }
510
511         return (char*) current;
512 }
513
514 int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
515         int r;
516         _cleanup_fclose_ FILE *f = NULL;
517         char fn[PATH_MAX], line[LINE_MAX], *p;
518         long unsigned ppid;
519
520         assert(pid > 0);
521         assert(_ppid);
522
523         assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1));
524         char_array_0(fn);
525
526         f = fopen(fn, "re");
527         if (!f)
528                 return -errno;
529
530         if (!fgets(line, sizeof(line), f)) {
531                 r = feof(f) ? -EIO : -errno;
532                 fclose(f);
533                 return r;
534         }
535
536         /* Let's skip the pid and comm fields. The latter is enclosed
537          * in () but does not escape any () in its value, so let's
538          * skip over it manually */
539
540         p = strrchr(line, ')');
541         if (!p)
542                 return -EIO;
543
544         p++;
545
546         if (sscanf(p, " "
547                    "%*c "  /* state */
548                    "%lu ", /* ppid */
549                    &ppid) != 1)
550                 return -EIO;
551
552         if ((long unsigned) (pid_t) ppid != ppid)
553                 return -ERANGE;
554
555         *_ppid = (pid_t) ppid;
556
557         return 0;
558 }
559
560 int get_starttime_of_pid(pid_t pid, unsigned long long *st) {
561         _cleanup_fclose_ FILE *f = NULL;
562         char fn[PATH_MAX], line[LINE_MAX], *p;
563
564         assert(pid > 0);
565         assert(st);
566
567         assert_se(snprintf(fn, sizeof(fn)-1, "/proc/%lu/stat", (unsigned long) pid) < (int) (sizeof(fn)-1));
568         char_array_0(fn);
569
570         f = fopen(fn, "re");
571         if (!f)
572                 return -errno;
573
574         if (!fgets(line, sizeof(line), f)) {
575                 if (ferror(f))
576                         return -errno;
577
578                 return -EIO;
579         }
580
581         /* Let's skip the pid and comm fields. The latter is enclosed
582          * in () but does not escape any () in its value, so let's
583          * skip over it manually */
584
585         p = strrchr(line, ')');
586         if (!p)
587                 return -EIO;
588
589         p++;
590
591         if (sscanf(p, " "
592                    "%*c "  /* state */
593                    "%*d "  /* ppid */
594                    "%*d "  /* pgrp */
595                    "%*d "  /* session */
596                    "%*d "  /* tty_nr */
597                    "%*d "  /* tpgid */
598                    "%*u "  /* flags */
599                    "%*u "  /* minflt */
600                    "%*u "  /* cminflt */
601                    "%*u "  /* majflt */
602                    "%*u "  /* cmajflt */
603                    "%*u "  /* utime */
604                    "%*u "  /* stime */
605                    "%*d "  /* cutime */
606                    "%*d "  /* cstime */
607                    "%*d "  /* priority */
608                    "%*d "  /* nice */
609                    "%*d "  /* num_threads */
610                    "%*d "  /* itrealvalue */
611                    "%llu "  /* starttime */,
612                    st) != 1)
613                 return -EIO;
614
615         return 0;
616 }
617
618 int write_one_line_file(const char *fn, const char *line) {
619         _cleanup_fclose_ FILE *f = NULL;
620
621         assert(fn);
622         assert(line);
623
624         f = fopen(fn, "we");
625         if (!f)
626                 return -errno;
627
628         errno = 0;
629         if (fputs(line, f) < 0)
630                 return errno ? -errno : -EIO;
631
632         if (!endswith(line, "\n"))
633                 fputc('\n', f);
634
635         fflush(f);
636
637         if (ferror(f))
638                 return errno ? -errno : -EIO;
639
640         return 0;
641 }
642
643 int fchmod_umask(int fd, mode_t m) {
644         mode_t u;
645         int r;
646
647         u = umask(0777);
648         r = fchmod(fd, m & (~u)) < 0 ? -errno : 0;
649         umask(u);
650
651         return r;
652 }
653
654 int write_one_line_file_atomic(const char *fn, const char *line) {
655         FILE *f;
656         int r;
657         char *p;
658
659         assert(fn);
660         assert(line);
661
662         r = fopen_temporary(fn, &f, &p);
663         if (r < 0)
664                 return r;
665
666         fchmod_umask(fileno(f), 0644);
667
668         errno = 0;
669         if (fputs(line, f) < 0) {
670                 r = -errno;
671                 goto finish;
672         }
673
674         if (!endswith(line, "\n"))
675                 fputc('\n', f);
676
677         fflush(f);
678
679         if (ferror(f)) {
680                 if (errno != 0)
681                         r = -errno;
682                 else
683                         r = -EIO;
684         } else {
685                 if (rename(p, fn) < 0)
686                         r = -errno;
687                 else
688                         r = 0;
689         }
690
691 finish:
692         if (r < 0)
693                 unlink(p);
694
695         fclose(f);
696         free(p);
697
698         return r;
699 }
700
701 int read_one_line_file(const char *fn, char **line) {
702         _cleanup_fclose_ FILE *f = NULL;
703         char t[LINE_MAX], *c;
704
705         assert(fn);
706         assert(line);
707
708         f = fopen(fn, "re");
709         if (!f)
710                 return -errno;
711
712         if (!fgets(t, sizeof(t), f)) {
713
714                 if (ferror(f))
715                         return errno ? -errno : -EIO;
716
717                 t[0] = 0;
718         }
719
720         c = strdup(t);
721         if (!c)
722                 return -ENOMEM;
723         truncate_nl(c);
724
725         *line = c;
726         return 0;
727 }
728
729 int read_full_file(const char *fn, char **contents, size_t *size) {
730         _cleanup_fclose_ FILE *f = NULL;
731         size_t n, l;
732         _cleanup_free_ char *buf = NULL;
733         struct stat st;
734
735         f = fopen(fn, "re");
736         if (!f)
737                 return -errno;
738
739         if (fstat(fileno(f), &st) < 0)
740                 return -errno;
741
742         /* Safety check */
743         if (st.st_size > 4*1024*1024)
744                 return -E2BIG;
745
746         n = st.st_size > 0 ? st.st_size : LINE_MAX;
747         l = 0;
748
749         for (;;) {
750                 char *t;
751                 size_t k;
752
753                 t = realloc(buf, n+1);
754                 if (!t)
755                         return -ENOMEM;
756
757                 buf = t;
758                 k = fread(buf + l, 1, n - l, f);
759
760                 if (k <= 0) {
761                         if (ferror(f))
762                                 return -errno;
763
764                         break;
765                 }
766
767                 l += k;
768                 n *= 2;
769
770                 /* Safety check */
771                 if (n > 4*1024*1024)
772                         return -E2BIG;
773         }
774
775         buf[l] = 0;
776         *contents = buf;
777         buf = NULL;
778
779         if (size)
780                 *size = l;
781
782         return 0;
783 }
784
785 int parse_env_file(
786                 const char *fname,
787                 const char *separator, ...) {
788
789         int r = 0;
790         char *contents = NULL, *p;
791
792         assert(fname);
793         assert(separator);
794
795         if ((r = read_full_file(fname, &contents, NULL)) < 0)
796                 return r;
797
798         p = contents;
799         for (;;) {
800                 const char *key = NULL;
801
802                 p += strspn(p, separator);
803                 p += strspn(p, WHITESPACE);
804
805                 if (!*p)
806                         break;
807
808                 if (!strchr(COMMENTS, *p)) {
809                         va_list ap;
810                         char **value;
811
812                         va_start(ap, separator);
813                         while ((key = va_arg(ap, char *))) {
814                                 size_t n;
815                                 char *v;
816
817                                 value = va_arg(ap, char **);
818
819                                 n = strlen(key);
820                                 if (strncmp(p, key, n) != 0 ||
821                                     p[n] != '=')
822                                         continue;
823
824                                 p += n + 1;
825                                 n = strcspn(p, separator);
826
827                                 if (n >= 2 &&
828                                     strchr(QUOTES, p[0]) &&
829                                     p[n-1] == p[0])
830                                         v = strndup(p+1, n-2);
831                                 else
832                                         v = strndup(p, n);
833
834                                 if (!v) {
835                                         r = -ENOMEM;
836                                         va_end(ap);
837                                         goto fail;
838                                 }
839
840                                 if (v[0] == '\0') {
841                                         /* return empty value strings as NULL */
842                                         free(v);
843                                         v = NULL;
844                                 }
845
846                                 free(*value);
847                                 *value = v;
848
849                                 p += n;
850
851                                 r ++;
852                                 break;
853                         }
854                         va_end(ap);
855                 }
856
857                 if (!key)
858                         p += strcspn(p, separator);
859         }
860
861 fail:
862         free(contents);
863         return r;
864 }
865
866 int load_env_file(
867                 const char *fname,
868                 char ***rl) {
869
870         FILE *f;
871         char **m = NULL;
872         int r;
873
874         assert(fname);
875         assert(rl);
876
877         if (!(f = fopen(fname, "re")))
878                 return -errno;
879
880         while (!feof(f)) {
881                 char l[LINE_MAX], *p, *u;
882                 char **t;
883
884                 if (!fgets(l, sizeof(l), f)) {
885                         if (feof(f))
886                                 break;
887
888                         r = -errno;
889                         goto finish;
890                 }
891
892                 p = strstrip(l);
893
894                 if (!*p)
895                         continue;
896
897                 if (strchr(COMMENTS, *p))
898                         continue;
899
900                 if (!(u = normalize_env_assignment(p))) {
901                         r = log_oom();
902                         goto finish;
903                 }
904
905                 t = strv_append(m, u);
906                 free(u);
907
908                 if (!t) {
909                         r = log_oom();
910                         goto finish;
911                 }
912
913                 strv_free(m);
914                 m = t;
915         }
916
917         r = 0;
918
919         *rl = m;
920         m = NULL;
921
922 finish:
923         if (f)
924                 fclose(f);
925
926         strv_free(m);
927
928         return r;
929 }
930
931 int write_env_file(const char *fname, char **l) {
932         char **i, *p;
933         FILE *f;
934         int r;
935
936         r = fopen_temporary(fname, &f, &p);
937         if (r < 0)
938                 return r;
939
940         fchmod_umask(fileno(f), 0644);
941
942         errno = 0;
943         STRV_FOREACH(i, l) {
944                 fputs(*i, f);
945                 fputc('\n', f);
946         }
947
948         fflush(f);
949
950         if (ferror(f)) {
951                 if (errno != 0)
952                         r = -errno;
953                 else
954                         r = -EIO;
955         } else {
956                 if (rename(p, fname) < 0)
957                         r = -errno;
958                 else
959                         r = 0;
960         }
961
962         if (r < 0)
963                 unlink(p);
964
965         fclose(f);
966         free(p);
967
968         return r;
969 }
970
971 char *truncate_nl(char *s) {
972         assert(s);
973
974         s[strcspn(s, NEWLINE)] = 0;
975         return s;
976 }
977
978 int get_process_comm(pid_t pid, char **name) {
979         int r;
980
981         assert(name);
982
983         if (pid == 0)
984                 r = read_one_line_file("/proc/self/comm", name);
985         else {
986                 char *p;
987                 if (asprintf(&p, "/proc/%lu/comm", (unsigned long) pid) < 0)
988                         return -ENOMEM;
989
990                 r = read_one_line_file(p, name);
991                 free(p);
992         }
993
994         return r;
995 }
996
997 int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
998         char *r, *k;
999         int c;
1000         bool space = false;
1001         size_t left;
1002         FILE *f;
1003
1004         assert(max_length > 0);
1005         assert(line);
1006
1007         if (pid == 0)
1008                 f = fopen("/proc/self/cmdline", "re");
1009         else {
1010                 char *p;
1011                 if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
1012                         return -ENOMEM;
1013
1014                 f = fopen(p, "re");
1015                 free(p);
1016         }
1017
1018         if (!f)
1019                 return -errno;
1020
1021         r = new(char, max_length);
1022         if (!r) {
1023                 fclose(f);
1024                 return -ENOMEM;
1025         }
1026
1027         k = r;
1028         left = max_length;
1029         while ((c = getc(f)) != EOF) {
1030
1031                 if (isprint(c)) {
1032                         if (space) {
1033                                 if (left <= 4)
1034                                         break;
1035
1036                                 *(k++) = ' ';
1037                                 left--;
1038                                 space = false;
1039                         }
1040
1041                         if (left <= 4)
1042                                 break;
1043
1044                         *(k++) = (char) c;
1045                         left--;
1046                 }  else
1047                         space = true;
1048         }
1049
1050         if (left <= 4) {
1051                 size_t n = MIN(left-1, 3U);
1052                 memcpy(k, "...", n);
1053                 k[n] = 0;
1054         } else
1055                 *k = 0;
1056
1057         fclose(f);
1058
1059         /* Kernel threads have no argv[] */
1060         if (r[0] == 0) {
1061                 char *t;
1062                 int h;
1063
1064                 free(r);
1065
1066                 if (!comm_fallback)
1067                         return -ENOENT;
1068
1069                 h = get_process_comm(pid, &t);
1070                 if (h < 0)
1071                         return h;
1072
1073                 r = strjoin("[", t, "]", NULL);
1074                 free(t);
1075
1076                 if (!r)
1077                         return -ENOMEM;
1078         }
1079
1080         *line = r;
1081         return 0;
1082 }
1083
1084 int is_kernel_thread(pid_t pid) {
1085         char *p;
1086         size_t count;
1087         char c;
1088         bool eof;
1089         FILE *f;
1090
1091         if (pid == 0)
1092                 return 0;
1093
1094         if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
1095                 return -ENOMEM;
1096
1097         f = fopen(p, "re");
1098         free(p);
1099
1100         if (!f)
1101                 return -errno;
1102
1103         count = fread(&c, 1, 1, f);
1104         eof = feof(f);
1105         fclose(f);
1106
1107         /* Kernel threads have an empty cmdline */
1108
1109         if (count <= 0)
1110                 return eof ? 1 : -errno;
1111
1112         return 0;
1113 }
1114
1115 int get_process_exe(pid_t pid, char **name) {
1116         int r;
1117
1118         assert(name);
1119
1120         if (pid == 0)
1121                 r = readlink_malloc("/proc/self/exe", name);
1122         else {
1123                 char *p;
1124                 if (asprintf(&p, "/proc/%lu/exe", (unsigned long) pid) < 0)
1125                         return -ENOMEM;
1126
1127                 r = readlink_malloc(p, name);
1128                 free(p);
1129         }
1130
1131         return r;
1132 }
1133
1134 static int get_process_id(pid_t pid, const char *field, uid_t *uid) {
1135         char *p;
1136         FILE *f;
1137         int r;
1138
1139         assert(uid);
1140
1141         if (pid == 0)
1142                 return getuid();
1143
1144         if (asprintf(&p, "/proc/%lu/status", (unsigned long) pid) < 0)
1145                 return -ENOMEM;
1146
1147         f = fopen(p, "re");
1148         free(p);
1149
1150         if (!f)
1151                 return -errno;
1152
1153         while (!feof(f)) {
1154                 char line[LINE_MAX], *l;
1155
1156                 if (!fgets(line, sizeof(line), f)) {
1157                         if (feof(f))
1158                                 break;
1159
1160                         r = -errno;
1161                         goto finish;
1162                 }
1163
1164                 l = strstrip(line);
1165
1166                 if (startswith(l, field)) {
1167                         l += strlen(field);
1168                         l += strspn(l, WHITESPACE);
1169
1170                         l[strcspn(l, WHITESPACE)] = 0;
1171
1172                         r = parse_uid(l, uid);
1173                         goto finish;
1174                 }
1175         }
1176
1177         r = -EIO;
1178
1179 finish:
1180         fclose(f);
1181
1182         return r;
1183 }
1184
1185 int get_process_uid(pid_t pid, uid_t *uid) {
1186         return get_process_id(pid, "Uid:", uid);
1187 }
1188
1189 int get_process_gid(pid_t pid, gid_t *gid) {
1190         return get_process_id(pid, "Gid:", gid);
1191 }
1192
1193 char *strnappend(const char *s, const char *suffix, size_t b) {
1194         size_t a;
1195         char *r;
1196
1197         if (!s && !suffix)
1198                 return strdup("");
1199
1200         if (!s)
1201                 return strndup(suffix, b);
1202
1203         if (!suffix)
1204                 return strdup(s);
1205
1206         assert(s);
1207         assert(suffix);
1208
1209         a = strlen(s);
1210         if (b > ((size_t) -1) - a)
1211                 return NULL;
1212
1213         r = new(char, a+b+1);
1214         if (!r)
1215                 return NULL;
1216
1217         memcpy(r, s, a);
1218         memcpy(r+a, suffix, b);
1219         r[a+b] = 0;
1220
1221         return r;
1222 }
1223
1224 char *strappend(const char *s, const char *suffix) {
1225         return strnappend(s, suffix, suffix ? strlen(suffix) : 0);
1226 }
1227
1228 int readlink_malloc(const char *p, char **r) {
1229         size_t l = 100;
1230
1231         assert(p);
1232         assert(r);
1233
1234         for (;;) {
1235                 char *c;
1236                 ssize_t n;
1237
1238                 if (!(c = new(char, l)))
1239                         return -ENOMEM;
1240
1241                 if ((n = readlink(p, c, l-1)) < 0) {
1242                         int ret = -errno;
1243                         free(c);
1244                         return ret;
1245                 }
1246
1247                 if ((size_t) n < l-1) {
1248                         c[n] = 0;
1249                         *r = c;
1250                         return 0;
1251                 }
1252
1253                 free(c);
1254                 l *= 2;
1255         }
1256 }
1257
1258 int readlink_and_make_absolute(const char *p, char **r) {
1259         char *target, *k;
1260         int j;
1261
1262         assert(p);
1263         assert(r);
1264
1265         if ((j = readlink_malloc(p, &target)) < 0)
1266                 return j;
1267
1268         k = file_in_same_dir(p, target);
1269         free(target);
1270
1271         if (!k)
1272                 return -ENOMEM;
1273
1274         *r = k;
1275         return 0;
1276 }
1277
1278 int readlink_and_canonicalize(const char *p, char **r) {
1279         char *t, *s;
1280         int j;
1281
1282         assert(p);
1283         assert(r);
1284
1285         j = readlink_and_make_absolute(p, &t);
1286         if (j < 0)
1287                 return j;
1288
1289         s = canonicalize_file_name(t);
1290         if (s) {
1291                 free(t);
1292                 *r = s;
1293         } else
1294                 *r = t;
1295
1296         path_kill_slashes(*r);
1297
1298         return 0;
1299 }
1300
1301 int reset_all_signal_handlers(void) {
1302         int sig;
1303
1304         for (sig = 1; sig < _NSIG; sig++) {
1305                 struct sigaction sa;
1306
1307                 if (sig == SIGKILL || sig == SIGSTOP)
1308                         continue;
1309
1310                 zero(sa);
1311                 sa.sa_handler = SIG_DFL;
1312                 sa.sa_flags = SA_RESTART;
1313
1314                 /* On Linux the first two RT signals are reserved by
1315                  * glibc, and sigaction() will return EINVAL for them. */
1316                 if ((sigaction(sig, &sa, NULL) < 0))
1317                         if (errno != EINVAL)
1318                                 return -errno;
1319         }
1320
1321         return 0;
1322 }
1323
1324 char *strstrip(char *s) {
1325         char *e;
1326
1327         /* Drops trailing whitespace. Modifies the string in
1328          * place. Returns pointer to first non-space character */
1329
1330         s += strspn(s, WHITESPACE);
1331
1332         for (e = strchr(s, 0); e > s; e --)
1333                 if (!strchr(WHITESPACE, e[-1]))
1334                         break;
1335
1336         *e = 0;
1337
1338         return s;
1339 }
1340
1341 char *delete_chars(char *s, const char *bad) {
1342         char *f, *t;
1343
1344         /* Drops all whitespace, regardless where in the string */
1345
1346         for (f = s, t = s; *f; f++) {
1347                 if (strchr(bad, *f))
1348                         continue;
1349
1350                 *(t++) = *f;
1351         }
1352
1353         *t = 0;
1354
1355         return s;
1356 }
1357
1358 bool in_charset(const char *s, const char* charset) {
1359         const char *i;
1360
1361         assert(s);
1362         assert(charset);
1363
1364         for (i = s; *i; i++)
1365                 if (!strchr(charset, *i))
1366                         return false;
1367
1368         return true;
1369 }
1370
1371 char *file_in_same_dir(const char *path, const char *filename) {
1372         char *e, *r;
1373         size_t k;
1374
1375         assert(path);
1376         assert(filename);
1377
1378         /* This removes the last component of path and appends
1379          * filename, unless the latter is absolute anyway or the
1380          * former isn't */
1381
1382         if (path_is_absolute(filename))
1383                 return strdup(filename);
1384
1385         if (!(e = strrchr(path, '/')))
1386                 return strdup(filename);
1387
1388         k = strlen(filename);
1389         if (!(r = new(char, e-path+1+k+1)))
1390                 return NULL;
1391
1392         memcpy(r, path, e-path+1);
1393         memcpy(r+(e-path)+1, filename, k+1);
1394
1395         return r;
1396 }
1397
1398 int rmdir_parents(const char *path, const char *stop) {
1399         size_t l;
1400         int r = 0;
1401
1402         assert(path);
1403         assert(stop);
1404
1405         l = strlen(path);
1406
1407         /* Skip trailing slashes */
1408         while (l > 0 && path[l-1] == '/')
1409                 l--;
1410
1411         while (l > 0) {
1412                 char *t;
1413
1414                 /* Skip last component */
1415                 while (l > 0 && path[l-1] != '/')
1416                         l--;
1417
1418                 /* Skip trailing slashes */
1419                 while (l > 0 && path[l-1] == '/')
1420                         l--;
1421
1422                 if (l <= 0)
1423                         break;
1424
1425                 if (!(t = strndup(path, l)))
1426                         return -ENOMEM;
1427
1428                 if (path_startswith(stop, t)) {
1429                         free(t);
1430                         return 0;
1431                 }
1432
1433                 r = rmdir(t);
1434                 free(t);
1435
1436                 if (r < 0)
1437                         if (errno != ENOENT)
1438                                 return -errno;
1439         }
1440
1441         return 0;
1442 }
1443
1444
1445 char hexchar(int x) {
1446         static const char table[16] = "0123456789abcdef";
1447
1448         return table[x & 15];
1449 }
1450
1451 int unhexchar(char c) {
1452
1453         if (c >= '0' && c <= '9')
1454                 return c - '0';
1455
1456         if (c >= 'a' && c <= 'f')
1457                 return c - 'a' + 10;
1458
1459         if (c >= 'A' && c <= 'F')
1460                 return c - 'A' + 10;
1461
1462         return -1;
1463 }
1464
1465 char octchar(int x) {
1466         return '0' + (x & 7);
1467 }
1468
1469 int unoctchar(char c) {
1470
1471         if (c >= '0' && c <= '7')
1472                 return c - '0';
1473
1474         return -1;
1475 }
1476
1477 char decchar(int x) {
1478         return '0' + (x % 10);
1479 }
1480
1481 int undecchar(char c) {
1482
1483         if (c >= '0' && c <= '9')
1484                 return c - '0';
1485
1486         return -1;
1487 }
1488
1489 char *cescape(const char *s) {
1490         char *r, *t;
1491         const char *f;
1492
1493         assert(s);
1494
1495         /* Does C style string escaping. */
1496
1497         r = new(char, strlen(s)*4 + 1);
1498         if (!r)
1499                 return NULL;
1500
1501         for (f = s, t = r; *f; f++)
1502
1503                 switch (*f) {
1504
1505                 case '\a':
1506                         *(t++) = '\\';
1507                         *(t++) = 'a';
1508                         break;
1509                 case '\b':
1510                         *(t++) = '\\';
1511                         *(t++) = 'b';
1512                         break;
1513                 case '\f':
1514                         *(t++) = '\\';
1515                         *(t++) = 'f';
1516                         break;
1517                 case '\n':
1518                         *(t++) = '\\';
1519                         *(t++) = 'n';
1520                         break;
1521                 case '\r':
1522                         *(t++) = '\\';
1523                         *(t++) = 'r';
1524                         break;
1525                 case '\t':
1526                         *(t++) = '\\';
1527                         *(t++) = 't';
1528                         break;
1529                 case '\v':
1530                         *(t++) = '\\';
1531                         *(t++) = 'v';
1532                         break;
1533                 case '\\':
1534                         *(t++) = '\\';
1535                         *(t++) = '\\';
1536                         break;
1537                 case '"':
1538                         *(t++) = '\\';
1539                         *(t++) = '"';
1540                         break;
1541                 case '\'':
1542                         *(t++) = '\\';
1543                         *(t++) = '\'';
1544                         break;
1545
1546                 default:
1547                         /* For special chars we prefer octal over
1548                          * hexadecimal encoding, simply because glib's
1549                          * g_strescape() does the same */
1550                         if ((*f < ' ') || (*f >= 127)) {
1551                                 *(t++) = '\\';
1552                                 *(t++) = octchar((unsigned char) *f >> 6);
1553                                 *(t++) = octchar((unsigned char) *f >> 3);
1554                                 *(t++) = octchar((unsigned char) *f);
1555                         } else
1556                                 *(t++) = *f;
1557                         break;
1558                 }
1559
1560         *t = 0;
1561
1562         return r;
1563 }
1564
1565 char *cunescape_length_with_prefix(const char *s, size_t length, const char *prefix) {
1566         char *r, *t;
1567         const char *f;
1568         size_t pl;
1569
1570         assert(s);
1571
1572         /* Undoes C style string escaping, and optionally prefixes it. */
1573
1574         pl = prefix ? strlen(prefix) : 0;
1575
1576         r = new(char, pl+length+1);
1577         if (!r)
1578                 return r;
1579
1580         if (prefix)
1581                 memcpy(r, prefix, pl);
1582
1583         for (f = s, t = r + pl; f < s + length; f++) {
1584
1585                 if (*f != '\\') {
1586                         *(t++) = *f;
1587                         continue;
1588                 }
1589
1590                 f++;
1591
1592                 switch (*f) {
1593
1594                 case 'a':
1595                         *(t++) = '\a';
1596                         break;
1597                 case 'b':
1598                         *(t++) = '\b';
1599                         break;
1600                 case 'f':
1601                         *(t++) = '\f';
1602                         break;
1603                 case 'n':
1604                         *(t++) = '\n';
1605                         break;
1606                 case 'r':
1607                         *(t++) = '\r';
1608                         break;
1609                 case 't':
1610                         *(t++) = '\t';
1611                         break;
1612                 case 'v':
1613                         *(t++) = '\v';
1614                         break;
1615                 case '\\':
1616                         *(t++) = '\\';
1617                         break;
1618                 case '"':
1619                         *(t++) = '"';
1620                         break;
1621                 case '\'':
1622                         *(t++) = '\'';
1623                         break;
1624
1625                 case 's':
1626                         /* This is an extension of the XDG syntax files */
1627                         *(t++) = ' ';
1628                         break;
1629
1630                 case 'x': {
1631                         /* hexadecimal encoding */
1632                         int a, b;
1633
1634                         a = unhexchar(f[1]);
1635                         b = unhexchar(f[2]);
1636
1637                         if (a < 0 || b < 0) {
1638                                 /* Invalid escape code, let's take it literal then */
1639                                 *(t++) = '\\';
1640                                 *(t++) = 'x';
1641                         } else {
1642                                 *(t++) = (char) ((a << 4) | b);
1643                                 f += 2;
1644                         }
1645
1646                         break;
1647                 }
1648
1649                 case '0':
1650                 case '1':
1651                 case '2':
1652                 case '3':
1653                 case '4':
1654                 case '5':
1655                 case '6':
1656                 case '7': {
1657                         /* octal encoding */
1658                         int a, b, c;
1659
1660                         a = unoctchar(f[0]);
1661                         b = unoctchar(f[1]);
1662                         c = unoctchar(f[2]);
1663
1664                         if (a < 0 || b < 0 || c < 0) {
1665                                 /* Invalid escape code, let's take it literal then */
1666                                 *(t++) = '\\';
1667                                 *(t++) = f[0];
1668                         } else {
1669                                 *(t++) = (char) ((a << 6) | (b << 3) | c);
1670                                 f += 2;
1671                         }
1672
1673                         break;
1674                 }
1675
1676                 case 0:
1677                         /* premature end of string.*/
1678                         *(t++) = '\\';
1679                         goto finish;
1680
1681                 default:
1682                         /* Invalid escape code, let's take it literal then */
1683                         *(t++) = '\\';
1684                         *(t++) = *f;
1685                         break;
1686                 }
1687         }
1688
1689 finish:
1690         *t = 0;
1691         return r;
1692 }
1693
1694 char *cunescape_length(const char *s, size_t length) {
1695         return cunescape_length_with_prefix(s, length, NULL);
1696 }
1697
1698 char *cunescape(const char *s) {
1699         assert(s);
1700
1701         return cunescape_length(s, strlen(s));
1702 }
1703
1704 char *xescape(const char *s, const char *bad) {
1705         char *r, *t;
1706         const char *f;
1707
1708         /* Escapes all chars in bad, in addition to \ and all special
1709          * chars, in \xFF style escaping. May be reversed with
1710          * cunescape. */
1711
1712         r = new(char, strlen(s) * 4 + 1);
1713         if (!r)
1714                 return NULL;
1715
1716         for (f = s, t = r; *f; f++) {
1717
1718                 if ((*f < ' ') || (*f >= 127) ||
1719                     (*f == '\\') || strchr(bad, *f)) {
1720                         *(t++) = '\\';
1721                         *(t++) = 'x';
1722                         *(t++) = hexchar(*f >> 4);
1723                         *(t++) = hexchar(*f);
1724                 } else
1725                         *(t++) = *f;
1726         }
1727
1728         *t = 0;
1729
1730         return r;
1731 }
1732
1733 char *bus_path_escape(const char *s) {
1734         char *r, *t;
1735         const char *f;
1736
1737         assert(s);
1738
1739         /* Escapes all chars that D-Bus' object path cannot deal
1740          * with. Can be reverse with bus_path_unescape() */
1741
1742         if (!(r = new(char, strlen(s)*3+1)))
1743                 return NULL;
1744
1745         for (f = s, t = r; *f; f++) {
1746
1747                 if (!(*f >= 'A' && *f <= 'Z') &&
1748                     !(*f >= 'a' && *f <= 'z') &&
1749                     !(*f >= '0' && *f <= '9')) {
1750                         *(t++) = '_';
1751                         *(t++) = hexchar(*f >> 4);
1752                         *(t++) = hexchar(*f);
1753                 } else
1754                         *(t++) = *f;
1755         }
1756
1757         *t = 0;
1758
1759         return r;
1760 }
1761
1762 char *bus_path_unescape(const char *f) {
1763         char *r, *t;
1764
1765         assert(f);
1766
1767         if (!(r = strdup(f)))
1768                 return NULL;
1769
1770         for (t = r; *f; f++) {
1771
1772                 if (*f == '_') {
1773                         int a, b;
1774
1775                         if ((a = unhexchar(f[1])) < 0 ||
1776                             (b = unhexchar(f[2])) < 0) {
1777                                 /* Invalid escape code, let's take it literal then */
1778                                 *(t++) = '_';
1779                         } else {
1780                                 *(t++) = (char) ((a << 4) | b);
1781                                 f += 2;
1782                         }
1783                 } else
1784                         *(t++) = *f;
1785         }
1786
1787         *t = 0;
1788
1789         return r;
1790 }
1791
1792 char *ascii_strlower(char *t) {
1793         char *p;
1794
1795         assert(t);
1796
1797         for (p = t; *p; p++)
1798                 if (*p >= 'A' && *p <= 'Z')
1799                         *p = *p - 'A' + 'a';
1800
1801         return t;
1802 }
1803
1804 static bool ignore_file_allow_backup(const char *filename) {
1805         assert(filename);
1806
1807         return
1808                 filename[0] == '.' ||
1809                 streq(filename, "lost+found") ||
1810                 streq(filename, "aquota.user") ||
1811                 streq(filename, "aquota.group") ||
1812                 endswith(filename, ".rpmnew") ||
1813                 endswith(filename, ".rpmsave") ||
1814                 endswith(filename, ".rpmorig") ||
1815                 endswith(filename, ".dpkg-old") ||
1816                 endswith(filename, ".dpkg-new") ||
1817                 endswith(filename, ".swp");
1818 }
1819
1820 bool ignore_file(const char *filename) {
1821         assert(filename);
1822
1823         if (endswith(filename, "~"))
1824                 return false;
1825
1826         return ignore_file_allow_backup(filename);
1827 }
1828
1829 int fd_nonblock(int fd, bool nonblock) {
1830         int flags;
1831
1832         assert(fd >= 0);
1833
1834         if ((flags = fcntl(fd, F_GETFL, 0)) < 0)
1835                 return -errno;
1836
1837         if (nonblock)
1838                 flags |= O_NONBLOCK;
1839         else
1840                 flags &= ~O_NONBLOCK;
1841
1842         if (fcntl(fd, F_SETFL, flags) < 0)
1843                 return -errno;
1844
1845         return 0;
1846 }
1847
1848 int fd_cloexec(int fd, bool cloexec) {
1849         int flags;
1850
1851         assert(fd >= 0);
1852
1853         if ((flags = fcntl(fd, F_GETFD, 0)) < 0)
1854                 return -errno;
1855
1856         if (cloexec)
1857                 flags |= FD_CLOEXEC;
1858         else
1859                 flags &= ~FD_CLOEXEC;
1860
1861         if (fcntl(fd, F_SETFD, flags) < 0)
1862                 return -errno;
1863
1864         return 0;
1865 }
1866
1867 static bool fd_in_set(int fd, const int fdset[], unsigned n_fdset) {
1868         unsigned i;
1869
1870         assert(n_fdset == 0 || fdset);
1871
1872         for (i = 0; i < n_fdset; i++)
1873                 if (fdset[i] == fd)
1874                         return true;
1875
1876         return false;
1877 }
1878
1879 int close_all_fds(const int except[], unsigned n_except) {
1880         DIR *d;
1881         struct dirent *de;
1882         int r = 0;
1883
1884         assert(n_except == 0 || except);
1885
1886         d = opendir("/proc/self/fd");
1887         if (!d) {
1888                 int fd;
1889                 struct rlimit rl;
1890
1891                 /* When /proc isn't available (for example in chroots)
1892                  * the fallback is brute forcing through the fd
1893                  * table */
1894
1895                 assert_se(getrlimit(RLIMIT_NOFILE, &rl) >= 0);
1896                 for (fd = 3; fd < (int) rl.rlim_max; fd ++) {
1897
1898                         if (fd_in_set(fd, except, n_except))
1899                                 continue;
1900
1901                         if (close_nointr(fd) < 0)
1902                                 if (errno != EBADF && r == 0)
1903                                         r = -errno;
1904                 }
1905
1906                 return r;
1907         }
1908
1909         while ((de = readdir(d))) {
1910                 int fd = -1;
1911
1912                 if (ignore_file(de->d_name))
1913                         continue;
1914
1915                 if (safe_atoi(de->d_name, &fd) < 0)
1916                         /* Let's better ignore this, just in case */
1917                         continue;
1918
1919                 if (fd < 3)
1920                         continue;
1921
1922                 if (fd == dirfd(d))
1923                         continue;
1924
1925                 if (fd_in_set(fd, except, n_except))
1926                         continue;
1927
1928                 if (close_nointr(fd) < 0) {
1929                         /* Valgrind has its own FD and doesn't want to have it closed */
1930                         if (errno != EBADF && r == 0)
1931                                 r = -errno;
1932                 }
1933         }
1934
1935         closedir(d);
1936         return r;
1937 }
1938
1939 bool chars_intersect(const char *a, const char *b) {
1940         const char *p;
1941
1942         /* Returns true if any of the chars in a are in b. */
1943         for (p = a; *p; p++)
1944                 if (strchr(b, *p))
1945                         return true;
1946
1947         return false;
1948 }
1949
1950 char *format_timestamp(char *buf, size_t l, usec_t t) {
1951         struct tm tm;
1952         time_t sec;
1953
1954         assert(buf);
1955         assert(l > 0);
1956
1957         if (t <= 0)
1958                 return NULL;
1959
1960         sec = (time_t) (t / USEC_PER_SEC);
1961
1962         if (strftime(buf, l, "%a, %Y-%m-%d %H:%M:%S %Z", localtime_r(&sec, &tm)) <= 0)
1963                 return NULL;
1964
1965         return buf;
1966 }
1967
1968 char *format_timestamp_pretty(char *buf, size_t l, usec_t t) {
1969         usec_t n, d;
1970
1971         n = now(CLOCK_REALTIME);
1972
1973         if (t <= 0 || t > n || t + USEC_PER_DAY*7 <= t)
1974                 return NULL;
1975
1976         d = n - t;
1977
1978         if (d >= USEC_PER_YEAR)
1979                 snprintf(buf, l, "%llu years and %llu months ago",
1980                          (unsigned long long) (d / USEC_PER_YEAR),
1981                          (unsigned long long) ((d % USEC_PER_YEAR) / USEC_PER_MONTH));
1982         else if (d >= USEC_PER_MONTH)
1983                 snprintf(buf, l, "%llu months and %llu days ago",
1984                          (unsigned long long) (d / USEC_PER_MONTH),
1985                          (unsigned long long) ((d % USEC_PER_MONTH) / USEC_PER_DAY));
1986         else if (d >= USEC_PER_WEEK)
1987                 snprintf(buf, l, "%llu weeks and %llu days ago",
1988                          (unsigned long long) (d / USEC_PER_WEEK),
1989                          (unsigned long long) ((d % USEC_PER_WEEK) / USEC_PER_DAY));
1990         else if (d >= 2*USEC_PER_DAY)
1991                 snprintf(buf, l, "%llu days ago", (unsigned long long) (d / USEC_PER_DAY));
1992         else if (d >= 25*USEC_PER_HOUR)
1993                 snprintf(buf, l, "1 day and %lluh ago",
1994                          (unsigned long long) ((d - USEC_PER_DAY) / USEC_PER_HOUR));
1995         else if (d >= 6*USEC_PER_HOUR)
1996                 snprintf(buf, l, "%lluh ago",
1997                          (unsigned long long) (d / USEC_PER_HOUR));
1998         else if (d >= USEC_PER_HOUR)
1999                 snprintf(buf, l, "%lluh %llumin ago",
2000                          (unsigned long long) (d / USEC_PER_HOUR),
2001                          (unsigned long long) ((d % USEC_PER_HOUR) / USEC_PER_MINUTE));
2002         else if (d >= 5*USEC_PER_MINUTE)
2003                 snprintf(buf, l, "%llumin ago",
2004                          (unsigned long long) (d / USEC_PER_MINUTE));
2005         else if (d >= USEC_PER_MINUTE)
2006                 snprintf(buf, l, "%llumin %llus ago",
2007                          (unsigned long long) (d / USEC_PER_MINUTE),
2008                          (unsigned long long) ((d % USEC_PER_MINUTE) / USEC_PER_SEC));
2009         else if (d >= USEC_PER_SEC)
2010                 snprintf(buf, l, "%llus ago",
2011                          (unsigned long long) (d / USEC_PER_SEC));
2012         else if (d >= USEC_PER_MSEC)
2013                 snprintf(buf, l, "%llums ago",
2014                          (unsigned long long) (d / USEC_PER_MSEC));
2015         else if (d > 0)
2016                 snprintf(buf, l, "%lluus ago",
2017                          (unsigned long long) d);
2018         else
2019                 snprintf(buf, l, "now");
2020
2021         buf[l-1] = 0;
2022         return buf;
2023 }
2024
2025 char *format_timespan(char *buf, size_t l, usec_t t) {
2026         static const struct {
2027                 const char *suffix;
2028                 usec_t usec;
2029         } table[] = {
2030                 { "w", USEC_PER_WEEK },
2031                 { "d", USEC_PER_DAY },
2032                 { "h", USEC_PER_HOUR },
2033                 { "min", USEC_PER_MINUTE },
2034                 { "s", USEC_PER_SEC },
2035                 { "ms", USEC_PER_MSEC },
2036                 { "us", 1 },
2037         };
2038
2039         unsigned i;
2040         char *p = buf;
2041
2042         assert(buf);
2043         assert(l > 0);
2044
2045         if (t == (usec_t) -1)
2046                 return NULL;
2047
2048         if (t == 0) {
2049                 snprintf(p, l, "0");
2050                 p[l-1] = 0;
2051                 return p;
2052         }
2053
2054         /* The result of this function can be parsed with parse_usec */
2055
2056         for (i = 0; i < ELEMENTSOF(table); i++) {
2057                 int k;
2058                 size_t n;
2059
2060                 if (t < table[i].usec)
2061                         continue;
2062
2063                 if (l <= 1)
2064                         break;
2065
2066                 k = snprintf(p, l, "%s%llu%s", p > buf ? " " : "", (unsigned long long) (t / table[i].usec), table[i].suffix);
2067                 n = MIN((size_t) k, l);
2068
2069                 l -= n;
2070                 p += n;
2071
2072                 t %= table[i].usec;
2073         }
2074
2075         *p = 0;
2076
2077         return buf;
2078 }
2079
2080 bool fstype_is_network(const char *fstype) {
2081         static const char table[] =
2082                 "cifs\0"
2083                 "smbfs\0"
2084                 "ncpfs\0"
2085                 "nfs\0"
2086                 "nfs4\0"
2087                 "gfs\0"
2088                 "gfs2\0";
2089
2090         return nulstr_contains(table, fstype);
2091 }
2092
2093 int chvt(int vt) {
2094         _cleanup_close_ int fd;
2095
2096         fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
2097         if (fd < 0)
2098                 return -errno;
2099
2100         if (vt < 0) {
2101                 int tiocl[2] = {
2102                         TIOCL_GETKMSGREDIRECT,
2103                         0
2104                 };
2105
2106                 if (ioctl(fd, TIOCLINUX, tiocl) < 0)
2107                         return -errno;
2108
2109                 vt = tiocl[0] <= 0 ? 1 : tiocl[0];
2110         }
2111
2112         if (ioctl(fd, VT_ACTIVATE, vt) < 0)
2113                 return -errno;
2114
2115         return 0;
2116 }
2117
2118 int read_one_char(FILE *f, char *ret, usec_t t, bool *need_nl) {
2119         struct termios old_termios, new_termios;
2120         char c;
2121         char line[LINE_MAX];
2122
2123         assert(f);
2124         assert(ret);
2125
2126         if (tcgetattr(fileno(f), &old_termios) >= 0) {
2127                 new_termios = old_termios;
2128
2129                 new_termios.c_lflag &= ~ICANON;
2130                 new_termios.c_cc[VMIN] = 1;
2131                 new_termios.c_cc[VTIME] = 0;
2132
2133                 if (tcsetattr(fileno(f), TCSADRAIN, &new_termios) >= 0) {
2134                         size_t k;
2135
2136                         if (t != (usec_t) -1) {
2137                                 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0) {
2138                                         tcsetattr(fileno(f), TCSADRAIN, &old_termios);
2139                                         return -ETIMEDOUT;
2140                                 }
2141                         }
2142
2143                         k = fread(&c, 1, 1, f);
2144
2145                         tcsetattr(fileno(f), TCSADRAIN, &old_termios);
2146
2147                         if (k <= 0)
2148                                 return -EIO;
2149
2150                         if (need_nl)
2151                                 *need_nl = c != '\n';
2152
2153                         *ret = c;
2154                         return 0;
2155                 }
2156         }
2157
2158         if (t != (usec_t) -1)
2159                 if (fd_wait_for_event(fileno(f), POLLIN, t) <= 0)
2160                         return -ETIMEDOUT;
2161
2162         if (!fgets(line, sizeof(line), f))
2163                 return -EIO;
2164
2165         truncate_nl(line);
2166
2167         if (strlen(line) != 1)
2168                 return -EBADMSG;
2169
2170         if (need_nl)
2171                 *need_nl = false;
2172
2173         *ret = line[0];
2174         return 0;
2175 }
2176
2177 int ask(char *ret, const char *replies, const char *text, ...) {
2178
2179         assert(ret);
2180         assert(replies);
2181         assert(text);
2182
2183         for (;;) {
2184                 va_list ap;
2185                 char c;
2186                 int r;
2187                 bool need_nl = true;
2188
2189                 if (on_tty())
2190                         fputs(ANSI_HIGHLIGHT_ON, stdout);
2191
2192                 va_start(ap, text);
2193                 vprintf(text, ap);
2194                 va_end(ap);
2195
2196                 if (on_tty())
2197                         fputs(ANSI_HIGHLIGHT_OFF, stdout);
2198
2199                 fflush(stdout);
2200
2201                 r = read_one_char(stdin, &c, (usec_t) -1, &need_nl);
2202                 if (r < 0) {
2203
2204                         if (r == -EBADMSG) {
2205                                 puts("Bad input, please try again.");
2206                                 continue;
2207                         }
2208
2209                         putchar('\n');
2210                         return r;
2211                 }
2212
2213                 if (need_nl)
2214                         putchar('\n');
2215
2216                 if (strchr(replies, c)) {
2217                         *ret = c;
2218                         return 0;
2219                 }
2220
2221                 puts("Read unexpected character, please try again.");
2222         }
2223 }
2224
2225 int reset_terminal_fd(int fd, bool switch_to_text) {
2226         struct termios termios;
2227         int r = 0;
2228
2229         /* Set terminal to some sane defaults */
2230
2231         assert(fd >= 0);
2232
2233         /* We leave locked terminal attributes untouched, so that
2234          * Plymouth may set whatever it wants to set, and we don't
2235          * interfere with that. */
2236
2237         /* Disable exclusive mode, just in case */
2238         ioctl(fd, TIOCNXCL);
2239
2240         /* Switch to text mode */
2241         if (switch_to_text)
2242                 ioctl(fd, KDSETMODE, KD_TEXT);
2243
2244         /* Enable console unicode mode */
2245         ioctl(fd, KDSKBMODE, K_UNICODE);
2246
2247         if (tcgetattr(fd, &termios) < 0) {
2248                 r = -errno;
2249                 goto finish;
2250         }
2251
2252         /* We only reset the stuff that matters to the software. How
2253          * hardware is set up we don't touch assuming that somebody
2254          * else will do that for us */
2255
2256         termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
2257         termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
2258         termios.c_oflag |= ONLCR;
2259         termios.c_cflag |= CREAD;
2260         termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
2261
2262         termios.c_cc[VINTR]    =   03;  /* ^C */
2263         termios.c_cc[VQUIT]    =  034;  /* ^\ */
2264         termios.c_cc[VERASE]   = 0177;
2265         termios.c_cc[VKILL]    =  025;  /* ^X */
2266         termios.c_cc[VEOF]     =   04;  /* ^D */
2267         termios.c_cc[VSTART]   =  021;  /* ^Q */
2268         termios.c_cc[VSTOP]    =  023;  /* ^S */
2269         termios.c_cc[VSUSP]    =  032;  /* ^Z */
2270         termios.c_cc[VLNEXT]   =  026;  /* ^V */
2271         termios.c_cc[VWERASE]  =  027;  /* ^W */
2272         termios.c_cc[VREPRINT] =  022;  /* ^R */
2273         termios.c_cc[VEOL]     =    0;
2274         termios.c_cc[VEOL2]    =    0;
2275
2276         termios.c_cc[VTIME]  = 0;
2277         termios.c_cc[VMIN]   = 1;
2278
2279         if (tcsetattr(fd, TCSANOW, &termios) < 0)
2280                 r = -errno;
2281
2282 finish:
2283         /* Just in case, flush all crap out */
2284         tcflush(fd, TCIOFLUSH);
2285
2286         return r;
2287 }
2288
2289 int reset_terminal(const char *name) {
2290         int fd, r;
2291
2292         fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
2293         if (fd < 0)
2294                 return fd;
2295
2296         r = reset_terminal_fd(fd, true);
2297         close_nointr_nofail(fd);
2298
2299         return r;
2300 }
2301
2302 int open_terminal(const char *name, int mode) {
2303         int fd, r;
2304         unsigned c = 0;
2305
2306         /*
2307          * If a TTY is in the process of being closed opening it might
2308          * cause EIO. This is horribly awful, but unlikely to be
2309          * changed in the kernel. Hence we work around this problem by
2310          * retrying a couple of times.
2311          *
2312          * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
2313          */
2314
2315         for (;;) {
2316                 fd = open(name, mode);
2317                 if (fd >= 0)
2318                         break;
2319
2320                 if (errno != EIO)
2321                         return -errno;
2322
2323                 /* Max 1s in total */
2324                 if (c >= 20)
2325                         return -errno;
2326
2327                 usleep(50 * USEC_PER_MSEC);
2328                 c++;
2329         }
2330
2331         if (fd < 0)
2332                 return -errno;
2333
2334         r = isatty(fd);
2335         if (r < 0) {
2336                 close_nointr_nofail(fd);
2337                 return -errno;
2338         }
2339
2340         if (!r) {
2341                 close_nointr_nofail(fd);
2342                 return -ENOTTY;
2343         }
2344
2345         return fd;
2346 }
2347
2348 int flush_fd(int fd) {
2349         struct pollfd pollfd;
2350
2351         zero(pollfd);
2352         pollfd.fd = fd;
2353         pollfd.events = POLLIN;
2354
2355         for (;;) {
2356                 char buf[LINE_MAX];
2357                 ssize_t l;
2358                 int r;
2359
2360                 if ((r = poll(&pollfd, 1, 0)) < 0) {
2361
2362                         if (errno == EINTR)
2363                                 continue;
2364
2365                         return -errno;
2366                 }
2367
2368                 if (r == 0)
2369                         return 0;
2370
2371                 if ((l = read(fd, buf, sizeof(buf))) < 0) {
2372
2373                         if (errno == EINTR)
2374                                 continue;
2375
2376                         if (errno == EAGAIN)
2377                                 return 0;
2378
2379                         return -errno;
2380                 }
2381
2382                 if (l <= 0)
2383                         return 0;
2384         }
2385 }
2386
2387 int acquire_terminal(
2388                 const char *name,
2389                 bool fail,
2390                 bool force,
2391                 bool ignore_tiocstty_eperm,
2392                 usec_t timeout) {
2393
2394         int fd = -1, notify = -1, r = 0, wd = -1;
2395         usec_t ts = 0;
2396         struct sigaction sa_old, sa_new;
2397
2398         assert(name);
2399
2400         /* We use inotify to be notified when the tty is closed. We
2401          * create the watch before checking if we can actually acquire
2402          * it, so that we don't lose any event.
2403          *
2404          * Note: strictly speaking this actually watches for the
2405          * device being closed, it does *not* really watch whether a
2406          * tty loses its controlling process. However, unless some
2407          * rogue process uses TIOCNOTTY on /dev/tty *after* closing
2408          * its tty otherwise this will not become a problem. As long
2409          * as the administrator makes sure not configure any service
2410          * on the same tty as an untrusted user this should not be a
2411          * problem. (Which he probably should not do anyway.) */
2412
2413         if (timeout != (usec_t) -1)
2414                 ts = now(CLOCK_MONOTONIC);
2415
2416         if (!fail && !force) {
2417                 notify = inotify_init1(IN_CLOEXEC | (timeout != (usec_t) -1 ? IN_NONBLOCK : 0));
2418                 if (notify < 0) {
2419                         r = -errno;
2420                         goto fail;
2421                 }
2422
2423                 wd = inotify_add_watch(notify, name, IN_CLOSE);
2424                 if (wd < 0) {
2425                         r = -errno;
2426                         goto fail;
2427                 }
2428         }
2429
2430         for (;;) {
2431                 if (notify >= 0) {
2432                         r = flush_fd(notify);
2433                         if (r < 0)
2434                                 goto fail;
2435                 }
2436
2437                 /* We pass here O_NOCTTY only so that we can check the return
2438                  * value TIOCSCTTY and have a reliable way to figure out if we
2439                  * successfully became the controlling process of the tty */
2440                 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
2441                 if (fd < 0)
2442                         return fd;
2443
2444                 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
2445                  * if we already own the tty. */
2446                 zero(sa_new);
2447                 sa_new.sa_handler = SIG_IGN;
2448                 sa_new.sa_flags = SA_RESTART;
2449                 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
2450
2451                 /* First, try to get the tty */
2452                 if (ioctl(fd, TIOCSCTTY, force) < 0)
2453                         r = -errno;
2454
2455                 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
2456
2457                 /* Sometimes it makes sense to ignore TIOCSCTTY
2458                  * returning EPERM, i.e. when very likely we already
2459                  * are have this controlling terminal. */
2460                 if (r < 0 && r == -EPERM && ignore_tiocstty_eperm)
2461                         r = 0;
2462
2463                 if (r < 0 && (force || fail || r != -EPERM)) {
2464                         goto fail;
2465                 }
2466
2467                 if (r >= 0)
2468                         break;
2469
2470                 assert(!fail);
2471                 assert(!force);
2472                 assert(notify >= 0);
2473
2474                 for (;;) {
2475                         uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
2476                         ssize_t l;
2477                         struct inotify_event *e;
2478
2479                         if (timeout != (usec_t) -1) {
2480                                 usec_t n;
2481
2482                                 n = now(CLOCK_MONOTONIC);
2483                                 if (ts + timeout < n) {
2484                                         r = -ETIMEDOUT;
2485                                         goto fail;
2486                                 }
2487
2488                                 r = fd_wait_for_event(fd, POLLIN, ts + timeout - n);
2489                                 if (r < 0)
2490                                         goto fail;
2491
2492                                 if (r == 0) {
2493                                         r = -ETIMEDOUT;
2494                                         goto fail;
2495                                 }
2496                         }
2497
2498                         l = read(notify, inotify_buffer, sizeof(inotify_buffer));
2499                         if (l < 0) {
2500
2501                                 if (errno == EINTR || errno == EAGAIN)
2502                                         continue;
2503
2504                                 r = -errno;
2505                                 goto fail;
2506                         }
2507
2508                         e = (struct inotify_event*) inotify_buffer;
2509
2510                         while (l > 0) {
2511                                 size_t step;
2512
2513                                 if (e->wd != wd || !(e->mask & IN_CLOSE)) {
2514                                         r = -EIO;
2515                                         goto fail;
2516                                 }
2517
2518                                 step = sizeof(struct inotify_event) + e->len;
2519                                 assert(step <= (size_t) l);
2520
2521                                 e = (struct inotify_event*) ((uint8_t*) e + step);
2522                                 l -= step;
2523                         }
2524
2525                         break;
2526                 }
2527
2528                 /* We close the tty fd here since if the old session
2529                  * ended our handle will be dead. It's important that
2530                  * we do this after sleeping, so that we don't enter
2531                  * an endless loop. */
2532                 close_nointr_nofail(fd);
2533         }
2534
2535         if (notify >= 0)
2536                 close_nointr_nofail(notify);
2537
2538         r = reset_terminal_fd(fd, true);
2539         if (r < 0)
2540                 log_warning("Failed to reset terminal: %s", strerror(-r));
2541
2542         return fd;
2543
2544 fail:
2545         if (fd >= 0)
2546                 close_nointr_nofail(fd);
2547
2548         if (notify >= 0)
2549                 close_nointr_nofail(notify);
2550
2551         return r;
2552 }
2553
2554 int release_terminal(void) {
2555         int r = 0, fd;
2556         struct sigaction sa_old, sa_new;
2557
2558         if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC)) < 0)
2559                 return -errno;
2560
2561         /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
2562          * by our own TIOCNOTTY */
2563
2564         zero(sa_new);
2565         sa_new.sa_handler = SIG_IGN;
2566         sa_new.sa_flags = SA_RESTART;
2567         assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
2568
2569         if (ioctl(fd, TIOCNOTTY) < 0)
2570                 r = -errno;
2571
2572         assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
2573
2574         close_nointr_nofail(fd);
2575         return r;
2576 }
2577
2578 int sigaction_many(const struct sigaction *sa, ...) {
2579         va_list ap;
2580         int r = 0, sig;
2581
2582         va_start(ap, sa);
2583         while ((sig = va_arg(ap, int)) > 0)
2584                 if (sigaction(sig, sa, NULL) < 0)
2585                         r = -errno;
2586         va_end(ap);
2587
2588         return r;
2589 }
2590
2591 int ignore_signals(int sig, ...) {
2592         struct sigaction sa;
2593         va_list ap;
2594         int r = 0;
2595
2596         zero(sa);
2597         sa.sa_handler = SIG_IGN;
2598         sa.sa_flags = SA_RESTART;
2599
2600         if (sigaction(sig, &sa, NULL) < 0)
2601                 r = -errno;
2602
2603         va_start(ap, sig);
2604         while ((sig = va_arg(ap, int)) > 0)
2605                 if (sigaction(sig, &sa, NULL) < 0)
2606                         r = -errno;
2607         va_end(ap);
2608
2609         return r;
2610 }
2611
2612 int default_signals(int sig, ...) {
2613         struct sigaction sa;
2614         va_list ap;
2615         int r = 0;
2616
2617         zero(sa);
2618         sa.sa_handler = SIG_DFL;
2619         sa.sa_flags = SA_RESTART;
2620
2621         if (sigaction(sig, &sa, NULL) < 0)
2622                 r = -errno;
2623
2624         va_start(ap, sig);
2625         while ((sig = va_arg(ap, int)) > 0)
2626                 if (sigaction(sig, &sa, NULL) < 0)
2627                         r = -errno;
2628         va_end(ap);
2629
2630         return r;
2631 }
2632
2633 int close_pipe(int p[]) {
2634         int a = 0, b = 0;
2635
2636         assert(p);
2637
2638         if (p[0] >= 0) {
2639                 a = close_nointr(p[0]);
2640                 p[0] = -1;
2641         }
2642
2643         if (p[1] >= 0) {
2644                 b = close_nointr(p[1]);
2645                 p[1] = -1;
2646         }
2647
2648         return a < 0 ? a : b;
2649 }
2650
2651 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
2652         uint8_t *p;
2653         ssize_t n = 0;
2654
2655         assert(fd >= 0);
2656         assert(buf);
2657
2658         p = buf;
2659
2660         while (nbytes > 0) {
2661                 ssize_t k;
2662
2663                 if ((k = read(fd, p, nbytes)) <= 0) {
2664
2665                         if (k < 0 && errno == EINTR)
2666                                 continue;
2667
2668                         if (k < 0 && errno == EAGAIN && do_poll) {
2669                                 struct pollfd pollfd;
2670
2671                                 zero(pollfd);
2672                                 pollfd.fd = fd;
2673                                 pollfd.events = POLLIN;
2674
2675                                 if (poll(&pollfd, 1, -1) < 0) {
2676                                         if (errno == EINTR)
2677                                                 continue;
2678
2679                                         return n > 0 ? n : -errno;
2680                                 }
2681
2682                                 if (pollfd.revents != POLLIN)
2683                                         return n > 0 ? n : -EIO;
2684
2685                                 continue;
2686                         }
2687
2688                         return n > 0 ? n : (k < 0 ? -errno : 0);
2689                 }
2690
2691                 p += k;
2692                 nbytes -= k;
2693                 n += k;
2694         }
2695
2696         return n;
2697 }
2698
2699 ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
2700         const uint8_t *p;
2701         ssize_t n = 0;
2702
2703         assert(fd >= 0);
2704         assert(buf);
2705
2706         p = buf;
2707
2708         while (nbytes > 0) {
2709                 ssize_t k;
2710
2711                 k = write(fd, p, nbytes);
2712                 if (k <= 0) {
2713
2714                         if (k < 0 && errno == EINTR)
2715                                 continue;
2716
2717                         if (k < 0 && errno == EAGAIN && do_poll) {
2718                                 struct pollfd pollfd;
2719
2720                                 zero(pollfd);
2721                                 pollfd.fd = fd;
2722                                 pollfd.events = POLLOUT;
2723
2724                                 if (poll(&pollfd, 1, -1) < 0) {
2725                                         if (errno == EINTR)
2726                                                 continue;
2727
2728                                         return n > 0 ? n : -errno;
2729                                 }
2730
2731                                 if (pollfd.revents != POLLOUT)
2732                                         return n > 0 ? n : -EIO;
2733
2734                                 continue;
2735                         }
2736
2737                         return n > 0 ? n : (k < 0 ? -errno : 0);
2738                 }
2739
2740                 p += k;
2741                 nbytes -= k;
2742                 n += k;
2743         }
2744
2745         return n;
2746 }
2747
2748 int parse_usec(const char *t, usec_t *usec) {
2749         static const struct {
2750                 const char *suffix;
2751                 usec_t usec;
2752         } table[] = {
2753                 { "seconds", USEC_PER_SEC },
2754                 { "second", USEC_PER_SEC },
2755                 { "sec", USEC_PER_SEC },
2756                 { "s", USEC_PER_SEC },
2757                 { "minutes", USEC_PER_MINUTE },
2758                 { "minute", USEC_PER_MINUTE },
2759                 { "min", USEC_PER_MINUTE },
2760                 { "months", USEC_PER_MONTH },
2761                 { "month", USEC_PER_MONTH },
2762                 { "msec", USEC_PER_MSEC },
2763                 { "ms", USEC_PER_MSEC },
2764                 { "m", USEC_PER_MINUTE },
2765                 { "hours", USEC_PER_HOUR },
2766                 { "hour", USEC_PER_HOUR },
2767                 { "hr", USEC_PER_HOUR },
2768                 { "h", USEC_PER_HOUR },
2769                 { "days", USEC_PER_DAY },
2770                 { "day", USEC_PER_DAY },
2771                 { "d", USEC_PER_DAY },
2772                 { "weeks", USEC_PER_WEEK },
2773                 { "week", USEC_PER_WEEK },
2774                 { "w", USEC_PER_WEEK },
2775                 { "years", USEC_PER_YEAR },
2776                 { "year", USEC_PER_YEAR },
2777                 { "y", USEC_PER_YEAR },
2778                 { "usec", 1ULL },
2779                 { "us", 1ULL },
2780                 { "", USEC_PER_SEC }, /* default is sec */
2781         };
2782
2783         const char *p;
2784         usec_t r = 0;
2785
2786         assert(t);
2787         assert(usec);
2788
2789         p = t;
2790         do {
2791                 long long l;
2792                 char *e;
2793                 unsigned i;
2794
2795                 errno = 0;
2796                 l = strtoll(p, &e, 10);
2797
2798                 if (errno != 0)
2799                         return -errno;
2800
2801                 if (l < 0)
2802                         return -ERANGE;
2803
2804                 if (e == p)
2805                         return -EINVAL;
2806
2807                 e += strspn(e, WHITESPACE);
2808
2809                 for (i = 0; i < ELEMENTSOF(table); i++)
2810                         if (startswith(e, table[i].suffix)) {
2811                                 r += (usec_t) l * table[i].usec;
2812                                 p = e + strlen(table[i].suffix);
2813                                 break;
2814                         }
2815
2816                 if (i >= ELEMENTSOF(table))
2817                         return -EINVAL;
2818
2819         } while (*p != 0);
2820
2821         *usec = r;
2822
2823         return 0;
2824 }
2825
2826 int parse_nsec(const char *t, nsec_t *nsec) {
2827         static const struct {
2828                 const char *suffix;
2829                 nsec_t nsec;
2830         } table[] = {
2831                 { "seconds", NSEC_PER_SEC },
2832                 { "second", NSEC_PER_SEC },
2833                 { "sec", NSEC_PER_SEC },
2834                 { "s", NSEC_PER_SEC },
2835                 { "minutes", NSEC_PER_MINUTE },
2836                 { "minute", NSEC_PER_MINUTE },
2837                 { "min", NSEC_PER_MINUTE },
2838                 { "months", NSEC_PER_MONTH },
2839                 { "month", NSEC_PER_MONTH },
2840                 { "msec", NSEC_PER_MSEC },
2841                 { "ms", NSEC_PER_MSEC },
2842                 { "m", NSEC_PER_MINUTE },
2843                 { "hours", NSEC_PER_HOUR },
2844                 { "hour", NSEC_PER_HOUR },
2845                 { "hr", NSEC_PER_HOUR },
2846                 { "h", NSEC_PER_HOUR },
2847                 { "days", NSEC_PER_DAY },
2848                 { "day", NSEC_PER_DAY },
2849                 { "d", NSEC_PER_DAY },
2850                 { "weeks", NSEC_PER_WEEK },
2851                 { "week", NSEC_PER_WEEK },
2852                 { "w", NSEC_PER_WEEK },
2853                 { "years", NSEC_PER_YEAR },
2854                 { "year", NSEC_PER_YEAR },
2855                 { "y", NSEC_PER_YEAR },
2856                 { "usec", NSEC_PER_USEC },
2857                 { "us", NSEC_PER_USEC },
2858                 { "nsec", 1ULL },
2859                 { "ns", 1ULL },
2860                 { "", 1ULL }, /* default is nsec */
2861         };
2862
2863         const char *p;
2864         nsec_t r = 0;
2865
2866         assert(t);
2867         assert(nsec);
2868
2869         p = t;
2870         do {
2871                 long long l;
2872                 char *e;
2873                 unsigned i;
2874
2875                 errno = 0;
2876                 l = strtoll(p, &e, 10);
2877
2878                 if (errno != 0)
2879                         return -errno;
2880
2881                 if (l < 0)
2882                         return -ERANGE;
2883
2884                 if (e == p)
2885                         return -EINVAL;
2886
2887                 e += strspn(e, WHITESPACE);
2888
2889                 for (i = 0; i < ELEMENTSOF(table); i++)
2890                         if (startswith(e, table[i].suffix)) {
2891                                 r += (nsec_t) l * table[i].nsec;
2892                                 p = e + strlen(table[i].suffix);
2893                                 break;
2894                         }
2895
2896                 if (i >= ELEMENTSOF(table))
2897                         return -EINVAL;
2898
2899         } while (*p != 0);
2900
2901         *nsec = r;
2902
2903         return 0;
2904 }
2905
2906 int parse_bytes(const char *t, off_t *bytes) {
2907         static const struct {
2908                 const char *suffix;
2909                 off_t factor;
2910         } table[] = {
2911                 { "B", 1 },
2912                 { "K", 1024ULL },
2913                 { "M", 1024ULL*1024ULL },
2914                 { "G", 1024ULL*1024ULL*1024ULL },
2915                 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
2916                 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2917                 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2918                 { "", 1 },
2919         };
2920
2921         const char *p;
2922         off_t r = 0;
2923
2924         assert(t);
2925         assert(bytes);
2926
2927         p = t;
2928         do {
2929                 long long l;
2930                 char *e;
2931                 unsigned i;
2932
2933                 errno = 0;
2934                 l = strtoll(p, &e, 10);
2935
2936                 if (errno != 0)
2937                         return -errno;
2938
2939                 if (l < 0)
2940                         return -ERANGE;
2941
2942                 if (e == p)
2943                         return -EINVAL;
2944
2945                 e += strspn(e, WHITESPACE);
2946
2947                 for (i = 0; i < ELEMENTSOF(table); i++)
2948                         if (startswith(e, table[i].suffix)) {
2949                                 r += (off_t) l * table[i].factor;
2950                                 p = e + strlen(table[i].suffix);
2951                                 break;
2952                         }
2953
2954                 if (i >= ELEMENTSOF(table))
2955                         return -EINVAL;
2956
2957         } while (*p != 0);
2958
2959         *bytes = r;
2960
2961         return 0;
2962 }
2963
2964 int make_stdio(int fd) {
2965         int r, s, t;
2966
2967         assert(fd >= 0);
2968
2969         r = dup3(fd, STDIN_FILENO, 0);
2970         s = dup3(fd, STDOUT_FILENO, 0);
2971         t = dup3(fd, STDERR_FILENO, 0);
2972
2973         if (fd >= 3)
2974                 close_nointr_nofail(fd);
2975
2976         if (r < 0 || s < 0 || t < 0)
2977                 return -errno;
2978
2979         /* We rely here that the new fd has O_CLOEXEC not set */
2980
2981         return 0;
2982 }
2983
2984 int make_null_stdio(void) {
2985         int null_fd;
2986
2987         null_fd = open("/dev/null", O_RDWR|O_NOCTTY);
2988         if (null_fd < 0)
2989                 return -errno;
2990
2991         return make_stdio(null_fd);
2992 }
2993
2994 bool is_device_path(const char *path) {
2995
2996         /* Returns true on paths that refer to a device, either in
2997          * sysfs or in /dev */
2998
2999         return
3000                 path_startswith(path, "/dev/") ||
3001                 path_startswith(path, "/sys/");
3002 }
3003
3004 int dir_is_empty(const char *path) {
3005         _cleanup_closedir_ DIR *d;
3006         int r;
3007
3008         d = opendir(path);
3009         if (!d)
3010                 return -errno;
3011
3012         for (;;) {
3013                 struct dirent *de;
3014                 union dirent_storage buf;
3015
3016                 r = readdir_r(d, &buf.de, &de);
3017                 if (r > 0)
3018                         return -r;
3019
3020                 if (!de)
3021                         return 1;
3022
3023                 if (!ignore_file(de->d_name))
3024                         return 0;
3025         }
3026 }
3027
3028 unsigned long long random_ull(void) {
3029         _cleanup_close_ int fd;
3030         uint64_t ull;
3031         ssize_t r;
3032
3033         fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
3034         if (fd < 0)
3035                 goto fallback;
3036
3037         r = loop_read(fd, &ull, sizeof(ull), true);
3038         if (r != sizeof(ull))
3039                 goto fallback;
3040
3041         return ull;
3042
3043 fallback:
3044         return random() * RAND_MAX + random();
3045 }
3046
3047 void rename_process(const char name[8]) {
3048         assert(name);
3049
3050         /* This is a like a poor man's setproctitle(). It changes the
3051          * comm field, argv[0], and also the glibc's internally used
3052          * name of the process. For the first one a limit of 16 chars
3053          * applies, to the second one usually one of 10 (i.e. length
3054          * of "/sbin/init"), to the third one one of 7 (i.e. length of
3055          * "systemd"). If you pass a longer string it will be
3056          * truncated */
3057
3058         prctl(PR_SET_NAME, name);
3059
3060         if (program_invocation_name)
3061                 strncpy(program_invocation_name, name, strlen(program_invocation_name));
3062
3063         if (saved_argc > 0) {
3064                 int i;
3065
3066                 if (saved_argv[0])
3067                         strncpy(saved_argv[0], name, strlen(saved_argv[0]));
3068
3069                 for (i = 1; i < saved_argc; i++) {
3070                         if (!saved_argv[i])
3071                                 break;
3072
3073                         memset(saved_argv[i], 0, strlen(saved_argv[i]));
3074                 }
3075         }
3076 }
3077
3078 void sigset_add_many(sigset_t *ss, ...) {
3079         va_list ap;
3080         int sig;
3081
3082         assert(ss);
3083
3084         va_start(ap, ss);
3085         while ((sig = va_arg(ap, int)) > 0)
3086                 assert_se(sigaddset(ss, sig) == 0);
3087         va_end(ap);
3088 }
3089
3090 char* gethostname_malloc(void) {
3091         struct utsname u;
3092
3093         assert_se(uname(&u) >= 0);
3094
3095         if (!isempty(u.nodename) && !streq(u.nodename, "(none)"))
3096                 return strdup(u.nodename);
3097
3098         return strdup(u.sysname);
3099 }
3100
3101 bool hostname_is_set(void) {
3102         struct utsname u;
3103
3104         assert_se(uname(&u) >= 0);
3105
3106         return !isempty(u.nodename) && !streq(u.nodename, "(none)");
3107 }
3108
3109 static char *lookup_uid(uid_t uid) {
3110         long bufsize;
3111         char *name;
3112         _cleanup_free_ char *buf = NULL;
3113         struct passwd pwbuf, *pw = NULL;
3114
3115         /* Shortcut things to avoid NSS lookups */
3116         if (uid == 0)
3117                 return strdup("root");
3118
3119         bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
3120         if (bufsize <= 0)
3121                 bufsize = 4096;
3122
3123         buf = malloc(bufsize);
3124         if (!buf)
3125                 return NULL;
3126
3127         if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
3128                 return strdup(pw->pw_name);
3129
3130         if (asprintf(&name, "%lu", (unsigned long) uid) < 0)
3131                 return NULL;
3132
3133         return name;
3134 }
3135
3136 char* getlogname_malloc(void) {
3137         uid_t uid;
3138         struct stat st;
3139
3140         if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
3141                 uid = st.st_uid;
3142         else
3143                 uid = getuid();
3144
3145         return lookup_uid(uid);
3146 }
3147
3148 char *getusername_malloc(void) {
3149         const char *e;
3150
3151         e = getenv("USER");
3152         if (e)
3153                 return strdup(e);
3154
3155         return lookup_uid(getuid());
3156 }
3157
3158 int getttyname_malloc(int fd, char **r) {
3159         char path[PATH_MAX], *c;
3160         int k;
3161
3162         assert(r);
3163
3164         k = ttyname_r(fd, path, sizeof(path));
3165         if (k != 0)
3166                 return -k;
3167
3168         char_array_0(path);
3169
3170         c = strdup(startswith(path, "/dev/") ? path + 5 : path);
3171         if (!c)
3172                 return -ENOMEM;
3173
3174         *r = c;
3175         return 0;
3176 }
3177
3178 int getttyname_harder(int fd, char **r) {
3179         int k;
3180         char *s;
3181
3182         k = getttyname_malloc(fd, &s);
3183         if (k < 0)
3184                 return k;
3185
3186         if (streq(s, "tty")) {
3187                 free(s);
3188                 return get_ctty(0, NULL, r);
3189         }
3190
3191         *r = s;
3192         return 0;
3193 }
3194
3195 int get_ctty_devnr(pid_t pid, dev_t *d) {
3196         int k;
3197         char line[LINE_MAX], *p, *fn;
3198         unsigned long ttynr;
3199         FILE *f;
3200
3201         if (asprintf(&fn, "/proc/%lu/stat", (unsigned long) (pid <= 0 ? getpid() : pid)) < 0)
3202                 return -ENOMEM;
3203
3204         f = fopen(fn, "re");
3205         free(fn);
3206         if (!f)
3207                 return -errno;
3208
3209         if (!fgets(line, sizeof(line), f)) {
3210                 k = feof(f) ? -EIO : -errno;
3211                 fclose(f);
3212                 return k;
3213         }
3214
3215         fclose(f);
3216
3217         p = strrchr(line, ')');
3218         if (!p)
3219                 return -EIO;
3220
3221         p++;
3222
3223         if (sscanf(p, " "
3224                    "%*c "  /* state */
3225                    "%*d "  /* ppid */
3226                    "%*d "  /* pgrp */
3227                    "%*d "  /* session */
3228                    "%lu ", /* ttynr */
3229                    &ttynr) != 1)
3230                 return -EIO;
3231
3232         *d = (dev_t) ttynr;
3233         return 0;
3234 }
3235
3236 int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
3237         int k;
3238         char fn[PATH_MAX], *s, *b, *p;
3239         dev_t devnr;
3240
3241         assert(r);
3242
3243         k = get_ctty_devnr(pid, &devnr);
3244         if (k < 0)
3245                 return k;
3246
3247         snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr));
3248         char_array_0(fn);
3249
3250         if ((k = readlink_malloc(fn, &s)) < 0) {
3251
3252                 if (k != -ENOENT)
3253                         return k;
3254
3255                 /* This is an ugly hack */
3256                 if (major(devnr) == 136) {
3257                         if (asprintf(&b, "pts/%lu", (unsigned long) minor(devnr)) < 0)
3258                                 return -ENOMEM;
3259
3260                         *r = b;
3261                         if (_devnr)
3262                                 *_devnr = devnr;
3263
3264                         return 0;
3265                 }
3266
3267                 /* Probably something like the ptys which have no
3268                  * symlink in /dev/char. Let's return something
3269                  * vaguely useful. */
3270
3271                 if (!(b = strdup(fn + 5)))
3272                         return -ENOMEM;
3273
3274                 *r = b;
3275                 if (_devnr)
3276                         *_devnr = devnr;
3277
3278                 return 0;
3279         }
3280
3281         if (startswith(s, "/dev/"))
3282                 p = s + 5;
3283         else if (startswith(s, "../"))
3284                 p = s + 3;
3285         else
3286                 p = s;
3287
3288         b = strdup(p);
3289         free(s);
3290
3291         if (!b)
3292                 return -ENOMEM;
3293
3294         *r = b;
3295         if (_devnr)
3296                 *_devnr = devnr;
3297
3298         return 0;
3299 }
3300
3301 int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
3302         DIR *d;
3303         int ret = 0;
3304
3305         assert(fd >= 0);
3306
3307         /* This returns the first error we run into, but nevertheless
3308          * tries to go on. This closes the passed fd. */
3309
3310         d = fdopendir(fd);
3311         if (!d) {
3312                 close_nointr_nofail(fd);
3313
3314                 return errno == ENOENT ? 0 : -errno;
3315         }
3316
3317         for (;;) {
3318                 struct dirent *de;
3319                 union dirent_storage buf;
3320                 bool is_dir, keep_around;
3321                 struct stat st;
3322                 int r;
3323
3324                 r = readdir_r(d, &buf.de, &de);
3325                 if (r != 0 && ret == 0) {
3326                         ret = -r;
3327                         break;
3328                 }
3329
3330                 if (!de)
3331                         break;
3332
3333                 if (streq(de->d_name, ".") || streq(de->d_name, ".."))
3334                         continue;
3335
3336                 if (de->d_type == DT_UNKNOWN ||
3337                     honour_sticky ||
3338                     (de->d_type == DT_DIR && root_dev)) {
3339                         if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
3340                                 if (ret == 0 && errno != ENOENT)
3341                                         ret = -errno;
3342                                 continue;
3343                         }
3344
3345                         is_dir = S_ISDIR(st.st_mode);
3346                         keep_around =
3347                                 honour_sticky &&
3348                                 (st.st_uid == 0 || st.st_uid == getuid()) &&
3349                                 (st.st_mode & S_ISVTX);
3350                 } else {
3351                         is_dir = de->d_type == DT_DIR;
3352                         keep_around = false;
3353                 }
3354
3355                 if (is_dir) {
3356                         int subdir_fd;
3357
3358                         /* if root_dev is set, remove subdirectories only, if device is same as dir */
3359                         if (root_dev && st.st_dev != root_dev->st_dev)
3360                                 continue;
3361
3362                         subdir_fd = openat(fd, de->d_name,
3363                                            O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
3364                         if (subdir_fd < 0) {
3365                                 if (ret == 0 && errno != ENOENT)
3366                                         ret = -errno;
3367                                 continue;
3368                         }
3369
3370                         r = rm_rf_children_dangerous(subdir_fd, only_dirs, honour_sticky, root_dev);
3371                         if (r < 0 && ret == 0)
3372                                 ret = r;
3373
3374                         if (!keep_around)
3375                                 if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
3376                                         if (ret == 0 && errno != ENOENT)
3377                                                 ret = -errno;
3378                                 }
3379
3380                 } else if (!only_dirs && !keep_around) {
3381
3382                         if (unlinkat(fd, de->d_name, 0) < 0) {
3383                                 if (ret == 0 && errno != ENOENT)
3384                                         ret = -errno;
3385                         }
3386                 }
3387         }
3388
3389         closedir(d);
3390
3391         return ret;
3392 }
3393
3394 int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
3395         struct statfs s;
3396
3397         assert(fd >= 0);
3398
3399         if (fstatfs(fd, &s) < 0) {
3400                 close_nointr_nofail(fd);
3401                 return -errno;
3402         }
3403
3404         /* We refuse to clean disk file systems with this call. This
3405          * is extra paranoia just to be sure we never ever remove
3406          * non-state data */
3407
3408         if (s.f_type != TMPFS_MAGIC &&
3409             s.f_type != RAMFS_MAGIC) {
3410                 log_error("Attempted to remove disk file system, and we can't allow that.");
3411                 close_nointr_nofail(fd);
3412                 return -EPERM;
3413         }
3414
3415         return rm_rf_children_dangerous(fd, only_dirs, honour_sticky, root_dev);
3416 }
3417
3418 static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) {
3419         int fd, r;
3420         struct statfs s;
3421
3422         assert(path);
3423
3424         /* We refuse to clean the root file system with this
3425          * call. This is extra paranoia to never cause a really
3426          * seriously broken system. */
3427         if (path_equal(path, "/")) {
3428                 log_error("Attempted to remove entire root file system, and we can't allow that.");
3429                 return -EPERM;
3430         }
3431
3432         fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
3433         if (fd < 0) {
3434
3435                 if (errno != ENOTDIR)
3436                         return -errno;
3437
3438                 if (!dangerous) {
3439                         if (statfs(path, &s) < 0)
3440                                 return -errno;
3441
3442                         if (s.f_type != TMPFS_MAGIC &&
3443                             s.f_type != RAMFS_MAGIC) {
3444                                 log_error("Attempted to remove disk file system, and we can't allow that.");
3445                                 return -EPERM;
3446                         }
3447                 }
3448
3449                 if (delete_root && !only_dirs)
3450                         if (unlink(path) < 0 && errno != ENOENT)
3451                                 return -errno;
3452
3453                 return 0;
3454         }
3455
3456         if (!dangerous) {
3457                 if (fstatfs(fd, &s) < 0) {
3458                         close_nointr_nofail(fd);
3459                         return -errno;
3460                 }
3461
3462                 if (s.f_type != TMPFS_MAGIC &&
3463                     s.f_type != RAMFS_MAGIC) {
3464                         log_error("Attempted to remove disk file system, and we can't allow that.");
3465                         close_nointr_nofail(fd);
3466                         return -EPERM;
3467                 }
3468         }
3469
3470         r = rm_rf_children_dangerous(fd, only_dirs, honour_sticky, NULL);
3471         if (delete_root) {
3472
3473                 if (honour_sticky && file_is_priv_sticky(path) > 0)
3474                         return r;
3475
3476                 if (rmdir(path) < 0 && errno != ENOENT) {
3477                         if (r == 0)
3478                                 r = -errno;
3479                 }
3480         }
3481
3482         return r;
3483 }
3484
3485 int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
3486         return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, false);
3487 }
3488
3489 int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
3490         return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, true);
3491 }
3492
3493 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
3494         assert(path);
3495
3496         /* Under the assumption that we are running privileged we
3497          * first change the access mode and only then hand out
3498          * ownership to avoid a window where access is too open. */
3499
3500         if (mode != (mode_t) -1)
3501                 if (chmod(path, mode) < 0)
3502                         return -errno;
3503
3504         if (uid != (uid_t) -1 || gid != (gid_t) -1)
3505                 if (chown(path, uid, gid) < 0)
3506                         return -errno;
3507
3508         return 0;
3509 }
3510
3511 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
3512         assert(fd >= 0);
3513
3514         /* Under the assumption that we are running privileged we
3515          * first change the access mode and only then hand out
3516          * ownership to avoid a window where access is too open. */
3517
3518         if (fchmod(fd, mode) < 0)
3519                 return -errno;
3520
3521         if (fchown(fd, uid, gid) < 0)
3522                 return -errno;
3523
3524         return 0;
3525 }
3526
3527 cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
3528         cpu_set_t *r;
3529         unsigned n = 1024;
3530
3531         /* Allocates the cpuset in the right size */
3532
3533         for (;;) {
3534                 if (!(r = CPU_ALLOC(n)))
3535                         return NULL;
3536
3537                 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
3538                         CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
3539
3540                         if (ncpus)
3541                                 *ncpus = n;
3542
3543                         return r;
3544                 }
3545
3546                 CPU_FREE(r);
3547
3548                 if (errno != EINVAL)
3549                         return NULL;
3550
3551                 n *= 2;
3552         }
3553 }
3554
3555 int status_vprintf(const char *status, bool ellipse, const char *format, va_list ap) {
3556         static const char status_indent[] = "         "; /* "[" STATUS "] " */
3557         _cleanup_free_ char *s = NULL;
3558         _cleanup_close_ int fd = -1;
3559         struct iovec iovec[5];
3560         int n = 0;
3561
3562         assert(format);
3563
3564         /* This is independent of logging, as status messages are
3565          * optional and go exclusively to the console. */
3566
3567         if (vasprintf(&s, format, ap) < 0)
3568                 return log_oom();
3569
3570         fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
3571         if (fd < 0)
3572                 return fd;
3573
3574         if (ellipse) {
3575                 char *e;
3576                 size_t emax, sl;
3577                 int c;
3578
3579                 c = fd_columns(fd);
3580                 if (c <= 0)
3581                         c = 80;
3582
3583                 sl = status ? sizeof(status_indent)-1 : 0;
3584
3585                 emax = c - sl - 1;
3586                 if (emax < 3)
3587                         emax = 3;
3588
3589                 e = ellipsize(s, emax, 75);
3590                 if (e) {
3591                         free(s);
3592                         s = e;
3593                 }
3594         }
3595
3596         zero(iovec);
3597
3598         if (status) {
3599                 if (!isempty(status)) {
3600                         IOVEC_SET_STRING(iovec[n++], "[");
3601                         IOVEC_SET_STRING(iovec[n++], status);
3602                         IOVEC_SET_STRING(iovec[n++], "] ");
3603                 } else
3604                         IOVEC_SET_STRING(iovec[n++], status_indent);
3605         }
3606
3607         IOVEC_SET_STRING(iovec[n++], s);
3608         IOVEC_SET_STRING(iovec[n++], "\n");
3609
3610         if (writev(fd, iovec, n) < 0)
3611                 return -errno;
3612
3613         return 0;
3614 }
3615
3616 int status_printf(const char *status, bool ellipse, const char *format, ...) {
3617         va_list ap;
3618         int r;
3619
3620         assert(format);
3621
3622         va_start(ap, format);
3623         r = status_vprintf(status, ellipse, format, ap);
3624         va_end(ap);
3625
3626         return r;
3627 }
3628
3629 int status_welcome(void) {
3630         int r;
3631         _cleanup_free_ char *pretty_name = NULL, *ansi_color = NULL;
3632
3633         r = parse_env_file("/etc/os-release", NEWLINE,
3634                            "PRETTY_NAME", &pretty_name,
3635                            "ANSI_COLOR", &ansi_color,
3636                            NULL);
3637         if (r < 0 && r != -ENOENT)
3638                 log_warning("Failed to read /etc/os-release: %s", strerror(-r));
3639
3640         return status_printf(NULL, false,
3641                              "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
3642                              isempty(ansi_color) ? "1" : ansi_color,
3643                              isempty(pretty_name) ? "Linux" : pretty_name);
3644 }
3645
3646 char *replace_env(const char *format, char **env) {
3647         enum {
3648                 WORD,
3649                 CURLY,
3650                 VARIABLE
3651         } state = WORD;
3652
3653         const char *e, *word = format;
3654         char *r = NULL, *k;
3655
3656         assert(format);
3657
3658         for (e = format; *e; e ++) {
3659
3660                 switch (state) {
3661
3662                 case WORD:
3663                         if (*e == '$')
3664                                 state = CURLY;
3665                         break;
3666
3667                 case CURLY:
3668                         if (*e == '{') {
3669                                 if (!(k = strnappend(r, word, e-word-1)))
3670                                         goto fail;
3671
3672                                 free(r);
3673                                 r = k;
3674
3675                                 word = e-1;
3676                                 state = VARIABLE;
3677
3678                         } else if (*e == '$') {
3679                                 if (!(k = strnappend(r, word, e-word)))
3680                                         goto fail;
3681
3682                                 free(r);
3683                                 r = k;
3684
3685                                 word = e+1;
3686                                 state = WORD;
3687                         } else
3688                                 state = WORD;
3689                         break;
3690
3691                 case VARIABLE:
3692                         if (*e == '}') {
3693                                 const char *t;
3694
3695                                 if (!(t = strv_env_get_with_length(env, word+2, e-word-2)))
3696                                         t = "";
3697
3698                                 if (!(k = strappend(r, t)))
3699                                         goto fail;
3700
3701                                 free(r);
3702                                 r = k;
3703
3704                                 word = e+1;
3705                                 state = WORD;
3706                         }
3707                         break;
3708                 }
3709         }
3710
3711         if (!(k = strnappend(r, word, e-word)))
3712                 goto fail;
3713
3714         free(r);
3715         return k;
3716
3717 fail:
3718         free(r);
3719         return NULL;
3720 }
3721
3722 char **replace_env_argv(char **argv, char **env) {
3723         char **r, **i;
3724         unsigned k = 0, l = 0;
3725
3726         l = strv_length(argv);
3727
3728         if (!(r = new(char*, l+1)))
3729                 return NULL;
3730
3731         STRV_FOREACH(i, argv) {
3732
3733                 /* If $FOO appears as single word, replace it by the split up variable */
3734                 if ((*i)[0] == '$' && (*i)[1] != '{') {
3735                         char *e;
3736                         char **w, **m;
3737                         unsigned q;
3738
3739                         if ((e = strv_env_get(env, *i+1))) {
3740
3741                                 if (!(m = strv_split_quoted(e))) {
3742                                         r[k] = NULL;
3743                                         strv_free(r);
3744                                         return NULL;
3745                                 }
3746                         } else
3747                                 m = NULL;
3748
3749                         q = strv_length(m);
3750                         l = l + q - 1;
3751
3752                         if (!(w = realloc(r, sizeof(char*) * (l+1)))) {
3753                                 r[k] = NULL;
3754                                 strv_free(r);
3755                                 strv_free(m);
3756                                 return NULL;
3757                         }
3758
3759                         r = w;
3760                         if (m) {
3761                                 memcpy(r + k, m, q * sizeof(char*));
3762                                 free(m);
3763                         }
3764
3765                         k += q;
3766                         continue;
3767                 }
3768
3769                 /* If ${FOO} appears as part of a word, replace it by the variable as-is */
3770                 if (!(r[k++] = replace_env(*i, env))) {
3771                         strv_free(r);
3772                         return NULL;
3773                 }
3774         }
3775
3776         r[k] = NULL;
3777         return r;
3778 }
3779
3780 int fd_columns(int fd) {
3781         struct winsize ws;
3782         zero(ws);
3783
3784         if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3785                 return -errno;
3786
3787         if (ws.ws_col <= 0)
3788                 return -EIO;
3789
3790         return ws.ws_col;
3791 }
3792
3793 unsigned columns(void) {
3794         const char *e;
3795         unsigned c;
3796
3797         if (_likely_(cached_columns > 0))
3798                 return cached_columns;
3799
3800         c = 0;
3801         e = getenv("COLUMNS");
3802         if (e)
3803                 safe_atou(e, &c);
3804
3805         if (c <= 0)
3806                 c = fd_columns(STDOUT_FILENO);
3807
3808         if (c <= 0)
3809                 c = 80;
3810
3811         cached_columns = c;
3812         return c;
3813 }
3814
3815 /* intended to be used as a SIGWINCH sighandler */
3816 void columns_cache_reset(int signum) {
3817         cached_columns = 0;
3818 }
3819
3820 bool on_tty(void) {
3821         static int cached_on_tty = -1;
3822
3823         if (_unlikely_(cached_on_tty < 0))
3824                 cached_on_tty = isatty(STDOUT_FILENO) > 0;
3825
3826         return cached_on_tty;
3827 }
3828
3829 int fd_lines(int fd) {
3830         struct winsize ws;
3831         zero(ws);
3832
3833         if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3834                 return -errno;
3835
3836         if (ws.ws_row <= 0)
3837                 return -EIO;
3838
3839         return ws.ws_row;
3840 }
3841
3842 unsigned lines(void) {
3843         static __thread int parsed_lines = 0;
3844         const char *e;
3845
3846         if (_likely_(parsed_lines > 0))
3847                 return parsed_lines;
3848
3849         e = getenv("LINES");
3850         if (e)
3851                 parsed_lines = atoi(e);
3852
3853         if (parsed_lines <= 0)
3854                 parsed_lines = fd_lines(STDOUT_FILENO);
3855
3856         if (parsed_lines <= 0)
3857                 parsed_lines = 25;
3858
3859         return parsed_lines;
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 bool is_valid_documentation_url(const char *url) {
5695         assert(url);
5696
5697         if (startswith(url, "http://") && url[7])
5698                 return true;
5699
5700         if (startswith(url, "https://") && url[8])
5701                 return true;
5702
5703         if (startswith(url, "file:") && url[5])
5704                 return true;
5705
5706         if (startswith(url, "info:") && url[5])
5707                 return true;
5708
5709         if (startswith(url, "man:") && url[4])
5710                 return true;
5711
5712         return false;
5713 }
5714
5715 bool in_initrd(void) {
5716         static __thread int saved = -1;
5717         struct statfs s;
5718
5719         if (saved >= 0)
5720                 return saved;
5721
5722         /* We make two checks here:
5723          *
5724          * 1. the flag file /etc/initrd-release must exist
5725          * 2. the root file system must be a memory file system
5726          *
5727          * The second check is extra paranoia, since misdetecting an
5728          * initrd can have bad bad consequences due the initrd
5729          * emptying when transititioning to the main systemd.
5730          */
5731
5732         saved = access("/etc/initrd-release", F_OK) >= 0 &&
5733                 statfs("/", &s) >= 0 &&
5734                 (s.f_type == TMPFS_MAGIC || s.f_type == RAMFS_MAGIC);
5735
5736         return saved;
5737 }
5738
5739 void warn_melody(void) {
5740         _cleanup_close_ int fd = -1;
5741
5742         fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY);
5743         if (fd < 0)
5744                 return;
5745
5746         /* Yeah, this is synchronous. Kinda sucks. But well... */
5747
5748         ioctl(fd, KIOCSOUND, (int)(1193180/440));
5749         usleep(125*USEC_PER_MSEC);
5750
5751         ioctl(fd, KIOCSOUND, (int)(1193180/220));
5752         usleep(125*USEC_PER_MSEC);
5753
5754         ioctl(fd, KIOCSOUND, (int)(1193180/220));
5755         usleep(125*USEC_PER_MSEC);
5756
5757         ioctl(fd, KIOCSOUND, 0);
5758 }
5759
5760 int make_console_stdio(void) {
5761         int fd, r;
5762
5763         /* Make /dev/console the controlling terminal and stdin/stdout/stderr */
5764
5765         fd = acquire_terminal("/dev/console", false, true, true, (usec_t) -1);
5766         if (fd < 0) {
5767                 log_error("Failed to acquire terminal: %s", strerror(-fd));
5768                 return fd;
5769         }
5770
5771         r = make_stdio(fd);
5772         if (r < 0) {
5773                 log_error("Failed to duplicate terminal fd: %s", strerror(-r));
5774                 return r;
5775         }
5776
5777         return 0;
5778 }
5779
5780 int get_home_dir(char **_h) {
5781         char *h;
5782         const char *e;
5783         uid_t u;
5784         struct passwd *p;
5785
5786         assert(_h);
5787
5788         /* Take the user specified one */
5789         e = getenv("HOME");
5790         if (e) {
5791                 h = strdup(e);
5792                 if (!h)
5793                         return -ENOMEM;
5794
5795                 *_h = h;
5796                 return 0;
5797         }
5798
5799         /* Hardcode home directory for root to avoid NSS */
5800         u = getuid();
5801         if (u == 0) {
5802                 h = strdup("/root");
5803                 if (!h)
5804                         return -ENOMEM;
5805
5806                 *_h = h;
5807                 return 0;
5808         }
5809
5810         /* Check the database... */
5811         errno = 0;
5812         p = getpwuid(u);
5813         if (!p)
5814                 return errno ? -errno : -ESRCH;
5815
5816         if (!path_is_absolute(p->pw_dir))
5817                 return -EINVAL;
5818
5819         h = strdup(p->pw_dir);
5820         if (!h)
5821                 return -ENOMEM;
5822
5823         *_h = h;
5824         return 0;
5825 }
5826
5827 int get_shell(char **_sh) {
5828         char *sh;
5829         const char *e;
5830         uid_t u;
5831         struct passwd *p;
5832
5833         assert(_sh);
5834
5835         /* Take the user specified one */
5836         e = getenv("SHELL");
5837         if (e) {
5838                 sh = strdup(e);
5839                 if (!sh)
5840                         return -ENOMEM;
5841
5842                 *_sh = sh;
5843                 return 0;
5844         }
5845
5846         /* Hardcode home directory for root to avoid NSS */
5847         u = getuid();
5848         if (u == 0) {
5849                 sh = strdup("/bin/sh");
5850                 if (!sh)
5851                         return -ENOMEM;
5852
5853                 *_sh = sh;
5854                 return 0;
5855         }
5856
5857         /* Check the database... */
5858         errno = 0;
5859         p = getpwuid(u);
5860         if (!p)
5861                 return errno ? -errno : -ESRCH;
5862
5863         if (!path_is_absolute(p->pw_shell))
5864                 return -EINVAL;
5865
5866         sh = strdup(p->pw_shell);
5867         if (!sh)
5868                 return -ENOMEM;
5869
5870         *_sh = sh;
5871         return 0;
5872 }
5873
5874 void freep(void *p) {
5875         free(*(void**) p);
5876 }
5877
5878 void fclosep(FILE **f) {
5879         if (*f)
5880                 fclose(*f);
5881 }
5882
5883 void closep(int *fd) {
5884         if (*fd >= 0)
5885                 close_nointr_nofail(*fd);
5886 }
5887
5888 void closedirp(DIR **d) {
5889         if (*d)
5890                 closedir(*d);
5891 }
5892
5893 void umaskp(mode_t *u) {
5894         umask(*u);
5895 }
5896
5897 bool filename_is_safe(const char *p) {
5898
5899         if (isempty(p))
5900                 return false;
5901
5902         if (strchr(p, '/'))
5903                 return false;
5904
5905         if (streq(p, "."))
5906                 return false;
5907
5908         if (streq(p, ".."))
5909                 return false;
5910
5911         if (strlen(p) > FILENAME_MAX)
5912                 return false;
5913
5914         return true;
5915 }
5916
5917 bool string_is_safe(const char *p) {
5918         const char *t;
5919
5920         assert(p);
5921
5922         for (t = p; *t; t++) {
5923                 if (*t > 0 && *t < ' ')
5924                         return false;
5925
5926                 if (strchr("\\\"\'", *t))
5927                         return false;
5928         }
5929
5930         return true;
5931 }
5932
5933 int parse_timestamp(const char *t, usec_t *usec) {
5934         const char *k;
5935         struct tm tm, copy;
5936         time_t x;
5937         usec_t plus = 0, minus = 0, ret;
5938         int r;
5939
5940         /*
5941          * Allowed syntaxes:
5942          *
5943          *   2012-09-22 16:34:22
5944          *   2012-09-22 16:34     (seconds will be set to 0)
5945          *   2012-09-22           (time will be set to 00:00:00)
5946          *   16:34:22             (date will be set to today)
5947          *   16:34                (date will be set to today, seconds to 0)
5948          *   now
5949          *   yesterday            (time is set to 00:00:00)
5950          *   today                (time is set to 00:00:00)
5951          *   tomorrow             (time is set to 00:00:00)
5952          *   +5min
5953          *   -5days
5954          *
5955          */
5956
5957         assert(t);
5958         assert(usec);
5959
5960         x = time(NULL);
5961         assert_se(localtime_r(&x, &tm));
5962
5963         if (streq(t, "now"))
5964                 goto finish;
5965
5966         else if (streq(t, "today")) {
5967                 tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
5968                 goto finish;
5969
5970         } else if (streq(t, "yesterday")) {
5971                 tm.tm_mday --;
5972                 tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
5973                 goto finish;
5974
5975         } else if (streq(t, "tomorrow")) {
5976                 tm.tm_mday ++;
5977                 tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
5978                 goto finish;
5979
5980         } else if (t[0] == '+') {
5981
5982                 r = parse_usec(t+1, &plus);
5983                 if (r < 0)
5984                         return r;
5985
5986                 goto finish;
5987         } else if (t[0] == '-') {
5988
5989                 r = parse_usec(t+1, &minus);
5990                 if (r < 0)
5991                         return r;
5992
5993                 goto finish;
5994         }
5995
5996         copy = tm;
5997         k = strptime(t, "%y-%m-%d %H:%M:%S", &tm);
5998         if (k && *k == 0)
5999                 goto finish;
6000
6001         tm = copy;
6002         k = strptime(t, "%Y-%m-%d %H:%M:%S", &tm);
6003         if (k && *k == 0)
6004                 goto finish;
6005
6006         tm = copy;
6007         k = strptime(t, "%y-%m-%d %H:%M", &tm);
6008         if (k && *k == 0) {
6009                 tm.tm_sec = 0;
6010                 goto finish;
6011         }
6012
6013         tm = copy;
6014         k = strptime(t, "%Y-%m-%d %H:%M", &tm);
6015         if (k && *k == 0) {
6016                 tm.tm_sec = 0;
6017                 goto finish;
6018         }
6019
6020         tm = copy;
6021         k = strptime(t, "%y-%m-%d", &tm);
6022         if (k && *k == 0) {
6023                 tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
6024                 goto finish;
6025         }
6026
6027         tm = copy;
6028         k = strptime(t, "%Y-%m-%d", &tm);
6029         if (k && *k == 0) {
6030                 tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
6031                 goto finish;
6032         }
6033
6034         tm = copy;
6035         k = strptime(t, "%H:%M:%S", &tm);
6036         if (k && *k == 0)
6037                 goto finish;
6038
6039         tm = copy;
6040         k = strptime(t, "%H:%M", &tm);
6041         if (k && *k == 0) {
6042                 tm.tm_sec = 0;
6043                 goto finish;
6044         }
6045
6046         return -EINVAL;
6047
6048 finish:
6049         x = mktime(&tm);
6050         if (x == (time_t) -1)
6051                 return -EINVAL;
6052
6053         ret = (usec_t) x * USEC_PER_SEC;
6054
6055         ret += plus;
6056         if (ret > minus)
6057                 ret -= minus;
6058         else
6059                 ret = 0;
6060
6061         *usec = ret;
6062
6063         return 0;
6064 }