chiark / gitweb /
1e1eb2af5f1bdfc6093b6490c9fa662b91cf1210
[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 int parsed_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, %d %b %Y %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         bool on_tty;
2179
2180         assert(ret);
2181         assert(replies);
2182         assert(text);
2183
2184         on_tty = isatty(STDOUT_FILENO);
2185
2186         for (;;) {
2187                 va_list ap;
2188                 char c;
2189                 int r;
2190                 bool need_nl = true;
2191
2192                 if (on_tty)
2193                         fputs(ANSI_HIGHLIGHT_ON, stdout);
2194
2195                 va_start(ap, text);
2196                 vprintf(text, ap);
2197                 va_end(ap);
2198
2199                 if (on_tty)
2200                         fputs(ANSI_HIGHLIGHT_OFF, stdout);
2201
2202                 fflush(stdout);
2203
2204                 r = read_one_char(stdin, &c, (usec_t) -1, &need_nl);
2205                 if (r < 0) {
2206
2207                         if (r == -EBADMSG) {
2208                                 puts("Bad input, please try again.");
2209                                 continue;
2210                         }
2211
2212                         putchar('\n');
2213                         return r;
2214                 }
2215
2216                 if (need_nl)
2217                         putchar('\n');
2218
2219                 if (strchr(replies, c)) {
2220                         *ret = c;
2221                         return 0;
2222                 }
2223
2224                 puts("Read unexpected character, please try again.");
2225         }
2226 }
2227
2228 int reset_terminal_fd(int fd, bool switch_to_text) {
2229         struct termios termios;
2230         int r = 0;
2231
2232         /* Set terminal to some sane defaults */
2233
2234         assert(fd >= 0);
2235
2236         /* We leave locked terminal attributes untouched, so that
2237          * Plymouth may set whatever it wants to set, and we don't
2238          * interfere with that. */
2239
2240         /* Disable exclusive mode, just in case */
2241         ioctl(fd, TIOCNXCL);
2242
2243         /* Switch to text mode */
2244         if (switch_to_text)
2245                 ioctl(fd, KDSETMODE, KD_TEXT);
2246
2247         /* Enable console unicode mode */
2248         ioctl(fd, KDSKBMODE, K_UNICODE);
2249
2250         if (tcgetattr(fd, &termios) < 0) {
2251                 r = -errno;
2252                 goto finish;
2253         }
2254
2255         /* We only reset the stuff that matters to the software. How
2256          * hardware is set up we don't touch assuming that somebody
2257          * else will do that for us */
2258
2259         termios.c_iflag &= ~(IGNBRK | BRKINT | ISTRIP | INLCR | IGNCR | IUCLC);
2260         termios.c_iflag |= ICRNL | IMAXBEL | IUTF8;
2261         termios.c_oflag |= ONLCR;
2262         termios.c_cflag |= CREAD;
2263         termios.c_lflag = ISIG | ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOPRT | ECHOKE;
2264
2265         termios.c_cc[VINTR]    =   03;  /* ^C */
2266         termios.c_cc[VQUIT]    =  034;  /* ^\ */
2267         termios.c_cc[VERASE]   = 0177;
2268         termios.c_cc[VKILL]    =  025;  /* ^X */
2269         termios.c_cc[VEOF]     =   04;  /* ^D */
2270         termios.c_cc[VSTART]   =  021;  /* ^Q */
2271         termios.c_cc[VSTOP]    =  023;  /* ^S */
2272         termios.c_cc[VSUSP]    =  032;  /* ^Z */
2273         termios.c_cc[VLNEXT]   =  026;  /* ^V */
2274         termios.c_cc[VWERASE]  =  027;  /* ^W */
2275         termios.c_cc[VREPRINT] =  022;  /* ^R */
2276         termios.c_cc[VEOL]     =    0;
2277         termios.c_cc[VEOL2]    =    0;
2278
2279         termios.c_cc[VTIME]  = 0;
2280         termios.c_cc[VMIN]   = 1;
2281
2282         if (tcsetattr(fd, TCSANOW, &termios) < 0)
2283                 r = -errno;
2284
2285 finish:
2286         /* Just in case, flush all crap out */
2287         tcflush(fd, TCIOFLUSH);
2288
2289         return r;
2290 }
2291
2292 int reset_terminal(const char *name) {
2293         int fd, r;
2294
2295         fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
2296         if (fd < 0)
2297                 return fd;
2298
2299         r = reset_terminal_fd(fd, true);
2300         close_nointr_nofail(fd);
2301
2302         return r;
2303 }
2304
2305 int open_terminal(const char *name, int mode) {
2306         int fd, r;
2307         unsigned c = 0;
2308
2309         /*
2310          * If a TTY is in the process of being closed opening it might
2311          * cause EIO. This is horribly awful, but unlikely to be
2312          * changed in the kernel. Hence we work around this problem by
2313          * retrying a couple of times.
2314          *
2315          * https://bugs.launchpad.net/ubuntu/+source/linux/+bug/554172/comments/245
2316          */
2317
2318         for (;;) {
2319                 fd = open(name, mode);
2320                 if (fd >= 0)
2321                         break;
2322
2323                 if (errno != EIO)
2324                         return -errno;
2325
2326                 /* Max 1s in total */
2327                 if (c >= 20)
2328                         return -errno;
2329
2330                 usleep(50 * USEC_PER_MSEC);
2331                 c++;
2332         }
2333
2334         if (fd < 0)
2335                 return -errno;
2336
2337         r = isatty(fd);
2338         if (r < 0) {
2339                 close_nointr_nofail(fd);
2340                 return -errno;
2341         }
2342
2343         if (!r) {
2344                 close_nointr_nofail(fd);
2345                 return -ENOTTY;
2346         }
2347
2348         return fd;
2349 }
2350
2351 int flush_fd(int fd) {
2352         struct pollfd pollfd;
2353
2354         zero(pollfd);
2355         pollfd.fd = fd;
2356         pollfd.events = POLLIN;
2357
2358         for (;;) {
2359                 char buf[LINE_MAX];
2360                 ssize_t l;
2361                 int r;
2362
2363                 if ((r = poll(&pollfd, 1, 0)) < 0) {
2364
2365                         if (errno == EINTR)
2366                                 continue;
2367
2368                         return -errno;
2369                 }
2370
2371                 if (r == 0)
2372                         return 0;
2373
2374                 if ((l = read(fd, buf, sizeof(buf))) < 0) {
2375
2376                         if (errno == EINTR)
2377                                 continue;
2378
2379                         if (errno == EAGAIN)
2380                                 return 0;
2381
2382                         return -errno;
2383                 }
2384
2385                 if (l <= 0)
2386                         return 0;
2387         }
2388 }
2389
2390 int acquire_terminal(
2391                 const char *name,
2392                 bool fail,
2393                 bool force,
2394                 bool ignore_tiocstty_eperm,
2395                 usec_t timeout) {
2396
2397         int fd = -1, notify = -1, r = 0, wd = -1;
2398         usec_t ts = 0;
2399         struct sigaction sa_old, sa_new;
2400
2401         assert(name);
2402
2403         /* We use inotify to be notified when the tty is closed. We
2404          * create the watch before checking if we can actually acquire
2405          * it, so that we don't lose any event.
2406          *
2407          * Note: strictly speaking this actually watches for the
2408          * device being closed, it does *not* really watch whether a
2409          * tty loses its controlling process. However, unless some
2410          * rogue process uses TIOCNOTTY on /dev/tty *after* closing
2411          * its tty otherwise this will not become a problem. As long
2412          * as the administrator makes sure not configure any service
2413          * on the same tty as an untrusted user this should not be a
2414          * problem. (Which he probably should not do anyway.) */
2415
2416         if (timeout != (usec_t) -1)
2417                 ts = now(CLOCK_MONOTONIC);
2418
2419         if (!fail && !force) {
2420                 notify = inotify_init1(IN_CLOEXEC | (timeout != (usec_t) -1 ? IN_NONBLOCK : 0));
2421                 if (notify < 0) {
2422                         r = -errno;
2423                         goto fail;
2424                 }
2425
2426                 wd = inotify_add_watch(notify, name, IN_CLOSE);
2427                 if (wd < 0) {
2428                         r = -errno;
2429                         goto fail;
2430                 }
2431         }
2432
2433         for (;;) {
2434                 if (notify >= 0) {
2435                         r = flush_fd(notify);
2436                         if (r < 0)
2437                                 goto fail;
2438                 }
2439
2440                 /* We pass here O_NOCTTY only so that we can check the return
2441                  * value TIOCSCTTY and have a reliable way to figure out if we
2442                  * successfully became the controlling process of the tty */
2443                 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
2444                 if (fd < 0)
2445                         return fd;
2446
2447                 /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
2448                  * if we already own the tty. */
2449                 zero(sa_new);
2450                 sa_new.sa_handler = SIG_IGN;
2451                 sa_new.sa_flags = SA_RESTART;
2452                 assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
2453
2454                 /* First, try to get the tty */
2455                 if (ioctl(fd, TIOCSCTTY, force) < 0)
2456                         r = -errno;
2457
2458                 assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
2459
2460                 /* Sometimes it makes sense to ignore TIOCSCTTY
2461                  * returning EPERM, i.e. when very likely we already
2462                  * are have this controlling terminal. */
2463                 if (r < 0 && r == -EPERM && ignore_tiocstty_eperm)
2464                         r = 0;
2465
2466                 if (r < 0 && (force || fail || r != -EPERM)) {
2467                         goto fail;
2468                 }
2469
2470                 if (r >= 0)
2471                         break;
2472
2473                 assert(!fail);
2474                 assert(!force);
2475                 assert(notify >= 0);
2476
2477                 for (;;) {
2478                         uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
2479                         ssize_t l;
2480                         struct inotify_event *e;
2481
2482                         if (timeout != (usec_t) -1) {
2483                                 usec_t n;
2484
2485                                 n = now(CLOCK_MONOTONIC);
2486                                 if (ts + timeout < n) {
2487                                         r = -ETIMEDOUT;
2488                                         goto fail;
2489                                 }
2490
2491                                 r = fd_wait_for_event(fd, POLLIN, ts + timeout - n);
2492                                 if (r < 0)
2493                                         goto fail;
2494
2495                                 if (r == 0) {
2496                                         r = -ETIMEDOUT;
2497                                         goto fail;
2498                                 }
2499                         }
2500
2501                         l = read(notify, inotify_buffer, sizeof(inotify_buffer));
2502                         if (l < 0) {
2503
2504                                 if (errno == EINTR || errno == EAGAIN)
2505                                         continue;
2506
2507                                 r = -errno;
2508                                 goto fail;
2509                         }
2510
2511                         e = (struct inotify_event*) inotify_buffer;
2512
2513                         while (l > 0) {
2514                                 size_t step;
2515
2516                                 if (e->wd != wd || !(e->mask & IN_CLOSE)) {
2517                                         r = -EIO;
2518                                         goto fail;
2519                                 }
2520
2521                                 step = sizeof(struct inotify_event) + e->len;
2522                                 assert(step <= (size_t) l);
2523
2524                                 e = (struct inotify_event*) ((uint8_t*) e + step);
2525                                 l -= step;
2526                         }
2527
2528                         break;
2529                 }
2530
2531                 /* We close the tty fd here since if the old session
2532                  * ended our handle will be dead. It's important that
2533                  * we do this after sleeping, so that we don't enter
2534                  * an endless loop. */
2535                 close_nointr_nofail(fd);
2536         }
2537
2538         if (notify >= 0)
2539                 close_nointr_nofail(notify);
2540
2541         r = reset_terminal_fd(fd, true);
2542         if (r < 0)
2543                 log_warning("Failed to reset terminal: %s", strerror(-r));
2544
2545         return fd;
2546
2547 fail:
2548         if (fd >= 0)
2549                 close_nointr_nofail(fd);
2550
2551         if (notify >= 0)
2552                 close_nointr_nofail(notify);
2553
2554         return r;
2555 }
2556
2557 int release_terminal(void) {
2558         int r = 0, fd;
2559         struct sigaction sa_old, sa_new;
2560
2561         if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_NDELAY|O_CLOEXEC)) < 0)
2562                 return -errno;
2563
2564         /* Temporarily ignore SIGHUP, so that we don't get SIGHUP'ed
2565          * by our own TIOCNOTTY */
2566
2567         zero(sa_new);
2568         sa_new.sa_handler = SIG_IGN;
2569         sa_new.sa_flags = SA_RESTART;
2570         assert_se(sigaction(SIGHUP, &sa_new, &sa_old) == 0);
2571
2572         if (ioctl(fd, TIOCNOTTY) < 0)
2573                 r = -errno;
2574
2575         assert_se(sigaction(SIGHUP, &sa_old, NULL) == 0);
2576
2577         close_nointr_nofail(fd);
2578         return r;
2579 }
2580
2581 int sigaction_many(const struct sigaction *sa, ...) {
2582         va_list ap;
2583         int r = 0, sig;
2584
2585         va_start(ap, sa);
2586         while ((sig = va_arg(ap, int)) > 0)
2587                 if (sigaction(sig, sa, NULL) < 0)
2588                         r = -errno;
2589         va_end(ap);
2590
2591         return r;
2592 }
2593
2594 int ignore_signals(int sig, ...) {
2595         struct sigaction sa;
2596         va_list ap;
2597         int r = 0;
2598
2599         zero(sa);
2600         sa.sa_handler = SIG_IGN;
2601         sa.sa_flags = SA_RESTART;
2602
2603         if (sigaction(sig, &sa, NULL) < 0)
2604                 r = -errno;
2605
2606         va_start(ap, sig);
2607         while ((sig = va_arg(ap, int)) > 0)
2608                 if (sigaction(sig, &sa, NULL) < 0)
2609                         r = -errno;
2610         va_end(ap);
2611
2612         return r;
2613 }
2614
2615 int default_signals(int sig, ...) {
2616         struct sigaction sa;
2617         va_list ap;
2618         int r = 0;
2619
2620         zero(sa);
2621         sa.sa_handler = SIG_DFL;
2622         sa.sa_flags = SA_RESTART;
2623
2624         if (sigaction(sig, &sa, NULL) < 0)
2625                 r = -errno;
2626
2627         va_start(ap, sig);
2628         while ((sig = va_arg(ap, int)) > 0)
2629                 if (sigaction(sig, &sa, NULL) < 0)
2630                         r = -errno;
2631         va_end(ap);
2632
2633         return r;
2634 }
2635
2636 int close_pipe(int p[]) {
2637         int a = 0, b = 0;
2638
2639         assert(p);
2640
2641         if (p[0] >= 0) {
2642                 a = close_nointr(p[0]);
2643                 p[0] = -1;
2644         }
2645
2646         if (p[1] >= 0) {
2647                 b = close_nointr(p[1]);
2648                 p[1] = -1;
2649         }
2650
2651         return a < 0 ? a : b;
2652 }
2653
2654 ssize_t loop_read(int fd, void *buf, size_t nbytes, bool do_poll) {
2655         uint8_t *p;
2656         ssize_t n = 0;
2657
2658         assert(fd >= 0);
2659         assert(buf);
2660
2661         p = buf;
2662
2663         while (nbytes > 0) {
2664                 ssize_t k;
2665
2666                 if ((k = read(fd, p, nbytes)) <= 0) {
2667
2668                         if (k < 0 && errno == EINTR)
2669                                 continue;
2670
2671                         if (k < 0 && errno == EAGAIN && do_poll) {
2672                                 struct pollfd pollfd;
2673
2674                                 zero(pollfd);
2675                                 pollfd.fd = fd;
2676                                 pollfd.events = POLLIN;
2677
2678                                 if (poll(&pollfd, 1, -1) < 0) {
2679                                         if (errno == EINTR)
2680                                                 continue;
2681
2682                                         return n > 0 ? n : -errno;
2683                                 }
2684
2685                                 if (pollfd.revents != POLLIN)
2686                                         return n > 0 ? n : -EIO;
2687
2688                                 continue;
2689                         }
2690
2691                         return n > 0 ? n : (k < 0 ? -errno : 0);
2692                 }
2693
2694                 p += k;
2695                 nbytes -= k;
2696                 n += k;
2697         }
2698
2699         return n;
2700 }
2701
2702 ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
2703         const uint8_t *p;
2704         ssize_t n = 0;
2705
2706         assert(fd >= 0);
2707         assert(buf);
2708
2709         p = buf;
2710
2711         while (nbytes > 0) {
2712                 ssize_t k;
2713
2714                 k = write(fd, p, nbytes);
2715                 if (k <= 0) {
2716
2717                         if (k < 0 && errno == EINTR)
2718                                 continue;
2719
2720                         if (k < 0 && errno == EAGAIN && do_poll) {
2721                                 struct pollfd pollfd;
2722
2723                                 zero(pollfd);
2724                                 pollfd.fd = fd;
2725                                 pollfd.events = POLLOUT;
2726
2727                                 if (poll(&pollfd, 1, -1) < 0) {
2728                                         if (errno == EINTR)
2729                                                 continue;
2730
2731                                         return n > 0 ? n : -errno;
2732                                 }
2733
2734                                 if (pollfd.revents != POLLOUT)
2735                                         return n > 0 ? n : -EIO;
2736
2737                                 continue;
2738                         }
2739
2740                         return n > 0 ? n : (k < 0 ? -errno : 0);
2741                 }
2742
2743                 p += k;
2744                 nbytes -= k;
2745                 n += k;
2746         }
2747
2748         return n;
2749 }
2750
2751 int parse_usec(const char *t, usec_t *usec) {
2752         static const struct {
2753                 const char *suffix;
2754                 usec_t usec;
2755         } table[] = {
2756                 { "seconds", USEC_PER_SEC },
2757                 { "second", USEC_PER_SEC },
2758                 { "sec", USEC_PER_SEC },
2759                 { "s", USEC_PER_SEC },
2760                 { "minutes", USEC_PER_MINUTE },
2761                 { "minute", USEC_PER_MINUTE },
2762                 { "min", USEC_PER_MINUTE },
2763                 { "months", USEC_PER_MONTH },
2764                 { "month", USEC_PER_MONTH },
2765                 { "msec", USEC_PER_MSEC },
2766                 { "ms", USEC_PER_MSEC },
2767                 { "m", USEC_PER_MINUTE },
2768                 { "hours", USEC_PER_HOUR },
2769                 { "hour", USEC_PER_HOUR },
2770                 { "hr", USEC_PER_HOUR },
2771                 { "h", USEC_PER_HOUR },
2772                 { "days", USEC_PER_DAY },
2773                 { "day", USEC_PER_DAY },
2774                 { "d", USEC_PER_DAY },
2775                 { "weeks", USEC_PER_WEEK },
2776                 { "week", USEC_PER_WEEK },
2777                 { "w", USEC_PER_WEEK },
2778                 { "years", USEC_PER_YEAR },
2779                 { "year", USEC_PER_YEAR },
2780                 { "y", USEC_PER_YEAR },
2781                 { "usec", 1ULL },
2782                 { "us", 1ULL },
2783                 { "", USEC_PER_SEC }, /* default is sec */
2784         };
2785
2786         const char *p;
2787         usec_t r = 0;
2788
2789         assert(t);
2790         assert(usec);
2791
2792         p = t;
2793         do {
2794                 long long l;
2795                 char *e;
2796                 unsigned i;
2797
2798                 errno = 0;
2799                 l = strtoll(p, &e, 10);
2800
2801                 if (errno != 0)
2802                         return -errno;
2803
2804                 if (l < 0)
2805                         return -ERANGE;
2806
2807                 if (e == p)
2808                         return -EINVAL;
2809
2810                 e += strspn(e, WHITESPACE);
2811
2812                 for (i = 0; i < ELEMENTSOF(table); i++)
2813                         if (startswith(e, table[i].suffix)) {
2814                                 r += (usec_t) l * table[i].usec;
2815                                 p = e + strlen(table[i].suffix);
2816                                 break;
2817                         }
2818
2819                 if (i >= ELEMENTSOF(table))
2820                         return -EINVAL;
2821
2822         } while (*p != 0);
2823
2824         *usec = r;
2825
2826         return 0;
2827 }
2828
2829 int parse_nsec(const char *t, nsec_t *nsec) {
2830         static const struct {
2831                 const char *suffix;
2832                 nsec_t nsec;
2833         } table[] = {
2834                 { "seconds", NSEC_PER_SEC },
2835                 { "second", NSEC_PER_SEC },
2836                 { "sec", NSEC_PER_SEC },
2837                 { "s", NSEC_PER_SEC },
2838                 { "minutes", NSEC_PER_MINUTE },
2839                 { "minute", NSEC_PER_MINUTE },
2840                 { "min", NSEC_PER_MINUTE },
2841                 { "months", NSEC_PER_MONTH },
2842                 { "month", NSEC_PER_MONTH },
2843                 { "msec", NSEC_PER_MSEC },
2844                 { "ms", NSEC_PER_MSEC },
2845                 { "m", NSEC_PER_MINUTE },
2846                 { "hours", NSEC_PER_HOUR },
2847                 { "hour", NSEC_PER_HOUR },
2848                 { "hr", NSEC_PER_HOUR },
2849                 { "h", NSEC_PER_HOUR },
2850                 { "days", NSEC_PER_DAY },
2851                 { "day", NSEC_PER_DAY },
2852                 { "d", NSEC_PER_DAY },
2853                 { "weeks", NSEC_PER_WEEK },
2854                 { "week", NSEC_PER_WEEK },
2855                 { "w", NSEC_PER_WEEK },
2856                 { "years", NSEC_PER_YEAR },
2857                 { "year", NSEC_PER_YEAR },
2858                 { "y", NSEC_PER_YEAR },
2859                 { "usec", NSEC_PER_USEC },
2860                 { "us", NSEC_PER_USEC },
2861                 { "nsec", 1ULL },
2862                 { "ns", 1ULL },
2863                 { "", 1ULL }, /* default is nsec */
2864         };
2865
2866         const char *p;
2867         nsec_t r = 0;
2868
2869         assert(t);
2870         assert(nsec);
2871
2872         p = t;
2873         do {
2874                 long long l;
2875                 char *e;
2876                 unsigned i;
2877
2878                 errno = 0;
2879                 l = strtoll(p, &e, 10);
2880
2881                 if (errno != 0)
2882                         return -errno;
2883
2884                 if (l < 0)
2885                         return -ERANGE;
2886
2887                 if (e == p)
2888                         return -EINVAL;
2889
2890                 e += strspn(e, WHITESPACE);
2891
2892                 for (i = 0; i < ELEMENTSOF(table); i++)
2893                         if (startswith(e, table[i].suffix)) {
2894                                 r += (nsec_t) l * table[i].nsec;
2895                                 p = e + strlen(table[i].suffix);
2896                                 break;
2897                         }
2898
2899                 if (i >= ELEMENTSOF(table))
2900                         return -EINVAL;
2901
2902         } while (*p != 0);
2903
2904         *nsec = r;
2905
2906         return 0;
2907 }
2908
2909 int parse_bytes(const char *t, off_t *bytes) {
2910         static const struct {
2911                 const char *suffix;
2912                 off_t factor;
2913         } table[] = {
2914                 { "B", 1 },
2915                 { "K", 1024ULL },
2916                 { "M", 1024ULL*1024ULL },
2917                 { "G", 1024ULL*1024ULL*1024ULL },
2918                 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
2919                 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2920                 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
2921                 { "", 1 },
2922         };
2923
2924         const char *p;
2925         off_t r = 0;
2926
2927         assert(t);
2928         assert(bytes);
2929
2930         p = t;
2931         do {
2932                 long long l;
2933                 char *e;
2934                 unsigned i;
2935
2936                 errno = 0;
2937                 l = strtoll(p, &e, 10);
2938
2939                 if (errno != 0)
2940                         return -errno;
2941
2942                 if (l < 0)
2943                         return -ERANGE;
2944
2945                 if (e == p)
2946                         return -EINVAL;
2947
2948                 e += strspn(e, WHITESPACE);
2949
2950                 for (i = 0; i < ELEMENTSOF(table); i++)
2951                         if (startswith(e, table[i].suffix)) {
2952                                 r += (off_t) l * table[i].factor;
2953                                 p = e + strlen(table[i].suffix);
2954                                 break;
2955                         }
2956
2957                 if (i >= ELEMENTSOF(table))
2958                         return -EINVAL;
2959
2960         } while (*p != 0);
2961
2962         *bytes = r;
2963
2964         return 0;
2965 }
2966
2967 int make_stdio(int fd) {
2968         int r, s, t;
2969
2970         assert(fd >= 0);
2971
2972         r = dup3(fd, STDIN_FILENO, 0);
2973         s = dup3(fd, STDOUT_FILENO, 0);
2974         t = dup3(fd, STDERR_FILENO, 0);
2975
2976         if (fd >= 3)
2977                 close_nointr_nofail(fd);
2978
2979         if (r < 0 || s < 0 || t < 0)
2980                 return -errno;
2981
2982         /* We rely here that the new fd has O_CLOEXEC not set */
2983
2984         return 0;
2985 }
2986
2987 int make_null_stdio(void) {
2988         int null_fd;
2989
2990         null_fd = open("/dev/null", O_RDWR|O_NOCTTY);
2991         if (null_fd < 0)
2992                 return -errno;
2993
2994         return make_stdio(null_fd);
2995 }
2996
2997 bool is_device_path(const char *path) {
2998
2999         /* Returns true on paths that refer to a device, either in
3000          * sysfs or in /dev */
3001
3002         return
3003                 path_startswith(path, "/dev/") ||
3004                 path_startswith(path, "/sys/");
3005 }
3006
3007 int dir_is_empty(const char *path) {
3008         _cleanup_closedir_ DIR *d;
3009         int r;
3010
3011         d = opendir(path);
3012         if (!d)
3013                 return -errno;
3014
3015         for (;;) {
3016                 struct dirent *de;
3017                 union dirent_storage buf;
3018
3019                 r = readdir_r(d, &buf.de, &de);
3020                 if (r > 0)
3021                         return -r;
3022
3023                 if (!de)
3024                         return 1;
3025
3026                 if (!ignore_file(de->d_name))
3027                         return 0;
3028         }
3029 }
3030
3031 unsigned long long random_ull(void) {
3032         _cleanup_close_ int fd;
3033         uint64_t ull;
3034         ssize_t r;
3035
3036         fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
3037         if (fd < 0)
3038                 goto fallback;
3039
3040         r = loop_read(fd, &ull, sizeof(ull), true);
3041         if (r != sizeof(ull))
3042                 goto fallback;
3043
3044         return ull;
3045
3046 fallback:
3047         return random() * RAND_MAX + random();
3048 }
3049
3050 void rename_process(const char name[8]) {
3051         assert(name);
3052
3053         /* This is a like a poor man's setproctitle(). It changes the
3054          * comm field, argv[0], and also the glibc's internally used
3055          * name of the process. For the first one a limit of 16 chars
3056          * applies, to the second one usually one of 10 (i.e. length
3057          * of "/sbin/init"), to the third one one of 7 (i.e. length of
3058          * "systemd"). If you pass a longer string it will be
3059          * truncated */
3060
3061         prctl(PR_SET_NAME, name);
3062
3063         if (program_invocation_name)
3064                 strncpy(program_invocation_name, name, strlen(program_invocation_name));
3065
3066         if (saved_argc > 0) {
3067                 int i;
3068
3069                 if (saved_argv[0])
3070                         strncpy(saved_argv[0], name, strlen(saved_argv[0]));
3071
3072                 for (i = 1; i < saved_argc; i++) {
3073                         if (!saved_argv[i])
3074                                 break;
3075
3076                         memset(saved_argv[i], 0, strlen(saved_argv[i]));
3077                 }
3078         }
3079 }
3080
3081 void sigset_add_many(sigset_t *ss, ...) {
3082         va_list ap;
3083         int sig;
3084
3085         assert(ss);
3086
3087         va_start(ap, ss);
3088         while ((sig = va_arg(ap, int)) > 0)
3089                 assert_se(sigaddset(ss, sig) == 0);
3090         va_end(ap);
3091 }
3092
3093 char* gethostname_malloc(void) {
3094         struct utsname u;
3095
3096         assert_se(uname(&u) >= 0);
3097
3098         if (!isempty(u.nodename) && !streq(u.nodename, "(none)"))
3099                 return strdup(u.nodename);
3100
3101         return strdup(u.sysname);
3102 }
3103
3104 bool hostname_is_set(void) {
3105         struct utsname u;
3106
3107         assert_se(uname(&u) >= 0);
3108
3109         return !isempty(u.nodename) && !streq(u.nodename, "(none)");
3110 }
3111
3112 static char *lookup_uid(uid_t uid) {
3113         long bufsize;
3114         char *name;
3115         _cleanup_free_ char *buf = NULL;
3116         struct passwd pwbuf, *pw = NULL;
3117
3118         /* Shortcut things to avoid NSS lookups */
3119         if (uid == 0)
3120                 return strdup("root");
3121
3122         bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
3123         if (bufsize <= 0)
3124                 bufsize = 4096;
3125
3126         buf = malloc(bufsize);
3127         if (!buf)
3128                 return NULL;
3129
3130         if (getpwuid_r(uid, &pwbuf, buf, bufsize, &pw) == 0 && pw)
3131                 return strdup(pw->pw_name);
3132
3133         if (asprintf(&name, "%lu", (unsigned long) uid) < 0)
3134                 return NULL;
3135
3136         return name;
3137 }
3138
3139 char* getlogname_malloc(void) {
3140         uid_t uid;
3141         struct stat st;
3142
3143         if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
3144                 uid = st.st_uid;
3145         else
3146                 uid = getuid();
3147
3148         return lookup_uid(uid);
3149 }
3150
3151 char *getusername_malloc(void) {
3152         const char *e;
3153
3154         e = getenv("USER");
3155         if (e)
3156                 return strdup(e);
3157
3158         return lookup_uid(getuid());
3159 }
3160
3161 int getttyname_malloc(int fd, char **r) {
3162         char path[PATH_MAX], *c;
3163         int k;
3164
3165         assert(r);
3166
3167         k = ttyname_r(fd, path, sizeof(path));
3168         if (k != 0)
3169                 return -k;
3170
3171         char_array_0(path);
3172
3173         c = strdup(startswith(path, "/dev/") ? path + 5 : path);
3174         if (!c)
3175                 return -ENOMEM;
3176
3177         *r = c;
3178         return 0;
3179 }
3180
3181 int getttyname_harder(int fd, char **r) {
3182         int k;
3183         char *s;
3184
3185         k = getttyname_malloc(fd, &s);
3186         if (k < 0)
3187                 return k;
3188
3189         if (streq(s, "tty")) {
3190                 free(s);
3191                 return get_ctty(0, NULL, r);
3192         }
3193
3194         *r = s;
3195         return 0;
3196 }
3197
3198 int get_ctty_devnr(pid_t pid, dev_t *d) {
3199         int k;
3200         char line[LINE_MAX], *p, *fn;
3201         unsigned long ttynr;
3202         FILE *f;
3203
3204         if (asprintf(&fn, "/proc/%lu/stat", (unsigned long) (pid <= 0 ? getpid() : pid)) < 0)
3205                 return -ENOMEM;
3206
3207         f = fopen(fn, "re");
3208         free(fn);
3209         if (!f)
3210                 return -errno;
3211
3212         if (!fgets(line, sizeof(line), f)) {
3213                 k = feof(f) ? -EIO : -errno;
3214                 fclose(f);
3215                 return k;
3216         }
3217
3218         fclose(f);
3219
3220         p = strrchr(line, ')');
3221         if (!p)
3222                 return -EIO;
3223
3224         p++;
3225
3226         if (sscanf(p, " "
3227                    "%*c "  /* state */
3228                    "%*d "  /* ppid */
3229                    "%*d "  /* pgrp */
3230                    "%*d "  /* session */
3231                    "%lu ", /* ttynr */
3232                    &ttynr) != 1)
3233                 return -EIO;
3234
3235         *d = (dev_t) ttynr;
3236         return 0;
3237 }
3238
3239 int get_ctty(pid_t pid, dev_t *_devnr, char **r) {
3240         int k;
3241         char fn[PATH_MAX], *s, *b, *p;
3242         dev_t devnr;
3243
3244         assert(r);
3245
3246         k = get_ctty_devnr(pid, &devnr);
3247         if (k < 0)
3248                 return k;
3249
3250         snprintf(fn, sizeof(fn), "/dev/char/%u:%u", major(devnr), minor(devnr));
3251         char_array_0(fn);
3252
3253         if ((k = readlink_malloc(fn, &s)) < 0) {
3254
3255                 if (k != -ENOENT)
3256                         return k;
3257
3258                 /* This is an ugly hack */
3259                 if (major(devnr) == 136) {
3260                         if (asprintf(&b, "pts/%lu", (unsigned long) minor(devnr)) < 0)
3261                                 return -ENOMEM;
3262
3263                         *r = b;
3264                         if (_devnr)
3265                                 *_devnr = devnr;
3266
3267                         return 0;
3268                 }
3269
3270                 /* Probably something like the ptys which have no
3271                  * symlink in /dev/char. Let's return something
3272                  * vaguely useful. */
3273
3274                 if (!(b = strdup(fn + 5)))
3275                         return -ENOMEM;
3276
3277                 *r = b;
3278                 if (_devnr)
3279                         *_devnr = devnr;
3280
3281                 return 0;
3282         }
3283
3284         if (startswith(s, "/dev/"))
3285                 p = s + 5;
3286         else if (startswith(s, "../"))
3287                 p = s + 3;
3288         else
3289                 p = s;
3290
3291         b = strdup(p);
3292         free(s);
3293
3294         if (!b)
3295                 return -ENOMEM;
3296
3297         *r = b;
3298         if (_devnr)
3299                 *_devnr = devnr;
3300
3301         return 0;
3302 }
3303
3304 int rm_rf_children_dangerous(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
3305         DIR *d;
3306         int ret = 0;
3307
3308         assert(fd >= 0);
3309
3310         /* This returns the first error we run into, but nevertheless
3311          * tries to go on. This closes the passed fd. */
3312
3313         d = fdopendir(fd);
3314         if (!d) {
3315                 close_nointr_nofail(fd);
3316
3317                 return errno == ENOENT ? 0 : -errno;
3318         }
3319
3320         for (;;) {
3321                 struct dirent *de;
3322                 union dirent_storage buf;
3323                 bool is_dir, keep_around;
3324                 struct stat st;
3325                 int r;
3326
3327                 r = readdir_r(d, &buf.de, &de);
3328                 if (r != 0 && ret == 0) {
3329                         ret = -r;
3330                         break;
3331                 }
3332
3333                 if (!de)
3334                         break;
3335
3336                 if (streq(de->d_name, ".") || streq(de->d_name, ".."))
3337                         continue;
3338
3339                 if (de->d_type == DT_UNKNOWN ||
3340                     honour_sticky ||
3341                     (de->d_type == DT_DIR && root_dev)) {
3342                         if (fstatat(fd, de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
3343                                 if (ret == 0 && errno != ENOENT)
3344                                         ret = -errno;
3345                                 continue;
3346                         }
3347
3348                         is_dir = S_ISDIR(st.st_mode);
3349                         keep_around =
3350                                 honour_sticky &&
3351                                 (st.st_uid == 0 || st.st_uid == getuid()) &&
3352                                 (st.st_mode & S_ISVTX);
3353                 } else {
3354                         is_dir = de->d_type == DT_DIR;
3355                         keep_around = false;
3356                 }
3357
3358                 if (is_dir) {
3359                         int subdir_fd;
3360
3361                         /* if root_dev is set, remove subdirectories only, if device is same as dir */
3362                         if (root_dev && st.st_dev != root_dev->st_dev)
3363                                 continue;
3364
3365                         subdir_fd = openat(fd, de->d_name,
3366                                            O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
3367                         if (subdir_fd < 0) {
3368                                 if (ret == 0 && errno != ENOENT)
3369                                         ret = -errno;
3370                                 continue;
3371                         }
3372
3373                         r = rm_rf_children_dangerous(subdir_fd, only_dirs, honour_sticky, root_dev);
3374                         if (r < 0 && ret == 0)
3375                                 ret = r;
3376
3377                         if (!keep_around)
3378                                 if (unlinkat(fd, de->d_name, AT_REMOVEDIR) < 0) {
3379                                         if (ret == 0 && errno != ENOENT)
3380                                                 ret = -errno;
3381                                 }
3382
3383                 } else if (!only_dirs && !keep_around) {
3384
3385                         if (unlinkat(fd, de->d_name, 0) < 0) {
3386                                 if (ret == 0 && errno != ENOENT)
3387                                         ret = -errno;
3388                         }
3389                 }
3390         }
3391
3392         closedir(d);
3393
3394         return ret;
3395 }
3396
3397 int rm_rf_children(int fd, bool only_dirs, bool honour_sticky, struct stat *root_dev) {
3398         struct statfs s;
3399
3400         assert(fd >= 0);
3401
3402         if (fstatfs(fd, &s) < 0) {
3403                 close_nointr_nofail(fd);
3404                 return -errno;
3405         }
3406
3407         /* We refuse to clean disk file systems with this call. This
3408          * is extra paranoia just to be sure we never ever remove
3409          * non-state data */
3410
3411         if (s.f_type != TMPFS_MAGIC &&
3412             s.f_type != RAMFS_MAGIC) {
3413                 log_error("Attempted to remove disk file system, and we can't allow that.");
3414                 close_nointr_nofail(fd);
3415                 return -EPERM;
3416         }
3417
3418         return rm_rf_children_dangerous(fd, only_dirs, honour_sticky, root_dev);
3419 }
3420
3421 static int rm_rf_internal(const char *path, bool only_dirs, bool delete_root, bool honour_sticky, bool dangerous) {
3422         int fd, r;
3423         struct statfs s;
3424
3425         assert(path);
3426
3427         /* We refuse to clean the root file system with this
3428          * call. This is extra paranoia to never cause a really
3429          * seriously broken system. */
3430         if (path_equal(path, "/")) {
3431                 log_error("Attempted to remove entire root file system, and we can't allow that.");
3432                 return -EPERM;
3433         }
3434
3435         fd = open(path, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME);
3436         if (fd < 0) {
3437
3438                 if (errno != ENOTDIR)
3439                         return -errno;
3440
3441                 if (!dangerous) {
3442                         if (statfs(path, &s) < 0)
3443                                 return -errno;
3444
3445                         if (s.f_type != TMPFS_MAGIC &&
3446                             s.f_type != RAMFS_MAGIC) {
3447                                 log_error("Attempted to remove disk file system, and we can't allow that.");
3448                                 return -EPERM;
3449                         }
3450                 }
3451
3452                 if (delete_root && !only_dirs)
3453                         if (unlink(path) < 0 && errno != ENOENT)
3454                                 return -errno;
3455
3456                 return 0;
3457         }
3458
3459         if (!dangerous) {
3460                 if (fstatfs(fd, &s) < 0) {
3461                         close_nointr_nofail(fd);
3462                         return -errno;
3463                 }
3464
3465                 if (s.f_type != TMPFS_MAGIC &&
3466                     s.f_type != RAMFS_MAGIC) {
3467                         log_error("Attempted to remove disk file system, and we can't allow that.");
3468                         close_nointr_nofail(fd);
3469                         return -EPERM;
3470                 }
3471         }
3472
3473         r = rm_rf_children_dangerous(fd, only_dirs, honour_sticky, NULL);
3474         if (delete_root) {
3475
3476                 if (honour_sticky && file_is_priv_sticky(path) > 0)
3477                         return r;
3478
3479                 if (rmdir(path) < 0 && errno != ENOENT) {
3480                         if (r == 0)
3481                                 r = -errno;
3482                 }
3483         }
3484
3485         return r;
3486 }
3487
3488 int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
3489         return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, false);
3490 }
3491
3492 int rm_rf_dangerous(const char *path, bool only_dirs, bool delete_root, bool honour_sticky) {
3493         return rm_rf_internal(path, only_dirs, delete_root, honour_sticky, true);
3494 }
3495
3496 int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
3497         assert(path);
3498
3499         /* Under the assumption that we are running privileged we
3500          * first change the access mode and only then hand out
3501          * ownership to avoid a window where access is too open. */
3502
3503         if (mode != (mode_t) -1)
3504                 if (chmod(path, mode) < 0)
3505                         return -errno;
3506
3507         if (uid != (uid_t) -1 || gid != (gid_t) -1)
3508                 if (chown(path, uid, gid) < 0)
3509                         return -errno;
3510
3511         return 0;
3512 }
3513
3514 int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
3515         assert(fd >= 0);
3516
3517         /* Under the assumption that we are running privileged we
3518          * first change the access mode and only then hand out
3519          * ownership to avoid a window where access is too open. */
3520
3521         if (fchmod(fd, mode) < 0)
3522                 return -errno;
3523
3524         if (fchown(fd, uid, gid) < 0)
3525                 return -errno;
3526
3527         return 0;
3528 }
3529
3530 cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
3531         cpu_set_t *r;
3532         unsigned n = 1024;
3533
3534         /* Allocates the cpuset in the right size */
3535
3536         for (;;) {
3537                 if (!(r = CPU_ALLOC(n)))
3538                         return NULL;
3539
3540                 if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), r) >= 0) {
3541                         CPU_ZERO_S(CPU_ALLOC_SIZE(n), r);
3542
3543                         if (ncpus)
3544                                 *ncpus = n;
3545
3546                         return r;
3547                 }
3548
3549                 CPU_FREE(r);
3550
3551                 if (errno != EINVAL)
3552                         return NULL;
3553
3554                 n *= 2;
3555         }
3556 }
3557
3558 int status_vprintf(const char *status, bool ellipse, const char *format, va_list ap) {
3559         static const char status_indent[] = "         "; /* "[" STATUS "] " */
3560         _cleanup_free_ char *s = NULL;
3561         _cleanup_close_ int fd = -1;
3562         struct iovec iovec[5];
3563         int n = 0;
3564
3565         assert(format);
3566
3567         /* This is independent of logging, as status messages are
3568          * optional and go exclusively to the console. */
3569
3570         if (vasprintf(&s, format, ap) < 0)
3571                 return log_oom();
3572
3573         fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
3574         if (fd < 0)
3575                 return fd;
3576
3577         if (ellipse) {
3578                 char *e;
3579                 size_t emax, sl;
3580                 int c;
3581
3582                 c = fd_columns(fd);
3583                 if (c <= 0)
3584                         c = 80;
3585
3586                 sl = status ? sizeof(status_indent)-1 : 0;
3587
3588                 emax = c - sl - 1;
3589                 if (emax < 3)
3590                         emax = 3;
3591
3592                 e = ellipsize(s, emax, 75);
3593                 if (e) {
3594                         free(s);
3595                         s = e;
3596                 }
3597         }
3598
3599         zero(iovec);
3600
3601         if (status) {
3602                 if (!isempty(status)) {
3603                         IOVEC_SET_STRING(iovec[n++], "[");
3604                         IOVEC_SET_STRING(iovec[n++], status);
3605                         IOVEC_SET_STRING(iovec[n++], "] ");
3606                 } else
3607                         IOVEC_SET_STRING(iovec[n++], status_indent);
3608         }
3609
3610         IOVEC_SET_STRING(iovec[n++], s);
3611         IOVEC_SET_STRING(iovec[n++], "\n");
3612
3613         if (writev(fd, iovec, n) < 0)
3614                 return -errno;
3615
3616         return 0;
3617 }
3618
3619 int status_printf(const char *status, bool ellipse, const char *format, ...) {
3620         va_list ap;
3621         int r;
3622
3623         assert(format);
3624
3625         va_start(ap, format);
3626         r = status_vprintf(status, ellipse, format, ap);
3627         va_end(ap);
3628
3629         return r;
3630 }
3631
3632 int status_welcome(void) {
3633         int r;
3634         _cleanup_free_ char *pretty_name = NULL, *ansi_color = NULL;
3635
3636         r = parse_env_file("/etc/os-release", NEWLINE,
3637                            "PRETTY_NAME", &pretty_name,
3638                            "ANSI_COLOR", &ansi_color,
3639                            NULL);
3640         if (r < 0 && r != -ENOENT)
3641                 log_warning("Failed to read /etc/os-release: %s", strerror(-r));
3642
3643         return status_printf(NULL, false,
3644                              "\nWelcome to \x1B[%sm%s\x1B[0m!\n",
3645                              isempty(ansi_color) ? "1" : ansi_color,
3646                              isempty(pretty_name) ? "Linux" : pretty_name);
3647 }
3648
3649 char *replace_env(const char *format, char **env) {
3650         enum {
3651                 WORD,
3652                 CURLY,
3653                 VARIABLE
3654         } state = WORD;
3655
3656         const char *e, *word = format;
3657         char *r = NULL, *k;
3658
3659         assert(format);
3660
3661         for (e = format; *e; e ++) {
3662
3663                 switch (state) {
3664
3665                 case WORD:
3666                         if (*e == '$')
3667                                 state = CURLY;
3668                         break;
3669
3670                 case CURLY:
3671                         if (*e == '{') {
3672                                 if (!(k = strnappend(r, word, e-word-1)))
3673                                         goto fail;
3674
3675                                 free(r);
3676                                 r = k;
3677
3678                                 word = e-1;
3679                                 state = VARIABLE;
3680
3681                         } else if (*e == '$') {
3682                                 if (!(k = strnappend(r, word, e-word)))
3683                                         goto fail;
3684
3685                                 free(r);
3686                                 r = k;
3687
3688                                 word = e+1;
3689                                 state = WORD;
3690                         } else
3691                                 state = WORD;
3692                         break;
3693
3694                 case VARIABLE:
3695                         if (*e == '}') {
3696                                 const char *t;
3697
3698                                 if (!(t = strv_env_get_with_length(env, word+2, e-word-2)))
3699                                         t = "";
3700
3701                                 if (!(k = strappend(r, t)))
3702                                         goto fail;
3703
3704                                 free(r);
3705                                 r = k;
3706
3707                                 word = e+1;
3708                                 state = WORD;
3709                         }
3710                         break;
3711                 }
3712         }
3713
3714         if (!(k = strnappend(r, word, e-word)))
3715                 goto fail;
3716
3717         free(r);
3718         return k;
3719
3720 fail:
3721         free(r);
3722         return NULL;
3723 }
3724
3725 char **replace_env_argv(char **argv, char **env) {
3726         char **r, **i;
3727         unsigned k = 0, l = 0;
3728
3729         l = strv_length(argv);
3730
3731         if (!(r = new(char*, l+1)))
3732                 return NULL;
3733
3734         STRV_FOREACH(i, argv) {
3735
3736                 /* If $FOO appears as single word, replace it by the split up variable */
3737                 if ((*i)[0] == '$' && (*i)[1] != '{') {
3738                         char *e;
3739                         char **w, **m;
3740                         unsigned q;
3741
3742                         if ((e = strv_env_get(env, *i+1))) {
3743
3744                                 if (!(m = strv_split_quoted(e))) {
3745                                         r[k] = NULL;
3746                                         strv_free(r);
3747                                         return NULL;
3748                                 }
3749                         } else
3750                                 m = NULL;
3751
3752                         q = strv_length(m);
3753                         l = l + q - 1;
3754
3755                         if (!(w = realloc(r, sizeof(char*) * (l+1)))) {
3756                                 r[k] = NULL;
3757                                 strv_free(r);
3758                                 strv_free(m);
3759                                 return NULL;
3760                         }
3761
3762                         r = w;
3763                         if (m) {
3764                                 memcpy(r + k, m, q * sizeof(char*));
3765                                 free(m);
3766                         }
3767
3768                         k += q;
3769                         continue;
3770                 }
3771
3772                 /* If ${FOO} appears as part of a word, replace it by the variable as-is */
3773                 if (!(r[k++] = replace_env(*i, env))) {
3774                         strv_free(r);
3775                         return NULL;
3776                 }
3777         }
3778
3779         r[k] = NULL;
3780         return r;
3781 }
3782
3783 int fd_columns(int fd) {
3784         struct winsize ws;
3785         zero(ws);
3786
3787         if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3788                 return -errno;
3789
3790         if (ws.ws_col <= 0)
3791                 return -EIO;
3792
3793         return ws.ws_col;
3794 }
3795
3796 static unsigned columns_cached(bool cached) {
3797         static __thread int env_columns = -1;
3798         const char *e;
3799
3800         if (_likely_(parsed_columns > 0 && cached))
3801                 return parsed_columns;
3802
3803         if (_unlikely_(env_columns == -1)) {
3804                 e = getenv("COLUMNS");
3805                 if (e)
3806                         env_columns = atoi(e);
3807                 else
3808                         env_columns = 0;
3809         }
3810
3811         if (env_columns > 0) {
3812                 parsed_columns = env_columns;
3813                 return parsed_columns;
3814         }
3815
3816         if (parsed_columns <= 0 || !cached)
3817                 parsed_columns = fd_columns(STDOUT_FILENO);
3818
3819         if (parsed_columns <= 0)
3820                 parsed_columns = 80;
3821
3822         return parsed_columns;
3823 }
3824
3825 unsigned columns(void) {
3826         return columns_cached(true);
3827 }
3828
3829 unsigned columns_uncached(void) {
3830         return columns_cached(false);
3831 }
3832
3833 /* intended to be used as a SIGWINCH sighandler */
3834 void columns_cache_reset(int signum) {
3835         parsed_columns = 0;
3836 }
3837
3838 int fd_lines(int fd) {
3839         struct winsize ws;
3840         zero(ws);
3841
3842         if (ioctl(fd, TIOCGWINSZ, &ws) < 0)
3843                 return -errno;
3844
3845         if (ws.ws_row <= 0)
3846                 return -EIO;
3847
3848         return ws.ws_row;
3849 }
3850
3851 unsigned lines(void) {
3852         static __thread int parsed_lines = 0;
3853         const char *e;
3854
3855         if (_likely_(parsed_lines > 0))
3856                 return parsed_lines;
3857
3858         e = getenv("LINES");
3859         if (e)
3860                 parsed_lines = atoi(e);
3861
3862         if (parsed_lines <= 0)
3863                 parsed_lines = fd_lines(STDOUT_FILENO);
3864
3865         if (parsed_lines <= 0)
3866                 parsed_lines = 25;
3867
3868         return parsed_lines;
3869 }
3870
3871 int running_in_chroot(void) {
3872         struct stat a, b;
3873
3874         zero(a);
3875         zero(b);
3876
3877         /* Only works as root */
3878
3879         if (stat("/proc/1/root", &a) < 0)
3880                 return -errno;
3881
3882         if (stat("/", &b) < 0)
3883                 return -errno;
3884
3885         return
3886                 a.st_dev != b.st_dev ||
3887                 a.st_ino != b.st_ino;
3888 }
3889
3890 char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
3891         size_t x;
3892         char *r;
3893
3894         assert(s);
3895         assert(percent <= 100);
3896         assert(new_length >= 3);
3897
3898         if (old_length <= 3 || old_length <= new_length)
3899                 return strndup(s, old_length);
3900
3901         r = new0(char, new_length+1);
3902         if (!r)
3903                 return r;
3904
3905         x = (new_length * percent) / 100;
3906
3907         if (x > new_length - 3)
3908                 x = new_length - 3;
3909
3910         memcpy(r, s, x);
3911         r[x] = '.';
3912         r[x+1] = '.';
3913         r[x+2] = '.';
3914         memcpy(r + x + 3,
3915                s + old_length - (new_length - x - 3),
3916                new_length - x - 3);
3917
3918         return r;
3919 }
3920
3921 char *ellipsize(const char *s, size_t length, unsigned percent) {
3922         return ellipsize_mem(s, strlen(s), length, percent);
3923 }
3924
3925 int touch(const char *path) {
3926         int fd;
3927
3928         assert(path);
3929
3930         /* This just opens the file for writing, ensuring it
3931          * exists. It doesn't call utimensat() the way /usr/bin/touch
3932          * does it. */
3933
3934         fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY, 0644);
3935         if (fd < 0)
3936                 return -errno;
3937
3938         close_nointr_nofail(fd);
3939         return 0;
3940 }
3941
3942 char *unquote(const char *s, const char* quotes) {
3943         size_t l;
3944         assert(s);
3945
3946         /* This is rather stupid, simply removes the heading and
3947          * trailing quotes if there is one. Doesn't care about
3948          * escaping or anything. We should make this smarter one
3949          * day...*/
3950
3951         l = strlen(s);
3952         if (l < 2)
3953                 return strdup(s);
3954
3955         if (strchr(quotes, s[0]) && s[l-1] == s[0])
3956                 return strndup(s+1, l-2);
3957
3958         return strdup(s);
3959 }
3960
3961 char *normalize_env_assignment(const char *s) {
3962         _cleanup_free_ char *name = NULL, *value = NULL, *p = NULL;
3963         char *eq, *r;
3964
3965         eq = strchr(s, '=');
3966         if (!eq) {
3967                 char *t;
3968
3969                 r = strdup(s);
3970                 if (!r)
3971                         return NULL;
3972
3973                 t = strstrip(r);
3974                 if (t == r)
3975                         return r;
3976
3977                 memmove(r, t, strlen(t) + 1);
3978                 return r;
3979         }
3980
3981         name = strndup(s, eq - s);
3982         if (!name)
3983                 return NULL;
3984
3985         p = strdup(eq + 1);
3986         if (!p)
3987                 return NULL;
3988
3989         value = unquote(strstrip(p), QUOTES);
3990         if (!value)
3991                 return NULL;
3992
3993         if (asprintf(&r, "%s=%s", strstrip(name), value) < 0)
3994                 r = NULL;
3995
3996         return r;
3997 }
3998
3999 int wait_for_terminate(pid_t pid, siginfo_t *status) {
4000         siginfo_t dummy;
4001
4002         assert(pid >= 1);
4003
4004         if (!status)
4005                 status = &dummy;
4006
4007         for (;;) {
4008                 zero(*status);
4009
4010                 if (waitid(P_PID, pid, status, WEXITED) < 0) {
4011
4012                         if (errno == EINTR)
4013                                 continue;
4014
4015                         return -errno;
4016                 }
4017
4018                 return 0;
4019         }
4020 }
4021
4022 int wait_for_terminate_and_warn(const char *name, pid_t pid) {
4023         int r;
4024         siginfo_t status;
4025
4026         assert(name);
4027         assert(pid > 1);
4028
4029         r = wait_for_terminate(pid, &status);
4030         if (r < 0) {
4031                 log_warning("Failed to wait for %s: %s", name, strerror(-r));
4032                 return r;
4033         }
4034
4035         if (status.si_code == CLD_EXITED) {
4036                 if (status.si_status != 0) {
4037                         log_warning("%s failed with error code %i.", name, status.si_status);
4038                         return status.si_status;
4039                 }
4040
4041                 log_debug("%s succeeded.", name);
4042                 return 0;
4043
4044         } else if (status.si_code == CLD_KILLED ||
4045                    status.si_code == CLD_DUMPED) {
4046
4047                 log_warning("%s terminated by signal %s.", name, signal_to_string(status.si_status));
4048                 return -EPROTO;
4049         }
4050
4051         log_warning("%s failed due to unknown reason.", name);
4052         return -EPROTO;
4053 }
4054
4055 _noreturn_ void freeze(void) {
4056
4057         /* Make sure nobody waits for us on a socket anymore */
4058         close_all_fds(NULL, 0);
4059
4060         sync();
4061
4062         for (;;)
4063                 pause();
4064 }
4065
4066 bool null_or_empty(struct stat *st) {
4067         assert(st);
4068
4069         if (S_ISREG(st->st_mode) && st->st_size <= 0)
4070                 return true;
4071
4072         if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
4073                 return true;
4074
4075         return false;
4076 }
4077
4078 int null_or_empty_path(const char *fn) {
4079         struct stat st;
4080
4081         assert(fn);
4082
4083         if (stat(fn, &st) < 0)
4084                 return -errno;
4085
4086         return null_or_empty(&st);
4087 }
4088
4089 DIR *xopendirat(int fd, const char *name, int flags) {
4090         int nfd;
4091         DIR *d;
4092
4093         nfd = openat(fd, name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags);
4094         if (nfd < 0)
4095                 return NULL;
4096
4097         d = fdopendir(nfd);
4098         if (!d) {
4099                 close_nointr_nofail(nfd);
4100                 return NULL;
4101         }
4102
4103         return d;
4104 }
4105
4106 int signal_from_string_try_harder(const char *s) {
4107         int signo;
4108         assert(s);
4109
4110         signo = signal_from_string(s);
4111         if (signo <= 0)
4112                 if (startswith(s, "SIG"))
4113                         return signal_from_string(s+3);
4114
4115         return signo;
4116 }
4117
4118 void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t) {
4119
4120         assert(f);
4121         assert(name);
4122         assert(t);
4123
4124         if (!dual_timestamp_is_set(t))
4125                 return;
4126
4127         fprintf(f, "%s=%llu %llu\n",
4128                 name,
4129                 (unsigned long long) t->realtime,
4130                 (unsigned long long) t->monotonic);
4131 }
4132
4133 void dual_timestamp_deserialize(const char *value, dual_timestamp *t) {
4134         unsigned long long a, b;
4135
4136         assert(value);
4137         assert(t);
4138
4139         if (sscanf(value, "%lli %llu", &a, &b) != 2)
4140                 log_debug("Failed to parse finish timestamp value %s", value);
4141         else {
4142                 t->realtime = a;
4143                 t->monotonic = b;
4144         }
4145 }
4146
4147 static char *tag_to_udev_node(const char *tagvalue, const char *by) {
4148         char *dn, *t, *u;
4149         int r;
4150
4151         /* FIXME: to follow udev's logic 100% we need to leave valid
4152          * UTF8 chars unescaped */
4153
4154         u = unquote(tagvalue, "\"\'");
4155         if (u == NULL)
4156                 return NULL;
4157
4158         t = xescape(u, "/ ");
4159         free(u);
4160
4161         if (t == NULL)
4162                 return NULL;
4163
4164         r = asprintf(&dn, "/dev/disk/by-%s/%s", by, t);
4165         free(t);
4166
4167         if (r < 0)
4168                 return NULL;
4169
4170         return dn;
4171 }
4172
4173 char *fstab_node_to_udev_node(const char *p) {
4174         assert(p);
4175
4176         if (startswith(p, "LABEL="))
4177                 return tag_to_udev_node(p+6, "label");
4178
4179         if (startswith(p, "UUID="))
4180                 return tag_to_udev_node(p+5, "uuid");
4181
4182         if (startswith(p, "PARTUUID="))
4183                 return tag_to_udev_node(p+9, "partuuid");
4184
4185         if (startswith(p, "PARTLABEL="))
4186                 return tag_to_udev_node(p+10, "partlabel");
4187
4188         return strdup(p);
4189 }
4190
4191 bool tty_is_vc(const char *tty) {
4192         assert(tty);
4193
4194         if (startswith(tty, "/dev/"))
4195                 tty += 5;
4196
4197         return vtnr_from_tty(tty) >= 0;
4198 }
4199
4200 bool tty_is_console(const char *tty) {
4201         assert(tty);
4202
4203         if (startswith(tty, "/dev/"))
4204                 tty += 5;
4205
4206         return streq(tty, "console");
4207 }
4208
4209 int vtnr_from_tty(const char *tty) {
4210         int i, r;
4211
4212         assert(tty);
4213
4214         if (startswith(tty, "/dev/"))
4215                 tty += 5;
4216
4217         if (!startswith(tty, "tty") )
4218                 return -EINVAL;
4219
4220         if (tty[3] < '0' || tty[3] > '9')
4221                 return -EINVAL;
4222
4223         r = safe_atoi(tty+3, &i);
4224         if (r < 0)
4225                 return r;
4226
4227         if (i < 0 || i > 63)
4228                 return -EINVAL;
4229
4230         return i;
4231 }
4232
4233 bool tty_is_vc_resolve(const char *tty) {
4234         char *active = NULL;
4235         bool b;
4236
4237         assert(tty);
4238
4239         if (startswith(tty, "/dev/"))
4240                 tty += 5;
4241
4242         /* Resolve where /dev/console is pointing to, if /sys is
4243          * actually ours (i.e. not read-only-mounted which is a sign
4244          * for container setups) */
4245         if (streq(tty, "console") && path_is_read_only_fs("/sys") <= 0)
4246                 if (read_one_line_file("/sys/class/tty/console/active", &active) >= 0) {
4247                         /* If multiple log outputs are configured the
4248                          * last one is what /dev/console points to */
4249                         tty = strrchr(active, ' ');
4250                         if (tty)
4251                                 tty++;
4252                         else
4253                                 tty = active;
4254                 }
4255
4256         b = tty_is_vc(tty);
4257         free(active);
4258
4259         return b;
4260 }
4261
4262 const char *default_term_for_tty(const char *tty) {
4263         assert(tty);
4264
4265         return tty_is_vc_resolve(tty) ? "TERM=linux" : "TERM=vt102";
4266 }
4267
4268 bool dirent_is_file(const struct dirent *de) {
4269         assert(de);
4270
4271         if (ignore_file(de->d_name))
4272                 return false;
4273
4274         if (de->d_type != DT_REG &&
4275             de->d_type != DT_LNK &&
4276             de->d_type != DT_UNKNOWN)
4277                 return false;
4278
4279         return true;
4280 }
4281
4282 bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
4283         assert(de);
4284
4285         if (de->d_type != DT_REG &&
4286             de->d_type != DT_LNK &&
4287             de->d_type != DT_UNKNOWN)
4288                 return false;
4289
4290         if (ignore_file_allow_backup(de->d_name))
4291                 return false;
4292
4293         return endswith(de->d_name, suffix);
4294 }
4295
4296 void execute_directory(const char *directory, DIR *d, char *argv[]) {
4297         DIR *_d = NULL;
4298         struct dirent *de;
4299         Hashmap *pids = NULL;
4300
4301         assert(directory);
4302
4303         /* Executes all binaries in a directory in parallel and waits
4304          * until all they all finished. */
4305
4306         if (!d) {
4307                 if (!(_d = opendir(directory))) {
4308
4309                         if (errno == ENOENT)
4310                                 return;
4311
4312                         log_error("Failed to enumerate directory %s: %m", directory);
4313                         return;
4314                 }
4315
4316                 d = _d;
4317         }
4318
4319         if (!(pids = hashmap_new(trivial_hash_func, trivial_compare_func))) {
4320                 log_error("Failed to allocate set.");
4321                 goto finish;
4322         }
4323
4324         while ((de = readdir(d))) {
4325                 char *path;
4326                 pid_t pid;
4327                 int k;
4328
4329                 if (!dirent_is_file(de))
4330                         continue;
4331
4332                 if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) {
4333                         log_oom();
4334                         continue;
4335                 }
4336
4337                 if ((pid = fork()) < 0) {
4338                         log_error("Failed to fork: %m");
4339                         free(path);
4340                         continue;
4341                 }
4342
4343                 if (pid == 0) {
4344                         char *_argv[2];
4345                         /* Child */
4346
4347                         if (!argv) {
4348                                 _argv[0] = path;
4349                                 _argv[1] = NULL;
4350                                 argv = _argv;
4351                         } else
4352                                 argv[0] = path;
4353
4354                         execv(path, argv);
4355
4356                         log_error("Failed to execute %s: %m", path);
4357                         _exit(EXIT_FAILURE);
4358                 }
4359
4360                 log_debug("Spawned %s as %lu", path, (unsigned long) pid);
4361
4362                 if ((k = hashmap_put(pids, UINT_TO_PTR(pid), path)) < 0) {
4363                         log_error("Failed to add PID to set: %s", strerror(-k));
4364                         free(path);
4365                 }
4366         }
4367
4368         while (!hashmap_isempty(pids)) {
4369                 pid_t pid = PTR_TO_UINT(hashmap_first_key(pids));
4370                 siginfo_t si;
4371                 char *path;
4372
4373                 zero(si);
4374                 if (waitid(P_PID, pid, &si, WEXITED) < 0) {
4375
4376                         if (errno == EINTR)
4377                                 continue;
4378
4379                         log_error("waitid() failed: %m");
4380                         goto finish;
4381                 }
4382
4383                 if ((path = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)))) {
4384                         if (!is_clean_exit(si.si_code, si.si_status, NULL)) {
4385                                 if (si.si_code == CLD_EXITED)
4386                                         log_error("%s exited with exit status %i.", path, si.si_status);
4387                                 else
4388                                         log_error("%s terminated by signal %s.", path, signal_to_string(si.si_status));
4389                         } else
4390                                 log_debug("%s exited successfully.", path);
4391
4392                         free(path);
4393                 }
4394         }
4395
4396 finish:
4397         if (_d)
4398                 closedir(_d);
4399
4400         if (pids)
4401                 hashmap_free_free(pids);
4402 }
4403
4404 int kill_and_sigcont(pid_t pid, int sig) {
4405         int r;
4406
4407         r = kill(pid, sig) < 0 ? -errno : 0;
4408
4409         if (r >= 0)
4410                 kill(pid, SIGCONT);
4411
4412         return r;
4413 }
4414
4415 bool nulstr_contains(const char*nulstr, const char *needle) {
4416         const char *i;
4417
4418         if (!nulstr)
4419                 return false;
4420
4421         NULSTR_FOREACH(i, nulstr)
4422                 if (streq(i, needle))
4423                         return true;
4424
4425         return false;
4426 }
4427
4428 bool plymouth_running(void) {
4429         return access("/run/plymouth/pid", F_OK) >= 0;
4430 }
4431
4432 char* strshorten(char *s, size_t l) {
4433         assert(s);
4434
4435         if (l < strlen(s))
4436                 s[l] = 0;
4437
4438         return s;
4439 }
4440
4441 static bool hostname_valid_char(char c) {
4442         return
4443                 (c >= 'a' && c <= 'z') ||
4444                 (c >= 'A' && c <= 'Z') ||
4445                 (c >= '0' && c <= '9') ||
4446                 c == '-' ||
4447                 c == '_' ||
4448                 c == '.';
4449 }
4450
4451 bool hostname_is_valid(const char *s) {
4452         const char *p;
4453
4454         if (isempty(s))
4455                 return false;
4456
4457         for (p = s; *p; p++)
4458                 if (!hostname_valid_char(*p))
4459                         return false;
4460
4461         if (p-s > HOST_NAME_MAX)
4462                 return false;
4463
4464         return true;
4465 }
4466
4467 char* hostname_cleanup(char *s) {
4468         char *p, *d;
4469
4470         for (p = s, d = s; *p; p++)
4471                 if ((*p >= 'a' && *p <= 'z') ||
4472                     (*p >= 'A' && *p <= 'Z') ||
4473                     (*p >= '0' && *p <= '9') ||
4474                     *p == '-' ||
4475                     *p == '_' ||
4476                     *p == '.')
4477                         *(d++) = *p;
4478
4479         *d = 0;
4480
4481         strshorten(s, HOST_NAME_MAX);
4482         return s;
4483 }
4484
4485 int pipe_eof(int fd) {
4486         struct pollfd pollfd;
4487         int r;
4488
4489         zero(pollfd);
4490         pollfd.fd = fd;
4491         pollfd.events = POLLIN|POLLHUP;
4492
4493         r = poll(&pollfd, 1, 0);
4494         if (r < 0)
4495                 return -errno;
4496
4497         if (r == 0)
4498                 return 0;
4499
4500         return pollfd.revents & POLLHUP;
4501 }
4502
4503 int fd_wait_for_event(int fd, int event, usec_t t) {
4504         struct pollfd pollfd;
4505         int r;
4506
4507         zero(pollfd);
4508         pollfd.fd = fd;
4509         pollfd.events = event;
4510
4511         r = poll(&pollfd, 1, t == (usec_t) -1 ? -1 : (int) (t / USEC_PER_MSEC));
4512         if (r < 0)
4513                 return -errno;
4514
4515         if (r == 0)
4516                 return 0;
4517
4518         return pollfd.revents;
4519 }
4520
4521 int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
4522         FILE *f;
4523         char *t;
4524         const char *fn;
4525         size_t k;
4526         int fd;
4527
4528         assert(path);
4529         assert(_f);
4530         assert(_temp_path);
4531
4532         t = new(char, strlen(path) + 1 + 6 + 1);
4533         if (!t)
4534                 return -ENOMEM;
4535
4536         fn = path_get_file_name(path);
4537         k = fn-path;
4538         memcpy(t, path, k);
4539         t[k] = '.';
4540         stpcpy(stpcpy(t+k+1, fn), "XXXXXX");
4541
4542         fd = mkostemp(t, O_WRONLY|O_CLOEXEC);
4543         if (fd < 0) {
4544                 free(t);
4545                 return -errno;
4546         }
4547
4548         f = fdopen(fd, "we");
4549         if (!f) {
4550                 unlink(t);
4551                 free(t);
4552                 return -errno;
4553         }
4554
4555         *_f = f;
4556         *_temp_path = t;
4557
4558         return 0;
4559 }
4560
4561 int terminal_vhangup_fd(int fd) {
4562         assert(fd >= 0);
4563
4564         if (ioctl(fd, TIOCVHANGUP) < 0)
4565                 return -errno;
4566
4567         return 0;
4568 }
4569
4570 int terminal_vhangup(const char *name) {
4571         int fd, r;
4572
4573         fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4574         if (fd < 0)
4575                 return fd;
4576
4577         r = terminal_vhangup_fd(fd);
4578         close_nointr_nofail(fd);
4579
4580         return r;
4581 }
4582
4583 int vt_disallocate(const char *name) {
4584         int fd, r;
4585         unsigned u;
4586
4587         /* Deallocate the VT if possible. If not possible
4588          * (i.e. because it is the active one), at least clear it
4589          * entirely (including the scrollback buffer) */
4590
4591         if (!startswith(name, "/dev/"))
4592                 return -EINVAL;
4593
4594         if (!tty_is_vc(name)) {
4595                 /* So this is not a VT. I guess we cannot deallocate
4596                  * it then. But let's at least clear the screen */
4597
4598                 fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4599                 if (fd < 0)
4600                         return fd;
4601
4602                 loop_write(fd,
4603                            "\033[r"    /* clear scrolling region */
4604                            "\033[H"    /* move home */
4605                            "\033[2J",  /* clear screen */
4606                            10, false);
4607                 close_nointr_nofail(fd);
4608
4609                 return 0;
4610         }
4611
4612         if (!startswith(name, "/dev/tty"))
4613                 return -EINVAL;
4614
4615         r = safe_atou(name+8, &u);
4616         if (r < 0)
4617                 return r;
4618
4619         if (u <= 0)
4620                 return -EINVAL;
4621
4622         /* Try to deallocate */
4623         fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
4624         if (fd < 0)
4625                 return fd;
4626
4627         r = ioctl(fd, VT_DISALLOCATE, u);
4628         close_nointr_nofail(fd);
4629
4630         if (r >= 0)
4631                 return 0;
4632
4633         if (errno != EBUSY)
4634                 return -errno;
4635
4636         /* Couldn't deallocate, so let's clear it fully with
4637          * scrollback */
4638         fd = open_terminal(name, O_RDWR|O_NOCTTY|O_CLOEXEC);
4639         if (fd < 0)
4640                 return fd;
4641
4642         loop_write(fd,
4643                    "\033[r"   /* clear scrolling region */
4644                    "\033[H"   /* move home */
4645                    "\033[3J", /* clear screen including scrollback, requires Linux 2.6.40 */
4646                    10, false);
4647         close_nointr_nofail(fd);
4648
4649         return 0;
4650 }
4651
4652 int copy_file(const char *from, const char *to) {
4653         int r, fdf, fdt;
4654
4655         assert(from);
4656         assert(to);
4657
4658         fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
4659         if (fdf < 0)
4660                 return -errno;
4661
4662         fdt = open(to, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY, 0644);
4663         if (fdt < 0) {
4664                 close_nointr_nofail(fdf);
4665                 return -errno;
4666         }
4667
4668         for (;;) {
4669                 char buf[PIPE_BUF];
4670                 ssize_t n, k;
4671
4672                 n = read(fdf, buf, sizeof(buf));
4673                 if (n < 0) {
4674                         r = -errno;
4675
4676                         close_nointr_nofail(fdf);
4677                         close_nointr(fdt);
4678                         unlink(to);
4679
4680                         return r;
4681                 }
4682
4683                 if (n == 0)
4684                         break;
4685
4686                 errno = 0;
4687                 k = loop_write(fdt, buf, n, false);
4688                 if (n != k) {
4689                         r = k < 0 ? k : (errno ? -errno : -EIO);
4690
4691                         close_nointr_nofail(fdf);
4692                         close_nointr(fdt);
4693
4694                         unlink(to);
4695                         return r;
4696                 }
4697         }
4698
4699         close_nointr_nofail(fdf);
4700         r = close_nointr(fdt);
4701
4702         if (r < 0) {
4703                 unlink(to);
4704                 return r;
4705         }
4706
4707         return 0;
4708 }
4709
4710 int symlink_atomic(const char *from, const char *to) {
4711         char *x;
4712         _cleanup_free_ char *t;
4713         const char *fn;
4714         size_t k;
4715         unsigned long long ull;
4716         unsigned i;
4717         int r;
4718
4719         assert(from);
4720         assert(to);
4721
4722         t = new(char, strlen(to) + 1 + 16 + 1);
4723         if (!t)
4724                 return -ENOMEM;
4725
4726         fn = path_get_file_name(to);
4727         k = fn-to;
4728         memcpy(t, to, k);
4729         t[k] = '.';
4730         x = stpcpy(t+k+1, fn);
4731
4732         ull = random_ull();
4733         for (i = 0; i < 16; i++) {
4734                 *(x++) = hexchar(ull & 0xF);
4735                 ull >>= 4;
4736         }
4737
4738         *x = 0;
4739
4740         if (symlink(from, t) < 0)
4741                 return -errno;
4742
4743         if (rename(t, to) < 0) {
4744                 r = -errno;
4745                 unlink(t);
4746                 return r;
4747         }
4748
4749         return 0;
4750 }
4751
4752 bool display_is_local(const char *display) {
4753         assert(display);
4754
4755         return
4756                 display[0] == ':' &&
4757                 display[1] >= '0' &&
4758                 display[1] <= '9';
4759 }
4760
4761 int socket_from_display(const char *display, char **path) {
4762         size_t k;
4763         char *f, *c;
4764
4765         assert(display);
4766         assert(path);
4767
4768         if (!display_is_local(display))
4769                 return -EINVAL;
4770
4771         k = strspn(display+1, "0123456789");
4772
4773         f = new(char, sizeof("/tmp/.X11-unix/X") + k);
4774         if (!f)
4775                 return -ENOMEM;
4776
4777         c = stpcpy(f, "/tmp/.X11-unix/X");
4778         memcpy(c, display+1, k);
4779         c[k] = 0;
4780
4781         *path = f;
4782
4783         return 0;
4784 }
4785
4786 int get_user_creds(
4787                 const char **username,
4788                 uid_t *uid, gid_t *gid,
4789                 const char **home,
4790                 const char **shell) {
4791
4792         struct passwd *p;
4793         uid_t u;
4794
4795         assert(username);
4796         assert(*username);
4797
4798         /* We enforce some special rules for uid=0: in order to avoid
4799          * NSS lookups for root we hardcode its data. */
4800
4801         if (streq(*username, "root") || streq(*username, "0")) {
4802                 *username = "root";
4803
4804                 if (uid)
4805                         *uid = 0;
4806
4807                 if (gid)
4808                         *gid = 0;
4809
4810                 if (home)
4811                         *home = "/root";
4812
4813                 if (shell)
4814                         *shell = "/bin/sh";
4815
4816                 return 0;
4817         }
4818
4819         if (parse_uid(*username, &u) >= 0) {
4820                 errno = 0;
4821                 p = getpwuid(u);
4822
4823                 /* If there are multiple users with the same id, make
4824                  * sure to leave $USER to the configured value instead
4825                  * of the first occurrence in the database. However if
4826                  * the uid was configured by a numeric uid, then let's
4827                  * pick the real username from /etc/passwd. */
4828                 if (p)
4829                         *username = p->pw_name;
4830         } else {
4831                 errno = 0;
4832                 p = getpwnam(*username);
4833         }
4834
4835         if (!p)
4836                 return errno != 0 ? -errno : -ESRCH;
4837
4838         if (uid)
4839                 *uid = p->pw_uid;
4840
4841         if (gid)
4842                 *gid = p->pw_gid;
4843
4844         if (home)
4845                 *home = p->pw_dir;
4846
4847         if (shell)
4848                 *shell = p->pw_shell;
4849
4850         return 0;
4851 }
4852
4853 int get_group_creds(const char **groupname, gid_t *gid) {
4854         struct group *g;
4855         gid_t id;
4856
4857         assert(groupname);
4858
4859         /* We enforce some special rules for gid=0: in order to avoid
4860          * NSS lookups for root we hardcode its data. */
4861
4862         if (streq(*groupname, "root") || streq(*groupname, "0")) {
4863                 *groupname = "root";
4864
4865                 if (gid)
4866                         *gid = 0;
4867
4868                 return 0;
4869         }
4870
4871         if (parse_gid(*groupname, &id) >= 0) {
4872                 errno = 0;
4873                 g = getgrgid(id);
4874
4875                 if (g)
4876                         *groupname = g->gr_name;
4877         } else {
4878                 errno = 0;
4879                 g = getgrnam(*groupname);
4880         }
4881
4882         if (!g)
4883                 return errno != 0 ? -errno : -ESRCH;
4884
4885         if (gid)
4886                 *gid = g->gr_gid;
4887
4888         return 0;
4889 }
4890
4891 int in_group(const char *name) {
4892         gid_t gid, *gids;
4893         int ngroups_max, r, i;
4894
4895         r = get_group_creds(&name, &gid);
4896         if (r < 0)
4897                 return r;
4898
4899         if (getgid() == gid)
4900                 return 1;
4901
4902         if (getegid() == gid)
4903                 return 1;
4904
4905         ngroups_max = sysconf(_SC_NGROUPS_MAX);
4906         assert(ngroups_max > 0);
4907
4908         gids = alloca(sizeof(gid_t) * ngroups_max);
4909
4910         r = getgroups(ngroups_max, gids);
4911         if (r < 0)
4912                 return -errno;
4913
4914         for (i = 0; i < r; i++)
4915                 if (gids[i] == gid)
4916                         return 1;
4917
4918         return 0;
4919 }
4920
4921 int glob_exists(const char *path) {
4922         glob_t g;
4923         int r, k;
4924
4925         assert(path);
4926
4927         zero(g);
4928         errno = 0;
4929         k = glob(path, GLOB_NOSORT|GLOB_BRACE, NULL, &g);
4930
4931         if (k == GLOB_NOMATCH)
4932                 r = 0;
4933         else if (k == GLOB_NOSPACE)
4934                 r = -ENOMEM;
4935         else if (k == 0)
4936                 r = !strv_isempty(g.gl_pathv);
4937         else
4938                 r = errno ? -errno : -EIO;
4939
4940         globfree(&g);
4941
4942         return r;
4943 }
4944
4945 int dirent_ensure_type(DIR *d, struct dirent *de) {
4946         struct stat st;
4947
4948         assert(d);
4949         assert(de);
4950
4951         if (de->d_type != DT_UNKNOWN)
4952                 return 0;
4953
4954         if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
4955                 return -errno;
4956
4957         de->d_type =
4958                 S_ISREG(st.st_mode)  ? DT_REG  :
4959                 S_ISDIR(st.st_mode)  ? DT_DIR  :
4960                 S_ISLNK(st.st_mode)  ? DT_LNK  :
4961                 S_ISFIFO(st.st_mode) ? DT_FIFO :
4962                 S_ISSOCK(st.st_mode) ? DT_SOCK :
4963                 S_ISCHR(st.st_mode)  ? DT_CHR  :
4964                 S_ISBLK(st.st_mode)  ? DT_BLK  :
4965                                        DT_UNKNOWN;
4966
4967         return 0;
4968 }
4969
4970 int in_search_path(const char *path, char **search) {
4971         char **i, *parent;
4972         int r;
4973
4974         r = path_get_parent(path, &parent);
4975         if (r < 0)
4976                 return r;
4977
4978         r = 0;
4979
4980         STRV_FOREACH(i, search) {
4981                 if (path_equal(parent, *i)) {
4982                         r = 1;
4983                         break;
4984                 }
4985         }
4986
4987         free(parent);
4988
4989         return r;
4990 }
4991
4992 int get_files_in_directory(const char *path, char ***list) {
4993         DIR *d;
4994         int r = 0;
4995         unsigned n = 0;
4996         char **l = NULL;
4997
4998         assert(path);
4999
5000         /* Returns all files in a directory in *list, and the number
5001          * of files as return value. If list is NULL returns only the
5002          * number */
5003
5004         d = opendir(path);
5005         if (!d)
5006                 return -errno;
5007
5008         for (;;) {
5009                 struct dirent *de;
5010                 union dirent_storage buf;
5011                 int k;
5012
5013                 k = readdir_r(d, &buf.de, &de);
5014                 if (k != 0) {
5015                         r = -k;
5016                         goto finish;
5017                 }
5018
5019                 if (!de)
5020                         break;
5021
5022                 dirent_ensure_type(d, de);
5023
5024                 if (!dirent_is_file(de))
5025                         continue;
5026
5027                 if (list) {
5028                         if ((unsigned) r >= n) {
5029                                 char **t;
5030
5031                                 n = MAX(16, 2*r);
5032                                 t = realloc(l, sizeof(char*) * n);
5033                                 if (!t) {
5034                                         r = -ENOMEM;
5035                                         goto finish;
5036                                 }
5037
5038                                 l = t;
5039                         }
5040
5041                         assert((unsigned) r < n);
5042
5043                         l[r] = strdup(de->d_name);
5044                         if (!l[r]) {
5045                                 r = -ENOMEM;
5046                                 goto finish;
5047                         }
5048
5049                         l[++r] = NULL;
5050                 } else
5051                         r++;
5052         }
5053
5054 finish:
5055         if (d)
5056                 closedir(d);
5057
5058         if (r >= 0) {
5059                 if (list)
5060                         *list = l;
5061         } else
5062                 strv_free(l);
5063
5064         return r;
5065 }
5066
5067 char *strjoin(const char *x, ...) {
5068         va_list ap;
5069         size_t l;
5070         char *r, *p;
5071
5072         va_start(ap, x);
5073
5074         if (x) {
5075                 l = strlen(x);
5076
5077                 for (;;) {
5078                         const char *t;
5079                         size_t n;
5080
5081                         t = va_arg(ap, const char *);
5082                         if (!t)
5083                                 break;
5084
5085                         n = strlen(t);
5086                         if (n > ((size_t) -1) - l) {
5087                                 va_end(ap);
5088                                 return NULL;
5089                         }
5090
5091                         l += n;
5092                 }
5093         } else
5094                 l = 0;
5095
5096         va_end(ap);
5097
5098         r = new(char, l+1);
5099         if (!r)
5100                 return NULL;
5101
5102         if (x) {
5103                 p = stpcpy(r, x);
5104
5105                 va_start(ap, x);
5106
5107                 for (;;) {
5108                         const char *t;
5109
5110                         t = va_arg(ap, const char *);
5111                         if (!t)
5112                                 break;
5113
5114                         p = stpcpy(p, t);
5115                 }
5116
5117                 va_end(ap);
5118         } else
5119                 r[0] = 0;
5120
5121         return r;
5122 }
5123
5124 bool is_main_thread(void) {
5125         static __thread int cached = 0;
5126
5127         if (_unlikely_(cached == 0))
5128                 cached = getpid() == gettid() ? 1 : -1;
5129
5130         return cached > 0;
5131 }
5132
5133 int block_get_whole_disk(dev_t d, dev_t *ret) {
5134         char *p, *s;
5135         int r;
5136         unsigned n, m;
5137
5138         assert(ret);
5139
5140         /* If it has a queue this is good enough for us */
5141         if (asprintf(&p, "/sys/dev/block/%u:%u/queue", major(d), minor(d)) < 0)
5142                 return -ENOMEM;
5143
5144         r = access(p, F_OK);
5145         free(p);
5146
5147         if (r >= 0) {
5148                 *ret = d;
5149                 return 0;
5150         }
5151
5152         /* If it is a partition find the originating device */
5153         if (asprintf(&p, "/sys/dev/block/%u:%u/partition", major(d), minor(d)) < 0)
5154                 return -ENOMEM;
5155
5156         r = access(p, F_OK);
5157         free(p);
5158
5159         if (r < 0)
5160                 return -ENOENT;
5161
5162         /* Get parent dev_t */
5163         if (asprintf(&p, "/sys/dev/block/%u:%u/../dev", major(d), minor(d)) < 0)
5164                 return -ENOMEM;
5165
5166         r = read_one_line_file(p, &s);
5167         free(p);
5168
5169         if (r < 0)
5170                 return r;
5171
5172         r = sscanf(s, "%u:%u", &m, &n);
5173         free(s);
5174
5175         if (r != 2)
5176                 return -EINVAL;
5177
5178         /* Only return this if it is really good enough for us. */
5179         if (asprintf(&p, "/sys/dev/block/%u:%u/queue", m, n) < 0)
5180                 return -ENOMEM;
5181
5182         r = access(p, F_OK);
5183         free(p);
5184
5185         if (r >= 0) {
5186                 *ret = makedev(m, n);
5187                 return 0;
5188         }
5189
5190         return -ENOENT;
5191 }
5192
5193 int file_is_priv_sticky(const char *p) {
5194         struct stat st;
5195
5196         assert(p);
5197
5198         if (lstat(p, &st) < 0)
5199                 return -errno;
5200
5201         return
5202                 (st.st_uid == 0 || st.st_uid == getuid()) &&
5203                 (st.st_mode & S_ISVTX);
5204 }
5205
5206 static const char *const ioprio_class_table[] = {
5207         [IOPRIO_CLASS_NONE] = "none",
5208         [IOPRIO_CLASS_RT] = "realtime",
5209         [IOPRIO_CLASS_BE] = "best-effort",
5210         [IOPRIO_CLASS_IDLE] = "idle"
5211 };
5212
5213 DEFINE_STRING_TABLE_LOOKUP(ioprio_class, int);
5214
5215 static const char *const sigchld_code_table[] = {
5216         [CLD_EXITED] = "exited",
5217         [CLD_KILLED] = "killed",
5218         [CLD_DUMPED] = "dumped",
5219         [CLD_TRAPPED] = "trapped",
5220         [CLD_STOPPED] = "stopped",
5221         [CLD_CONTINUED] = "continued",
5222 };
5223
5224 DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
5225
5226 static const char *const log_facility_unshifted_table[LOG_NFACILITIES] = {
5227         [LOG_FAC(LOG_KERN)] = "kern",
5228         [LOG_FAC(LOG_USER)] = "user",
5229         [LOG_FAC(LOG_MAIL)] = "mail",
5230         [LOG_FAC(LOG_DAEMON)] = "daemon",
5231         [LOG_FAC(LOG_AUTH)] = "auth",
5232         [LOG_FAC(LOG_SYSLOG)] = "syslog",
5233         [LOG_FAC(LOG_LPR)] = "lpr",
5234         [LOG_FAC(LOG_NEWS)] = "news",
5235         [LOG_FAC(LOG_UUCP)] = "uucp",
5236         [LOG_FAC(LOG_CRON)] = "cron",
5237         [LOG_FAC(LOG_AUTHPRIV)] = "authpriv",
5238         [LOG_FAC(LOG_FTP)] = "ftp",
5239         [LOG_FAC(LOG_LOCAL0)] = "local0",
5240         [LOG_FAC(LOG_LOCAL1)] = "local1",
5241         [LOG_FAC(LOG_LOCAL2)] = "local2",
5242         [LOG_FAC(LOG_LOCAL3)] = "local3",
5243         [LOG_FAC(LOG_LOCAL4)] = "local4",
5244         [LOG_FAC(LOG_LOCAL5)] = "local5",
5245         [LOG_FAC(LOG_LOCAL6)] = "local6",
5246         [LOG_FAC(LOG_LOCAL7)] = "local7"
5247 };
5248
5249 DEFINE_STRING_TABLE_LOOKUP(log_facility_unshifted, int);
5250
5251 static const char *const log_level_table[] = {
5252         [LOG_EMERG] = "emerg",
5253         [LOG_ALERT] = "alert",
5254         [LOG_CRIT] = "crit",
5255         [LOG_ERR] = "err",
5256         [LOG_WARNING] = "warning",
5257         [LOG_NOTICE] = "notice",
5258         [LOG_INFO] = "info",
5259         [LOG_DEBUG] = "debug"
5260 };
5261
5262 DEFINE_STRING_TABLE_LOOKUP(log_level, int);
5263
5264 static const char* const sched_policy_table[] = {
5265         [SCHED_OTHER] = "other",
5266         [SCHED_BATCH] = "batch",
5267         [SCHED_IDLE] = "idle",
5268         [SCHED_FIFO] = "fifo",
5269         [SCHED_RR] = "rr"
5270 };
5271
5272 DEFINE_STRING_TABLE_LOOKUP(sched_policy, int);
5273
5274 static const char* const rlimit_table[] = {
5275         [RLIMIT_CPU] = "LimitCPU",
5276         [RLIMIT_FSIZE] = "LimitFSIZE",
5277         [RLIMIT_DATA] = "LimitDATA",
5278         [RLIMIT_STACK] = "LimitSTACK",
5279         [RLIMIT_CORE] = "LimitCORE",
5280         [RLIMIT_RSS] = "LimitRSS",
5281         [RLIMIT_NOFILE] = "LimitNOFILE",
5282         [RLIMIT_AS] = "LimitAS",
5283         [RLIMIT_NPROC] = "LimitNPROC",
5284         [RLIMIT_MEMLOCK] = "LimitMEMLOCK",
5285         [RLIMIT_LOCKS] = "LimitLOCKS",
5286         [RLIMIT_SIGPENDING] = "LimitSIGPENDING",
5287         [RLIMIT_MSGQUEUE] = "LimitMSGQUEUE",
5288         [RLIMIT_NICE] = "LimitNICE",
5289         [RLIMIT_RTPRIO] = "LimitRTPRIO",
5290         [RLIMIT_RTTIME] = "LimitRTTIME"
5291 };
5292
5293 DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
5294
5295 static const char* const ip_tos_table[] = {
5296         [IPTOS_LOWDELAY] = "low-delay",
5297         [IPTOS_THROUGHPUT] = "throughput",
5298         [IPTOS_RELIABILITY] = "reliability",
5299         [IPTOS_LOWCOST] = "low-cost",
5300 };
5301
5302 DEFINE_STRING_TABLE_LOOKUP(ip_tos, int);
5303
5304 static const char *const __signal_table[] = {
5305         [SIGHUP] = "HUP",
5306         [SIGINT] = "INT",
5307         [SIGQUIT] = "QUIT",
5308         [SIGILL] = "ILL",
5309         [SIGTRAP] = "TRAP",
5310         [SIGABRT] = "ABRT",
5311         [SIGBUS] = "BUS",
5312         [SIGFPE] = "FPE",
5313         [SIGKILL] = "KILL",
5314         [SIGUSR1] = "USR1",
5315         [SIGSEGV] = "SEGV",
5316         [SIGUSR2] = "USR2",
5317         [SIGPIPE] = "PIPE",
5318         [SIGALRM] = "ALRM",
5319         [SIGTERM] = "TERM",
5320 #ifdef SIGSTKFLT
5321         [SIGSTKFLT] = "STKFLT",  /* Linux on SPARC doesn't know SIGSTKFLT */
5322 #endif
5323         [SIGCHLD] = "CHLD",
5324         [SIGCONT] = "CONT",
5325         [SIGSTOP] = "STOP",
5326         [SIGTSTP] = "TSTP",
5327         [SIGTTIN] = "TTIN",
5328         [SIGTTOU] = "TTOU",
5329         [SIGURG] = "URG",
5330         [SIGXCPU] = "XCPU",
5331         [SIGXFSZ] = "XFSZ",
5332         [SIGVTALRM] = "VTALRM",
5333         [SIGPROF] = "PROF",
5334         [SIGWINCH] = "WINCH",
5335         [SIGIO] = "IO",
5336         [SIGPWR] = "PWR",
5337         [SIGSYS] = "SYS"
5338 };
5339
5340 DEFINE_PRIVATE_STRING_TABLE_LOOKUP(__signal, int);
5341
5342 const char *signal_to_string(int signo) {
5343         static __thread char buf[12];
5344         const char *name;
5345
5346         name = __signal_to_string(signo);
5347         if (name)
5348                 return name;
5349
5350         if (signo >= SIGRTMIN && signo <= SIGRTMAX)
5351                 snprintf(buf, sizeof(buf) - 1, "RTMIN+%d", signo - SIGRTMIN);
5352         else
5353                 snprintf(buf, sizeof(buf) - 1, "%d", signo);
5354         char_array_0(buf);
5355         return buf;
5356 }
5357
5358 int signal_from_string(const char *s) {
5359         int signo;
5360         int offset = 0;
5361         unsigned u;
5362
5363         signo = __signal_from_string(s);
5364         if (signo > 0)
5365                 return signo;
5366
5367         if (startswith(s, "RTMIN+")) {
5368                 s += 6;
5369                 offset = SIGRTMIN;
5370         }
5371         if (safe_atou(s, &u) >= 0) {
5372                 signo = (int) u + offset;
5373                 if (signo > 0 && signo < _NSIG)
5374                         return signo;
5375         }
5376         return -1;
5377 }
5378
5379 bool kexec_loaded(void) {
5380        bool loaded = false;
5381        char *s;
5382
5383        if (read_one_line_file("/sys/kernel/kexec_loaded", &s) >= 0) {
5384                if (s[0] == '1')
5385                        loaded = true;
5386                free(s);
5387        }
5388        return loaded;
5389 }
5390
5391 int strdup_or_null(const char *a, char **b) {
5392         char *c;
5393
5394         assert(b);
5395
5396         if (!a) {
5397                 *b = NULL;
5398                 return 0;
5399         }
5400
5401         c = strdup(a);
5402         if (!c)
5403                 return -ENOMEM;
5404
5405         *b = c;
5406         return 0;
5407 }
5408
5409 int prot_from_flags(int flags) {
5410
5411         switch (flags & O_ACCMODE) {
5412
5413         case O_RDONLY:
5414                 return PROT_READ;
5415
5416         case O_WRONLY:
5417                 return PROT_WRITE;
5418
5419         case O_RDWR:
5420                 return PROT_READ|PROT_WRITE;
5421
5422         default:
5423                 return -EINVAL;
5424         }
5425 }
5426
5427 char *format_bytes(char *buf, size_t l, off_t t) {
5428         unsigned i;
5429
5430         static const struct {
5431                 const char *suffix;
5432                 off_t factor;
5433         } table[] = {
5434                 { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
5435                 { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
5436                 { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
5437                 { "G", 1024ULL*1024ULL*1024ULL },
5438                 { "M", 1024ULL*1024ULL },
5439                 { "K", 1024ULL },
5440         };
5441
5442         for (i = 0; i < ELEMENTSOF(table); i++) {
5443
5444                 if (t >= table[i].factor) {
5445                         snprintf(buf, l,
5446                                  "%llu.%llu%s",
5447                                  (unsigned long long) (t / table[i].factor),
5448                                  (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
5449                                  table[i].suffix);
5450
5451                         goto finish;
5452                 }
5453         }
5454
5455         snprintf(buf, l, "%lluB", (unsigned long long) t);
5456
5457 finish:
5458         buf[l-1] = 0;
5459         return buf;
5460
5461 }
5462
5463 void* memdup(const void *p, size_t l) {
5464         void *r;
5465
5466         assert(p);
5467
5468         r = malloc(l);
5469         if (!r)
5470                 return NULL;
5471
5472         memcpy(r, p, l);
5473         return r;
5474 }
5475
5476 int fd_inc_sndbuf(int fd, size_t n) {
5477         int r, value;
5478         socklen_t l = sizeof(value);
5479
5480         r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
5481         if (r >= 0 &&
5482             l == sizeof(value) &&
5483             (size_t) value >= n*2)
5484                 return 0;
5485
5486         value = (int) n;
5487         r = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value));
5488         if (r < 0)
5489                 return -errno;
5490
5491         return 1;
5492 }
5493
5494 int fd_inc_rcvbuf(int fd, size_t n) {
5495         int r, value;
5496         socklen_t l = sizeof(value);
5497
5498         r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
5499         if (r >= 0 &&
5500             l == sizeof(value) &&
5501             (size_t) value >= n*2)
5502                 return 0;
5503
5504         value = (int) n;
5505         r = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value));
5506         if (r < 0)
5507                 return -errno;
5508
5509         return 1;
5510 }
5511
5512 int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
5513         pid_t parent_pid, agent_pid;
5514         int fd;
5515         bool stdout_is_tty, stderr_is_tty;
5516         unsigned n, i;
5517         va_list ap;
5518         char **l;
5519
5520         assert(pid);
5521         assert(path);
5522
5523         parent_pid = getpid();
5524
5525         /* Spawns a temporary TTY agent, making sure it goes away when
5526          * we go away */
5527
5528         agent_pid = fork();
5529         if (agent_pid < 0)
5530                 return -errno;
5531
5532         if (agent_pid != 0) {
5533                 *pid = agent_pid;
5534                 return 0;
5535         }
5536
5537         /* In the child:
5538          *
5539          * Make sure the agent goes away when the parent dies */
5540         if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
5541                 _exit(EXIT_FAILURE);
5542
5543         /* Check whether our parent died before we were able
5544          * to set the death signal */
5545         if (getppid() != parent_pid)
5546                 _exit(EXIT_SUCCESS);
5547
5548         /* Don't leak fds to the agent */
5549         close_all_fds(except, n_except);
5550
5551         stdout_is_tty = isatty(STDOUT_FILENO);
5552         stderr_is_tty = isatty(STDERR_FILENO);
5553
5554         if (!stdout_is_tty || !stderr_is_tty) {
5555                 /* Detach from stdout/stderr. and reopen
5556                  * /dev/tty for them. This is important to
5557                  * ensure that when systemctl is started via
5558                  * popen() or a similar call that expects to
5559                  * read EOF we actually do generate EOF and
5560                  * not delay this indefinitely by because we
5561                  * keep an unused copy of stdin around. */
5562                 fd = open("/dev/tty", O_WRONLY);
5563                 if (fd < 0) {
5564                         log_error("Failed to open /dev/tty: %m");
5565                         _exit(EXIT_FAILURE);
5566                 }
5567
5568                 if (!stdout_is_tty)
5569                         dup2(fd, STDOUT_FILENO);
5570
5571                 if (!stderr_is_tty)
5572                         dup2(fd, STDERR_FILENO);
5573
5574                 if (fd > 2)
5575                         close(fd);
5576         }
5577
5578         /* Count arguments */
5579         va_start(ap, path);
5580         for (n = 0; va_arg(ap, char*); n++)
5581                 ;
5582         va_end(ap);
5583
5584         /* Allocate strv */
5585         l = alloca(sizeof(char *) * (n + 1));
5586
5587         /* Fill in arguments */
5588         va_start(ap, path);
5589         for (i = 0; i <= n; i++)
5590                 l[i] = va_arg(ap, char*);
5591         va_end(ap);
5592
5593         execv(path, l);
5594         _exit(EXIT_FAILURE);
5595 }
5596
5597 int setrlimit_closest(int resource, const struct rlimit *rlim) {
5598         struct rlimit highest, fixed;
5599
5600         assert(rlim);
5601
5602         if (setrlimit(resource, rlim) >= 0)
5603                 return 0;
5604
5605         if (errno != EPERM)
5606                 return -errno;
5607
5608         /* So we failed to set the desired setrlimit, then let's try
5609          * to get as close as we can */
5610         assert_se(getrlimit(resource, &highest) == 0);
5611
5612         fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max);
5613         fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max);
5614
5615         if (setrlimit(resource, &fixed) < 0)
5616                 return -errno;
5617
5618         return 0;
5619 }
5620
5621 int getenv_for_pid(pid_t pid, const char *field, char **_value) {
5622         char path[sizeof("/proc/")-1+10+sizeof("/environ")], *value = NULL;
5623         int r;
5624         FILE *f;
5625         bool done = false;
5626         size_t l;
5627
5628         assert(field);
5629         assert(_value);
5630
5631         if (pid == 0)
5632                 pid = getpid();
5633
5634         snprintf(path, sizeof(path), "/proc/%lu/environ", (unsigned long) pid);
5635         char_array_0(path);
5636
5637         f = fopen(path, "re");
5638         if (!f)
5639                 return -errno;
5640
5641         l = strlen(field);
5642         r = 0;
5643
5644         do {
5645                 char line[LINE_MAX];
5646                 unsigned i;
5647
5648                 for (i = 0; i < sizeof(line)-1; i++) {
5649                         int c;
5650
5651                         c = getc(f);
5652                         if (_unlikely_(c == EOF)) {
5653                                 done = true;
5654                                 break;
5655                         } else if (c == 0)
5656                                 break;
5657
5658                         line[i] = c;
5659                 }
5660                 line[i] = 0;
5661
5662                 if (memcmp(line, field, l) == 0 && line[l] == '=') {
5663                         value = strdup(line + l + 1);
5664                         if (!value) {
5665                                 r = -ENOMEM;
5666                                 break;
5667                         }
5668
5669                         r = 1;
5670                         break;
5671                 }
5672
5673         } while (!done);
5674
5675         fclose(f);
5676
5677         if (r >= 0)
5678                 *_value = value;
5679
5680         return r;
5681 }
5682
5683 int can_sleep(const char *type) {
5684         char *w, *state;
5685         size_t l, k;
5686         int r;
5687         _cleanup_free_ char *p = NULL;
5688
5689         assert(type);
5690
5691         r = read_one_line_file("/sys/power/state", &p);
5692         if (r < 0)
5693                 return r == -ENOENT ? 0 : r;
5694
5695         k = strlen(type);
5696         FOREACH_WORD_SEPARATOR(w, l, p, WHITESPACE, state)
5697                 if (l == k && memcmp(w, type, l) == 0)
5698                         return true;
5699
5700         return false;
5701 }
5702
5703 bool is_valid_documentation_url(const char *url) {
5704         assert(url);
5705
5706         if (startswith(url, "http://") && url[7])
5707                 return true;
5708
5709         if (startswith(url, "https://") && url[8])
5710                 return true;
5711
5712         if (startswith(url, "file:") && url[5])
5713                 return true;
5714
5715         if (startswith(url, "info:") && url[5])
5716                 return true;
5717
5718         if (startswith(url, "man:") && url[4])
5719                 return true;
5720
5721         return false;
5722 }
5723
5724 bool in_initrd(void) {
5725         static __thread int saved = -1;
5726         struct statfs s;
5727
5728         if (saved >= 0)
5729                 return saved;
5730
5731         /* We make two checks here:
5732          *
5733          * 1. the flag file /etc/initrd-release must exist
5734          * 2. the root file system must be a memory file system
5735          *
5736          * The second check is extra paranoia, since misdetecting an
5737          * initrd can have bad bad consequences due the initrd
5738          * emptying when transititioning to the main systemd.
5739          */
5740
5741         saved = access("/etc/initrd-release", F_OK) >= 0 &&
5742                 statfs("/", &s) >= 0 &&
5743                 (s.f_type == TMPFS_MAGIC || s.f_type == RAMFS_MAGIC);
5744
5745         return saved;
5746 }
5747
5748 void warn_melody(void) {
5749         _cleanup_close_ int fd = -1;
5750
5751         fd = open("/dev/console", O_WRONLY|O_CLOEXEC|O_NOCTTY);
5752         if (fd < 0)
5753                 return;
5754
5755         /* Yeah, this is synchronous. Kinda sucks. But well... */
5756
5757         ioctl(fd, KIOCSOUND, (int)(1193180/440));
5758         usleep(125*USEC_PER_MSEC);
5759
5760         ioctl(fd, KIOCSOUND, (int)(1193180/220));
5761         usleep(125*USEC_PER_MSEC);
5762
5763         ioctl(fd, KIOCSOUND, (int)(1193180/220));
5764         usleep(125*USEC_PER_MSEC);
5765
5766         ioctl(fd, KIOCSOUND, 0);
5767 }
5768
5769 int make_console_stdio(void) {
5770         int fd, r;
5771
5772         /* Make /dev/console the controlling terminal and stdin/stdout/stderr */
5773
5774         fd = acquire_terminal("/dev/console", false, true, true, (usec_t) -1);
5775         if (fd < 0) {
5776                 log_error("Failed to acquire terminal: %s", strerror(-fd));
5777                 return fd;
5778         }
5779
5780         r = make_stdio(fd);
5781         if (r < 0) {
5782                 log_error("Failed to duplicate terminal fd: %s", strerror(-r));
5783                 return r;
5784         }
5785
5786         return 0;
5787 }
5788
5789 int get_home_dir(char **_h) {
5790         char *h;
5791         const char *e;
5792         uid_t u;
5793         struct passwd *p;
5794
5795         assert(_h);
5796
5797         /* Take the user specified one */
5798         e = getenv("HOME");
5799         if (e) {
5800                 h = strdup(e);
5801                 if (!h)
5802                         return -ENOMEM;
5803
5804                 *_h = h;
5805                 return 0;
5806         }
5807
5808         /* Hardcode home directory for root to avoid NSS */
5809         u = getuid();
5810         if (u == 0) {
5811                 h = strdup("/root");
5812                 if (!h)
5813                         return -ENOMEM;
5814
5815                 *_h = h;
5816                 return 0;
5817         }
5818
5819         /* Check the database... */
5820         errno = 0;
5821         p = getpwuid(u);
5822         if (!p)
5823                 return errno ? -errno : -ESRCH;
5824
5825         if (!path_is_absolute(p->pw_dir))
5826                 return -EINVAL;
5827
5828         h = strdup(p->pw_dir);
5829         if (!h)
5830                 return -ENOMEM;
5831
5832         *_h = h;
5833         return 0;
5834 }
5835
5836 int get_shell(char **_sh) {
5837         char *sh;
5838         const char *e;
5839         uid_t u;
5840         struct passwd *p;
5841
5842         assert(_sh);
5843
5844         /* Take the user specified one */
5845         e = getenv("SHELL");
5846         if (e) {
5847                 sh = strdup(e);
5848                 if (!sh)
5849                         return -ENOMEM;
5850
5851                 *_sh = sh;
5852                 return 0;
5853         }
5854
5855         /* Hardcode home directory for root to avoid NSS */
5856         u = getuid();
5857         if (u == 0) {
5858                 sh = strdup("/bin/sh");
5859                 if (!sh)
5860                         return -ENOMEM;
5861
5862                 *_sh = sh;
5863                 return 0;
5864         }
5865
5866         /* Check the database... */
5867         errno = 0;
5868         p = getpwuid(u);
5869         if (!p)
5870                 return errno ? -errno : -ESRCH;
5871
5872         if (!path_is_absolute(p->pw_shell))
5873                 return -EINVAL;
5874
5875         sh = strdup(p->pw_shell);
5876         if (!sh)
5877                 return -ENOMEM;
5878
5879         *_sh = sh;
5880         return 0;
5881 }
5882
5883 void freep(void *p) {
5884         free(*(void**) p);
5885 }
5886
5887 void fclosep(FILE **f) {
5888         if (*f)
5889                 fclose(*f);
5890 }
5891
5892 void closep(int *fd) {
5893         if (*fd >= 0)
5894                 close_nointr_nofail(*fd);
5895 }
5896
5897 void closedirp(DIR **d) {
5898         if (*d)
5899                 closedir(*d);
5900 }
5901
5902 void umaskp(mode_t *u) {
5903         umask(*u);
5904 }
5905
5906 bool filename_is_safe(const char *p) {
5907
5908         if (isempty(p))
5909                 return false;
5910
5911         if (strchr(p, '/'))
5912                 return false;
5913
5914         if (streq(p, "."))
5915                 return false;
5916
5917         if (streq(p, ".."))
5918                 return false;
5919
5920         if (strlen(p) > FILENAME_MAX)
5921                 return false;
5922
5923         return true;
5924 }
5925
5926 bool string_is_safe(const char *p) {
5927         const char *t;
5928
5929         assert(p);
5930
5931         for (t = p; *t; t++) {
5932                 if (*t < ' ')
5933                         return false;
5934
5935                 if (strchr("\\\"\'", *t))
5936                         return false;
5937         }
5938
5939         return true;
5940 }
5941
5942 int parse_timestamp(const char *t, usec_t *usec) {
5943         const char *k;
5944         struct tm tm, copy;
5945         time_t x;
5946         usec_t plus = 0, minus = 0, ret;
5947         int r;
5948
5949         /*
5950          * Allowed syntaxes:
5951          *
5952          *   2012-09-22 16:34:22
5953          *   2012-09-22 16:34     (seconds will be set to 0)
5954          *   2012-09-22           (time will be set to 00:00:00)
5955          *   16:34:22             (date will be set to today)
5956          *   16:34                (date will be set to today, seconds to 0)
5957          *   now
5958          *   yesterday            (time is set to 00:00:00)
5959          *   today                (time is set to 00:00:00)
5960          *   tomorrow             (time is set to 00:00:00)
5961          *   +5min
5962          *   -5days
5963          *
5964          */
5965
5966         assert(t);
5967         assert(usec);
5968
5969         x = time(NULL);
5970         assert_se(localtime_r(&x, &tm));
5971
5972         if (streq(t, "now"))
5973                 goto finish;
5974
5975         else if (streq(t, "today")) {
5976                 tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
5977                 goto finish;
5978
5979         } else if (streq(t, "yesterday")) {
5980                 tm.tm_mday --;
5981                 tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
5982                 goto finish;
5983
5984         } else if (streq(t, "tomorrow")) {
5985                 tm.tm_mday ++;
5986                 tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
5987                 goto finish;
5988
5989         } else if (t[0] == '+') {
5990
5991                 r = parse_usec(t+1, &plus);
5992                 if (r < 0)
5993                         return r;
5994
5995                 goto finish;
5996         } else if (t[0] == '-') {
5997
5998                 r = parse_usec(t+1, &minus);
5999                 if (r < 0)
6000                         return r;
6001
6002                 goto finish;
6003         }
6004
6005         copy = tm;
6006         k = strptime(t, "%y-%m-%d %H:%M:%S", &tm);
6007         if (k && *k == 0)
6008                 goto finish;
6009
6010         tm = copy;
6011         k = strptime(t, "%Y-%m-%d %H:%M:%S", &tm);
6012         if (k && *k == 0)
6013                 goto finish;
6014
6015         tm = copy;
6016         k = strptime(t, "%y-%m-%d %H:%M", &tm);
6017         if (k && *k == 0) {
6018                 tm.tm_sec = 0;
6019                 goto finish;
6020         }
6021
6022         tm = copy;
6023         k = strptime(t, "%Y-%m-%d %H:%M", &tm);
6024         if (k && *k == 0) {
6025                 tm.tm_sec = 0;
6026                 goto finish;
6027         }
6028
6029         tm = copy;
6030         k = strptime(t, "%y-%m-%d", &tm);
6031         if (k && *k == 0) {
6032                 tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
6033                 goto finish;
6034         }
6035
6036         tm = copy;
6037         k = strptime(t, "%Y-%m-%d", &tm);
6038         if (k && *k == 0) {
6039                 tm.tm_sec = tm.tm_min = tm.tm_hour = 0;
6040                 goto finish;
6041         }
6042
6043         tm = copy;
6044         k = strptime(t, "%H:%M:%S", &tm);
6045         if (k && *k == 0)
6046                 goto finish;
6047
6048         tm = copy;
6049         k = strptime(t, "%H:%M", &tm);
6050         if (k && *k == 0) {
6051                 tm.tm_sec = 0;
6052                 goto finish;
6053         }
6054
6055         return -EINVAL;
6056
6057 finish:
6058         x = mktime(&tm);
6059         if (x == (time_t) -1)
6060                 return -EINVAL;
6061
6062         ret = (usec_t) x * USEC_PER_SEC;
6063
6064         ret += plus;
6065         if (ret > minus)
6066                 ret -= minus;
6067         else
6068                 ret = 0;
6069
6070         *usec = ret;
6071
6072         return 0;
6073 }