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